美文网首页
pa-metis文档阅读

pa-metis文档阅读

作者: 不想当社畜 | 来源:发表于2018-12-26 18:26 被阅读0次

parmetis功能介绍

英语能力有限,使用的是谷歌翻译.

切分图

ParMETIS V3 PartKway是PARMETIS中用于分区非结构化图形的例程。该例程采用图表并计算k路分区(其中k等于期望的子域的数量),同时试图最小化由分区切割的边缘的数量(即,边缘切割)。 ParMETIS V3 PartKway不假设图表最初如何在处理器之间分配。它可以有效地划分随机分布的图形以及分布良好的图形1。如果图表最初在处理器之间分配得很好,那么ParMETIS V3 PartKway将花费更少的时间来运行。但是,计算分区的质量不依赖于初始分布。

ParMETIS V3 PartKway中使用的并行图分区算法基于串行多级k-
[6,7]中描述的并且在[4,14]中并行化的分区算法。已经证明该算法可以快速产生非常高质量的分区。它由三个阶段组成:图形粗化,初始分区和非粗化/细化。在图粗化阶段,通过将输入图的相邻顶点折叠在一起来构造一系列图,以便形成相关的较粗略图。初始分区的计算是在这些图的最粗糙(并因此最小)上执行的,因此非常快。最后,使用KL / FM类型细化算法[2,9]在每个级别图上执行分区细化,从最粗糙到最精细(即原始图)。图2说明了多级图分区范例。

PARMETIS提供了ParMETIS V3 PartGeomKway例程,用于计算从有限元网格派生的图形的分区,其中顶点具有与之关联的坐标。给定一个分布在处理器和顶点坐标之间的图形,ParMETIS V3 PartGeomKway使用空间填充曲线方法快速计算初始分区,根据此分区重新分配图形,然后调用ParMETIS V3 PartKway来计算最终的高质量分区。我们的实验表明,ParMETIS V3 PartGeomKway通常比ParMETIS V3 PartKway快两倍,并且具有相同的分区质量。请注意,根据图形从底层网格构造的方式,坐标可以对应于网格的实际节点坐标(节点图)或元素中心坐标的坐标(双图)。

PARMETIS还提供ParMETIS V3 PartGeom函数,用于在顶点坐标可用时对非结构化图形进行分区。 ParMETIS V3 PartGeom仅根据空间填充曲线方法计算分区。因此,它非常快(通常比ParMETIS V3 PartGeomKway快5到10倍),但它计算质量差的分区(它可能比ParMETIS V3 PartGeomKway削减2到10倍的边缘)。该例程对于某些计算是有用的,其中空间填充曲线的使用是适当的分区技术(例如,n体计算)。

切分网格(可以直接切分网格 原因本质还是调用切分图形的那一套程序)

PARMETIS还提供了支持计算分区和重新分区的例程,给定网格(而不是图形)作为输入。 特别是,ParMETIS V3 PartMeshKway将网格作为输入并计算网格元素的分区。 在内部,ParMETIS V3 PartMeshKway使用网格到图形例程,然后调用ParMETIS V3 PartKway使用的相同核心分区例程。
PARMETIS没有提供直接从网格计算自适应重新分区的例程。 然而,它确实提供了常规的ParMETIS V3 Mesh2Dual,用于在给定网格的情况下快速并行地构建双图。 由于双图的构造是并行的,因此可以用它来构造ParMETIS V3 AdaptiveRepart的输入图。

分区自适应精化网格(由于在科学计算中需要观察局部细节 此时就需要对局部进行加密处理,加密后需要重新分区 不然导致负载不平衡)

对于大规模科学模拟,依赖于全局精化网格的技术的计算要求变得非常高,尤其是随着问题的复杂性和大小的增加。通过局部细化和去细化网格以捕获感兴趣的流场现象[1]或考虑到误差的变化[11],自适应方法使标准计算方法更具成本效益。在并行计算机上有效执行这种自适应科学模拟需要对底层计算网格进行周期性重新分区。这些重新分区应最小化迭代基于网格的计算中产生的处理器间通信以及平衡负载所需的数据重新分配成本。因此,自适应重新分区是一个多目标优化问题。 PARMETIS提供常规的ParMETIS V3 AdaptiveRepart,用于重新分配这种适应性细化的网格。该例程假设网格在处理器之间分布良好,但是(由于网格细化和去细化)这种分布很差地负载平衡。

重新分区算法分为两大类。 第一类通过将具有更多工作的子域的负载递增地扩散到具有较少工作的相邻子域来平衡计算。 这些方案称为扩散方案。 第二类通过计算全新的分区来平衡负载,然后智能地将新分区的子域映射到处理器,从而最小化再分配成本。 这些方案通常称为重映射方案。 重新映射方案通常会导致重新分区具有较小的边缘削减,而扩散方案会导致重新分配,从而导致较小的再分配成本。 但是,由于这些结果在不同类型的应用程序之间可能会有很大差异,因此很难为作业选择最佳的重新分区方案。

ParMETIS V3 AdaptiveRepart是用于自适应重新分区的统一重新分区算法[15]的并行实现,它结合了重映射和基于扩散的重新分区方案的最佳特性。 该算法使用的关键参数是ITR因子。 此参数描述了执行并行处理期间发生的处理器间通信所需的时间与执行与平衡负载相关的数据重新分配的时间之间的比率。 因此,它允许我们计算描述重新分区质量的单个度量,即使自适应重新分区是多目标优化问题。

ParMETIS V3 AdaptiveRepart基于多级分区算法,因此本质上类似于ParMETIS V3 PartKway中实现的算法。然而,该例程使用称为局部粗化的技术。这里,只有分布在同一处理器上的顶点被粗化在一起。在最粗糙的图上,不需要计算初始分区,因为可以从初始图分布中导出(在子域耦合到处理器的情况下),或者需要将其作为输入提供给例程(在子域从处理器解耦的情况下)。但是,这种分区确实需要平衡。通过替代方法在最粗糙的图上执行两次平衡阶段。也就是说,重映射和扩散算法的优化变体[16]都用于计算新的分区。然后计算每个这些分区的质量度量(使用ITR因子),并选择具有最高质量的分区。无论重新分配问题的类型或ITR因子的值如何,该技术都倾向于提供非常好的点,从中开始多级细化。请注意,只要最粗糙图的大小适当小,算法计算两个初始分区的事实不会影响其可伸缩性[8]。最后,对平衡分区进行多级细化,以进一步提高其质量。由于ParMETIS V3 AdaptiveRepart从已经分布良好的图形开始,因此速度非常快。

