使用 MPI 和 C++ 从不同节点收集数据
Gathering data from different node using MPI and C++
我正在处理一个包含多个从节点和一个主节点的项目。在某些时候,我需要从不同的从属节点(主节点也可以被视为从节点)收集数据到主节点。数据可以是任何类型的,但假设它是无符号的 int。这就是数据在从属节点上的外观:
node0: |chunk01|chunk02|chunk03|chunk04|....
节点 1: |chunk11|chunk12|chunk13|chunk14|....
。
noden: |chunkn1|chunkn2|chunkn3|chunkn4|....
数据应全部收集到 node0,如下所示:
节点0: |chunk01|chunk11|chunk21|....|chunkn1|chunk02|chunk12|...|Chunkn2|...|东磁|
这意味着我们将每个节点的第一个块连接在一起,然后每个节点的第二个块连接在一起......
我不知道如何使用MPI_Gatherv来实现这一点,因为每个 chunkij 都有不同的大小,而且每个节点只知道自己的块大小和启动索引,而不知道其他节点的信息。
我对 MPI 不太熟悉,所以我想知道是否有任何 API 可以将不同大小的数据从不同节点收集到一个节点?
下面是一个可以编辑的示例,应该可以工作。几乎可以肯定这不是解决问题的最佳方法 - 我需要您的代码的更多详细信息来评论这一点。我还没有检查它是否可以编译,但如果您修复任何拼写错误,我很乐意尝试修复任何未解决的错误。
我也不知道效率对你有多重要——这个操作是每秒进行数百次还是每天一次?如果是后者,那么这段代码可能没问题。我也假设 C/C++。
// Populate this on each node from MPI_Comm_rank.
int myRank;
// Populate this on each node from MPI_Comm_size.
int P;
// Num chunks per core.
const int M = 4;
// I'm assuming 0 is the master.
int masterNodeRank = 0;
// Populate this.
// It only needs to have meaningful data on the master node.
//If master node doesn't have the data, fill with MPI_GATHER.
int* sizeOfEachChunkOnEachRank[M];
// Populate this.
//It needs to exist on every 'slave' node.
int sizeOfMyChunks[M];
// Assuming you already have this array
// it should be the contiguous store of each core's data.
unsigned* myData;
// This is what we'll gather all the data into on master node only.
unsigned* gatheredData = new unsigned[totalDataSize];
// This array will keep all of the displacements from each sending node.
int* displacements = new int[P];
// This keeps track of how many unsigneds we've received so far.
int totalCountSoFar = 0;
// We'll work through all the first chunks on each node at once, then all
// the second chunks, etc.
for(int localChunkNum = 0; localChunkNum < M; ++localChunkNum)
{
// On the receiving node we need to calculate all the displacements
// for the received data to go into the array
if (myRank == masterNodeRank)
{
displacements[0] = 0;
for(int otherCore = 1; otherCore < P; ++otherCore)
{
displacements[otherCore] = displacements[otherCore-1] + sizeOfEachChunkOnEachRank[localChunkNum][otherCore-1];
}
}
// On all cores, we'll need to calculate how far into our local array
// to start the sending from.
int myFirstIndex = 0;
for(int previousChunk=0; previousChunk < localChunkNum; previousChunk++)
{
myFirstIndex += sizeOfMyChunks[previousChunk];
}
// Do the variable gather
MPI_Gatherv(&myData[myFirstIndex], // Start address to send from
sizeOfMyChunks[localChunkNum], // Number to send
MPI_UNSIGNED, // Type to send
&gatheredData[totalCountSoFar], // Start address to receive into
sizeOfEachChunkOnEachRank[localChunkNum], // Number expected from each core
displacements, // Displacements to receive into from each core
MPI_UNSIGNED, // Type to receive
masterNodeRank, // Receiving core rank
MPI_COMM_WORLD); // MPI communicator.
// If this is the receiving rank, update the count we've received so far
// so that we don't overwrite data the next time we do the gather.
// Note that the total received is the displacement to the receive from the
// last core + the total received from that core.
if(myRank == masterNodeRank)
{
totalCountSoFar += displacements[P-1] + sizeOfEachChunkOnEachRank[localChunkNum][P-1];
}
}
delete[] displacements;
delete[] gatheredData;
相关文章:
- 如何使用发送数据包所花费的时间计算两个节点之间的距离?
- 如何在Visual C+++中从JSON文件中读取节点数据
- 修改链表主函数代码,用户将在其中输入节点的索引和数据以及正确的消息
- 如何在C++中实现节点数任意的通用树数据结构?
- 如何在C++中使用带有SFML的http reqest从节点.js服务器获取数据?
- 如果我们不创建一个新节点并使用指针插入数据并建立链接(在链表中)怎么办?
- 使用 Broadcast 发出的从节点服务器发送的数据不能被 C++ 套接字 IO 客户端读取
- C++ Eclipse:二叉搜索树节点>数据=变量似乎不起作用
- C++ 在节点内存储对数据对象的引用,而不复制数据
- 如何通过其持有的数据从链表中删除某个节点?
- 基于给定字符串数据类型的链表删除节点
- 为什么我的节点临时节点不能显示正确的数据?
- C++中的数据结构,插入链表中节点的开头
- 从链表数组访问节点数据
- 如何取消引用作为指针的链表节点数据
- 如何将XML节点数据转换为QT中的字符串
- 无法访问类中的节点数据
- C++ 使用 std::p air 模板专用化定义树节点数据结构
- 如何使用pugixml解析获得具有相同节点名称的节点的节点数据
- 如何添加备用节点数据