Как отправить 2D-массив в MPI с изменением для каждого процессора

Я пытаюсь взять произвольно сгенерированный массив на корень 0, изменить его слегка и случайным образом и отправить каждый вариант другому процессору. Вот мой код:

#include "stdio.h" #include "stdlib.h" #include "mpi.h" #include "math.h" int main(int argc, char **argv) { int N = 32; int dim = 3; float a = 10.0; int size, rank, i, j, k, q; float **C; float rijx, rijy, rijz, rij, Vij, E=0; float stepsize = 0.05; double Start_time, End_time, Elapse_time; MPI_Status status; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &size); MPI_Comm_rank(MPI_COMM_WORLD, &rank); C = (float **)malloc(N * sizeof(float*)); // 32 particles for (i = 0; i < N; i++) { C[i]=(float *)malloc(dim*sizeof(float)); // x, y, z } MPI_Barrier(MPI_COMM_WORLD); if(rank == 0) { Start_time = MPI_Wtime(); } if (rank == 0) { for(i = 0; i < N; i++) { for(j = 0; j < dim; j++) { C[i][j] = (float)rand()/(float)(RAND_MAX/a); //printf("%f\n",C[i][j]); } } } // this is to generate some slight variations in the array float** randomsteps(float **matrix) { for(i = 0; i < N; i = i+(rand()%(32/size))) { for (j = 0; j  10) { C[i][j] = C[i][j] - 10; } } else { C[i][j] = C[i][j]-stepsize; if(C[i][j] < 0) { C[i][j] = C[i][j] + 10; } } } } return C; } // and here I try to send the array if(rank == 0) { for(i=0; i<size; i++) { C = randomsteps(C); MPI_Send(&C, N*3, MPI_FLOAT, i, 10+i, MPI_COMM_WORLD); } } if(rank != 0) { for(i=0; i<size; i++) { MPI_Recv(&C, N*3, MPI_FLOAT, 0, 10+i, MPI_COMM_WORLD, &status); } } MPI_Barrier(MPI_COMM_WORLD); MPI_Finalize(); return 0; } 

Очевидная проблема с кодом заключается в том, что способ генерирования случайных чисел несколько наивен (он дает одинаковые значения каждый раз, когда я запускаю программу). Это то, над чем я смогу работать позже.

На данный момент мне просто интересно: что не так с тем, как я отправляю и получаю массив? У меня много проблем, обертывая голову тем, как лучше форматировать данные при отправке и получении с использованием MPI. Как я могу исправить эту часть кода?

Заранее спасибо за помощь!

Проблема здесь в том, что все вызовы MPI ожидают, что память смежна. Ваша память только смежна в данной строке, и то, что вы называете 2D-массивом, действительно представляет собой массив указателей. Указатели не переносимы, поэтому попытка отправки или трансляции массива указателей на другой процесс не имеет смысла, а сам MPI не поддерживает глубокую копию, поэтому такой подход не будет работать.

Однако, если вы измените распределение массива на что-то вроде этого:

  float** C; float* C_buff; C = (float**)malloc(N * sizeof(float*)); // 32 particles C_buff = (float*)malloc(N * dim * sizeof(float)); // buffer for particles float* p = &C_buff[0]; for (i = 0; i < N; i++) { C[i]=p; p+= dim*sizeof(float)); } 

[отказ от ответственности: написан в браузере, полностью непроверенный, использовать на свой страх и риск]

так что C_buff представляет непрерывную память для вашего 2D-массива, а C содержит указатели строк в памяти в непрерывном распределении C_buff , тогда вы можете использовать свой существующий код для инициализации, но затем выполните примерно так:

 MPI_Send(&C_buff[0][0], N*DIM, MPI_FLOAT, i, 10+i, MPI_COMM_WORLD); 

то есть. используйте C_buff для вызовов MPI, и он должен работать.