8 typedef struct {
long long vtx[
MAXNV];
long long eid;
int proc;}
edata;
16 int parMETIS_partMesh(
int *part,
long long *vl,
int nel,
int nv,
int *opt, comm_ext ce)
58 part_ = (idx_t*) malloc(nel*
sizeof(idx_t));
60 if (
sizeof(idx_t) !=
sizeof(
long long)){
61 printf(
"ERROR: invalid sizeof(idx_t)!\n");
64 if (nv != 4 && nv != 8){
65 printf(
"ERROR: nv is %d but only 4 and 8 are supported!\n", nv);
69 color = MPI_UNDEFINED;
70 if (nel > 0) color = 1;
71 MPI_Comm_split(ce, color, 0, &comms);
72 if (color == MPI_UNDEFINED)
75 comm_init(&comm,comms);
77 printf(
"Running parMETIS ... "), fflush(stdout);
79 nelarray = (
long long*) malloc(comm.np*
sizeof(
long long));
80 MPI_Allgather(&nell, 1, MPI_LONG_LONG_INT, nelarray, 1, MPI_LONG_LONG_INT, comm.c);
81 elmdist = (idx_t*) malloc((comm.np+1)*
sizeof(idx_t));
83 for (i=0; i<comm.np; ++i)
84 elmdist[i+1] = elmdist[i] + (idx_t)nelarray[i];
87 evlptr = (idx_t*) malloc((nel+1)*
sizeof(idx_t));
90 evlptr[i+1] = evlptr[i] + nv;
91 nelsm = elmdist[comm.id+1] - elmdist[comm.id];
94 if (nv == 8) ncommonnodes = 4;
98 options[PMV3_OPTION_DBGLVL] = 0;
99 options[PMV3_OPTION_SEED] = 0;
101 options[PMV3_OPTION_DBGLVL] = opt[1];
103 options[3] = PARMETIS_PSR_UNCOUPLED;
108 tpwgts = (real_t*) malloc(ncon*nparts*
sizeof(real_t));
109 for (i=0; i<ncon*nparts; ++i)
110 tpwgts[i] = 1./(real_t)nparts;
112 if (options[3] == PARMETIS_PSR_UNCOUPLED)
113 for (i=0; i<nel; ++i)
118 ierrm = ParMETIS_V3_PartMeshKway(elmdist,
134 time = comm_time() - time0;
136 printf(
"%lf sec\n", time), fflush(stdout);
138 for (i=0; i<nel; ++i)
144 MPI_Comm_free(&comms);
149 comm_allreduce(&comm, gs_int, gs_min, &ierrm, 1, &ibuf);
150 if (ierrm != METIS_OK)
goto err;
169 int ncMin, ncMax, ncSum;
170 int nsMin, nsMax, nsSum;
171 int nssMin, nssMax, nssSum;
186 data = (
long long*) malloc(numPoints*
sizeof(
long long));
187 for(i = 0; i < numPoints; i++) data[i] = vtx[i];
189 gsh = gs_setup(data, numPoints, &
comm, 0, gs_pairwise, 0);
191 pw_data_nmsg(gsh, &Nmsg);
192 Ncomm = (
int *) malloc(Nmsg*
sizeof(
int));
193 pw_data_size(gsh, Ncomm);
201 comm_allreduce(&
comm, gs_int, gs_max, &ncMax , 1, &b);
202 comm_allreduce(&
comm, gs_int, gs_min, &ncMin , 1, &b);
203 comm_allreduce(&
comm, gs_int, gs_add, &ncSum , 1, &b);
208 for (i=1; i<Nmsg; ++i){
209 nsMax = Ncomm[i] > Ncomm[i-1] ? Ncomm[i] : Ncomm[i-1];
210 nsMin = Ncomm[i] < Ncomm[i-1] ? Ncomm[i] : Ncomm[i-1];
213 comm_allreduce(&
comm, gs_int, gs_max, &nsMax , 1, &b);
214 comm_allreduce(&
comm, gs_int, gs_min, &nsMin , 1, &b);
219 comm_allreduce(&
comm, gs_int, gs_max, &nssMax , 1, &b);
220 comm_allreduce(&
comm, gs_int, gs_min, &nssMin , 1, &b);
221 comm_allreduce(&
comm, gs_int, gs_add, &nssSum , 1, &b);
224 comm_allreduce(&
comm, gs_int, gs_add, &nsSum , 1, &b);
228 comm_allreduce(&
comm, gs_int, gs_max, &nelMax, 1, &b);
229 comm_allreduce(&
comm, gs_int, gs_min, &nelMin, 1, &b);
233 " Max neighbors: %d | Min neighbors: %d | Avg neighbors: %lf\n",
234 ncMax, ncMin, (
double)ncSum/np);
236 " Max nvolume: %d | Min nvolume: %d | Avg nvolume: %lf\n",
237 nsMax, nsMin, (
double)nsSum/np);
239 " Max volume: %d | Min volume: %d | Avg volume: %lf\n",
240 nssMax, nssMin, (
double)nssSum/np);
242 " Max elements: %d | Min elements: %d | Balance: %lf\n",
243 nelMax, nelMin, (
double)nelMax/nelMin);
262 array_init(
edata, &eList, nel), eList.n = nel;
263 for(data = eList.ptr, e = 0; e < nel; ++e) {
264 data[e].
proc = part[e];
266 for(n = 0; n < nv; ++n) {
267 data[e].vtx[n] = vl[e*nv + n];
271 crystal_init(&cr,comm);
272 sarray_transfer(
edata, &eList, proc, 0, &cr);
278 if (nel >
lelt) count = 1;
279 comm_allreduce(comm, gs_int, gs_add, &count, 1, &ibuf);
282 printf(
"ERROR: resulting parition requires lelt=%d!\n", nel);
286 for(data = eList.ptr, e = 0; e < nel; ++e) {
288 for(n = 0; n < nv; ++n) {
289 vl[e*nv + n] = data[e].vtx[n];
298 #define fpartMesh FORTRAN_UNPREFIXED(fpartmesh,FPARTMESH)
299 void fpartMesh(
long long *el,
long long *vl,
double *xyz,
300 const int *
lelt,
int *nell,
const int *nve,
301 int *fcomm,
int *fmode,
int *rtval)
307 int count, ierr, ibuf;
316 comm_ext cext = MPI_Comm_f2c(*fcomm);
320 comm_init(&comm, cext);
322 part = (
int*) malloc(*
lelt *
sizeof(
int));
337 ierr = parRCB_partMesh(part, xyz, nel, nv, opt, comm.c);
338 if (ierr != 0)
goto err;
341 if (ierr != 0)
goto err;
347 ierr = parRSB_partMesh(part, vl, nel, nv, opt, comm.c);
348 if (ierr != 0)
goto err;
351 if (ierr != 0)
goto err;
355 #elif defined(PARMETIS)
356 int metis; metis=mode&4;
363 ierr = parMETIS_partMesh(part, vl, nel, nv, opt, comm.c);
366 if (ierr != 0)
goto err;
381 #define fprintPartStat FORTRAN_UNPREFIXED(printpartstat,PRINTPARTSTAT)
386 comm_ext c = MPI_Comm_f2c(*comm);
int redistributeData(int *nel_, long long *vl, long long *el, int *part, int nv, int lelt, struct comm *comm)
void printPartStat(long long *vtx, int nel, int nv, comm_ext ce)