0

I'm trying to gather different struct into an pointer of struct which is inside a struct.

A container container a cartesian 2d, the cartesian2d contains a pointer of grid.

I tried to first gather with the type MPI_Byte, but the gather hanged indefinitely.

Now I created a data_type, but I receive a segfault on the process 0.

Here is the three structs involved and some relevant code, I won't post all my program since it's pretty long, but I know the create_grid function cause no problem:

typedef struct grid {
  int *data;
    int width;
    int height;
    int padding;
    int pw;
    int ph;
} 

typedef struct cartesian {
    grid_t **grids;
    int width;
    int height;
} 

typedef struct container {
  cart_t* cartesian;
  grid_t* global_grid;
  grid_t* curr_grid;
  grid_t* next_grid;
  int numprocs;
  int rank;
  MPI_Comm communication;
  // Other irrelevant stuff
} container_t


// Inside the gather function

grid* local_grid = create_grid_withpadding(container->next_grid, 0);

MPI_Datatype struct_type;
MPI_Datatype final_type;
MPI_Aint lb, extent;
MPI_Datatype array_of_types [6] = { MPI_INT, MPI_INT,MPI_INT,MPI_INT,MPI_INT,MPI_INT};
   int array_of_blocklengths[6] = { local_grid->height*local_grid->width, 1, 1, 1, 1, 1};
MPI_Aint array_of_displacements[6] = {  offsetof( grid, data ), offsetof( grid, width), offsetof( grid, height), 
   offsetof( grid, padding), offsetof( grid, pw),  offsetof( grid,ph) };
MPI_Type_create_struct( 6, array_of_blocklengths, array_of_displacements,
                        array_of_types, &struct_type );
MPI_Type_get_extent( struct_type, &lb, &extent );
MPI_Type_create_resized( struct_type, lb, extent, &final_type );
MPI_Type_commit( &final_type );
  
if (container->rank == 0) {
 
     MPI_Gather(&local_grid[0], 1, final_type, 
     &container->cartesian->grids[0][0],1, final_type, 0, 
     container->communication);
    }

What should I change in my code?

  • 1
    1. fix your indentation. 2. a gather within a conditional doesn't work. 3. what is the point of resizing a type with the lb and extent it already has? – Victor Eijkhout Dec 06 '21 at 02:47
  • I inspired myself from this example, which said that you needed to do it if you wanted to receive multiple struct in a gather: https://stackoverflow.com/questions/33618937/trouble-understanding-mpi-type-create-struct. As for the conditional, it's there because I want only the first process (rank == 0) to retrieve the local_grid of all other process. Fixed indentation. – NearFinished_CS Dec 06 '21 at 02:57
  • 1
    Gather is a collective call, meaning that every process (in the communicator) should call it. Only the root receives, but every other process calls it to send the data. How did you think process zero would receive data if the others don't do anything? – Victor Eijkhout Dec 06 '21 at 03:06
  • 1
    Next, you say you get a segfault. On what call? I'm not even sure what you're gathering. What is the type of `local_grid`? Is that a pointer to grid or an array of? No matter: your `grid` contains an `int*` and you can not gather those. Assuming that that's an array, MPI doesn't magically pack it up. It doesn't even know how long the array is. Why don't you experiment with a much simpler code until the have the basics working? This has too many moving parts. – Victor Eijkhout Dec 06 '21 at 03:14
  • Thank you, this is cleary a basic concept I didn't grasp. Now the program doesn't hang anymore but I receive segmentation fault on random process. I will look into this next problem. – NearFinished_CS Dec 06 '21 at 03:21
  • To answer you question, local_grid is a pointer to grid. I might be gathering the wrong thing, I will look into it. – NearFinished_CS Dec 06 '21 at 03:22

0 Answers0