可以根据执行(i)自上次重新分区以来发生的所有处理器间通信所需的时间,以及(ii)与上次重新分区/加载相关的数据重新分配,轻松确定为ITR因子参数传递的适当值。 平衡阶段。 只需将第一次除以第二次。 结果是正确的ITR因子。 如果无法确定这些时间(例如,对于第一次重新分配/负载平衡阶段),我们的实验已经表明,100到1000之间的值适用于各种情况。

ParMETIS V3 AdaptiveRepart可用于在网格自适应之前或之后对网格进行负载平衡。 在后一种情况下,每个处理器首先在本地调整其网格,从而导致具有不同数量元素的不同处理器。 然后,ParMETIS V3 AdaptiveRepart可以计算负载平衡的分区。 然而,如果可以先验地估计每个元素的细化程度,则也可以在自适应之前完成负载平衡。 也就是说,如果我们提前知道每个旧元素将细分多少个新元素,我们可以使用这些估计作为对应于网格对偶的图的顶点权重。 在这种情况下,可以在进行适配之前重新分配网格。 这种技术可以显着减少数据重新分配时间[10]。

分区细化(对已经分好区进行再次的精细分区)

ParMETIS V3 RefineKway是PARMETIS提供的用于提高现有分区质量的例程。 一旦图形被分区(并相应地重新分配),就可以调用ParMETIS V3 RefineKway来计算新的分区,从而进一步提高质量。 ParMETIS V3 RefineKway可用于提高由其他分区算法产生的分区质量(例如在ParMETIS V3 PartGeom中使用的第3.1节中讨论的技术)。 ParMETIS V3 RefineKway也可以反复使用,以进一步提高分区的质量。 但是,每次连续调用ParMETIS V3 RefineKway都会产生较小的质量改进。

多相和多物理计算的分区(在科学计算的过程中,不是每个节点都是只有一种属性 有些有温度场 位移场 电磁场)

传统的图分区问题公式在可以有效建模的应用类型中受到限制,因为它规定只有一个数量是负载平衡的。 许多重要类型的多相和多物理计算需要同时对多个量进行负载平衡。 这是因为计算的不同阶段之间存在同步步骤,因此,每个阶段必须单独地进行负载平衡。 也就是说,简单地总结每个阶段所需的相对时间并基于该总和来计算分区是不够的。 这样做可能会导致某些处理器在计算的一个阶段中有太多工作(因此,在其他处理器空闲之后,这些处理器可能仍在工作),而在另一个处理器期间则没有足够的工作。 相反,每个处理器在每个计算阶段都有相同的工作量是至关重要的。

两个例子是粒子在细胞[17]和接触碰撞模拟[3]。图3显示了这些模拟所需的分区特征。图3(a)显示了用于细胞内粒子计算的网格。假设同步将基于网格的计算与粒子计算分开,则需要进行分区以平衡网格元素的数量和子域之间的粒子数量。图3(b)显示了用于接触碰撞模拟的网格。在接触检测阶段期间,仅在表面(即,浅阴影)元件上执行计算,而在冲击阶段期间,对所有元件执行计算。因此,为了确保两个阶段都是负载平衡的,分区必须平衡网格元素的总数和跨子域的表面元素的数量。图3(b)中的固体分区就是这样做的。虚线分区类似于传统图分区器可能计算的分区。此分区仅平衡网格元素的总数。表面元素不平衡超过50%。

在[6]中提出了图分区问题的新公式,其能够模拟同时平衡多个计算阶段的问题,同时还最小化处理器间通信。 在该公式中,大小为m的权重向量被分配给图的每个顶点。 然后,多约束图分区问题是计算分区,使得边切最小化并且每个子域具有与每个顶点权重大致相同的量。 ParMETIS V3 PartKway,ParMETIS V3 PartGeomKway,ParMETIS V3 RefineKway和ParMETIS V3 AdaptiveRepart例程都能够计算满足多个平衡约束的分区。

图4给出了图3中所示的单元格粒子网格的双重图。每个顶点在这里有两个权重。第一个表示与相应元素的基于网格的计算相关的工作。 (这些都是因为我们在这种情况下假设所有元素都具有与它们相关的基于网格的相同数量的工作。)第二个权重表示与基于粒子的计算相关的工作。 该值由每个元素内的粒子数估算。 显示了多约束分区,以平衡这两个权重。

异构计算体系结构的分区

复杂的异构计算平台,例如通过高带宽和高延迟互连网络松散连接的紧密耦合的共享内存节点组,和/或具有复杂内存层次结构的处理节点,正变得越来越普遍,因为它们具有竞争力 成本 - 性能比。 地理位置分散的平台也是如此。 大多数现有的并行仿真代码可以轻松地移植到各种并行架构,因为它们采用标准消息传递层,如MPI。 然而,复杂和异构体系结构对这种代码的可伸缩执行提出了新的挑战,因为许多基本的并行算法设计假设不再有效。

我们已经迈出了开发架构感知图分区算法的第一步。这些能够计算分区,无论计算平台如何,计算都可以实现最高级别的性能。具体来说,我们启用了ParMETIS V3 PartKway,ParMETIS V3 PartGeomKway,ParMETIS V3 PartMeshKway,ParMETIS V3 RefineKway和ParMETIS V3 AdaptiveRepart来计算异构处理器网络的高效分区。为此,这些例程需要一个额外的数组(tpwgts)作为参数传递。此数组描述了每个子域应包含的总顶点权重的分数。例如,如果您有一个由四个处理器组成的网络,前三个处理器具有相同的处理速度,而第四个处理器的速度是其他处理器的两倍,则用户将传递包含这些值的数组(0.2, 0.2,0.2,0.4)。注意,通过允许用户如此指定目标子域权重,在计算分区时可以考虑异构处理能力。但是,这不允许我们考虑异构网络带宽和延迟。优化异构网络的分区仍然是正在进行的研究的重点。

计算减小填充数(矩阵求解中需要可以使用)

ParMETIS V3 NodeND和ParMETIS V32 NodeND是PARMETIS提供的用于计算填充减少排序的例程,适用于基于Cholesky的直接分解算法。 请注意,ParMETIS V3 NodeND只是更一般的ParMETIS V32 NodeND例程的包装器,包含在后向兼容性中。 ParMETIS V32 NodeND不假设图表最初如何在处理器之间分配。 它可以有效地计算随机分布的图形的填充减少顺序以及分布均匀的图形。

