Ошибка выхода OpenMPI

Я использую OpenMPI 1.3 для небольшого кластера.

Это функция, которую я вызываю:

void invertColor_Parallel(struct image *im, int size, int rank) { int i,j,aux,r; int total_pixels = (*im).ih.width * (*im).ih.height; int qty = total_pixels/(size-1); int rest = total_pixels % (size-1); MPI_Status status; //printf("\n%d\n", rank); if(rank == 0) { for(i=1; i<size; i++){ j = i*qty - qty; aux = j; if(rest != 0 && i==size-1) {qty=qty+rest;} //para distrubuir toda la carga //printf("\nj: %d qty: %d rest: %d\n", j, qty, rest); MPI_Send(&aux, 1, MPI_INT, i, MASTER_TO_SLAVE_TAG+1, MPI_COMM_WORLD); MPI_Send(&qty, 1, MPI_INT, i, MASTER_TO_SLAVE_TAG+2, MPI_COMM_WORLD); MPI_Send(&(*im).array[j], qty*3, MPI_BYTE, i, MASTER_TO_SLAVE_TAG, MPI_COMM_WORLD); } } else { MPI_Recv(&aux, 1, MPI_INT, MPI_ANY_SOURCE, MASTER_TO_SLAVE_TAG+1, MPI_COMM_WORLD,&status); MPI_Recv(&qty, 1, MPI_INT, MPI_ANY_SOURCE, MASTER_TO_SLAVE_TAG+2, MPI_COMM_WORLD,&status); pixel *arreglo = (pixel *)calloc(qty, sizeof(pixel)); MPI_Recv(&arreglo[0], qty*3, MPI_BYTE, MPI_ANY_SOURCE, MASTER_TO_SLAVE_TAG, MPI_COMM_WORLD,&status); //printf("Receiving node=%d, message=%d\n", rank, aux); for(i=0;i<qty;i++) { arreglo[i].R = 255-arreglo[i].R; arreglo[i].G = 255-arreglo[i].G; arreglo[i].B = 255-arreglo[i].B; } MPI_Send(&aux, 1, MPI_INT, 0, SLAVE_TO_MASTER_TAG+1, MPI_COMM_WORLD); MPI_Send(&qty, 1, MPI_INT, 0, SLAVE_TO_MASTER_TAG+2, MPI_COMM_WORLD); MPI_Send(&arreglo[0], qty*3, MPI_BYTE, 0, SLAVE_TO_MASTER_TAG, MPI_COMM_WORLD); free(arreglo); } if (rank==0){ //printf("\nrank: %d\n", rank); for (i=1; i<size; i++) // untill all slaves have handed back the processed data { MPI_Recv(&aux, 1, MPI_INT, MPI_ANY_SOURCE, SLAVE_TO_MASTER_TAG+1, MPI_COMM_WORLD,&status); MPI_Recv(&qty, 1, MPI_INT, MPI_ANY_SOURCE, SLAVE_TO_MASTER_TAG+2, MPI_COMM_WORLD,&status); MPI_Recv(&(*im).array[aux], qty*3, MPI_BYTE, MPI_ANY_SOURCE, SLAVE_TO_MASTER_TAG, MPI_COMM_WORLD,&status); } } } int main(int argc, char *argv[]) { //////////time counter clock_t begin; int rank, size; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &size); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Status status; int op = (int)atof(argv[1]); char filename_toload[50]; int bright_number=0; struct image image2; if (rank==0) { loadImage(&image2, argv[2]); } //Broadcast the user's choice to all other ranks MPI_Bcast(&op, 1, MPI_INT, 0, MPI_COMM_WORLD); switch(op) { case 1: if (rank==0) {begin = clock();} MPI_Barrier(MPI_COMM_WORLD); invertColor_Parallel(&image2, size, rank); MPI_Barrier(MPI_COMM_WORLD); if (rank==0) {runningTime(begin, clock()); printf("Se invirtieron los colores de la imagen\n\n");} break; } MPI_Barrier(MPI_COMM_WORLD); if (rank==0) { saveImage(&image2, argv[3]); free(image2.array); } MPI_Finalize(); return 0; } 

и иногда я получаю следующую ошибку.

 cluster@maestro:/mpi$ mpirun -np 60 -hostfile /home/hostfile paralelo 1 image.bmp out.bmp cluster@nodo1's password: [maestro:5194] *** An error occurred in MPI_Recv [maestro:5194] *** on communicator MPI_COMM_WORLD [maestro:5194] *** MPI_ERR_TRUNCATE: message truncated [maestro:5194] *** MPI_ERRORS_ARE_FATAL (your MPI job will now abort) -------------------------------------------------------------------------- mpirun has exited due to process rank 0 with PID 5194 on node maestro exiting without calling "finalize". This may have caused other processes in the application to be terminated by signals sent by mpirun (as reported here). -------------------------------------------------------------------------- [nodo1] [[49223,1],55][../../../../../../ompi/mca/btl/tcp/btl_tcp_frag.c:216:mca_btl_tcp_frag_recv] mca_btl_tcp_frag_recv: readv failed: Connection reset by peer (104) 

Это зависит от того, будет ли процесс -np 99 ошибку или нет, например, с -np 99 работает очень хорошо.

Любая идея о том, что происходит?

    Этот код, вероятно, является виновником:

     if (rank==0){ //printf("\nrank: %d\n", rank); for (i=1; i 

    Поскольку вы (ab-) используете MPI_ANY_SOURCE , вы, по сути, создаете идеальные условия для рассылок приема сообщений. Вполне возможно, что первый MPI_Recv соответствует сообщению из ранга i , второй соответствует сообщению из ранга j, а третий соответствует сообщению из ранга k , где i , j и k имеют совершенно разные значения. Поэтому возможно, что вы получили неправильное количество пикселей в неправильном слоте изображения. Кроме того, если это произойдет, то ранг k отправляет больше пикселей, чем значение qty из значения j j , вы получите ошибку усечения (и вы на самом деле получаете его). Совет: никогда не используйте MPI_ANY_SOURCE легкомысленно, если не MPI_ANY_SOURCE абсолютно уверены, что алгоритм верен, и никакие расы не могут произойти.

    Перепишите код как:

     if (rank==0){ //printf("\nrank: %d\n", rank); for (i=1; i 

    или даже лучше:

     if (rank==0){ //printf("\nrank: %d\n", rank); for (i=1; i 

    Таким образом, три получателя всегда получат сообщения от одного и того же процесса, и состояние гонки будет устранено. Способ, которым работает вторая версия, состоит в том, что он сначала получает сообщение от любого ранга, но затем использует поле status.MPI_SOURCE чтобы получить фактический ранг и использовать его для следующего получения.