- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
是否有一种干净的方法来使用 MPI_Scatter 来分散不涉及打包或解包的结构?
假设我有一个这样的结构:
struct Foo
{
int a;
int* b;
int* c;
}
其中 a
和 b
是整数“数组”,可以按如下方式实例化:
struct Foo f1;
f1.a = 0;
f1.b = malloc(sizeof(int) * 10));
f1.c = malloc(sizeof(int) * 15));
我有一个 Foo
实例数组,其中每个实例都有不同大小的 b
和 c
。
我可以为每个实例定义新的 MPI 类型并使用 MPI_Send 发送它们,但显然,这不是很聪明。
所以我的问题是,MPI 对此有内置支持吗?
最佳答案
不幸的是,没有简单的方法通过 MPI 传输数据,尽管显然有不那么简单的方法。
这里问题的核心是您要传输的数据,即包含数据和指向其他数据的指针的结构,不是自包含的:结构内的指针仅引用您要传输的数据的一部分,他们不包含它。因此,仅使用 MPI_Type_create_struct()
创建 MPI 结构化类型将不允许您传输结构逻辑上包含的所有数据,只能传输它实际 包含。
但是,您仍然可以在一些 MPI 通信中实现这一技巧,为了方便起见,您可以将其包装在函数中。但要使其可行,您必须确保以下几点:
malloc
您的数据。 malloc
越少越好。相反,您可以尝试(如果在代码上下文中可能的话)分配与所有 b
和/或 c
字段相对应的一个大型数据数组你的struct Foo
,并让指针b
指向它在这个大数组中的份额。从 MPI 通信的角度来看,这会更简单,而且代码的性能也会更好。a
。以下是其工作原理的完整示例:
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct Foo {
int a;
int *b;
int *c;
} Foo;
int main( int argc, char *argv[] ) {
MPI_Init( &argc, &argv );
int rank, size;
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
MPI_Comm_size( MPI_COMM_WORLD, &size );
int len = 3;
Foo *array = malloc( len * sizeof( Foo ) );
// let's assume for simplicity that each process already knows the sizes of the individual arrays (it would need to be transmitted otherwise)
int lenB[] = { 1, 2, 3 };
int lenC[] = { 5, 6, 7 };
// now we create the data for the arrays
int lenAllBs = 0, lenAllCs = 0;
for ( int i = 0; i < len; i++ ) {
lenAllBs += lenB[i];
lenAllCs += lenC[i];
}
int *BandC = malloc( ( lenAllBs + lenAllCs ) * sizeof( int ) );
// And we adjust the pointers
array[0].b = BandC;
array[0].c = BandC + lenAllBs;
for ( int i = 1; i < len; i++ ) {
array[i].b = array[i-1].b + lenB[i];
array[i].c = array[i-1].c + lenC[i];
}
// Now we create the MPI structured type for Foo. Here a resized will suffice
MPI_Datatype mpiFoo;
MPI_Type_create_resized( MPI_INT, 0, sizeof( Foo ), &mpiFoo );
MPI_Type_commit( &mpiFoo );
// Ok, the preparation phase was long, but here comes the actual transfer
if ( rank == 0 ) {
// Only rank 0 has some meaningful data
for ( int i = 0; i < len; i++ ) {
array[i].a = i;
for ( int j = 0; j < lenB[i]; j++ ) {
array[i].b[j] = 10 * i + j;
}
for ( int j = 0; j < lenC[i]; j++ ) {
array[i].c[j] = 100 * i + j;
}
}
// Sending it to rank size-1
// First the structure shells
MPI_Send( array, len, mpiFoo, size - 1, 0, MPI_COMM_WORLD );
// Then the pointed data
MPI_Send( BandC, lenAllBs + lenAllCs, MPI_INT, size - 1, 0, MPI_COMM_WORLD );
}
if ( rank == size - 1 ) {
// Receiving from 0
// First the structure shells
MPI_Recv( array, len, mpiFoo, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE );
// Then the actual data
MPI_Recv( BandC, lenAllBs + lenAllCs, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE );
// And printing some
printf( "array[1].a = %d, array[2].b[1] = %d, array[0].c[4]=%d\n", array[1].a, array[2].b[1], array[0].c[4] );
}
MPI_Type_free( &mpiFoo );
free( BandC );
free( array );
MPI_Finalize();
return 0;
}
用mpicc -std=c99 dyn_struct.c -o dyn_struct
编译,它给了我:
$ mpirun -n 2 ./dyn_struct
array[1].a = 1, array[2].b[1] = 21, array[0].c[4]=4
正如您所看到的,一旦结构正确创建,它是可行的,并且不会太复杂。如果在传输之前不知道每个成员数据的单独大小,则必须在传输实际数据之前传输它,并且必须在接收之前相应地设置接收缓冲区和结构。
关于c - C 中的 MPI_Scatter 结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33250076/
我想发送二维数组的列,每个列到单独的进程。我现在有一个完整的 2d 数组,但我被 MPI_Scatter 困住了。如何将整列作为字段发送? 谢谢 编辑: 我有数组 - float a[100][101
我正在尝试修改我的程序,以便代码看起来更好。现在我正在使用 MPI_Send 和 MPI_Recv,但我正在尝试使其与 MPI_Scatter 一起使用。我有一个名为 All_vals 的数组,我尝试
我正在开发一个并行排序程序来学习 MPI,但我一直在使用 MPI_Scatter 时遇到问题。每次我尝试运行时,我都会得到以下信息: reading input Scattering input _p
我知道,在处理 openMpi 时没有全局变量的概念/含义,因此当特定线程正在更改变量时,该变量的值仍将设置为其他进程中的默认值。我知道 MPI_Scatter() 的功能。 当我使用这样的东西时,
我是 MPI 世界的新手,我有点困惑.. 我使用“MPI_Scatter”将数组“分解”成多个部分。但情况是...它可以在多台机器上运行该程序吗? 我的观点是:我是否必须使用 MPI_Send 和 M
我有一个分配在连续内存空间中的动态二维数组,但是如果我尝试使用 MPI_Scatter 将该数组分散到两个 MPI 进程中,将导致段错误,整个代码粘贴在这里: dynamic_2d_array.h #
我是 MPI 的新手,我正在尝试编写使用 MPI_scatter 的程序。我有 4 个节点(0、1、2、3)。 Node0是master,其他都是slave。 Master 询问用户要发送给 slav
我正在尝试通过同一个通信器,使用非阻塞版本的通信,将两个不同的、独立的数组从等级 0 分散到所有其他数组。 沿着这些线的东西: //do some stuff with arrays here...
我想使用这种特定的内存分配方式将一个二维数组分散到其他二维数组中(每个进程一个)。 int (*matrix)[cols] = malloc(sizeof *matrix* rows); 我一直收到
我有这个串行代码,我正在尝试使用 MPI 将其转换为并行代码。但是,我似乎无法让 MPI_Scatter() 函数在不崩溃的情况下正常工作。该函数遍历名为 cells 的数组并修改一些值。 下面是原始
我正在使用 MPI 编写我的第一个程序,我很难尝试使用 MPI_Scatter 将数据正确发送到其他进程,修改它们并使用 MPI_Gather 接收值。代码如下: int** matrix; int
我正在尝试使用 MPI 库解决一个简单的程序。 进程0上存储了4*N×4*N的矩阵,矩阵每边的长度为DIM LEN = 4*N。我需要创建一个对角数据类型。但是,数据类型应该只覆盖对角线上的 N 个连
伙计们!我写了一段代码,用 MPI 计算两个巨大 vector 的标量积。首先,等级为 0 的进程创建两个随机 vector ,并通过 MPI_Scatter 将其发送给其余进程。之后,他们计算部分和
我的第一个想法是MPI_Scatter并且应该在if(proc_id == 0)子句中使用发送缓冲区分配,因为数据应该只分散一次并且每次进程只需要发送缓冲区中的一部分数据,但它无法正常工作。 看来,在
我正在学习 OpenMPI。尝试了一个简单的 MPI_Scatter 示例: #include using namespace std; int main() { int numProcs,
我的问题很简单,MPI_Scatter函数定义是: #include void MPI::Comm::Scatter(const void* sendbuf, int sendcount, cons
我正在尝试找到随机生成的数字的最大值。对此有任何想法... 我正在使用 MPI_Scatter 将随机生成的数字分成相等的进程。我正在使用 MPI_Reduce 从每个进程中获取最大值。 #inclu
我对 MPI_Scatter 有疑问。不知道如何使用它,我当前的程序在启动时因段错误而崩溃。 我猜 MPI_Scatter 的参数存在问题,尤其是在使用正确的运算符(& 或 * 或 void)调用它时
我是 mpi 编程的新手。我刚刚在 c 中使用 mpi_scatter 尝试了一个并行搜索程序。我想知道我的程序是否正确。但是当我执行一个没有 MPI_SCATTER 的程序时,即线性搜索,与并行程序
我正在尝试使用 MPI 编写矩阵 vector 乘法程序。我正在尝试将矩阵的列发送到单独的进程并在本地计算结果。最后,我使用 MPI_SUM 操作执行了 MPI_Reduce。 发送矩阵的行很容易,因
我是一名优秀的程序员,十分优秀!