ParMETIS V32 NodeND实现的算法基于多级嵌套解剖算法。该算法已被证明可以为各种矩阵产生低填充顺序。 此外,它导致平衡消除树,这对于并行直接分解是必不可少的。 ParMETIS V32 NodeND使用基于节点的多级细化算法,特别适合直接细化分隔符的大小。 为了实现高性能,ParMETIS V32 NodeND首先使用ParMETIS V3 PartKway来计算高质量分区并相应地重新分配图形。 接下来,它继续计算?log p? 同时消除树的级别。 当图形被分成p部分(其中p是处理器的数量)时,图形在处理器之间重新分配,以便每个处理器接收单个子图,并且METIS的串行嵌套解剖排序算法用于对这些较小的子图进行排序。

使用说明(API操作使用)

输入数据的格式

  1. 图的输入格式

PARMETIS中的所有图形例程都将图的邻接结构,顶点和边的权重(如果有的话)作为输入,并且描述图如何在处理器之间分布的数组。请注意,根据应用程序,此图表可以表示不同的内容。例如,当PARMETIS用于计算填充减少排序时,该图对应于矩阵的非零结构(不包括对角线条目)。在有限元计算的情况下,图的顶点可以对应于网格中的节点(点),而边表示这些节点之间的连接。或者,图形可以对应于有限元网格的对偶。在这种情况下,如果相应的元素共享边(在2D中)或面(在3D中),则每个顶点对应于一个元素并且两个顶点通过边连接。此外,图表可以类似于双重图表,但可以或多或少地连接。也就是说,不是将边缘限制为共享面的那些元素,而是边可以连接甚至共享单个节点的任何两个元素。然而,构造了图形,它通常是无向的。也就是说,对于每对连接的顶点v和u,它包含边(v,u)和(u,v)。

在PARMETIS中,图的结构由压缩存储格式(CSR)表示,扩展用于并行分布式存储器计算的上下文。 我们将首先描述串行图的CSR格式,然后描述如何扩展它以存储在处理器之间分布的图形。

  • 串行的CSR格式

CSR格式是用于存储稀疏图的广泛使用的方案。 这里,图的邻接结构由两个数组xadj和adjncy表示。 顶点和边(如果有)的权重通过使用另外两个数组vwgt和adjwgt来表示。 例如,考虑具有n个顶点和m个边的图。 在CSR格式中,可以使用以下大小的数组来描述此图:
xadj[n+1](节点值存放每个节点周围) vwgt[n](每个节点的权重) adjncy[2m](边之间的关系) adjwgt[2m](每条边的权重)

xadj[n+1]存放每个节点周围节点数并且为后面数组的值是前面节点和加上当前节点周围节点,比如:第一个节点周围有2个节点 第二节点有3个节点 xadj[0]=0,

注意,adjncyadjwgt的大小都是2m的原因是因为每个边都被列出两次(即,(v,u)(u,v))。 还要注意,在图形未加权的情况下(即,所有顶点和/或边缘具有相同的权重),则数组vwgtadjwgt中的任一个或两个可以设置为NULL。在ParMETIS V3 AdaptiveRepart还需要一个vsize数组。此数组类似于vwgt数组,不同之处在于它不是描述与每个顶点关联的工作量,而是描述与每个顶点关联的内存量。

图的邻接结构存储如下。 假设顶点编号从0(C样式)开始,顶点i的邻接列表存储在从索引xadj[i]开始并以(但不包括)索引xadj [i + 1]结束的数组调整中(换句话说,adjncy[xadj[i]]通过并包括adjncy[xadj[i+1] -1])。因此,每个顶点的邻接列表连续存储在数组约定中。数组xadj用于指向每个特定顶点的列表开始和结束的位置。 图5(b)说明了图5(a)所示的15-顶点图的CSR格式。 如果图是顶点上的权重,则vwgt[i]用于存储顶点i的权重。 类似地,如果图形在边缘上具有权重,则边缘约束[j]的权重存储在adjwgt[j]中。 这与(串行)METIS库例程使用的格式相同。

  • 分布式CSR格式

分布式的CSR使用CSR格式的扩展,允许图形的顶点及其邻接列表在处理器之间分配。特别地,PARMETIS假设每个处理器P_i存储图的n_i顶点和相应的m_i边缘,因此整个图的节点数n=\sum_i(n_i)和边 2*m=\sum_i(m_i)。因此,每个处理器只需要使用CSR格式储存本地进程应该存放的数据xadj[n_i+1],vwgt[n_i](点权重),adjncy[m_i]adjwgt[m_i](边权重)中。同样,如果图不需要设置权重(应该在多物理场中需要设置),则数组vwgtadjwgt可以设置为NULL。最直接的方法,直接将节点根据xadj[n_i+1]切分成n/p份,通过程序进行分区。并将它们存储在连续的处理器上(其中p是处理器的数量)。此外,每个处理器都需要其本地xadj数组来指向其本地顶点的每个邻接列表的开始和结束位置。因此,如果我们采用所有本地的adjncy数组并将它们连接起来,我们将获得与串行CSR中使用的完全相同的adjncy数组(此时本地进程数据与串行的CSR完全相同)。但是,连接本地xadj数组不会给我们提供串行xadj数组。这是因为每个本地xadj中的条目必须指向它们的本地约束数组,因此,对于所有处理器,xadj [0]为零。因此为了分布式的切分,除了这四个数组之外,每个处理器还需要数组vtxdist[p+1],它指示每个处理器本地的顶点范围。特别地,每个本地处理器P_i存储来自vtxdist[i]的顶点直到(但不包括)顶点vtxdist[i+1]
图5(c)通过三处理器系统上的示例说明了分布式CSR格式。 图5(a)中的15-顶点图分布在处理器之间,使得每个处理器获得5个顶点及其对应的邻接列表。 也就是说,处理器零获取顶点0到4,处理器一获取顶点5到9,处理器二获取顶点10到14.该图显示了每个处理器的xadj,adjncy和vtxdist数组。 请注意,对于每个处理器,vtxdist数组始终是相同的。 (vtxdist表示每个进程存放的节点数,所以vtxdist数组大小为P+1,进程数加1)

