/* * Copyright 1997, Regents of the University of Minnesota * * pio.c * * This file contains routines related to I/O * * Started 10/19/94 * George * * $Id: io.c,v 1.1 2003/07/22 21:47:18 karypis Exp $ * */ #include #define MAXLINE 8192 /************************************************************************* * This function reads the CSR matrix **************************************************************************/ void ParallelReadGraph(GraphType *graph, char *filename, MPI_Comm comm) { int i, k, l, pe; int npes, mype, ier; int gnvtxs, nvtxs, your_nvtxs, your_nedges, gnedges; int maxnvtxs = -1, maxnedges = -1; int readew = -1, readvw = -1, dummy, edge; idxtype *vtxdist, *xadj, *adjncy, *vwgt, *adjwgt; idxtype *your_xadj, *your_adjncy, *your_vwgt, *your_adjwgt, graphinfo[4]; int fmt, ncon, nobj; MPI_Status stat; char *line = NULL, *oldstr, *newstr; FILE *fpin = NULL; MPI_Comm_size(comm, &npes); MPI_Comm_rank(comm, &mype); vtxdist = graph->vtxdist = idxsmalloc(npes+1, 0, "ReadGraph: vtxdist"); if (mype == npes-1) { ier = 0; fpin = fopen(filename, "r"); if (fpin == NULL){ printf("COULD NOT OPEN FILE '%s' FOR SOME REASON!\n", filename); ier++; } MPI_Bcast(&ier, 1, MPI_INT, npes-1, comm); if (ier > 0){ MPI_Finalize(); exit(0); } line = (char *)GKmalloc(sizeof(char)*(MAXLINE+1), "line"); do { fgets(line, MAXLINE, fpin); } while (line[0] == '%' && !feof(fpin)); fmt = ncon = nobj = 0; sscanf(line, "%d %d %d %d %d", &gnvtxs, &gnedges, &fmt, &ncon, &nobj); gnedges *=2; readew = (fmt%10 > 0); readvw = ((fmt/10)%10 > 0); graph->ncon = ncon = (ncon == 0 ? 1 : ncon); graph->nobj = nobj = (nobj == 0 ? 1 : nobj); /* printf("Nvtxs: %d, Nedges: %d, Ncon: %d\n", gnvtxs, gnedges, ncon); */ graphinfo[0] = ncon; graphinfo[1] = nobj; graphinfo[2] = readvw; graphinfo[3] = readew; MPI_Bcast((void *)graphinfo, 4, IDX_DATATYPE, npes-1, comm); /* Construct vtxdist and send it to all the processors */ vtxdist[0] = 0; for (i=0,k=gnvtxs; i 0){ MPI_Finalize(); exit(0); } MPI_Bcast((void *)graphinfo, 4, IDX_DATATYPE, npes-1, comm); graph->ncon = ncon = graphinfo[0]; graph->nobj = nobj = graphinfo[1]; readvw = graphinfo[2]; readew = graphinfo[3]; MPI_Bcast((void *)vtxdist, npes+1, IDX_DATATYPE, npes-1, comm); } if ((ncon > 1 && !readvw) || (nobj > 1 && !readew)) { printf("fmt and ncon/nobj are inconsistant. Exiting...\n"); MPI_Finalize(); exit(-1); } graph->gnvtxs = vtxdist[npes]; nvtxs = graph->nvtxs = vtxdist[mype+1]-vtxdist[mype]; xadj = graph->xadj = idxmalloc(graph->nvtxs+1, "ParallelReadGraph: xadj"); vwgt = graph->vwgt = idxmalloc(graph->nvtxs*ncon, "ParallelReadGraph: vwgt"); /*******************************************/ /* Go through first time and generate xadj */ /*******************************************/ if (mype == npes-1) { maxnvtxs = 0; for (i=0; inedges = xadj[nvtxs]; adjncy = graph->adjncy = idxmalloc(xadj[nvtxs], "ParallelReadGraph: adjncy"); adjwgt = graph->adjwgt = idxmalloc(xadj[nvtxs]*nobj, "ParallelReadGraph: adjwgt"); /***********************************************/ /* Now go through again and record adjncy data */ /***********************************************/ if (mype == npes-1) { ier = 0; fpin = fopen(filename, "r"); if (fpin == NULL){ printf("COULD NOT OPEN FILE '%s' FOR SOME REASON!\n", filename); ier++; } MPI_Bcast(&ier, 1, MPI_INT, npes-1, comm); if (ier > 0){ MPI_Finalize(); exit(0); } /* get first line again */ do { fgets(line, MAXLINE, fpin); } while (line[0] == '%' && !feof(fpin)); your_adjncy = idxmalloc(maxnedges, "your_adjncy"); your_adjwgt = idxmalloc(maxnedges*nobj, "your_adjwgt"); for (pe=0; pe 0){ MPI_Finalize(); exit(0); } MPI_Recv((void *)adjncy, xadj[nvtxs], IDX_DATATYPE, npes-1, 0, comm, &stat); MPI_Recv((void *)adjwgt, xadj[nvtxs]*nobj, IDX_DATATYPE, npes-1, 1, comm, &stat); } } /************************************************************************* * This function writes a distributed graph to file **************************************************************************/ void Moc_ParallelWriteGraph(CtrlType *ctrl, GraphType *graph, char *filename, int nparts, int testset) { int h, i, j; int npes, mype, penum, gnedges; char partfile[256]; FILE *fpin; MPI_Comm comm; comm = ctrl->comm; MPI_Comm_size(comm, &npes); MPI_Comm_rank(comm, &mype); gnedges = GlobalSESum(ctrl, graph->nedges); sprintf(partfile, "%s.%d.%d.%d", filename, testset, graph->ncon, nparts); if (mype == 0) { if ((fpin = fopen(partfile, "w")) == NULL) errexit("Failed to open file %s", partfile); fprintf(fpin, "%d %d %d %d %d\n", graph->gnvtxs, gnedges/2, 11, graph->ncon, 1); fclose(fpin); } MPI_Barrier(comm); for (penum=0; penumnvtxs; i++) { for (h=0; hncon; h++) fprintf(fpin, "%d ", graph->vwgt[i*graph->ncon+h]); for (j=graph->xadj[i]; jxadj[i+1]; j++) { fprintf(fpin, "%d ", graph->adjncy[j]+1); fprintf(fpin, "%d ", graph->adjwgt[j]); } fprintf(fpin, "\n"); } fclose(fpin); } MPI_Barrier(comm); } return; } /************************************************************************* * This function reads the CSR matrix **************************************************************************/ void ReadTestGraph(GraphType *graph, char *filename, MPI_Comm comm) { int i, k, l, npes, mype; int nvtxs, penum, snvtxs; idxtype *gxadj, *gadjncy; idxtype *vtxdist, *sxadj, *ssize = NULL; MPI_Status status; MPI_Comm_size(comm, &npes); MPI_Comm_rank(comm, &mype); vtxdist = graph->vtxdist = idxsmalloc(npes+1, 0, "ReadGraph: vtxdist"); if (mype == 0) { ssize = idxsmalloc(npes, 0, "ReadGraph: ssize"); ReadMetisGraph(filename, &nvtxs, &gxadj, &gadjncy); printf("Nvtxs: %d, Nedges: %d\n", nvtxs, gxadj[nvtxs]); /* Construct vtxdist and send it to all the processors */ vtxdist[0] = 0; for (i=0,k=nvtxs; ignvtxs = vtxdist[npes]; graph->nvtxs = vtxdist[mype+1]-vtxdist[mype]; graph->xadj = idxmalloc(graph->nvtxs+1, "ReadGraph: xadj"); if (mype == 0) { for (penum=0; penum=0; i--) sxadj[i] -= sxadj[0]; ssize[penum] = gxadj[vtxdist[penum+1]] - gxadj[vtxdist[penum]]; if (penum == mype) idxcopy(snvtxs+1, sxadj, graph->xadj); else MPI_Send((void *)sxadj, snvtxs+1, IDX_DATATYPE, penum, 1, comm); free(sxadj); } } else MPI_Recv((void *)graph->xadj, graph->nvtxs+1, IDX_DATATYPE, 0, 1, comm, &status); graph->nedges = graph->xadj[graph->nvtxs]; graph->adjncy = idxmalloc(graph->nedges, "ReadGraph: graph->adjncy"); if (mype == 0) { for (penum=0; penumadjncy); else MPI_Send((void *)(gadjncy+gxadj[vtxdist[penum]]), ssize[penum], IDX_DATATYPE, penum, 1, comm); } free(ssize); } else MPI_Recv((void *)graph->adjncy, graph->nedges, IDX_DATATYPE, 0, 1, comm, &status); graph->vwgt = NULL; graph->adjwgt = NULL; if (mype == 0) GKfree(&gxadj, &gadjncy, LTERM); MALLOC_CHECK(NULL); } /************************************************************************* * This function reads the CSR matrix **************************************************************************/ float *ReadTestCoordinates(GraphType *graph, char *filename, int ndims, MPI_Comm comm) { int i, j, k, npes, mype, penum; float *xyz, *txyz; FILE *fpin; idxtype *vtxdist; MPI_Status status; char xyzfile[256]; MPI_Comm_size(comm, &npes); MPI_Comm_rank(comm, &mype); vtxdist = graph->vtxdist; xyz = fmalloc(graph->nvtxs*ndims, "io"); if (mype == 0) { sprintf(xyzfile, "%s.xyz", filename); if ((fpin = fopen(xyzfile, "r")) == NULL) errexit("Failed to open file %s\n", xyzfile); } if (mype == 0) { txyz = fmalloc(2*graph->nvtxs*ndims, "io"); for (penum=0; penumnvtxs, MPI_FLOAT, 0, 1, comm, &status); return xyz; } /************************************************************************* * This function reads the spd matrix **************************************************************************/ void ReadMetisGraph(char *filename, int *r_nvtxs, idxtype **r_xadj, idxtype **r_adjncy) { int i, k, edge, nvtxs, nedges; idxtype *xadj, *adjncy; char *line, *oldstr, *newstr; FILE *fpin; line = (char *)malloc(sizeof(char)*(8192+1)); if ((fpin = fopen(filename, "r")) == NULL) { printf("Failed to open file %s\n", filename); exit(0); } fgets(line, 8192, fpin); sscanf(line, "%d %d", &nvtxs, &nedges); nedges *=2; xadj = idxmalloc(nvtxs+1, "ReadGraph: xadj"); adjncy = idxmalloc(nedges, "ReadGraph: adjncy"); /* Start reading the graph file */ for (xadj[0]=0, k=0, i=0; ivtxdist = idxsmalloc(npes+1, 0, "ReadGraph: vtxdist"); if (mype == 0) { ssize = idxsmalloc(npes, 0, "ReadGraph: ssize"); Moc_SerialReadMetisGraph(filename, &nvtxs, &ncon, &nobj, &fmt, &gxadj, &gvwgt, &gadjncy, &gadjwgt, wgtflag); printf("Nvtxs: %d, Nedges: %d\n", nvtxs, gxadj[nvtxs]); /* Construct vtxdist and send it to all the processors */ vtxdist[0] = 0; for (i=0,k=nvtxs; ignvtxs = vtxdist[npes]; graph->nvtxs = vtxdist[mype+1]-vtxdist[mype]; graph->ncon = ncon; graph->xadj = idxmalloc(graph->nvtxs+1, "ReadGraph: xadj"); /*************************************************/ /* distribute xadj array */ if (mype == 0) { for (penum=0; penum=0; i--) sxadj[i] -= sxadj[0]; ssize[penum] = gxadj[vtxdist[penum+1]] - gxadj[vtxdist[penum]]; if (penum == mype) idxcopy(snvtxs+1, sxadj, graph->xadj); else MPI_Send((void *)sxadj, snvtxs+1, IDX_DATATYPE, penum, 1, comm); free(sxadj); } } else MPI_Recv((void *)graph->xadj, graph->nvtxs+1, IDX_DATATYPE, 0, 1, comm, &status); graph->nedges = graph->xadj[graph->nvtxs]; graph->adjncy = idxmalloc(graph->nedges, "ReadGraph: graph->adjncy"); /*************************************************/ /* distribute adjncy array */ if (mype == 0) { for (penum=0; penumadjncy); else MPI_Send((void *)(gadjncy+gxadj[vtxdist[penum]]), ssize[penum], IDX_DATATYPE, penum, 1, comm); } } else MPI_Recv((void *)graph->adjncy, graph->nedges, IDX_DATATYPE, 0, 1, comm, &status); graph->adjwgt = idxmalloc(graph->nedges*nobj, "ReadGraph: graph->adjwgt"); if (fmt%10 > 0) { /*************************************************/ /* distribute adjwgt array */ if (mype == 0) { for (penum=0; penumadjwgt); else MPI_Send((void *)(gadjwgt+(gxadj[vtxdist[penum]]*nobj)), ssize[penum], IDX_DATATYPE, penum, 1, comm); } } else MPI_Recv((void *)graph->adjwgt, graph->nedges*nobj, IDX_DATATYPE, 0, 1, comm, &status); } else { for (i=0; inedges*nobj; i++) graph->adjwgt[i] = 1; } graph->vwgt = idxmalloc(graph->nvtxs*ncon, "ReadGraph: graph->vwgt"); if ((fmt/10)%10 > 0) { /*************************************************/ /* distribute vwgt array */ if (mype == 0) { for (penum=0; penumvwgt); else MPI_Send((void *)(gvwgt+(vtxdist[penum]*ncon)), ssize[penum], IDX_DATATYPE, penum, 1, comm); } free(ssize); } else MPI_Recv((void *)graph->vwgt, graph->nvtxs*ncon, IDX_DATATYPE, 0, 1, comm, &status); } else { for (i=0; invtxs*ncon; i++) graph->vwgt[i] = 1; } if (mype == 0) GKfree((void *)&gxadj, (void *)&gadjncy, (void *)&gvwgt, (void *)&gadjwgt, LTERM); MALLOC_CHECK(NULL); } /************************************************************************* * This function reads the spd matrix **************************************************************************/ void Moc_SerialReadMetisGraph(char *filename, int *r_nvtxs, int *r_ncon, int *r_nobj, int *r_fmt, idxtype **r_xadj, idxtype **r_vwgt, idxtype **r_adjncy, idxtype **r_adjwgt, int *wgtflag) { int i, k, l; int ncon, nobj, edge, nvtxs, nedges; idxtype *xadj, *adjncy, *vwgt, *adjwgt; char *line, *oldstr, *newstr; int fmt, readew, readvw; int ewgt[MAXNOBJ]; FILE *fpin; line = (char *)GKmalloc(sizeof(char)*(8192+1), "line"); if ((fpin = fopen(filename, "r")) == NULL) { printf("Failed to open file %s\n", filename); exit(-1); } fgets(line, 8192, fpin); fmt = ncon = nobj = 0; sscanf(line, "%d %d %d %d %d", &nvtxs, &nedges, &fmt, &ncon, &nobj); readew = (fmt%10 > 0); readvw = ((fmt/10)%10 > 0); *wgtflag = 0; if (readew) *wgtflag += 1; if (readvw) *wgtflag += 2; if ((ncon > 0 && !readvw) || (nobj > 0 && !readew)) { printf("fmt and ncon/nobj are inconsistant.\n"); exit(-1); } nedges *=2; ncon = (ncon == 0 ? 1 : ncon); nobj = (nobj == 0 ? 1 : nobj); xadj = idxmalloc(nvtxs+1, "ReadGraph: xadj"); adjncy = idxmalloc(nedges, "Moc_ReadGraph: adjncy"); vwgt = (readvw ? idxmalloc(ncon*nvtxs, "RG: vwgt") : NULL); adjwgt = (readew ? idxmalloc(nobj*nedges, "RG: adjwgt") : NULL); /* Start reading the graph file */ for (xadj[0]=0, k=0, i=0; ielmdist = idxsmalloc(npes+1, 0, "ReadGraph: elmdist"); if (mype == npes-1) { ier = 0; fpin = fopen(filename, "r"); if (fpin == NULL){ printf("COULD NOT OPEN FILE '%s' FOR SOME REASON!\n", filename); ier++; } MPI_Bcast(&ier, 1, MPI_INT, npes-1, comm); if (ier > 0){ fclose(fpin); MPI_Finalize(); exit(0); } line = (char *)GKmalloc(sizeof(char)*(MAXLINE+1), "line"); fgets(line, MAXLINE, fpin); sscanf(line, "%d %d", &gnelms, &etype); /* Construct elmdist and send it to all the processors */ elmdist[0] = 0; for (i=0,j=gnelms; i 0){ MPI_Finalize(); exit(0); } MPI_Bcast((void *)elmdist, npes+1, IDX_DATATYPE, npes-1, comm); } MPI_Bcast((void *)(&etype), 1, MPI_INT, npes-1, comm); gnelms = mesh->gnelms = elmdist[npes]; nelms = mesh->nelms = elmdist[mype+1]-elmdist[mype]; mesh->etype = etype; esize = esizes[etype]; mgcnum = mgcnums[etype]; elements = mesh->elements = idxmalloc(nelms*esize, "ParallelReadMesh: elements"); if (mype == npes-1) { maxnelms = 0; for (i=0; i elmdist[i+1]-elmdist[i]) ? maxnelms : elmdist[i+1]-elmdist[i]; } your_elements = idxmalloc(maxnelms*esize, "your_elements"); for (pe=0; pegnns = gmaxnode+1; if (mype==0) printf("Nelements: %d, Nnodes: %d, EType: %d\n", gnelms, mesh->gnns, etype); }