Пример #1
0
void
CalcSubSurface(int xmin, int xmax,
               int ymin, int ymax, int pmin, int pmax, int level, int box[MAXBOX_D], int mype, int pass) {
  long pmid;
  int split;
  int xmin1, xmax1, ymin1, ymax1;
  int xmin2, xmax2, ymin2, ymax2;

  if (pmin == pmax) {
    // We're down to one PE it's our sub vol limits.
    // printf("[%4d] %4d %4d %4d %4d (%d)\n", pmin, xmin, xmax, ymin, ymax, level);
    if (pmin == mype) {
      box[0] = xmin;
      box[1] = xmax;
      box[2] = ymin;
      box[3] = ymax;
    } else {
      // look for a common edge
      if ((box[XMIN_D] == xmax) && (box[YMIN_D] == ymin) && (box[YMAX_D] == ymax))
        box[LEFT_D] = pmin;
      if ((box[XMAX_D] == xmin) && (box[YMIN_D] == ymin) && (box[YMAX_D] == ymax))
        box[RIGHT_D] = pmin;
      if ((box[YMIN_D] == ymax) && (box[XMIN_D] == xmin) && (box[XMAX_D] == xmax))
        box[DOWN_D] = pmin;
      if ((box[YMAX_D] == ymin) && (box[XMIN_D] == xmin) && (box[XMAX_D] == xmax))
        box[UP_D] = pmin;
    }
    return;
  }

  split = SplitSurface(level, xmin, xmax, ymin, ymax, &xmin1, &xmax1, &ymin1, &ymax1, &xmin2, &xmax2, &ymin2, &ymax2);

  if (split) {
    // recurse on sub problems
    pmid = (pmax + pmin) / 2;
    CalcSubSurface(xmin1, xmax1, ymin1, ymax1, pmin, pmid, level + 1, box, mype, pass);
    CalcSubSurface(xmin2, xmax2, ymin2, ymax2, pmid + 1, pmax, level + 1, box, mype, pass);
  } else {
    // cerr << "Too many PE for this problem size " << endl;
    fprintf(stderr, "Too many PE for this problem size => box[0] = -1\n");
    box[0] = -1;
    box[1] = -1;
    box[2] = -1;
    box[3] = -1;
  }
}
Пример #2
0
int
main(int argc, char **argv) {
  int nx = 128;
  int ny = 128;
  int nbproc = 32;
  int mype = 0;
  int bord = 0;

  for (mype = 0; mype < nbproc; mype++) {
    int box[MAXBOX_D] = { -1, -1, -1, -1, -1, -1, -1, -1 };
    // first pass determin our box
    CalcSubSurface(0, nx - 1, 0, ny - 1, 0, nbproc - 1, 0, box, mype, 0);
    // second pass determin our neighbours
    CalcSubSurface(0, nx - 1, 0, ny - 1, 0, nbproc - 1, 0, box, mype, 1);
    printf("[%4d] %4d %4d %4d %4d / %4d %4d %4d %4d \n", mype,
           box[XMIN_D], box[XMAX_D], box[YMIN_D], box[YMAX_D], box[UP_D], box[DOWN_D], box[LEFT_D], box[RIGHT_D]);
    if ((box[UP_D] == -1) || (box[DOWN_D] == -1) || (box[LEFT_D] == -1) || (box[RIGHT_D] == -1)
      )
      bord++;
  }
  printf("B=%d / %d\n", bord, nbproc);
  return 0;
}
Пример #3
0
void
process_args (int argc, char **argv, hydroparam_t * H)
{
  int n = 1;
  char donnees[512];

  default_values (H);

  MPI_Comm_size (MPI_COMM_WORLD, &H->nproc);
  MPI_Comm_rank (MPI_COMM_WORLD, &H->mype);
  while (n < argc)
    {
      if (strcmp (argv[n], "--help") == 0)
	{
	  usage ();
	  n++;
	  continue;
	}
      if (strcmp (argv[n], "-v") == 0)
	{
	  n++;
	  H->prt++;
	  continue;
	}
      if (strcmp (argv[n], "-i") == 0)
	{
	  n++;
	  strncpy (donnees, argv[n], 512);
	  donnees[511] = 0;	// security
	  n++;
	  continue;
	}
      fprintf (stderr, "Clef %s inconnue\n", argv[n]);
      n++;
    }
  if (donnees != NULL)
    {
      process_input (donnees, H);
    }
  else
    {
      fprintf (stderr, "Option -f donnees manquantes\n");
      exit (1);
    }

  H->globnx = H->nx;
  H->globny = H->ny;
  H->box[XMIN_BOX] = 0;
  H->box[XMAX_BOX] = H->nx;
  H->box[YMIN_BOX] = 0;
  H->box[YMAX_BOX] = H->ny;

  if (H->nproc > 1)
    {
      // MPI_Barrier(MPI_COMM_WORLD);
      // first pass : determin our actual sub problem size
      CalcSubSurface (0, H->globnx, 0, H->globny, 0, H->nproc - 1, 0, H->box,
		      H->mype, 0);
      // second pass : determin our neighbours
      CalcSubSurface (0, H->globnx, 0, H->globny, 0, H->nproc - 1, 0, H->box,
		      H->mype, 1);

      H->nx = H->box[XMAX_BOX] - H->box[XMIN_BOX];
      H->ny = H->box[YMAX_BOX] - H->box[YMIN_BOX];
      printf
	("[%4d/%4d] x=%4d X=%4d y=%4d Y=%4d / u=%4d d=%4d l=%4d r=%4d \n",
	 H->mype, H->nproc, H->box[XMIN_BOX], H->box[XMAX_BOX],
	 H->box[YMIN_BOX], H->box[YMAX_BOX], H->box[UP_BOX], H->box[DOWN_BOX],
	 H->box[LEFT_BOX], H->box[RIGHT_BOX]);
      // adapt the boundary conditions 
      if (H->box[LEFT_BOX] != -1)
	{
	  H->boundary_left = 0;
	}
      if (H->box[RIGHT_BOX] != -1)
	{
	  H->boundary_right = 0;
	}
      if (H->box[DOWN_BOX] != -1)
	{
	  H->boundary_down = 0;
	}
      if (H->box[UP_BOX] != -1)
	{
	  H->boundary_up = 0;
	}
    }
}
Пример #4
0
void
process_args(int argc, char **argv, hydroparam_t * H) {
  int n = 1;
  char donnees[512];

  default_values(H);

#ifdef MPI
  MPI_Comm_size(MPI_COMM_WORLD, &H->nproc);
  MPI_Comm_rank(MPI_COMM_WORLD, &H->mype);
#else
  H->nproc = 1;
  H->mype = 0;
#endif
  while (n < argc) {
    if (strcmp(argv[n], "--help") == 0) {
      usage();
      n++;
      continue;
    }
    if (strcmp(argv[n], "-v") == 0) {
      n++;
      H->prt++;
      continue;
    }
    if (strcmp(argv[n], "-i") == 0) {
      n++;
      strncpy(donnees, argv[n], 512);
      donnees[511] = 0;         // security
      n++;
      continue;
    }
    fprintf(stderr, "Key %s is unkown\n", argv[n]);
    n++;
  }
  if (donnees != NULL) {
    process_input(donnees, H);
  } else {
    fprintf(stderr, "Option -i is missing\n");
    exit(1);
  }

  H->globnx = H->nx;
  H->globny = H->ny;
  H->box[XMIN_BOX] = 0;
  H->box[XMAX_BOX] = H->nx;
  H->box[YMIN_BOX] = 0;
  H->box[YMAX_BOX] = H->ny;

#ifdef MPI
  if (H->nproc > 1) {
    MPI_Barrier(MPI_COMM_WORLD);
    // first pass : determin our actual sub problem size
    CalcSubSurface(0, H->globnx, 0, H->globny, 0, H->nproc - 1, 0, H->box, H->mype, 0);
    // second pass : determin our neighbours
    CalcSubSurface(0, H->globnx, 0, H->globny, 0, H->nproc - 1, 0, H->box, H->mype, 1);

    H->nx = H->box[XMAX_BOX] - H->box[XMIN_BOX];
    H->ny = H->box[YMAX_BOX] - H->box[YMIN_BOX];
    printf("[%4d/%4d] x=%4d X=%4d y=%4d Y=%4d / u=%4d d=%4d l=%4d r=%4d \n", H->mype, H->nproc, H->box[XMIN_BOX], H->box[XMAX_BOX], H->box[YMIN_BOX], H->box[YMAX_BOX], H->box[UP_BOX], H->box[DOWN_BOX], H->box[LEFT_BOX], H->box[RIGHT_BOX]);

    if (H->nx <= 0) {
      printf("Decomposition not suited for this geometry along X: increase nx or change number of procs\n");
    }

    if (H->ny <= 0) {
      printf("Decomposition not suited for this geometry along Y: increase ny or change number of procs\n");
    }

    if (H->nx == 0 || H->ny == 0) {
      MPI_Abort(MPI_COMM_WORLD, 123);
    }

    // adapt the boundary conditions 
    if (H->box[LEFT_BOX] != -1) {
      H->boundary_left = 0;
    }
    if (H->box[RIGHT_BOX] != -1) {
      H->boundary_right = 0;
    }
    if (H->box[DOWN_BOX] != -1) {
      H->boundary_down = 0;
    }
    if (H->box[UP_BOX] != -1) {
      H->boundary_up = 0;
    }
  }
  fflush(stdout);
#endif

  if (H->nxystep == -1) {
    // default = full slab
    H->nxystep = (H->nx < H->ny) ? H->nx: H->ny;
  } else {
    if (H->nxystep > H->nx) H->nxystep = H->nx;
    if (H->nxystep > H->ny) H->nxystep = H->ny;
  }

    H->nxystep = omp_get_max_threads();

  // small summary of the run conditions
  if (H->mype == 0) {
    printf("+-------------------+\n");
    printf("|GlobNx=%-7d     |\n", H->globnx);
    printf("|GlobNy=%-7d     |\n", H->globny);
    printf("|nx=%-7d         |\n", H->nx);
    printf("|ny=%-7d         |\n", H->ny);
    printf("|nxystep=%-7d    |\n", H->nxystep);
    printf("|tend=%-10.3f    |\n", H->tend);
    printf("|nstepmax=%-7d   |\n", H->nstepmax);
    printf("|noutput=%-7d    |\n", H->noutput);
    printf("|dtoutput=%-10.3f|\n", H->dtoutput);
    printf("+-------------------+\n");
  }
}