这里有一段代码可以满足您的描述。在注释中,我放了一些关于代码的小描述。通常它呈现一个动态的RMA窗口,需要分配内存并添加到窗口中。
MPI_Win_lock_all(0, win)
Open MPI文档中的描述:
开始对win中所有进程进行RMA访问纪元,锁定类型为MPI_LOCK_SHARED。在此期间,调用进程可以通过使用RMA操作访问win中所有进程的窗口内存。
在我使用
MPI_INFO_NULL
时,您可以使用MPI_Info对象提供额外的信息给MPI,但它取决于您的内存访问模式。
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
typedef struct MyArray {
double* data;
int length;
}MyArray;
#define ARRAY_SIZE 10
int main(int argc, char *argv[]) {
int rank, worldSize, i;
MPI_Win win;
MPI_Aint disp;
MPI_Aint *allProcessDisp;
MPI_Request *requestArray;
MyArray myArray;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &worldSize);
MPI_Win_create_dynamic(MPI_INFO_NULL, MPI_COMM_WORLD, &win);
allProcessDisp = malloc(sizeof(MPI_Aint) * worldSize);
requestArray = malloc(sizeof(MPI_Request) * worldSize);
for (i = 0; i < worldSize; i++)
requestArray[i] = MPI_REQUEST_NULL;
myArray.data = malloc(sizeof(double) * ARRAY_SIZE);
myArray.length = ARRAY_SIZE;
MPI_Alloc_mem(sizeof(double) * ARRAY_SIZE, MPI_INFO_NULL, &myArray.data);
for (i = 0; i < ARRAY_SIZE; i++)
myArray.data[i] = rank;
MPI_Win_attach(win, myArray.data, sizeof(double) * ARRAY_SIZE);
MPI_Get_address(myArray.data, &disp);
if (rank == 0) {
allProcessDisp[0] = disp;
for (i = 1; i < worldSize; i++) {
MPI_Irecv(&allProcessDisp[i], 1, MPI_AINT, i, 0, MPI_COMM_WORLD, &requestArray[i]);
}
MPI_Waitall(worldSize, requestArray, MPI_STATUS_IGNORE);
MPI_Bcast(allProcessDisp, worldSize, MPI_AINT, 0, MPI_COMM_WORLD);
}
else {
MPI_Send(&disp, 1, MPI_AINT, 0, 0, MPI_COMM_WORLD);
MPI_Bcast(allProcessDisp, worldSize, MPI_AINT, 0, MPI_COMM_WORLD);
}
double otherRankData = -1.0;
int otherRank = 1;
if (rank == 0) {
MPI_Win_lock_all(0, win);
MPI_Get(&otherRankData, 1, MPI_DOUBLE, otherRank, allProcessDisp[otherRank], 1, MPI_DOUBLE, win);
MPI_Win_unlock_all(win);
printf("Rank 0 : Got %.2f from %d\n", otherRankData, otherRank);
}
if (rank == 1) {
MPI_Win_lock_all(0, win);
MPI_Put(myArray.data, ARRAY_SIZE, MPI_DOUBLE, 0, allProcessDisp[0], ARRAY_SIZE, MPI_DOUBLE, win);
MPI_Win_unlock_all(win);
}
printf("Rank %d: ", rank);
for (i = 0; i < ARRAY_SIZE; i++)
printf("%.2f ", myArray.data[i]);
printf("\n");
if (rank == 0) {
for (i = 0; i < ARRAY_SIZE; i++)
myArray.data[i] = -1.0;
printf("Rank %d: ", rank);
for (i = 0; i < ARRAY_SIZE; i++)
printf("%.2f ", myArray.data[i]);
printf("\n");
}
free(allProcessDisp);
free(requestArray);
free(myArray.data);
MPI_Win_detach(win, myArray.data);
MPI_Win_free(&win);
MPI_Finalize();
return 0;
}
iso_c_binding
模块中的c_f_pointer()
函数将其与由MPI_Win_allocate_shared
返回的基本指针地址关联起来。 - Hristo Iliev