问题描述:

Hello I have a file containing that kind of data lines:

AsfAGHM5om 00000000000000000000000000000000 0000222200002222000022220000222200002222000000001111

I want to read this kind of data and send them over using C and MPI. So I've reached the following C code:

 #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;

}

So the problem here is, as far as I can understand_ the creation and allocation of memory of my struct at first and the packing and sending of it at second.

As you can see I've tried both MPI_Scatter & MPI_Bcast but none of them helped me.

The result is that, as it supposed to, process 0 that reads the file has data but all others not. Also I'm getting this weird message of

= BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES

= EXIT CODE: 11

= CLEANING UP REMAINING PROCESSES

= YOU CAN IGNORE THE BELOW CLEANUP MESSAGES

I'll be so grateful if someone can enlighten me!!

Alright I 've changed my code to the following:

`#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;

}`

but that lead me to new error:

 ============================================================================== =====

= 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

after last 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;

}

网友答案:

I applied all the comments about problems in the posted code, this is the result:

#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;
}

I setup the tuples_mini file to contain:

AsfAGHM5om  00000000000000000000000000000000  0000222200002222000022220000222200002222000000001111

when I ran the program on my ubuntu linux 14.04 with 4 core processor, this is the output:

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: 

then several dozens of this line:

I'm process 0 and my result is: 

followed by these lines:

I'm process 0 and my result is: 
I'm process 0 and my result is: AsfAGHM5om
Data sent from process 0 to others...

so there seems to be a logic problem in the code, but it does not seg fault

网友答案:

on the second version of the posted code

The most likely cause of the signal 6/sigabort is because the first call to strtok() has NULL as the first parameter rather than the address of a visible buffer.

IMO: that first call to strtok() should be completely removed from the program.

相关阅读:
Top