当多个顶点权重用于多约束分区时,每个顶点的c个顶点权重将连续存储在vwgt数组中。 在这种情况下,vwgt数组的大小为nc,其中n是本地存储顶点的数量,c是顶点权重的数量(以及平衡约束的数量)。

  1. 顶点的坐标数据的输入形式

如3.1节所述,PARMETIS提供了使用顶点坐标信息快速预分配图形的例程,从而加快了并行k路分区的执行速度。 这些坐标在名为xyz的数组中指定,数据类型为real_t。 如果d是网格的维数(即,2D网格d=23D网格d=3),在分布式中,则每个处理器需要一个大小为d*n_i的数组,其中n_i表示本地存储顶点的数量。(请注意,网格的维数d需要作为例程的参数。)在此数组中,顶点i的坐标从位置xyz[i*d]开始存储,直到(但不包括) 本地的节点xyz[i*d+d]。例如,如果d=3,那么顶点ixyz坐标分别存储在xyz[3*i],xyz[3*i+1]xyz[3*i+2]中。

  1. 网格数据的输入形式

程序ParMETIS _ V3 _ PartMeshKway采用分布式网格并计算其分区,而ParMETIS _ V3 _ Mesh2Dual采用分布式网格并构造分布式双图。 这两个算法都需要一个elmdist数组来指定网格元素的分布,但这与vtxdist数组作用相同。它们还需要一对名为eptreind的数组,以及整数参数ncommonnodes

eptr(每个单元的节点数求和)和eind(存放每个单元的节点编号)数组在本质上类似于用于指定图的邻接列表的xadjadjncy数组,但现在对于每个元素(单元),它们指定组成每个元素的节点集。 具体来说,属于元素i的节点集存储在数组eind中,从索引eptr[i]开始,结束于(但不包括)索引eptr[i+1](换句话说,eind[eptr[i]]通过并包括eind[eptr[i+1]-1])。 因此,每个元素的节点列表连续存储在数组eind中。 此格式允许指定包含混合类型元素的网格。

ncommonnodes参数指定双图的顶点之间所需的连续性程度。 具体地,如果边缘位于两个顶点之间,如果它们对应的网格元素共享至少g个节点,则其中gncommonnodes参数。 因此,可以将该参数设置为产生传统的双图(例如,三角形网格的值为2 因为共享边是一条线 2个节点,或者六面体网格的值为4 因为共享边是四边形4个节点)。 但是,它也可以设置得更高或更低,以增加或减少连接。

此外,ParMETIS _ V3 _ PartMeshKway需要一个类似于vwgt数组的elmwgt数组来表示对应的权重。

  1. 计算分区和排序的输入格式
  • 分区数组的输入格式

分区和重新分区例程要求一个数组(称为part)其大小为n_i(其中n_i是每个处理器顶点的数量),作为参数传递给每个处理器。 在PARMETIS的程序完成切后,对于每个顶点j,该顶点所属的子域号(即处理器标签)将被写入part[j]。请注意,PARMETIS不会根据新分区重新分发图形,它只是计算分区并将其写入part数组。 (当不管使用什么程序进行切分,切分完成后输出结果在part数组中)。

此外,每当子域的数量不等于用于计算重新分区的处理器的数量时,ParMETIS _ V3 _ RefineKwayParMETIS _ V3 _ AdaptiveRepart要求先前计算的分区作为参数通过part数组进行传递。 (每当用户选择从处理器中解耦子域时,也需要这样做。请参见5.2节中的讨论。)这是因为需要从部件数组中提供的值获取初始分区。如果子域和处理器的数量相等,则可以从初始图分布获得初始分区,因此不需要提供该信息.(在这种情况下,对于每个处理器i,部分的每个元素都将设置为i.)

  • 排序和分隔符大小数组的格式(在矩阵求解方面有使用)

在运行ParMETIS _ V3 _ NodeND(和ParMETIS _ V32 _ NodeND)的每个处理器将其计算的填充减少排序的一部分写入称为顺序的数组。 与part数组类似,order数组的大小等于每个处理器存储的顶点数。 完成后,对于每个顶点jorder[j]将该顶点的新全局编号存储在填充减少排列中。

除了排序向量,ParMETIS V3 NodeND还返回有关不同子域的大小以及不同级别的分隔符的信息。 此数组称为sizes,大小为2p(其中p是处理器数)。 每个处理器必须提供此阵列,并且在返回时,每个大小的阵列都是相同的。

为了适应处理器数量不是2的幂的运行,ParMETIS _ V3 _ NodeND执行log(p)嵌套解剖水平。 因此,让p^t = 2^{log(p)}是小于p的最大处理器数,即2的幂。

给定p^t的上述定义,size数组的格式如下。第一个p^t大小从0到p的条目? - 1存储每个节点中的节点数量?子域。剩下的p? - 从大小[p?]到大小[2p? - 2]将分隔符的大小存储在log p?嵌套解剖水平。特别是尺寸[2p? - 2]存储顶级分隔符的大小,大小[2p? - 4]和尺寸[2p?-3]将两个分隔符的大小存储在第二级(从左到右)。同样,尺寸[2p?-8]到尺寸[2p? - 5]存储第三级(从左到右)的四个分隔符的大小,依此类推。该数组可用于快速构造分离树(一种消除树的形式)以进行直接分解。给定此分隔符树和子域的大小,由ParMETIS V3 NodeND生成的排序中的节点以后序方式编号。图6显示了尺寸数组和后序排序。(不了解)

编号和内存分配

PARMETIS允许用户指定编号从0(C样式)或1(Fortran样式)开始的图形。 当然,PARMETIS要求对传递给它的所有数组使用相同的编号方案,在切分数据完成后,并且它同样写入partorder数组。

PARMETIS使动态分配它需要的所有内存。这具有用户不必提供工作空间的优点。 但是,如果计算机上没有足够的内存,PARMETIS中的例程将中止。请注意,PARMETIS中的例程不会修改存储图形的数组(例如,xadjadjncy)。 他们只修改partorder数组。

程序调用

切分图

ParMETIS V3 PartKway

- int ParMETIS V3 PartKway ( idx t *vtxdist, idx t *xadj, idx t *adjncy, idx t *vwgt, idx t *adjwgt, idx t *wgtflag, idx t *numflag, idx t *ncon, idx t *nparts, real t *tpwgts, real t *ubvec, idx t *options, idx t *edgecut, idx t *part, MPI Comm *comm)

描述:
该例程用于使用多级k路多约束分区算法计算p个处理器上的图的k路分区。

参数说明:

