MPI masortingce-vecteur-multiplication renvoie parfois des valeurs parfois étranges

J’ai le code suivant:

//Start MPI... MPI_Init(&argc, &argv); int size = atoi(argv[1]); int delta = 10; int rnk; int p; int root = 0; MPI_Status mystatus; MPI_Comm_rank(MPI_COMM_WORLD, &rnk); MPI_Comm_size(MPI_COMM_WORLD, &p); //Checking compatibility of size and number of processors assert(size % p == 0); //Initialize vector... double *vector = NULL; vector = malloc(size*sizeof(double)); double *masortingx = NULL; //Rank 0 ----------------------------------- if (rnk == 0) { //Initialize vector... srand(1); for (int i = 0; i < size; i++) { vector[i] = rand() % delta + 1; } printf("Initial vector:"); print_vector(vector, size); //Initialize matrix... matrix = malloc(size*size*sizeof(double)); srand(2); for (int i = 0; i < (size*size); i++) { matrix[i] = rand() % delta + 1; } //Print matrix... printf("Initial matrix:"); print_flat_matrix(matrix, size); } //Calculating chunk_size... int chunk_size = size/p; //Initialize submatrix.. double *submatrix = malloc(size*chunk_size*sizeof(double)); //Initialize result vector... double *result = malloc(chunk_size*sizeof(double)); //Broadcasting vector... MPI_Bcast(vector, size, MPI_DOUBLE, root, MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD); //Scattering matrix... MPI_Scatter(matrix, (size*chunk_size), MPI_DOUBLE, submatrix, (size*chunk_size), MPI_DOUBLE, root, MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD); printf("I am rank %d and first element of my vector is: %f and of my matrix1: %f/matrix2: %f/matrix3: %f/matrix4: %f\n", rnk, vector[0], submatrix[0], submatrix[1], submatrix[2], submatrix[3]); //Calculating... for (int i = 0; i < chunk_size; i++) { for (int j = 0; j < size; j++) { result[i] += (submatrix[(i*size)+j] * vector[j]); printf("Rank %d; current result: %f, ", rnk, result[i]); } printf("\n"); printf("Rank %d; result: %f...\n", rnk, result[i]); } printf("Rank: %d; first result: %f\n", rnk, result[0]); double *final_result = NULL; //Rank 0 ----------------------------------- if (rnk == 0) { final_result = malloc(size*sizeof(double)); } //Gather... MPI_Gather(result, chunk_size, MPI_DOUBLE, final_result, chunk_size, MPI_DOUBLE, root, MPI_COMM_WORLD); //Rank 0 ----------------------------------- if (rnk == 0) { printf("Final result:\n"); print_vector(final_result, size); free(matrix); free(final_result); } free(submatrix); free(result); free(vector); MPI_Finalize(); 

Lorsque j’exécute le programme, il s’exécute sans erreur, mais les valeurs imprimées à la fin ne sont pas toujours les bonnes. Parfois, je reçois le vecteur avec une sortie correcte, parfois partiellement et parfois totalement faux. Les valeurs fausses sont soit fausses de exactement la valeur 2, soit une séquence de nombres très longue et inutile (ce qui me semble devoir être un mauvais access à la mémoire, mais je ne trouve rien et aussi travaux).

Je choisis aussi toujours ma taille pour qu’elle corresponde au nombre de processus créés par mpi. mpi crée 4 processus sur ma machine (valeur testée et vérifiée), donc pour tester mon algorithme, j’ai toujours choisi 4 comme valeur pour la taille. Le même problème se produit également avec des tailles plus grandes.

Dans l’attente de votre aide et de vos consortingbutions, merci d’avance!

PS: je suis en C

Connaissez-vous Valgrind? Cela attirera immédiatement votre attention sur la ligne problématique.

Votre problème semble être cette ligne:

 result[i] += (submasortingx[(i*size)+j] * vector[j]); 

Quel était le résultat [] initialement? Il a été retiré du tas. Parfois, si vous avez de la chance, ce sera zéro. Ne comptez pas sur votre chance avec C.

Il y a plusieurs façons d’initialiser le tableau. Voici quelques approches, classées par ordre de priorité pour être optimisées:

Allouer le résultat [] avec calloc:

 double *result = calloc(chunk_size , sizeof(double)); 

Ou initialisez le tableau avec memset:

 double *result = malloc(chunk_size *sizeof(double)); memset(result, 0, chunk_size *sizeof(double)); 

ou, on pourrait faire une boucle sur le tableau

 for (i=0; i < chunk_size; i++) result[i] = 0.0