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; } }
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; }
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; } } }
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"); } }