vtxdist: 该数组描述了图的顶点如何在处理器之间分配。 (见4.2.1节中的讨论)。 其内容对于每个处理器都是相同的。
数组大小:进程数+1  表示每个进程的节点数

xadj,adjncy: 这些在每个处理器存储图的(本地)邻接结构。 (参见第4.2.1节中的讨论)。
本地进程存放节点的关系,分布式CSR的储存.

vwgt,adjwgt: 这些存储顶点和边的权重。 (见4.2.1节的讨论)。
节点或者边是有权重.

wgtflag:这用于指示图表是否加权。 wgtflag可以采用以下四个值之一:
0. 没有权重(vwgt和adjwgt都是NULL)。
1. 仅边缘的权重(vwgt为NULL)。
2. 仅在顶点上的权重(adjwgt为NULL)。
3. 顶点和边的权重。

numflag:这用于指示用于vtxdist,xadj,adjncy和part数组的编号方案。 numflag可以采用以下两个值之一:
0从0开始的C风格编号。
1个从1开始的Fortran风格编号。

ncon:这用于指定每个顶点具有的权重数。 它也是必须满足的平衡约束的数量。

nparts:用于指定所需的子域数。请注意,子域的数量与调用此例程的处理器数量无关。
需要将图切分多少个子域内.

tpwgts:一个大小为$ncon×nparts$的数组,用于指定应为每个余额约束分配给每个子域的顶点权重的分数。 如果所有子域对于每个顶点权重要具有相同的大小,则应将每个ncon×nparts元素设置为1/nparts的值。 如果ncon大于1,则每个子域的目标子域权重是连续存储的(类似于vwgt数组)。 请注意,给定顶点权重的所有tpwgts的总和应为1。

ubvec:一个大小为ncon的数组,用于指定每个顶点权重的不平衡容差,1表示完美平衡,nparts是完美不平衡。 建议每个ncon权重值为1.05。

options:这是一个整数数组,用于传递例程的其他参数。 第一个元素(即options [0])可以取值0或1.如果是0,则使用默认值,否则选项的其余两个元素解释如下:
options [1]指定在执行算法期间返回的信息级别。 通过将此设置为1可以获得时序信息。通过查看parmetis.h可以获得此参数的其他选项。 应添加数值以获得正确的值。 默认值为0。
options [2]这是例程的随机数种子。

edgecut:成功完成后,分区剪切的边数将写入此参数。

part:这是一个大小等于本地存储顶点数的数组。 成功完成后,将本地存储的顶点的分区向量写入此数组。 (见4.2.4节的讨论)。

comm:这是一个指向调用PARMETIS的进程的MPI通信器的指针。 对于大多数程序,这将指向MPI COMM WORLD。

返回值:

METIS OK  正常执行成功.
METIS ERROR 执行错误.


ParMETIS V3 PartGeomKway

int ParMETIS V3 PartGeomKway ( idx t *vtxdist, idx t *xadj, idx t *adjncy, idx t *vwgt, idx t *adjwgt, idx t *wgtflag, idx t *numflag, idx t *ndims, real t *xyz, idx t *ncon, idx t *nparts, real t *tpwgts, real t *ubvec, idx t *options, idx t *edgecut, idx t *part, MPI Comm *comm)

函数描述:
该例程用于通过结合基于坐标和多约束的k路分区方案来计算p个处理器上的图的k路分区。 (根据图的属性和坐标信息)

参数说明:

vtxdist: 该数组描述了图的顶点如何在处理器之间分配。 (见4.2.1节中的讨论)。 其内容对于每个处理器都是相同的。
数组大小:进程数+1  表示每个进程的节点数

xadj,adjncy: 这些在每个处理器存储图的(本地)邻接结构。 (参见第4.2.1节中的讨论)。
本地进程存放节点的关系,分布式CSR的储存.

vwgt,adjwgt: 这些存储顶点和边的权重。 (见4.2.1节的讨论)。
节点或者边是有权重.

wgtflag:这用于指示图表是否加权。 wgtflag可以采用以下四个值之一:
0. 没有权重(vwgt和adjwgt都是NULL)。
1. 仅边缘的权重(vwgt为NULL)。
2. 仅在顶点上的权重(adjwgt为NULL)。
3. 顶点和边的权重。

numflag:这用于指示用于vtxdist,xadj,adjncy和part数组的编号方案。 numflag可以采用以下两个值之一:
0从0开始的C风格编号。
1个从1开始的Fortran风格编号。

ndims:图形的空间的维数。

xyz: 各个进程内顶点的坐标.

ncon:这用于指定每个顶点具有的权重数。 它也是必须满足的平衡约束的数量。

nparts:用于指定所需的子域数。请注意,子域的数量与调用此例程的处理器数量无关。
需要将图切分多少个子域内.

tpwgts:一个大小为$ncon×nparts$的数组,用于指定应为每个余额约束分配给每个子域的顶点权重的分数。 如果所有子域对于每个顶点权重要具有相同的大小,则应将每个ncon×nparts元素设置为1/nparts的值。 如果ncon大于1,则每个子域的目标子域权重是连续存储的(类似于vwgt数组)。 请注意,给定顶点权重的所有tpwgts的总和应为1。

ubvec:一个大小为ncon的数组,用于指定每个顶点权重的不平衡容差,1表示完美平衡,nparts是完美不平衡。 建议每个ncon权重值为1.05。

options:这是一个整数数组,用于传递例程的其他参数。 第一个元素(即options [0])可以取值0或1.如果是0,则使用默认值,否则选项的其余两个元素解释如下:
options [1]指定在执行算法期间返回的信息级别。 通过将此设置为1可以获得时序信息。通过查看parmetis.h可以获得此参数的其他选项。 应添加数值以获得正确的值。 默认值为0。
options [2]这是例程的随机数种子。

edgecut:成功完成后,分区剪切的边数将写入此参数。

part:这是一个大小等于本地存储顶点数的数组。 成功完成后,将本地存储的顶点的分区向量写入此数组。 (见4.2.4节的讨论)。

comm:这是一个指向调用PARMETIS的进程的MPI通信器的指针。 对于大多数程序,这将指向MPI COMM WORLD。

返回值:

METIS OK  正常执行成功.
METIS ERROR 执行错误.

说明;
ParMETIS V3 PartGeomKway计算的分区质量与ParMETIS V3 PartKway生成的分区质量相当。 但是,例行程序的运行时间可能快两倍。

