天道酬勤,学无止境

mpi

如何使用 C 在 MPI 中发送(MPI_Send)具有指针字段的嵌套结构(How to send(MPI_Send) nested structure having pointer fields in MPI using C)

问题 我有一个结构: struct vertex { double a; double b; } struct polygon { int numofVertex; vertex *v; } 如何使用 MPI_Send 在 MPI 中发送这个嵌套结构? 问题是该结构包含指针字段“v”,因此 MPI_Send 崩溃。 我已经尝试过 MPI_Datatype 来定义新的数据类型,但它不起作用。 我读到序列化是唯一的解决方案,但 C 没有提供这样的实现。 有什么建议可以解决这个问题吗? 回答1 您必须通过两条消息发送它: // 'p' is a pointer to your polygon vertex *tmp = p->v; p->v = NULL; MPI_Send(p, sizeof(struct polygon), MPI_BYTES, dest, 1, ...); MPI_Send(tmp, sizeof(struct vertex), MPI_BYTES, dest, 2, ...); p->v = tmp; 在接收端,您只需分两步接收结构体: polygon p; MPI_Recv(&p, sizeof(struct polygon), MPI_BYTES, src, 1, ...); p.vertex = malloc(sizeof(struct vertex))

2021-12-05 08:57:37    分类:技术分享    c   serialization   mpi   distributed-computing

使用 MPI_Type_create_subarray 发送时可以转置数组吗?(Can you transpose array when sending using MPI_Type_create_subarray?)

问题 我正在尝试使用 C 中的 MPI 转置矩阵。每个进程都有一个方形子矩阵,我想将其发送到正确的进程(网格上的“相反”进程),将其转置为通信的一部分。 我正在使用MPI_Type_create_subarray它有一个顺序参数,分别是行MPI_ORDER_FORTRAN和列MPI_ORDER_C或MPI_ORDER_FORTRAN 。 我想,如果我作为其中一个发送,并作为另一个接收,那么我的矩阵将作为通信的一部分被转置。 然而,这似乎并没有发生——它只是保持非转置。 代码的重要部分在下面,整个代码文件都可以在这个要点上找到。 有没有人知道为什么这不起作用? 这种进行转置的方法应该起作用吗? 在阅读了MPI_ORDER_C和MPI_ORDER_FORTRAN的描述后,我原以为会,但也许不会。 /* ----------- DO TRANSPOSE ----------- */ /* Find the opposite co-ordinates (as we know it's a square) */ coords2[0] = coords[1]; coords2[1] = coords[0]; /* Get the rank for this process */ MPI_Cart_rank(cart_comm, coords2, &rank2); /* Send to

2021-12-05 03:20:19    分类:技术分享    c   mpi   parallel-processing   hpc   openmpi

如何以编程方式检测内核数量并使用所有内核运行 MPI 程序(How to programmatically detect the number of cores and run an MPI program using all cores)

问题 我不想使用mpiexec -n 4 ./a.out在我的核心 i7 处理器(有 4 个内核)上运行我的程序。 相反,我想运行./a.out ,让它检测内核数量并启动 MPI 以运行每个内核的进程。 这个 SO 问答 MPI 处理器数量? 引导我使用mpiexec 。 我想避免使用 mpiexec 的原因是我的代码注定要成为我正在处理的更大项目中的库。 较大的项目有一个 GUI,用户将开始长时间的计算,这些计算将调用我的库,而我的库又将使用 MPI。 UI 和计算代码之间的集成并非微不足道……因此启动外部进程并通过套接字或其他方式进行通信不是一种选择。 它必须是一个库调用。 这可能吗? 我该怎么做? 回答1 一般来说,这是一件非常重要的事情。 此外,几乎没有任何便携式解决方案不依赖于某些 MPI 实现细节。 下面是一个示例解决方案,它适用于 Open MPI,也可能适用于其他通用 MPI 实现(MPICH、Intel MPI 等)。 它涉及第二个可执行文件或原始可执行文件直接调用您提供一些特殊命令行参数的库的方法。 它是这样的。 假设原始可执行文件只是作为./a.out启动的。 当你的库函数被调用时,它调用MPI_Init(NULL, NULL) ,它初始化 MPI。 由于该可执行文件不是通过mpiexec启动的,所以它回退到所谓的单例 MPI 初始化

2021-12-01 04:40:59    分类:技术分享    mpi

如何在循环中重用 MPI_Scatter 和 MPI_Gather(How to reuse MPI_Scatter and MPI_Gather in a loop)

问题 我正在尝试多次使用MPI_Scatter和MPI_Gather ,并在等待这两个MPI函数完成后打印出结果。 在程序顶部的进程 0,我想使用一个调用 Scatter 和 Gather 的 while 循环。 完成所有计算后,我想将此数组发送回这些函数以进行更多计算。 我已经在下面的代码中解释了我想要做什么。 /*.....*/中的注释是我试图实现的任务。 以下代码使用 4 个处理器运行。 :$ mpicc test.c -o test :$ mpirun -np 4 test #include <mpi.h> #include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) { int size, rank; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &size); MPI_Comm_rank(MPI_COMM_WORLD, &rank); int globaldata[8]; int localdata[2]; int counter, i; if (rank == 0) { for (i=0; i<size*2; i++)//initializing array to all zeros, one time globaldata[i

