C-MPI 发送创建的带有字符数组的 typedef 结构
C-MPI Send created typedef struct with array of chars
你好,我有一个包含这种数据行的文件:
AsfAGHM5om 00000000000000000000000000000000 0000222200002222000022220000222200002222000000001111
我想读取这种数据并使用C和MPI将它们发送过来。所以我得到了以下 C 代码:
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h> // used for offsetof
typedef struct tuple_str{
char *key;
char *index;
char *value;
} tuple;
int main(int argc, char** argv) {
// Initialize the MPI environment
MPI_Init(&argc, &argv);
// Initialize file pointer
FILE *fp = fopen("tuples","r");
// define original structure that stores file and temp used by each process
tuple A[10000],B[10000];
// mpi structure name
MPI_Datatype mpi_tuples_str;
// number of structure members
const int nitems = 3;
// array of structure member sizes
int blocklengths[3];
blocklengths[0] = sizeof(A->key);
blocklengths[1] = sizeof(A->index);
blocklengths[2] = sizeof(A->value);
// structure member types
MPI_Datatype types[3] = {MPI_CHAR,MPI_CHAR,MPI_CHAR};
// status
MPI_Status status;
// offset of structure members
MPI_Aint offsets[3];
offsets[0] = offsetof(tuple,key);
offsets[1] = offsetof(tuple,index);
offsets[2] = offsetof(tuple,value);
// create mpi struct
MPI_Type_create_struct(nitems,blocklengths, offsets, types, &mpi_tuples_str);
MPI_Type_commit(&mpi_tuples_str);
// Get the number of processes
int size;
MPI_Comm_size(MPI_COMM_WORLD, &size);
// Get the rank of the process
int my_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
int index = 0;
int i;
int local_A_size = (10000%size == 0) ? 10000/size : 0;
if ( my_rank == 0){
char text[10000];
char *p;
p=strtok(NULL," ");
// node0 reads file form hard drive and saves file to struct
while( fgets(text,10000,fp)!=NULL){
p = strtok (text," ");
char *temp[3];
temp[0]=p;
A[index].key=temp[0];
p = strtok (NULL, " ");
temp[1] = p;
A[index].index=temp[1];
p = strtok (NULL, " ");
temp[2] = p;
A[index].value=temp[2];
// printf("%s ",A[index].key);
// printf("%s ",A[index].index);
// printf("%s\n",A[index].value);
index++;
}
fclose(fp);
}
if ( local_A_size != 0){
if (my_rank == 0) {
printf("File saved to memory of process %d!\n",my_rank);
printf("Process %d sending struct data to others...\n",my_rank);
}
// send struct to all processes
MPI_Scatter(&A,local_A_size,mpi_tuples_str,B,local_A_size,mpi_tuples_str,0,MPI_COMM_WORLD);
// MPI_Bcast(&A,index,mpi_tuples_str,0,MPI_COMM_WORLD);
for(i=0;i<=local_A_size;i++)
printf("I'm process %d and my result is: %s\n",my_rank,B[i].key);
if (my_rank == 0) printf("Data sent from process %d to others...\n",my_rank);
}
else
{
if (my_rank == 0) printf("Number of processes must be an exact divisor of %d, %d in not %ds divisor\n",index,size,index);
}
// free memory used by mpi_tuples_str
MPI_Type_free(&mpi_tuples_str);
// Finalize
MPI_Finalize();
return 0;
}
所以这里的问题是,据我所知_首先创建和分配我的结构的内存,然后打包和发送它。
如您所见,我已经尝试了 MPI_Scatter
和 MPI_Bcast
,但其中 none 帮助了我。
结果是,正如它应该的那样,读取文件的进程 0 有数据,但所有其他进程没有。我还收到
的奇怪消息
= BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES
= EXIT CODE: 11
= CLEANING UP REMAINING PROCESSES
= YOU CAN IGNORE THE BELOW CLEANUP MESSAGES
如果有人能赐教,我将不胜感激!!
好的,我已将代码更改为以下内容:
`#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h> // used for offsetof
typedef struct tuple_str{
char key[10];
char index[12];
char value[52];
} tuple;
int main(int argc, char** argv) {
// Initialize the MPI environment
MPI_Init(NULL, NULL);
// Initialize file pointer
FILE *fp = fopen("tuples_mini","r");
// define original structure that stores file and temp used by each process
tuple A[10000],B[10000];
// mpi structure name
MPI_Datatype mpi_tuples_str;
// number of structure members
const int nitems = 3;
// array of structure member sizes
int blocklengths[3];
blocklengths[0] = sizeof(10);
blocklengths[1] = sizeof(12);
blocklengths[2] = sizeof(52);
// structure member types
MPI_Datatype types[3] = {MPI_CHAR,MPI_CHAR,MPI_CHAR};
// status
MPI_Status status;
// offset of structure members
MPI_Aint offsets[3];
offsets[0] = offsetof(tuple,key);
offsets[1] = offsetof(tuple,index);
offsets[2] = offsetof(tuple,value);
// create mpi struct
MPI_Type_create_struct(nitems,blocklengths, offsets, types, &mpi_tuples_str);
MPI_Type_commit(&mpi_tuples_str);
// Get the number of processes
int size;
MPI_Comm_size(MPI_COMM_WORLD, &size);
// Get the rank of the process
int my_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
int index = 0;
int i;
int local_A_size = (10000%size == 0) ? 10000/size : 0;
char *tmp[10000],*b[10000];
if ( my_rank == 0){
char text[10000];
char *p;
p=strtok(NULL," ");
// node0 reads file form hard drive and saves file to struct
while( fgets(text,10000,fp)!=NULL){
p = strtok (text," ");
char *temp[3];
temp[0]=p;
strcpy(A[index].key,temp[0]);
p = strtok (NULL, " ");
temp[1] = p;
strcpy(A[index].index,temp[1]);
p = strtok (NULL, " ");
temp[2] = p;
strcpy(A[index].value,temp[2]);
printf("%s ",A[index].key);
printf("%s ",A[index].index);
printf("%s\n",A[index].value);
index++;
}
fclose(fp);
}
if ( local_A_size != 0){
if (my_rank == 0) {
printf("File saved to memory of process %d!\n",my_rank);
printf("Process %d sending struct data to others...\n",my_rank);
}
// send struct to all processes
MPI_Scatter(&A,index,mpi_tuples_str,B,index,mpi_tuples_str,0,MPI_COMM_WORLD);
// MPI_Bcast(&tmp,index,MPI_CHAR,0,MPI_COMM_WORLD);
for(i=0;i<=local_A_size;i++){
// MPI_Recv(&tmp,index,MPI_CHAR,0,10,MPI_COMM_WORLD,&status);
printf("I'm process %d and my result is: %s\n",my_rank,B[i].key);
}
if (my_rank == 0) printf("Data sent from process %d to others...\n",my_rank);
}
else
{
if (my_rank == 0) printf("Number of processes must be an exact divisor of %d, %d in not %ds divisor\n",index,size,index);
}
// free memory used by mpi_tuples_str
MPI_Type_free(&mpi_tuples_str);
// Finalize
MPI_Finalize();
return 0;
}`
但这导致我出现新的错误:
============================================================================== =====
= BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES
= EXIT CODE: 6
= CLEANING UP REMAINING PROCESSES
= YOU CAN IGNORE THE BELOW CLEANUP MESSAGES
============================================================================== =====
YOUR APPLICATION TERMINATED WITH THE EXIT STRING: Aborted (signal 6)
This typically refers to a problem with your application.
Please see the FAQ page for debugging suggestions
经过最后的建议!
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h> // used for offsetof
typedef struct tuple_str{
char key[10];
char index[12];
char value[52];
} tuple;
int main(int argc, char** argv) {
// Initialize the MPI environment
MPI_Init(NULL, NULL);
// Initialize file pointer
FILE *fp = fopen("tuples_mini","r");
// define original structure that stores file and temp used by each process
tuple A[10000],B[10000];
// mpi structure name
MPI_Datatype mpi_tuples_str;
// number of structure members
const int nitems = 3;
// array of structure member sizes
int blocklengths[3];
blocklengths[0] = 11;
blocklengths[1] = 33;
blocklengths[2] = 53;
// structure member types
MPI_Datatype types[3] = {MPI_CHAR,MPI_CHAR,MPI_CHAR};
// status
MPI_Status status;
// offset of structure members
MPI_Aint offsets[3];
offsets[0] = offsetof(tuple,key);
offsets[1] = offsetof(tuple,index);
offsets[2] = offsetof(tuple,value);
// create mpi struct
MPI_Type_create_struct(nitems,blocklengths, offsets, types, &mpi_tuples_str);
MPI_Type_commit(&mpi_tuples_str);
// Get the number of processes
int size;
MPI_Comm_size(MPI_COMM_WORLD, &size);
// Get the rank of the process
int my_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
int index = 0;
int i;
int local_A_size = (10000%size == 0) ? 10000/size : 0;
char *tmp[10000],*b[10000];
if ( my_rank == 0){
char text[10000];
char *p;
// p=strtok(NULL," ");
// node0 reads file form hard drive and saves file to struct
while( fgets(text,10000,fp) != NULL && fp != NULL){
p = strtok (text," ");
char *temp[3];
temp[0]=p;
strcpy(A[index].key,temp[0]);
p = strtok (NULL, " ");
temp[1] = p;
strcpy(A[index].index,temp[1]);
p = strtok (NULL, " ");
temp[2] = p;
strcpy(A[index].value,temp[2]);
printf("%s ",A[index].key);
printf("%s ",A[index].index);
printf("%s\n",A[index].value);
tmp[index] = temp[0];
// printf("%s\n",tmp[index]);
index++;
}
fclose(fp);
}
if ( local_A_size != 0){
if (my_rank == 0) {
printf("File saved to memory of process %d!\n",my_rank);
printf("Process %d sending struct data to others...\n",my_rank);
// MPI_Send(&A,index,mpi_tuples_str,0,10,MPI_COMM_WORLD);
}
// send struct to all processes
MPI_Scatter(&A,index,mpi_tuples_str,B,index,mpi_tuples_str,0,MPI_COMM_WORLD);
// MPI_Bcast(&tmp,index,MPI_CHAR,0,MPI_COMM_WORLD);
// MPI_Bcast(&A,index,mpi_tuples_str,0,MPI_COMM_WORLD);
for(i=0;i<=local_A_size;i++){
// MPI_Recv(&tmp,index,MPI_CHAR,0,10,MPI_COMM_WORLD,&status);
// MPI_Recv(&A,index,mpi_tuples_str,0,10,MPI_COMM_WORLD,&status);
printf("I'm process %d and my result is: %s\n",my_rank,B[i].key);
}
if (my_rank == 0) printf("Data sent from process %d to others...\n",my_rank);
}
else
{
if (my_rank == 0) printf("Number of processes must be an exact divisor of %d, %d in not %ds divisor\n",index,size,index);
}
// free memory used by mpi_tuples_str
MPI_Type_free(&mpi_tuples_str);
// Finalize
MPI_Finalize();
return 0;
}
关于发布代码的第二个版本
最有可能导致 signal 6/sigabort
的原因是第一次调用 strtok()
时第一个参数为 NULL 而不是可见缓冲区的地址。
IMO:第一次调用 strtok()
应该从程序中完全删除。
我在发布的代码中应用了所有关于问题的评论,这是结果:
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h> // used for offsetof
typedef struct tuple_str
{
char key[11];
char index[33];
char value[53];
} tuple;
int main( void )
{
// Initialize the MPI environment
MPI_Init( NULL, NULL );
// Initialize file pointer
FILE *fp = NULL;
if( NULL == ( fp = fopen( "tuples_mini" ,"r" ) ) )
{
perror( "fopen for read of truples_mini failed" );
exit( EXIT_FAILURE );
}
// implied else, fopen successful
// define original structure that stores file and temp used by each process
tuple A[10000];
tuple B[10000];
// mpi structure name
MPI_Datatype mpi_tuples_str;
// number of structure members
const int nitems = 3;
// array of structure member sizes
int blocklengths[3];
blocklengths[0] = 11;
blocklengths[1] = 33;
blocklengths[2] = 53;
// structure member types
MPI_Datatype types[3] = { MPI_CHAR, MPI_CHAR, MPI_CHAR };
// status
//MPI_Status status;
// offset of structure members
MPI_Aint offsets[3];
offsets[0] = offsetof( tuple,key);
offsets[1] = offsetof( tuple,index);
offsets[2] = offsetof( tuple,value);
// create mpi struct
MPI_Type_create_struct( nitems, blocklengths, offsets, types, &mpi_tuples_str);
MPI_Type_commit( &mpi_tuples_str);
// Get the number of processes
int size;
MPI_Comm_size( MPI_COMM_WORLD, &size);
// Get the rank of the process
int my_rank;
MPI_Comm_rank( MPI_COMM_WORLD, &my_rank);
int index = 0;
int i;
int local_A_size = (10000%size == 0) ? 10000/size : 0;
//char *tmp[10000];
//char *b[10000];
if ( my_rank == 0)
{
char text[10000];
char *p;
//p=strtok(NULL," ");
// node0 reads file from hard drive and saves file to struct
while( fgets( text, sizeof text, fp ) )
{
p = strtok (text," ");
char *temp[3];
temp[0]=p;
strcpy( A[index].key,temp[0]);
p = strtok (NULL, " ");
temp[1] = p;
strcpy( A[index].index,temp[1]);
p = strtok (NULL, " ");
temp[2] = p;
strcpy( A[index].value,temp[2]);
printf( "%s ",A[index].key);
printf( "%s ",A[index].index);
printf( "%s\n",A[index].value);
index++;
}
fclose(fp);
}
if ( local_A_size != 0)
{
if (my_rank == 0)
{
printf( "File saved to memory of process %d!\n",my_rank);
printf( "Process %d sending struct data to others...\n",my_rank);
}
// send struct to all processes
MPI_Scatter( &A,index, mpi_tuples_str, B, index, mpi_tuples_str, 0, MPI_COMM_WORLD;
// MPI_Bcast( &tmp,index, MPI_CHAR, 0, MPI_COMM_WORLD);
for(i=0;i<=local_A_size;i++)
{
// MPI_Recv( &tmp, index, MPI_CHAR, 0, 10, MPI_COMM_WORLD, &status);
printf( "I'm process %d and my result is: %s\n", my_rank, B[i].key);
}
if (my_rank == 0)
printf("Data sent from process %d to others...\n", my_rank);
}
else
{
if (my_rank == 0)
printf( "Number of processes must be an exact divisor of %d, %d in not %ds divisor\n", index, size,index);
}
// free memory used by mpi_tuples_str
MPI_Type_free( &mpi_tuples_str);
// Finalize
MPI_Finalize();
return 0;
}
我将 tuples_mini 文件设置为包含:
AsfAGHM5om 00000000000000000000000000000000 0000222200002222000022220000222200002222000000001111
当我 运行 我的 ubuntu linux 14.04 4 核处理器上的程序时,这是输出:
AsfAGHM5om 00000000000000000000000000000000 0000222200002222000022220000222200002222000000001111
File saved to memory of process 0!
Process 0 sending struct data to others...
I'm process 0 and my result is: AsfAGHM5om
I'm process 0 and my result is:
然后几十行:
I'm process 0 and my result is:
后跟这些行:
I'm process 0 and my result is:
I'm process 0 and my result is: AsfAGHM5om
Data sent from process 0 to others...
所以代码中好像有逻辑问题,但是没有seg fault
你好,我有一个包含这种数据行的文件:
AsfAGHM5om 00000000000000000000000000000000 0000222200002222000022220000222200002222000000001111
我想读取这种数据并使用C和MPI将它们发送过来。所以我得到了以下 C 代码:
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h> // used for offsetof
typedef struct tuple_str{
char *key;
char *index;
char *value;
} tuple;
int main(int argc, char** argv) {
// Initialize the MPI environment
MPI_Init(&argc, &argv);
// Initialize file pointer
FILE *fp = fopen("tuples","r");
// define original structure that stores file and temp used by each process
tuple A[10000],B[10000];
// mpi structure name
MPI_Datatype mpi_tuples_str;
// number of structure members
const int nitems = 3;
// array of structure member sizes
int blocklengths[3];
blocklengths[0] = sizeof(A->key);
blocklengths[1] = sizeof(A->index);
blocklengths[2] = sizeof(A->value);
// structure member types
MPI_Datatype types[3] = {MPI_CHAR,MPI_CHAR,MPI_CHAR};
// status
MPI_Status status;
// offset of structure members
MPI_Aint offsets[3];
offsets[0] = offsetof(tuple,key);
offsets[1] = offsetof(tuple,index);
offsets[2] = offsetof(tuple,value);
// create mpi struct
MPI_Type_create_struct(nitems,blocklengths, offsets, types, &mpi_tuples_str);
MPI_Type_commit(&mpi_tuples_str);
// Get the number of processes
int size;
MPI_Comm_size(MPI_COMM_WORLD, &size);
// Get the rank of the process
int my_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
int index = 0;
int i;
int local_A_size = (10000%size == 0) ? 10000/size : 0;
if ( my_rank == 0){
char text[10000];
char *p;
p=strtok(NULL," ");
// node0 reads file form hard drive and saves file to struct
while( fgets(text,10000,fp)!=NULL){
p = strtok (text," ");
char *temp[3];
temp[0]=p;
A[index].key=temp[0];
p = strtok (NULL, " ");
temp[1] = p;
A[index].index=temp[1];
p = strtok (NULL, " ");
temp[2] = p;
A[index].value=temp[2];
// printf("%s ",A[index].key);
// printf("%s ",A[index].index);
// printf("%s\n",A[index].value);
index++;
}
fclose(fp);
}
if ( local_A_size != 0){
if (my_rank == 0) {
printf("File saved to memory of process %d!\n",my_rank);
printf("Process %d sending struct data to others...\n",my_rank);
}
// send struct to all processes
MPI_Scatter(&A,local_A_size,mpi_tuples_str,B,local_A_size,mpi_tuples_str,0,MPI_COMM_WORLD);
// MPI_Bcast(&A,index,mpi_tuples_str,0,MPI_COMM_WORLD);
for(i=0;i<=local_A_size;i++)
printf("I'm process %d and my result is: %s\n",my_rank,B[i].key);
if (my_rank == 0) printf("Data sent from process %d to others...\n",my_rank);
}
else
{
if (my_rank == 0) printf("Number of processes must be an exact divisor of %d, %d in not %ds divisor\n",index,size,index);
}
// free memory used by mpi_tuples_str
MPI_Type_free(&mpi_tuples_str);
// Finalize
MPI_Finalize();
return 0;
}
所以这里的问题是,据我所知_首先创建和分配我的结构的内存,然后打包和发送它。
如您所见,我已经尝试了 MPI_Scatter
和 MPI_Bcast
,但其中 none 帮助了我。
结果是,正如它应该的那样,读取文件的进程 0 有数据,但所有其他进程没有。我还收到
= BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES
= EXIT CODE: 11
= CLEANING UP REMAINING PROCESSES
= YOU CAN IGNORE THE BELOW CLEANUP MESSAGES
如果有人能赐教,我将不胜感激!!
好的,我已将代码更改为以下内容:
`#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h> // used for offsetof
typedef struct tuple_str{
char key[10];
char index[12];
char value[52];
} tuple;
int main(int argc, char** argv) {
// Initialize the MPI environment
MPI_Init(NULL, NULL);
// Initialize file pointer
FILE *fp = fopen("tuples_mini","r");
// define original structure that stores file and temp used by each process
tuple A[10000],B[10000];
// mpi structure name
MPI_Datatype mpi_tuples_str;
// number of structure members
const int nitems = 3;
// array of structure member sizes
int blocklengths[3];
blocklengths[0] = sizeof(10);
blocklengths[1] = sizeof(12);
blocklengths[2] = sizeof(52);
// structure member types
MPI_Datatype types[3] = {MPI_CHAR,MPI_CHAR,MPI_CHAR};
// status
MPI_Status status;
// offset of structure members
MPI_Aint offsets[3];
offsets[0] = offsetof(tuple,key);
offsets[1] = offsetof(tuple,index);
offsets[2] = offsetof(tuple,value);
// create mpi struct
MPI_Type_create_struct(nitems,blocklengths, offsets, types, &mpi_tuples_str);
MPI_Type_commit(&mpi_tuples_str);
// Get the number of processes
int size;
MPI_Comm_size(MPI_COMM_WORLD, &size);
// Get the rank of the process
int my_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
int index = 0;
int i;
int local_A_size = (10000%size == 0) ? 10000/size : 0;
char *tmp[10000],*b[10000];
if ( my_rank == 0){
char text[10000];
char *p;
p=strtok(NULL," ");
// node0 reads file form hard drive and saves file to struct
while( fgets(text,10000,fp)!=NULL){
p = strtok (text," ");
char *temp[3];
temp[0]=p;
strcpy(A[index].key,temp[0]);
p = strtok (NULL, " ");
temp[1] = p;
strcpy(A[index].index,temp[1]);
p = strtok (NULL, " ");
temp[2] = p;
strcpy(A[index].value,temp[2]);
printf("%s ",A[index].key);
printf("%s ",A[index].index);
printf("%s\n",A[index].value);
index++;
}
fclose(fp);
}
if ( local_A_size != 0){
if (my_rank == 0) {
printf("File saved to memory of process %d!\n",my_rank);
printf("Process %d sending struct data to others...\n",my_rank);
}
// send struct to all processes
MPI_Scatter(&A,index,mpi_tuples_str,B,index,mpi_tuples_str,0,MPI_COMM_WORLD);
// MPI_Bcast(&tmp,index,MPI_CHAR,0,MPI_COMM_WORLD);
for(i=0;i<=local_A_size;i++){
// MPI_Recv(&tmp,index,MPI_CHAR,0,10,MPI_COMM_WORLD,&status);
printf("I'm process %d and my result is: %s\n",my_rank,B[i].key);
}
if (my_rank == 0) printf("Data sent from process %d to others...\n",my_rank);
}
else
{
if (my_rank == 0) printf("Number of processes must be an exact divisor of %d, %d in not %ds divisor\n",index,size,index);
}
// free memory used by mpi_tuples_str
MPI_Type_free(&mpi_tuples_str);
// Finalize
MPI_Finalize();
return 0;
}`
但这导致我出现新的错误:
============================================================================== =====
= BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES
= EXIT CODE: 6
= CLEANING UP REMAINING PROCESSES
= YOU CAN IGNORE THE BELOW CLEANUP MESSAGES
============================================================================== =====
YOUR APPLICATION TERMINATED WITH THE EXIT STRING: Aborted (signal 6)
This typically refers to a problem with your application.
Please see the FAQ page for debugging suggestions
经过最后的建议!
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h> // used for offsetof
typedef struct tuple_str{
char key[10];
char index[12];
char value[52];
} tuple;
int main(int argc, char** argv) {
// Initialize the MPI environment
MPI_Init(NULL, NULL);
// Initialize file pointer
FILE *fp = fopen("tuples_mini","r");
// define original structure that stores file and temp used by each process
tuple A[10000],B[10000];
// mpi structure name
MPI_Datatype mpi_tuples_str;
// number of structure members
const int nitems = 3;
// array of structure member sizes
int blocklengths[3];
blocklengths[0] = 11;
blocklengths[1] = 33;
blocklengths[2] = 53;
// structure member types
MPI_Datatype types[3] = {MPI_CHAR,MPI_CHAR,MPI_CHAR};
// status
MPI_Status status;
// offset of structure members
MPI_Aint offsets[3];
offsets[0] = offsetof(tuple,key);
offsets[1] = offsetof(tuple,index);
offsets[2] = offsetof(tuple,value);
// create mpi struct
MPI_Type_create_struct(nitems,blocklengths, offsets, types, &mpi_tuples_str);
MPI_Type_commit(&mpi_tuples_str);
// Get the number of processes
int size;
MPI_Comm_size(MPI_COMM_WORLD, &size);
// Get the rank of the process
int my_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
int index = 0;
int i;
int local_A_size = (10000%size == 0) ? 10000/size : 0;
char *tmp[10000],*b[10000];
if ( my_rank == 0){
char text[10000];
char *p;
// p=strtok(NULL," ");
// node0 reads file form hard drive and saves file to struct
while( fgets(text,10000,fp) != NULL && fp != NULL){
p = strtok (text," ");
char *temp[3];
temp[0]=p;
strcpy(A[index].key,temp[0]);
p = strtok (NULL, " ");
temp[1] = p;
strcpy(A[index].index,temp[1]);
p = strtok (NULL, " ");
temp[2] = p;
strcpy(A[index].value,temp[2]);
printf("%s ",A[index].key);
printf("%s ",A[index].index);
printf("%s\n",A[index].value);
tmp[index] = temp[0];
// printf("%s\n",tmp[index]);
index++;
}
fclose(fp);
}
if ( local_A_size != 0){
if (my_rank == 0) {
printf("File saved to memory of process %d!\n",my_rank);
printf("Process %d sending struct data to others...\n",my_rank);
// MPI_Send(&A,index,mpi_tuples_str,0,10,MPI_COMM_WORLD);
}
// send struct to all processes
MPI_Scatter(&A,index,mpi_tuples_str,B,index,mpi_tuples_str,0,MPI_COMM_WORLD);
// MPI_Bcast(&tmp,index,MPI_CHAR,0,MPI_COMM_WORLD);
// MPI_Bcast(&A,index,mpi_tuples_str,0,MPI_COMM_WORLD);
for(i=0;i<=local_A_size;i++){
// MPI_Recv(&tmp,index,MPI_CHAR,0,10,MPI_COMM_WORLD,&status);
// MPI_Recv(&A,index,mpi_tuples_str,0,10,MPI_COMM_WORLD,&status);
printf("I'm process %d and my result is: %s\n",my_rank,B[i].key);
}
if (my_rank == 0) printf("Data sent from process %d to others...\n",my_rank);
}
else
{
if (my_rank == 0) printf("Number of processes must be an exact divisor of %d, %d in not %ds divisor\n",index,size,index);
}
// free memory used by mpi_tuples_str
MPI_Type_free(&mpi_tuples_str);
// Finalize
MPI_Finalize();
return 0;
}
关于发布代码的第二个版本
最有可能导致 signal 6/sigabort
的原因是第一次调用 strtok()
时第一个参数为 NULL 而不是可见缓冲区的地址。
IMO:第一次调用 strtok()
应该从程序中完全删除。
我在发布的代码中应用了所有关于问题的评论,这是结果:
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h> // used for offsetof
typedef struct tuple_str
{
char key[11];
char index[33];
char value[53];
} tuple;
int main( void )
{
// Initialize the MPI environment
MPI_Init( NULL, NULL );
// Initialize file pointer
FILE *fp = NULL;
if( NULL == ( fp = fopen( "tuples_mini" ,"r" ) ) )
{
perror( "fopen for read of truples_mini failed" );
exit( EXIT_FAILURE );
}
// implied else, fopen successful
// define original structure that stores file and temp used by each process
tuple A[10000];
tuple B[10000];
// mpi structure name
MPI_Datatype mpi_tuples_str;
// number of structure members
const int nitems = 3;
// array of structure member sizes
int blocklengths[3];
blocklengths[0] = 11;
blocklengths[1] = 33;
blocklengths[2] = 53;
// structure member types
MPI_Datatype types[3] = { MPI_CHAR, MPI_CHAR, MPI_CHAR };
// status
//MPI_Status status;
// offset of structure members
MPI_Aint offsets[3];
offsets[0] = offsetof( tuple,key);
offsets[1] = offsetof( tuple,index);
offsets[2] = offsetof( tuple,value);
// create mpi struct
MPI_Type_create_struct( nitems, blocklengths, offsets, types, &mpi_tuples_str);
MPI_Type_commit( &mpi_tuples_str);
// Get the number of processes
int size;
MPI_Comm_size( MPI_COMM_WORLD, &size);
// Get the rank of the process
int my_rank;
MPI_Comm_rank( MPI_COMM_WORLD, &my_rank);
int index = 0;
int i;
int local_A_size = (10000%size == 0) ? 10000/size : 0;
//char *tmp[10000];
//char *b[10000];
if ( my_rank == 0)
{
char text[10000];
char *p;
//p=strtok(NULL," ");
// node0 reads file from hard drive and saves file to struct
while( fgets( text, sizeof text, fp ) )
{
p = strtok (text," ");
char *temp[3];
temp[0]=p;
strcpy( A[index].key,temp[0]);
p = strtok (NULL, " ");
temp[1] = p;
strcpy( A[index].index,temp[1]);
p = strtok (NULL, " ");
temp[2] = p;
strcpy( A[index].value,temp[2]);
printf( "%s ",A[index].key);
printf( "%s ",A[index].index);
printf( "%s\n",A[index].value);
index++;
}
fclose(fp);
}
if ( local_A_size != 0)
{
if (my_rank == 0)
{
printf( "File saved to memory of process %d!\n",my_rank);
printf( "Process %d sending struct data to others...\n",my_rank);
}
// send struct to all processes
MPI_Scatter( &A,index, mpi_tuples_str, B, index, mpi_tuples_str, 0, MPI_COMM_WORLD;
// MPI_Bcast( &tmp,index, MPI_CHAR, 0, MPI_COMM_WORLD);
for(i=0;i<=local_A_size;i++)
{
// MPI_Recv( &tmp, index, MPI_CHAR, 0, 10, MPI_COMM_WORLD, &status);
printf( "I'm process %d and my result is: %s\n", my_rank, B[i].key);
}
if (my_rank == 0)
printf("Data sent from process %d to others...\n", my_rank);
}
else
{
if (my_rank == 0)
printf( "Number of processes must be an exact divisor of %d, %d in not %ds divisor\n", index, size,index);
}
// free memory used by mpi_tuples_str
MPI_Type_free( &mpi_tuples_str);
// Finalize
MPI_Finalize();
return 0;
}
我将 tuples_mini 文件设置为包含:
AsfAGHM5om 00000000000000000000000000000000 0000222200002222000022220000222200002222000000001111
当我 运行 我的 ubuntu linux 14.04 4 核处理器上的程序时,这是输出:
AsfAGHM5om 00000000000000000000000000000000 0000222200002222000022220000222200002222000000001111
File saved to memory of process 0!
Process 0 sending struct data to others...
I'm process 0 and my result is: AsfAGHM5om
I'm process 0 and my result is:
然后几十行:
I'm process 0 and my result is:
后跟这些行:
I'm process 0 and my result is:
I'm process 0 and my result is: AsfAGHM5om
Data sent from process 0 to others...
所以代码中好像有逻辑问题,但是没有seg fault