这个程序相对上一个程序只是多了节点的坐标信息和空间维度信息.


ParMETIS V3 PartGeom

int ParMETIS V3 PartGeom ( idx t *vtxdist, idx t *ndims, real t *xyz, idx t *part, MPI Comm *comm)

描述:
该例程用于使用基于坐标的空间填充曲线方法计算p个处理器上的图的p路分区。

参数说明:

vtxdist: 该数组描述了图的顶点如何在处理器之间分配。 (见4.2.1节中的讨论)。 其内容对于每个处理器都是相同的。
数组大小:进程数+1  表示每个进程的节点数

ndims:图形的空间的维数。

xyz: 各个进程内顶点的坐标.

part:这是一个大小等于本地存储顶点数的数组。 成功完成后,将本地存储的顶点的分区向量写入此数组。 (见4.2.4节的讨论)。

comm:这是一个指向调用PARMETIS的进程的MPI通信器的指针。 对于大多数程序,这将指向MPI COMM WORLD。

返回值;

METIS OK  正常执行成功.
METIS ERROR 执行错误.

说明:
ParmeTIS V3 PartGeom计算的分区质量明显差于ParMETIS V3 PartKway和ParMETIS V3 PartGeomKway生成的分区质量。
(提供的参数越细节,速度越快,而且质量越高.)


ParMETIS V3 PartMeshKway

int ParMETIS V3 PartMeshKway ( idx t *elmdist, idx t *eptr, idx t *eind, idx t *elmwgt, idx t *wgtflag, idx t *numflag, idx t *ncon, idx t *ncommonnodes, idx t *nparts, real t *tpwgts, real t *ubvec, idx t *options, idx t *edgecut, idx t *part, MPI Comm *comm)

描述:
该例程用于计算p个处理器上的网格的k路分区。 网格可以包含不同类型的单元,6节点8节点。

参数说明:

elmdist:此数组描述了网格元素如何在处理器之间分配。 这对于vtxdist数组来说是分析的。 其内容对于每个处理器都是相同的。 (见4.2.3节的讨论)。
与图切分的vtxdist数组意义相同,表示每个进程的单元数,数组大小,进程数+1;

eptr,eind:这些数组指定在每个处理器本地存储的元素。 (见4.2.3节的讨论)。 前一个单元节点数求和,后一个表示单元的节点对应的编号.

elmwgt:此数组存储元素的权重。 (见4.2.3节的讨论)。

wgtflag这用于指示网格的元素是否具有与之关联的权重。 wgtflag可以采用两个值:
0:没有权重(elmwgt为NULL)。
2:仅限顶点的权重。

numflag:这用于指示用于vtxdist,xadj,adjncy和part数组的编号方案。 numflag可以采用以下两个值之一:
0从0开始的C风格编号。
1个从1开始的Fortran风格编号。

ncon:用于指定每个顶点所具有的权重数。 它也是必须满足的平衡约束的数量。

ncommonnodes:此参数确定双图中顶点之间的连通度。 特别地,当且仅当它们共享至少这么多节点时,在任何两个元素之间放置边缘。 此值应大于0,对于大多数网格,值为2将创建合理的双图。 但是,根据网格中元素的类型,大于2的值也可能是有效选择。 例如,对于仅包含三角形,四面体,六面体或矩形元素的网格,此参数可分别设置为两个,三个,四个或两个。
请注意,将此参数设置为较小的值会增加生成的双图中的边数以及相应的分区时间。

nparts:用于指定所需的子域数。 请注意,子域的数量与调用此例程的处理器数量无关。

tpwgts:大小为ncon×nparts的数组,用于指定应为每个余额约束分配给每个子域的顶点权重的分数。 如果所有子域对于每个顶点权重要具有相同的大小,则应将每个ncon×nparts元素设置为1 / nparts的值。 如果ncon大于1,则每个子域的目标子域权重是连续存储的(类似于vwgt数组)。 请注意,给定顶点权重的所有tpwgts的总和应为1。

ubvec:一个大小为ncon的数组,用于指定每个顶点权重的不平衡容差,1表示完美平衡,nparts是完美不平衡。 建议每个ncon权重值为1.05。

options:这是一个整数数组,用于传递例程的其他参数。 第一个元素(即options [0])可以取值0或1.如果是0,则使用默认值,否则选项的其余两个元素解释如下:
options [1]指定在执行算法期间返回的信息级别。 通过将此设置为1可以获得时序信息。通过查看parmetis.h可以获得此参数的其他选项。 应添加数值以获得正确的值。 默认值为0。
options [2]这是例程的随机数种子。

edgecut:成功完成后,分区剪切的边数将写入此参数。

part:这是一个大小等于本地存储顶点数的数组。 成功完成后,将本地存储的顶点的分区向量写入此数组。 (见4.2.4节的讨论)。

comm:这是一个指向调用PARMETIS的进程的MPI通信器的指针。 对于大多数程序,这将指向MPI COMM WORLD。

返回值:

METIS OK  正常执行成功.
METIS ERROR 执行错误.

问题:为什么根据网格切分数据,part数组还是本地节点的值. 本地节点的数组大小怎么确定?


图重新切分

ParMETIS V3 AdaptiveRepart

int ParMETIS V3 AdaptiveRepart ( idx t *vtxdist, idx t *xadj, idx t *adjncy, idx t *vwgt, idx t *vsize, idx t *adjwgt, idx t *wgtflag, idx t *numflag, idx t *ncon, int *nparts, real t *tpwgts, real t *ubvec, real t *itr, idx t *options, idx t *edgecut, idx t *part, MPI Comm *comm)

描述:
该例程用于平衡对应于自适应细化网格的图形的工作负荷。

参数说明:

vtxdist: 该数组描述了图的顶点如何在处理器之间分配。 (见4.2.1节中的讨论)。 其内容对于每个处理器都是相同的。
数组大小:进程数+1  表示每个进程的节点数

xadj,adjncy: 这些在每个处理器存储图的(本地)邻接结构。 (参见第4.2.1节中的讨论)。
本地进程存放节点的关系,分布式CSR的储存.

vwgt,adjwgt: 这些存储顶点和边的权重。 (见4.2.1节的讨论)。
节点或者边是有权重.

vsize:此数组存储与重新分配成本相关的顶点大小。 因此,与需要大量内存的网格元素相关联的顶点将在此数组中具有更大的对应条目。 否则,此数组类似于vwgt数组。 (见4.2.1节的讨论)。

