我正在尝试学习RMA(远程内存访问(。以下代码是我为测试MPI_Put而编写的示例代码,然后我想在实际代码中使用相同的方法。
在这个示例代码中,我有一个向量的向量,我希望每个具有rank_ID的秩更新v_a[rank_ID][m]。
代码是:
#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char *argv[])
{
// MPI Start
MPI_Init(NULL, NULL);
int pCurrentID, pRightID, pLeftID, tag = 1 , size, value;
MPI_Comm_rank(MPI_COMM_WORLD, &pCurrentID);
MPI_Comm_size(MPI_COMM_WORLD, &size);
std::vector<std::vector<double> > v_A;
int n = 2;
int m = 5;
for (int i =0; i<n; i++) {
v_A[i].resize(m);
}
double temp = 0.0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
v_A[i][j] = temp;
}
temp++;
}
MPI_Win win;
int disp_unit = sizeof(double);
int size_inner_obj_D = v_A[0].size();
MPI_Win_create(v_A[0].data(), v_A.size() * size_inner_obj_D * sizeof(double),
disp_unit, MPI_INFO_NULL, MPI_COMM_WORLD, &win);
MPI_Win_fence(0, win);
for(int i= 0; i<n; i++) {
if (pCurrentID == i) {
double* buf = new double[m];
for (int j = 0; j < m; j++) {
buf[i] = i + 1.0;
}
MPI_Put(buf, size_inner_obj_D, MPI_DOUBLE, pCurrentID, i * size_inner_obj_D, size_inner_obj_D, MPI_DOUBLE, win);
}
}
MPI_Win_fence(0, win);
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
std::cout<<v_A[i][j]<<", "<<std::endl;
}
}
MPI_Win_free(&win);
/* All done */
MPI_Finalize();
return 0;
}
错误为:
[FK] *** Process received signal ***
[FK] Signal: Segmentation fault: 11 (11)
[FK] Signal code: Address not mapped (1)
[FK] Failing at address: 0x8
[FK] [ 0] 0 libsystem_platform.dylib 0x00007fff2044dd7d _sigtramp + 29
[FK] [ 1] 0 libdyld.dylib 0x00007fff20422c46 dyld_stub_binder + 282
[FK] [ 2] 0 ch1 0x000000010a939e40 _ZNSt3__16vectorIdNS_9allocatorIdEEE6resizeEm + 32
[FK] [ 3] 0 ch1 0x000000010a939a6a main + 170
[FK] [ 4] [FK] *** Process received signal ***
[FK] Signal: Segmentation fault: 11 (11)
[FK] Signal code: Address not mapped (1)
[FK] Failing at address: 0x8
[FK] [ 0] 0 libsystem_platform.dylib 0x00007fff2044dd7d _sigtramp + 29
[FK] [ 1] 0 libdyld.dylib 0x00007fff20422c46 dyld_stub_binder + 282
[FK] [ 2] 0 ch1 0x0000000104838e40 _ZNSt3__16vectorIdNS_9allocatorIdEEE6resizeEm + 32
[FK] [ 3] 0 ch1 0x0000000104838a6a main + 170
[FK] [ 4] 0 libdyld.dylib 0x00007fff20423f5d start + 1
[FK] [ 5] 0 ??? 0x0000000000000001 0x0 + 1
[FK] *** End of error message ***
0 libdyld.dylib 0x00007fff20423f5d start + 1
[FK] [ 5] 0 ??? 0x0000000000000001 0x0 + 1
[FK] *** End of error message ***
--------------------------------------------------------------------------
Primary job terminated normally, but 1 process returned
a non-zero exit code. Per user-direction, the job has been aborted.
--------------------------------------------------------------------------
--------------------------------------------------------------------------
mpiexec noticed that process rank 1 with PID 0 on node cecs-064185 exited on signal 11 (Segmentation fault: 11).
--------------------------------------------------------------------------
编辑:
我还尝试使用1D数组来保存向量的这个向量:
#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char *argv[])
{
// MPI Start
MPI_Init(NULL, NULL);
int pCurrentID, pRightID, pLeftID, tag = 1 , size, value;
MPI_Comm_rank(MPI_COMM_WORLD, &pCurrentID);
MPI_Comm_size(MPI_COMM_WORLD, &size);
std::vector<std::vector<double> > v_A;
int n = 2;
int m = 5;
v_A.resize( n );
for(int i = 0; i < n; i++){
v_A[i].resize(m);
}
double temp = 0.0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
v_A[i][j] = temp;
}
temp++;
}
double* myArray = new double[n*m];
double* ptrArray = myArray;
for (int i =0;i < n; i++) {
std::copy(v_A[i].begin(), v_A[i].end(), ptrArray);
ptrArray += v_A[i].size();
}
if (pCurrentID == 0) {
for (int j=0; j< (m*n); j++) {
std::cout<<myArray[j]<<" ,";
}
std::cout<<std::endl;
}
MPI_Win win;
int disp_unit = sizeof(double);
int size_inner_obj_D = m;
MPI_Win_create(myArray, n*m * size_inner_obj_D * sizeof(double),
disp_unit, MPI_INFO_NULL, MPI_COMM_WORLD, &win);
MPI_Win_fence(0, win);
for(int i= 0; i<n; i++) {
if (pCurrentID == i) {
double* buf = new double[m];
for (int j = 0; j < m; j++) {
buf[j] = i + 1.0;
}
std::cout<<"i = "<<i<<" buf : "<<buf[i]<<std::endl;
MPI_Put(buf, size_inner_obj_D, MPI_DOUBLE, pCurrentID, i * size_inner_obj_D, size_inner_obj_D, MPI_DOUBLE, win);
}
}
MPI_Win_fence(0, win);
//
if (pCurrentID == 0) {
for (int j=0; j< (m*n); j++) {
std::cout<<myArray[j]<<" ,";
}
}
MPI_Win_free(&win);
/* All done */
MPI_Finalize();
return 0;
}
问题是结果是:
0 ,0 ,0 ,0 ,0 ,1 ,1 ,1 ,1 ,1 ,
i = 0 buf : 1
i = 1 buf : 2
1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1
我期望成为:
0 ,0 ,0 ,0 ,0 ,1 ,1 ,1 ,1 ,1 ,
i = 0 buf : 1
i = 1 buf : 2
1 ,1 ,1 ,1 ,1 ,2 ,2 ,2 ,2 ,2
我检查了buf,它被改为2,但为什么我们没有以正确的方式将它们打印出来?
如果我们在这个问题中使用1D阵列,它是有效的吗?还有别的办法吗?
我甚至不能运行2倍的向量,如下所示:
#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char *argv[])
{
// MPI Start
MPI_Init(NULL, NULL);
int pCurrentID, pRightID, pLeftID, tag = 1 , size, value;
MPI_Comm_rank(MPI_COMM_WORLD, &pCurrentID);
MPI_Comm_size(MPI_COMM_WORLD, &size);
std::vector<double> v_A;
int n = 2;
v_A.resize(2);
double temp = 0.0;
for (int i = 0; i < n; i++) {
v_A[i] = temp;
temp++;
}
MPI_Win win;
int disp_unit = sizeof(double);
MPI_Win_create(&v_A, n * sizeof(double),
disp_unit, MPI_INFO_NULL, MPI_COMM_WORLD, &win);
MPI_Win_fence(0, win);
double* buf = new double[n];
for(int i= 0; i<n; i++) {
buf[i] = i + 1.0;
}
if (pCurrentID == 1) {
MPI_Put(buf, n, MPI_DOUBLE, 0, 0, n, MPI_DOUBLE, win);
}
MPI_Win_fence(0, win);
if (pCurrentID == 0) {
for (int i = 0; i < n; i++) {
std::cout<<v_A[i]<<", "<<std::endl;
}
}
MPI_Win_free(&win);
/* All done */
MPI_Finalize();
return 0;
}
但有一个替身就行了:
int main(int argc, char *argv[])
{
// MPI Start
MPI_Init(NULL, NULL);
int pCurrentID, pRightID, pLeftID, tag = 1 , size, value;
MPI_Comm_rank(MPI_COMM_WORLD, &pCurrentID);
MPI_Comm_size(MPI_COMM_WORLD, &size);
double v_A;
MPI_Win win;
int disp_unit = sizeof(double);
MPI_Win_create(&v_A, 1 * sizeof(double) ,
disp_unit, MPI_INFO_NULL, MPI_COMM_WORLD, &win);
MPI_Win_fence(0, win);
if (pCurrentID == 1) {
double v_b = 3.0;
MPI_Put(&v_b, 1, MPI_DOUBLE, 0, 0, 1, MPI_DOUBLE, win);
}
MPI_Win_fence(0, win);
if (pCurrentID == 0) std::cout<<v_A<<", "<<std::endl;
MPI_Win_free(&win);
/* All done */
MPI_Finalize();
return 0;
}