我有一個奇怪的問題與C型結構有關,它是在MPI派生數據類型的幫助下傳遞的。下面的例子工作;它只是發送一個包含一個integer
加上4 float
值的消息。MPI派生數據類型適用於浮點數,但不適用於雙精度浮點數。這是一個對齊問題?
Minmum工作示例:
#include <mpi.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
MPI_Init(&argc, &argv);
int i, rank, tag = 1;
MPI_Status status;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
// Array of doubles plus element count
typedef struct {
int row;
float elements[4];
} My_array;
// Derived datatype for an array of doubles plus element count
MPI_Datatype MY_ARRAY_TYPE;
const int nr_blocks = 2;
int blocklengths[2] = {1, 4};
MPI_Datatype oldtypes[2] = {MPI_INT, MPI_FLOAT};
MPI_Aint extent, lb;
MPI_Type_get_extent(MPI_INT, &lb, &extent);
MPI_Aint displacements[2] = {0, extent};
MPI_Type_create_struct(nr_blocks, blocklengths, displacements,
oldtypes, &MY_ARRAY_TYPE);
MPI_Type_commit(&MY_ARRAY_TYPE);
if(rank == 0) {
My_array array1 = {3, 3.1, 3.2, 3.3, 3.4};
MPI_Send(&array1, 1, MY_ARRAY_TYPE, 1, tag, MPI_COMM_WORLD);
}
if(rank == 1) {
My_array array2;
MPI_Recv(&array2, 1, MY_ARRAY_TYPE, 0, tag, MPI_COMM_WORLD, &status);
printf("Rank %d received elements of row %d:\n", rank, array2.row);
for(i = 0; i < 4; i++)
printf("\t%.1f\n", array2.elements[i]);
}
MPI_Type_free(&MY_ARRAY_TYPE);
MPI_Finalize();
}
如果你有機會到MPI安裝,例如可以通過mpicc -o example example.c
編譯和運行mpirun -np 2 example
。 輸出應該
Rank 1 received elements of row 3:
3.1
3.2
3.3
3.4
問題: 現在當float
在數組變化爲double
秒的陣列,並相應地對MPI_FLOAT
MPI_DOUBLE
,我得到一個錯誤的結果。
此代碼:
#include <mpi.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
MPI_Init(&argc, &argv);
int i, rank, tag = 1;
MPI_Status status;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
// Array of doubles plus element count
typedef struct {
int row;
double elements[4];
} My_array;
// Derived datatype for an array of doubles plus element count
MPI_Datatype MY_ARRAY_TYPE;
const int nr_blocks = 2;
int blocklengths[2] = {1, 4};
MPI_Datatype oldtypes[2] = {MPI_INT, MPI_DOUBLE};
MPI_Aint extent, lb;
MPI_Type_get_extent(MPI_INT, &lb, &extent);
MPI_Aint displacements[2] = {0, extent};
MPI_Type_create_struct(nr_blocks, blocklengths, displacements,
oldtypes, &MY_ARRAY_TYPE);
MPI_Type_commit(&MY_ARRAY_TYPE);
if(rank == 0) {
My_array array1 = {3, 3.1, 3.2, 3.3, 3.4};
MPI_Send(&array1, 1, MY_ARRAY_TYPE, 1, tag, MPI_COMM_WORLD);
}
if(rank == 1) {
My_array array2;
MPI_Recv(&array2, 1, MY_ARRAY_TYPE, 0, tag, MPI_COMM_WORLD, &status);
printf("Rank %d received elements of row %d:\n", rank, array2.row);
for(i = 0; i < 4; i++)
printf("\t%.1f\n", array2.elements[i]);
}
MPI_Type_free(&MY_ARRAY_TYPE);
MPI_Finalize();
}
生產:
Rank 1 received elements of row 3:
3.1
3.2
3.3
0.0
我試圖圍繞一個位,在該結構和所導出的數據類型使用其它數據(例如,整數,而不是僅僅一個的陣列,int
/MPI_INT
而不是float
/MPI_FLOAT
等),並且發現問題只在使用雙打時出現。這讓我懷疑這可能是一種排列問題 - 但我被困在那裏。 MPI應自動處理對齊。
問:爲什麼用float
/MPI_FLOAT
上面的例子中工作,但不與double
/MPI_DOUBLE
,我該如何解決?
一些機細節,可能是相關的:
- CPU:AMD皓龍6134
- 地址尺寸:48位
- 陣營:64
- 編譯器:GCC 4.4.7
- MPI庫:(不幸)供應商特定
編輯:as su在弗拉基米爾F的評論中,我添加了不起作用的代碼。
最好顯示導致錯誤的代碼,以避免任何可能的不確定性,並對其進行測試。當您不顯示導致代碼的確切錯誤時,可能會隱藏一個微妙的問題。 –
嘗試使用lf不打印的打印雙打... – Jeff