wgtflag:这用于指示图表是否加权。 wgtflag可以采用以下四个值之一:
0. 没有权重(vwgt和adjwgt都是NULL)。
1. 仅边缘的权重(vwgt为NULL)。
2. 仅在顶点上的权重(adjwgt为NULL)。
3. 顶点和边的权重。

numflag:这用于指示用于vtxdist,xadj,adjncy和part数组的编号方案。 numflag可以采用以下两个值之一:
0从0开始的C风格编号。
1个从1开始的Fortran风格编号。

ncon:这用于指定每个顶点具有的权重数。 它也是必须满足的平衡约束的数量。

nparts:用于指定所需的子域数。请注意,子域的数量与调用此例程的处理器数量无关。
需要将图切分多少个子域内.

tpwgts:一个大小为$ncon×nparts$的数组,用于指定应为每个余额约束分配给每个子域的顶点权重的分数。 如果所有子域对于每个顶点权重要具有相同的大小,则应将每个ncon×nparts元素设置为1/nparts的值。 如果ncon大于1,则每个子域的目标子域权重是连续存储的(类似于vwgt数组)。 请注意,给定顶点权重的所有tpwgts的总和应为1。

ubvec:一个大小为ncon的数组,用于指定每个顶点权重的不平衡容差,1表示完美平衡,nparts是完美不平衡。 建议每个ncon权重值为1.05。

itr:此参数描述了处理器间通信时间与数据重新分配时间的比率。 它应设置在0.000001和1000000.0之间。 如果ITR设置为高,则将计算具有低边切的重新分区。 如果设置为低,则将计算需要很少数据重新分配的重新分区。 通过将处理器间通信时间除以数据重新分配时间,可以获得该参数的良好值。 否则,建议值为1000.0。

options:这是一个整数数组,用于传递例程的其他参数。第一个元素(即options [0])可以取值0或1.如果是0,则使用默认值,否则选项的其余三个元素解释如下:
options [1]指定在执行算法期间返回的信息级别。通过将此设置为1可以获得时序信息。通过查看parmetis.h可以获得此参数的其他选项。应添加数值以获得正确的值。默认值为0。
options [2]这是例程的随机数种子。
options [3]指定子域和处理器是耦合还是非耦合。如果期望的子域的数量(即,nparts)和正在使用的处理器的数量不相同,则这些必须是未耦合的。但是,如果nparts等于处理器的数量,则它们可以耦合或解耦合。如果子域和处理器耦合,则将从图分布中隐式地获得初始分区。但是,如果子域未从处理器耦合,则需要从分配给部件阵列的初始值获取初始分区。 PARMETIS PSR COUPLED的值表示子域和处理器是耦合的,PARMETIS PSR UNCOUPLED的值表示它们是去耦合的。如果nparts等于处理器的数量,则默认值为PARMETIS PSR COUPLED,否则为PARMETIS PSR UNCOUPLED(未耦合)。这些常量在parmetis.h中定义。

edgecut:成功完成后,分区剪切的边数将写入此参数。

part:这是一个大小等于本地存储顶点数的数组。 成功完成后,将本地存储的顶点的分区向量写入此数组。 (见4.2.4节的讨论)。 如果处理器的数量不等于子域的数量和/或options [3]设置为PARMETIS PSR UNCOUPLED,则先前计算的分区必须作为参数通过此数组传递给例程。

comm:这是一个指向调用PARMETIS的进程的MPI通信器的指针。 对于大多数程序,这将指向MPI COMM WORLD。

返回值:

METIS OK  正常执行成功.
METIS ERROR 执行错误.

分区细化

ParMETIS V3 RefineKway

int ParMETIS V3 RefineKway ( idx t *vtxdist, idx t *xadj, idx t *adjncy, idx t *vwgt, idx t *adjwgt, idx t *wgtflag, idx t *numflag, idx t *ncon, idx t *nparts, real t *tpwgts, real t *ubvec, idx t *options, idx t *edgecut, idx t *part, MPI Comm *comm)

描述
该例程用于使用多级k路精化算法来改善p处理器上现有k路分区的质量。

参数说明;

vtxdist: 该数组描述了图的顶点如何在处理器之间分配。 (见4.2.1节中的讨论)。 其内容对于每个处理器都是相同的。
数组大小:进程数+1  表示每个进程的节点数

xadj,adjncy: 这些在每个处理器存储图的(本地)邻接结构。 (参见第4.2.1节中的讨论)。
本地进程存放节点的关系,分布式CSR的储存.

vwgt,adjwgt: 这些存储顶点和边的权重。 (见4.2.1节的讨论)。
节点或者边是有权重.

ncon:这用于指定每个顶点具有的权重数。 它也是必须满足的平衡约束的数量。

nparts:用于指定所需的子域数。请注意,子域的数量与调用此例程的处理器数量无关。
需要将图切分多少个子域内.

wgtflag:这用于指示图表是否加权。 wgtflag可以采用以下四个值之一:
0. 没有权重(vwgt和adjwgt都是NULL)。
1. 仅边缘的权重(vwgt为NULL)。
2. 仅在顶点上的权重(adjwgt为NULL)。
3. 顶点和边的权重。

numflag:这用于指示用于vtxdist,xadj,adjncy和part数组的编号方案。 numflag可以采用以下两个值之一:
0从0开始的C风格编号。
1个从1开始的Fortran风格编号。

tpwgts:一个大小为$ncon×nparts$的数组,用于指定应为每个余额约束分配给每个子域的顶点权重的分数。 如果所有子域对于每个顶点权重要具有相同的大小,则应将每个ncon×nparts元素设置为1/nparts的值。 如果ncon大于1,则每个子域的目标子域权重是连续存储的(类似于vwgt数组)。 请注意,给定顶点权重的所有tpwgts的总和应为1。

ubvec:一个大小为ncon的数组,用于指定每个顶点权重的不平衡容差,1表示完美平衡,nparts是完美不平衡。 建议每个ncon权重值为1.05。

