void* evaluate(void) { int ulx, uly, lrx, lry; int i, j, region_size, len0, len1; char *region,*aux, *pgrid; struct work_t *WorkToDo; while (( WorkToDo = GetWork()) != NULL) { /* Apenas para simplificar a visualização do código, copia para variáveis locais */ ulx = WorkToDo->ulx; uly = WorkToDo->uly; lrx = WorkToDo->lrx; lry = WorkToDo->lry; region_size = (lrx - ulx + 1) * (lry - uly +1); region = (char *) malloc( sizeof(char) * region_size); if (region == NULL) { printf("Memory allocation error on evaluate (region)...\n"); exit(0); } aux = region; for(i = uly ; i <= lry ; i++) for(j =ulx ; j <=lrx; j ++) *aux++=xy2color(translate_x + scale_x*j, translate_y + scale_y*i); len0 = lrx - ulx + 1; len1 = lry - uly + 1; pgrid = grid + (IMAGE_SIZE * uly + ulx); aux = region; for (i = 0; i < len1; ++i) { memcpy(pgrid, aux, len0); aux += len0; pgrid += IMAGE_SIZE; } free(region); } /* Final do while */ pthread_exit(0); }
int main(int argc, char *argv[]) { /* Domaine de calcul dans le plan complexe */ double xmin, ymin; double xmax, ymax; /* Dimension de l'image */ int w,h; /* Le nombre de lignes pour chaque block*/ int nb_lignes = 20; /* Pas d'incrementation */ double xinc, yinc; /* Profondeur d'iteration */ int prof; /* Déclaration de true et false*/ int true = 1; int false = 0; /* Image resultat */ unsigned char *ima, *pima, *ima_loc, *pima_loc; /* Variables intermediaires */ int i, j; double x, y; /* Chronometrage */ double debut, fin; /* debut du chronometrage */ debut = my_gettimeofday(); if( argc == 1) fprintf( stderr, "%s\n", info); /* Valeurs par defaut de la fractale */ xmin = -2; ymin = -2; xmax = 2; ymax = 2; w = h = 800; prof = 10000; /* Recuperation des parametres */ if( argc > 1) w = atoi(argv[1]); if( argc > 2) h = atoi(argv[2]); if( argc > 3) xmin = atof(argv[3]); if( argc > 4) ymin = atof(argv[4]); if( argc > 5) xmax = atof(argv[5]); if( argc > 6) ymax = atof(argv[6]); if( argc > 7) prof = atoi(argv[7]); /* Calcul des pas d'incrementation */ xinc = (xmax - xmin) / (w-1); yinc = (ymax - ymin) / (h-1); /**** INIT MPI ****/ int rank, p; MPI_Init(&argc, &argv); /* starts MPI */ MPI_Comm_rank(MPI_COMM_WORLD, &rank); /* get current process id */ MPI_Comm_size(MPI_COMM_WORLD, &p); if (p < 2) { printf("Erreur : le nombre de processeurs n'est pas suffisant\n"); MPI_Finalize(); return 0; } if (h % nb_lignes != 0) { printf("Erreur : la hauteur n'est pas multiple du nombre de lignes de chaque bloc"); MPI_Finalize(); return 0; } int fini = 0; int nb_blocs = h / nb_lignes; int nb_bloc_recus = 0; int nb_bloc_envoyes = 0; // numero du bloc à envoyé mais aussi le nombre de blocs envoyés int num_bloc = 0; //int end_nb_bloc = -1; MPI_Status status; /**** ****/ if (p-1 > nb_blocs) { printf("Erreur : le nombre de processeurs n'est pas suffisant car inférieur au nombre de blocs\n"); MPI_Finalize(); return 0; } if (rank == MAITRE) { /* affichage parametres pour verificatrion */ fprintf(stdout, "Affichage des paramètres pour vérification\n"); fprintf( stderr, "Master : %d/%d\n", rank+1, p); fprintf( stderr, " Domaine: {[%lg,%lg]x[%lg,%lg]}\n", xmin, ymin, xmax, ymax); fprintf( stderr, " Increment : %lg %lg\n", xinc, yinc); fprintf( stderr, " Prof: %d\n", prof); fprintf( stderr, " Dim image: %dx%d\n", w, h); /* Allocation memoire du tableau resultat */ pima = ima = (unsigned char *)malloc(w * h * sizeof(unsigned char)); if (ima == NULL) { fprintf(stderr, "Erreur allocation mémoire du tableau \n"); return 0; } for (i = 1; i < p; i++) { MPI_Send(&nb_bloc_envoyes, 1, MPI_INT, i, TAG_REQ, MPI_COMM_WORLD); nb_bloc_envoyes++; } while (fini == false) { MPI_Probe(MPI_ANY_SOURCE, TAG_REQ, MPI_COMM_WORLD, &status); int s = status.MPI_SOURCE; if(s != MAITRE) { MPI_Recv(&num_bloc, 1, MPI_INT, MPI_ANY_SOURCE, TAG_REQ, MPI_COMM_WORLD, &status); MPI_Recv(&ima[num_bloc * nb_lignes * w], nb_lignes * w, MPI_CHAR, s, TAG_DATA, MPI_COMM_WORLD, &status); nb_bloc_recus++; if (nb_bloc_envoyes < nb_blocs) { /*Il reste encore des blocs à calculer */ MPI_Send(&nb_bloc_envoyes, 1, MPI_INT, s, TAG_REQ, MPI_COMM_WORLD); MPI_Send(&false, 1, MPI_INT, s, TAG_END, MPI_COMM_WORLD); nb_bloc_envoyes++; } else { /*Il reste plus de calcul à faire*/ MPI_Send(&true, 1, MPI_INT, s, TAG_END, MPI_COMM_WORLD); } if (nb_bloc_recus == nb_blocs) { // Le calcul est fini fini = true; /* fin du chronometrage */ fin = my_gettimeofday(); fprintf(stderr, "Temps total de calcul : %g sec\n", fin - debut); //fprintf(stdout, "%g\n", fin - debut); /* Sauvegarde de la grille dans le fichier resultat "mandel.ras" */ sauver_rasterfile("output/mandel2.ras", w, h, ima); } } } } else { // Allocation en local ima_loc = (unsigned char *)malloc(nb_lignes * w * sizeof(unsigned char)); if (ima_loc == NULL) { fprintf(stderr, "Erreur allocation mémoire du tableau !\n"); return 0; } while (fini == false) { MPI_Recv(&num_bloc, 1, MPI_INT, MAITRE, TAG_REQ, MPI_COMM_WORLD, &status); pima_loc = ima_loc; /* Traitement de la grille point par point */ y = ymin + nb_lignes * num_bloc * yinc; for (i = 0; i < nb_lignes; i++) { x = xmin; for (j = 0; j < w; j++) { *pima_loc++ = xy2color(x, y, prof); x += xinc; } y += yinc; } MPI_Send(&num_bloc, 1, MPI_INT, MAITRE, TAG_REQ, MPI_COMM_WORLD); MPI_Send(ima_loc, nb_lignes * w, MPI_CHAR, MAITRE, TAG_DATA, MPI_COMM_WORLD); MPI_Recv(&fini, 1, MPI_INT, MAITRE, TAG_END, MPI_COMM_WORLD, &status); } fin = my_gettimeofday(); fprintf(stderr, "Fin du processus : %d , Temps de calcul total : %g sec\n", rank+1, fin - debut); } MPI_Finalize(); return 0; }
int main(int argc, char *argv[]) { /* Domaine de calcul dans le plan complexe */ double xmin, ymin; double xmax, ymax; /* Dimension de l'image */ int w,h; /* Pas d'incrementation */ double xinc, yinc; /* Profondeur d'iteration */ int prof; /* Image resultat */ unsigned char *ima, *pima, *ima_loc, *pima_loc; /* Variables intermediaires */ int i, j; double x, y; /* Chronometrage */ double debut, fin; /* debut du chronometrage */ debut = my_gettimeofday(); if( argc == 1) fprintf( stderr, "%s\n", info); /* Valeurs par defaut de la fractale */ xmin = -2; ymin = -2; xmax = 2; ymax = 2; w = h = 800; prof = 10000; /* Recuperation des parametres */ if( argc > 1) w = atoi(argv[1]); if( argc > 2) h = atoi(argv[2]); if( argc > 3) xmin = atof(argv[3]); if( argc > 4) ymin = atof(argv[4]); if( argc > 5) xmax = atof(argv[5]); if( argc > 6) ymax = atof(argv[6]); if( argc > 7) prof = atoi(argv[7]); /* Calcul des pas d'incrementation */ xinc = (xmax - xmin) / (w-1); yinc = (ymax - ymin) / (h-1); /* affichage parametres pour verificatrion */ fprintf( stderr, "Domaine: {[%lg,%lg]x[%lg,%lg]}\n", xmin, ymin, xmax, ymax); fprintf( stderr, "Increment : %lg %lg\n", xinc, yinc); fprintf( stderr, "Prof: %d\n", prof); fprintf( stderr, "Dim image: %dx%d\n", w, h); /**** INIT MPI ****/ int rank, p; MPI_Init(&argc, &argv); /* starts MPI */ MPI_Comm_rank(MPI_COMM_WORLD, &rank); /* get current process id */ MPI_Comm_size(MPI_COMM_WORLD, &p); if (h % p != 0) { printf("Erreur : la hauteur n'est pas divisible pas le nombre de processus\n"); MPI_Finalize(); return 0; } if (p < 1) { printf("Erreur : le nombre de processus n'est pas suffisant\n"); MPI_Finalize(); return 0; } //nb_lignes = 10; // pour la distri dynamique int h_loc = h / p; /**** ****/ if (rank == MAITRE) { /* Allocation memoire du tableau resultat */ pima = ima = (unsigned char *)malloc(w * h * sizeof(unsigned char)); if( ima == NULL) { fprintf( stderr, "Erreur allocation mémoire du tableau \n"); return 0; } // Decalage à la position du master //pima += rank * w * h_loc; // inutile car MAITRE == 0 /* Traitement de la grille point par point */ y = ymin + h_loc * rank * yinc; for (i = 0; i < h_loc; i++) { x = xmin; for (j = 0; j < w; j++) { *pima++ = xy2color(x, y, prof); x += xinc; } y += yinc; } // Reception des slaves : MPI_Status status; for (i = 0; i < p; i++) { if (i != MAITRE) { MPI_Probe(MPI_ANY_SOURCE, TAG_DATA, MPI_COMM_WORLD, &status); int s = status.MPI_SOURCE; // rank de la source if (s != MAITRE) { MPI_Recv(ima + s * h_loc * w * sizeof(unsigned char), h_loc * w, MPI_CHAR, s, TAG_DATA, MPI_COMM_WORLD, &status); } } } /* fin du chronometrage */ fin = my_gettimeofday(); fprintf( stderr, "Temps total de calcul : %g sec\n", fin - debut); fprintf( stdout, "%g\n", fin - debut); /* Sauvegarde de la grille dans le fichier resultat "mandel.ras" */ sauver_rasterfile( "output/mandel.ras", w, h, ima); } else { // Allocation en local pima_loc = ima_loc = (unsigned char *)malloc(w * h_loc * sizeof(unsigned char)); /* Traitement de la grille point par point */ y = ymin + h_loc * rank * yinc; // y_rank for (i = 0; i < h_loc; i++) { x = xmin; for (j = 0; j < w; j++) { *pima_loc++ = xy2color(x, y, prof); x += xinc; } y += yinc; } // Envoie au master MPI_Send(ima_loc, h_loc * w, MPI_CHAR, MAITRE, TAG_DATA, MPI_COMM_WORLD); } MPI_Finalize(); return 0; }