2021-11-30 21:47:29    分类:技术分享    c   parallel-processing   mpi

MPI 在 C++ 中发送具有向量属性的结构(MPI send struct with a vector property in C++)

问题 我想发送一个具有向量属性的结构。 typedef struct { int id; vector<int> neighbors; } Node; 我知道我必须像在这个答案中一样创建一个 MPI 派生数据类型,但我不知道如何在我的情况下做到这一点,我在结构中有一个向量。 回答1 如果您想保持高水平并发送对象,那么 Boost.MPI 是一个不错的选择。 使用 Boost.MPI,您可以为您的结构指定高级序列化。 您不能(正确)静态地确定向量的数据成员的偏移量。 当然可以拼凑出一种有效的类型。 但这也是用脚射击自己的好方法。 您会在代码中引入假设(例如向量大小不会改变),一旦违反就会产生微妙的错误。 因此,在这种情况下,在MPI_Send单独发送id和neighbours::data()对我来说似乎更干净,更不容易出错 - 而不是使用不适合此用例的 MPI 类型。 回答2 我不喜欢为了做这个简单的事情而导入库的想法。 所以这就是我所做的: 我认为没有理由让 MPI 了解对象的底层结构。 因此,我可以手动将其转换为缓冲区数组,并且由于接收器知道需要一个 Node 结构,因此可以在另一侧重新创建该对象。 所以最初我定义了一个MPI_Contiguous数据类型并发送它: int size = (int) ((node.second.neighbors.size() + 1) *

2021-11-30 05:35:57    分类:技术分享    c++   vector   struct   mpi   stdvector

使用gdb在多屏窗口中调试MPI(Use gdb to debug MPI in multiple screen windows)

问题 如果我有一个 MPI 程序,我想使用 gdb 进行调试,同时能够看到所有单独进程的输出,我可以使用: mpirun -n <NP> xterm -hold -e gdb -ex run --args ./program [arg1] [arg2] [...] 当我有一个 GUI 可以玩时,这很好。 但情况并非总是如此。 是否有类似的设置可以与 screen 一起使用,以便每个进程都有自己的窗口? 这对于在远程环境中调试很有用,因为它允许我使用Ctrl+an在输出之间切换。 回答1 我认为这个答案在“如何调试 MPI 程序?” 线程做你想要的。 编辑: 作为对评论的回应,你可以更容易地做到这一点,尽管简洁并不是我会使用的术语: 通过 mpirun 启动一个分离的屏幕——运行你的调试器和进程。 我已经调用了会话 mpi,并且我正在通过我的库路径,因为它被屏幕剥离并且我的演示需要它(我也在 mac 上,因此是 lldb 和 DYLD): mpirun -np 4 screen -AdmS mpi env DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH lldb demo.out 然后启动一个单独的屏幕会话,我称之为“调试”: screen -AdmS debug 使用screen -ls列出正在运行的会话: >> 屏幕 -ls 屏幕上有: 19871

2021-11-29 23:13:33    分类:技术分享    gdb   mpi   gnu-screen

如何使用 MPI_Gatherv 从包括主节点在内的不同处理器收集不同长度的字符串?(How to use MPI_Gatherv for collecting strings of diiferent length from different processor including master node?)

问题 我试图将来自所有处理器(包括主节点)的不同长度的不同字符串收集到主节点上的单个字符串(字符数组)中。 这是 MPI_Gatherv 的原型: int MPI_Gatherv(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, const int *recvcounts, const int *displs, MPI_Datatype recvtype, int root, MPI_Comm comm)**. 我无法定义一些参数,如recvbuf 、 recvcounts和displs 。 任何人都可以为此提供 C 中的源代码示例吗? 回答1 正如已经指出的,有很多使用MPI_Gatherv的例子,包括这里的堆栈溢出; 可以在此处找到一个答案,该答案首先描述了 scatter 和 gather 的工作原理,然后是 scatterv/gatherv 变体如何扩展它。 至关重要的是,对于更简单的 Gather 操作,其中每个块的大小都相同,MPI 库可以轻松地预先计算每个块在最终编译数组中的位置; 在更一般的 Gatherv 操作中,这不太清楚,您可以选择 - 实际上是要求 - 明确说明每个项目应该从哪里开始。 这里唯一额外的复杂之处是您正在处理字符串

2021-11-29 21:25:08    分类:技术分享    c   arrays   parallel-processing   mpi

Implied synchronization with MPI_BCAST for both sender and receivers?

When calling MPI_BCAST, is there any implied synchronization? For example, if the sender process were to get to the MPI_BCAST before others could it do the BCAST and then continue without any acknowledgements? Some recent tests with code like: program test include 'mpif.h' integer ierr, tid, tmp call MPI_INIT(ierr) call MPI_COMM_RANK(MPI_COMM_WORLD, tid, ierr) tmp = tid if(tid.eq.0) then call MPI_BCAST(tmp,1,MPI_INTEGER,MPI_ROOT,MPI_COMM_WORLD, ierr) else endif write(*,*) tid,'done' call MPI_FINALIZE(ierr) end shows that with two threads they both reach completion, despite only the sender

2021-11-28 23:15:06    分类:问答    synchronization   mpi   broadcast

MPI: Change number of processors in CMakelists

I'm using CLion. My CMakeLists.txt looks like this: cmake_minimum_required(VERSION 3.2) project(MPI) add_executable(MPI main.cpp) # Require MPI for this project: find_package(MPI REQUIRED) set(CMAKE_CXX_COMPILE_FLAGS ${CMAKE_CXX_COMPILE_FLAGS} ${MPI_COMPILE_FLAGS}) set(CMAKE_CXX_LINK_FLAGS ${CMAKE_CXX_LINK_FLAGS} ${MPI_LINK_FLAGS}) include_directories(MPI_INCLUDE_PATH) target_link_libraries(MPI ${MPI_LIBRARIES}) The MPI - Hello World runs well. But how do I change the number of the processors in the cmakelists? I already tried to add -np 4 and -n 4 to the program arguments in CLion. But still

2021-11-28 19:01:49    分类:问答    c++   mpi   mpich   clion

使用 MPI_Scatterv 来分散数组的重叠区域(Use MPI_Scatterv to Scatter Overlapping Regions of an Array)

问题 我有一个二维数组的一维数组表示:下面是一个 6x6 示例: [00000012300456700890100234500000] => [------] [|0123|] [|4567|] [|8901|] [|2345|] [------] 典型的大小是 514*514 个元素(512 + 2 个光环单元)。 我必须在四个处理器之间分配数据: Rank 0: Rank 1: Rank 2: Rank 3: [----] [----] [|456] [567|] [|012] [123|] [|890] [901|] [|456] [567|] [|234] [345|] [|890] [901|] [----] [----] 也就是说,以某种方式,排名 0 的数据的最右侧部分也必须转到排名 1 的数据的左侧部分,依此类推,所有其他邻居对。 我知道如何制作大小为 4x4 的数据类型,但不知道如何将该数组的最后一个元素作为新元素的开始重新发送到另一个等级。 如何分发具有重叠的数据? ===编辑=== 在使用你的实现后,乔纳森...... 我目前正在尝试使用字符数组(2D)来执行此操作,但是在从处理器/列中收集它们时我收到了“垃圾”。 我更改了类型和所有内容,但目前无法弄清楚问题出在哪里。 void distributeBySend_c(unsigned char *

2021-11-28 16:41:50    分类:技术分享    c   mpi   scatter