Второй MPI_Send висит, если размер буфера превышает 256

int n, j, i, i2, i3, rank, size, rowChunk, **cells, **cellChunk; MPI_Status status; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); if(!rank){ printf("\nEnter board size:\n"); fflush(stdout); scanf("%d", &n); printf("\nEnter the total iterations to play:\n"); fflush(stdout); scanf("%d", &j); srand(3); rowChunk = n/size; //how many rows each process will get for(i=1; i<size; i++){ MPI_Send(&n,1, MPI_INT, i, 0, MPI_COMM_WORLD); MPI_Send(&j,1, MPI_INT, i, 7, MPI_COMM_WORLD); } cells = (int**) malloc(n*sizeof(int*)); //create main 2D array for(i=0; i<n; i++){ cells[i] = (int*) malloc(n*sizeof(int)); } for(i=0; i<n; i++){ for(i2=0; i2<n; i2++){ //fill array with random data cells[i][i2] = rand() % 2; } } for(i=1; i<size; i++){ //send blocks of rows to each process for(i2=0; i2<rowChunk; i2++){ //this works for all n MPI_Send(cells[i2+(rowChunk*i)], n, MPI_INT, i, i2, MPI_COMM_WORLD); } } cellChunk = (int**) malloc(rowChunk*sizeof(int*)); for(i=0; i<rowChunk; i++){ //declare 2D array for process zero's array chunk cellChunk[i] = (int*) malloc(n*sizeof(int)); } for(i=0; i<rowChunk; i++){ //give process zero it's proper chunk of the array for(i2=0; i2<n; i2++){ cellChunk[i][i2] = cells[i][i2]; } } for(i3=1; i3256 MPI_Send(cellChunk[rowChunk-1], n, MPI_INT, 1,2,MPI_COMM_WORLD); //also hangs if n > 256 ... //Leaving out code that works 

Этот код работает отлично, если n (размер массива) меньше или равен 256. Любой больше, и он зависает на первом MPI_Send. Кроме того, при отправке массивов строк массива другим процессам (сначала MPI_Send) другие процессы получают свои данные отлично, даже если n> 256. Что может привести к тому, что именно этот MPI_Send будет зависать, если размер буфера превышает 256?

Вы никогда не получаете никаких сообщений, поэтому код заполняет местное пространство буфера MPI, а затем тупик, ожидающий вызова MPI_Recv (или аналогичного), который должен быть запущен. Вам нужно будет вставить операции приема, чтобы ваши сообщения действительно отправлялись и обрабатывались получателями.

MPI_Send – это блокирующий вызов. Стандарт предусматривает, что MPI_Send может вернуть управление уже в буфере сообщений, которое может быть безопасно изменено. Кроме того, MPI_Send может ждать возвращения до некоторого времени после запуска или завершения MPI_Recv.

Реализация MPI, который вы используете, скорее всего, выполняет «нетерпеливую» прогрессию сообщения, если сообщение <256 count (с типом данных MPI_INT это будет сообщение 1k). Сообщение копируется в другой буфер, и управление возвращается «раньше». Для больших (r) сообщений вызов MPI_Send не возвращается до тех пор, пока (по крайней мере) не будет выполнен соответствующий запрос MPI_Recv.

Если вы опубликуете полный репроектор, вы, скорее всего, получите лучший ответ.

MPI_Send “может блокироваться до тех пор, пока сообщение не будет получено.”, Поэтому, скорее всего, совпадение не будет достигнуто. Вы должны убедиться, что MPI_Recv s размещены в правильном порядке. Поскольку вы не отправляли свою часть приема, невозможно сообщить подробности.

Вы можете реструктурировать свое приложение, чтобы убедиться, что соответствие получено в порядке. Вам также может быть удобно использовать комбинированный MPI_Sendrecv или неблокирующий MPI_Isend , MPI_Irecv и MPI_Wait .