options:这是一个整数数组,用于传递例程的其他参数。第一个元素(即options [0])可以取值0或1.如果是0,则使用默认值,否则选项的其余三个元素解释如下:
options [1]指定在执行算法期间返回的信息级别。通过将此设置为1可以获得时序信息。通过查看parmetis.h可以获得此参数的其他选项。应添加数值以获得正确的值。默认值为0。
options [2]这是例程的随机数种子。
options [3]指定子域和处理器是耦合还是非耦合。如果期望的子域的数量(即,nparts)和正在使用的处理器的数量不相同,则这些必须是未耦合的。但是,如果nparts等于处理器的数量,则它们可以耦合或解耦合。如果子域和处理器耦合,则将从图分布中隐式地获得初始分区。但是,如果子域未从处理器耦合,则需要从分配给部件阵列的初始值获取初始分区。 PARMETIS PSR COUPLED的值表示子域和处理器是耦合的,PARMETIS PSR UNCOUPLED的值表示它们是去耦合的。如果nparts等于处理器的数量,则默认值为PARMETIS PSR COUPLED,否则为PARMETIS PSR UNCOUPLED(未耦合)。这些常量在parmetis.h中定义。

edgecut:成功完成后,分区剪切的边数将写入此参数。

part:这是一个大小等于本地存储顶点数的数组。 成功完成后,将本地存储的顶点的分区向量写入此数组。 (见4.2.4节的讨论)。 如果处理器的数量不等于子域的数量和/或options [3]设置为PARMETIS PSR UNCOUPLED,则先前计算的分区必须作为参数通过此数组传递给例程。

comm:这是一个指向调用PARMETIS的进程的MPI通信器的指针。 对于大多数程序,这将指向MPI COMM WORLD。

返回值:

METIS OK  正常执行成功.
METIS ERROR 执行错误.

Fill-reducing Orderings(先不写)

网格到图之间的转换

ParMETIS V32 Mesh2Dual

int ParMETIS V32 Mesh2Dual ( idx t *elmdist, idx t *eptr, idx t *eind, idx t *numflag, idx t *ncommonnodes, idx t **xadj, idx t **adjncy, MPI Comm *comm)

描述:
该例程用于在给定分布式网格的情况下构造分布式图。 它可以与PARMETIS库中的其他例程一起使用。 网格可以包含不同类型的元素。

参数说明;

elmdist:此数组描述了网格元素如何在处理器之间分配。 这对于vtxdist数组来说是分析的。 其内容对于每个处理器都是相同的。 (见4.2.3节的讨论)。
与图切分的vtxdist数组意义相同,表示每个进程的单元数,数组大小,进程数+1;

eptr,eind:这些数组指定在每个处理器本地存储的元素。 (见4.2.3节的讨论)。 前一个单元节点数求和,后一个表示单元的节点对应的编号.

numflag:这用于指示用于vtxdist,xadj,adjncy和part数组的编号方案。 numflag可以采用以下两个值之一:
0从0开始的C风格编号。
1个从1开始的Fortran风格编号。

ncommonnodes:此参数确定双图中顶点之间的连通度。 特别地,当且仅当它们共享至少这么多节点时,在任何两个元素之间放置边缘。 此值应大于0,对于大多数网格,值为2将创建合理的双图。 但是,根据网格中元素的类型,大于2的值也可能是有效选择。 例如,对于仅包含三角形,四面体,六面体或矩形元素的网格,此参数可分别设置为两个,三个,四个或两个。
请注意,将此参数设置为较小的值会增加生成的双图中的边数以及相应的分区时间。

xadj,adjncy: 成功完成例程后,指向构造的xadj和adjncy数组的指针将写入这些参数。 (见4.2.1节的讨论)。 调用程序可以通过调用METIS手册中描述的METIS Free例程来释放该内存。
本地进程存放节点的关系,分布式CSR的储存.

comm:这是一个指向调用PARMETIS的进程的MPI通信器的指针。 对于大多数程序,这将指向MPI COMM WORLD。

返回值:

METIS OK  正常执行成功.
METIS ERROR 执行错误.

说明:
该程序可与ParMETIS V3 PartKway,ParMETIS V3 PartGeomKway或ParMETIS V3 AdaptiveRepart一起使用。 它的运行时间通常为ParMETIS V3 PartKway所需时间的一半。

限定与限制

以下是当前版本的PARMETIS所施加的限制和限制列表。 请注意,这些限制是基于每个API函数描述的任何其他限制。

  1. 该图必须最初分布在处理器之间,使得每个处理器具有至少一个顶点。 如果顶点是分布的,那么将实现基本上更好的性能,使得每个处理器获得相同数量的顶点。
  2. 必须至少由两个处理器调用例程。 也就是说,PARMETIS不能在单个处理器上使用。 如果需要在单个处理器上进行分区,请使用METIS。
  3. 当满足以下条件时,PARMETIS中的分区例程切换到纯串行实现(通过调用相应的METIS'例程):( i)图形/矩阵包含少于10000个顶点,(ii)图形包含 没有边缘,以及(iii)图中顶点的数量小于20×p,其中p是处理器的数量。

相关文章

  • pa-metis文档阅读

    parmetis功能介绍 英语能力有限,使用的是谷歌翻译. 切分图 ParMETIS V3 PartKway是PA...

  • 文档阅读

    官方source-code 阿里十分钟入门RocketMQ RocketMQ 迈入50万TPS消息俱乐部 Apac...

  • 文档阅读

    // $("#btn1"...

  • 《科技文档写作实务》

    文档目的 编写文档前需要明确文档要达成的目的是什么?搞清出3点:文档阅读对象?背景以及为了达成目标?阅读人...

  • 使用apiDoc书写API文档规范

    首发于fxm5547的博客 详细阅读apiDoc官方文档 详细阅读官方文档:http://apidocjs.com...

  • libcloud 文档阅读

    我估计是。 2.对实例和卷做快照备份。 3.如果一个实例受了损坏,被攻击,那么所有的使用相同的镜像和配置的实例都会...

  • 如何阅读文档

    很多时候 我们阅读文档的时候 都是先把 tutorial 看一篇 把代码跑一篇 然后跟着 documentatio...

  • React文档阅读

    自己最近的项目是基于react的,于是读了一遍react的文档,做了一些记录(除了REFERENCE部分还没开始读...

  • 写好技术文档的几个建议

    1. 技术文档怎样才算好? 技术文档怎么才算好?从自己的阅读体验结合技术文档的阅读对象进行分析,答案就很明显。 一...

  • PDFelement玩转PDF文档注释攻略

    我们在阅读PDF文档的时候,经常会使用PDF文档注释功能。这个功能可以让我们在阅读PDF文档的时候,可标记重点内容...

网友评论

      本文标题:pa-metis文档阅读

      本文链接:https://www.haomeiwen.com/subject/uelklqtx.html