Пример #1
0
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);
}  
Пример #2
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;
}
Пример #3
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;
}