diff options
author | tradke <tradke@ebee0441-1374-4afa-a3b5-247f3ba15b9a> | 2000-01-20 10:26:23 +0000 |
---|---|---|
committer | tradke <tradke@ebee0441-1374-4afa-a3b5-247f3ba15b9a> | 2000-01-20 10:26:23 +0000 |
commit | d58e1c47d498896b0c1f208724c7d138abce6349 (patch) | |
tree | 167737d22f870e26ef4188196f87dc2df90f2b9c | |
parent | aac197b92353ee71641fc4c9ec874a60704a14d5 (diff) |
Fixed a bug in recovering scalars.
Added grdoc.
git-svn-id: http://svn.cactuscode.org/arrangements/CactusPUGHIO/IOFlexIO/trunk@77 ebee0441-1374-4afa-a3b5-247f3ba15b9a
-rw-r--r-- | src/RestoreFile.c | 684 |
1 files changed, 362 insertions, 322 deletions
diff --git a/src/RestoreFile.c b/src/RestoreFile.c index 5a5cfd2..fbbf125 100644 --- a/src/RestoreFile.c +++ b/src/RestoreFile.c @@ -30,6 +30,307 @@ static char *rcsid = "$Id$"; #define MAXDIM 3 +/* local function prototypes */ +static int GetChunkAttributes (cGH *GH, IOFile ifp, int index); +static int GetCommonAttributes (cGH *GH, IOFile ifp, int unchunked, int *index, + int *grouptype, int *timelevel); + + + /*@@ + @routine IOFlexIO_RestoreIEEEIOfile + @date Fri Jun 19 09:19:48 1998 + @author Tom Goodale + @desc + Reads in data from an IEEEIO file. + The file has to be opened already, and the file layout + determined (ioproc, ioproc_every, unchunked). + This information is used to read the file and distribute + the data among all processors. + @enddesc + @calledby IOFlexIO_RecoverGH + @history + @hauthor Gabrielle Allen @hdate Oct 17 1998 + @hdesc Changed logic so that cactus stops if any of the dimensions of the + input file and the current cactus run differ. + @hauthor Thomas Radke @hdate May 05 1999 + @hdesc Added parameter unchunked + @endhistory + + @var GH + @vdesc Pointer to CCTK grid hierarchy + @vtype cGH + @vio in + @endvar + @var ifp + @vdesc IEEEIO file pointer + @vtype IOFile + @vio in + @endvar + @var file_ioproc + @vdesc for the current processor: the IO processor to receive my data + from + @vtype int + @vio in + @endvar + @var file_ioproc_every + @vdesc number of IO processors to use to read the file + @vtype int + @vio in + @endvar + @var file_unchunked + @vdesc flag indicating whether we read from an unchunked file or not + @vtype int + @vio in + @endvar +@@*/ +int IOFlexIO_RestoreIEEEIOfile (cGH *GH, IOFile ifp, int file_ioproc, + int file_ioproc_every, int file_unchunked) +{ + DECLARE_CCTK_PARAMETERS + int index, gtype; + int myproc, nprocs; + int nDatasets, currentDataset; + int timelevel; /* current timelevel to be restored */ + pGH *pughGH; /* PUGH extension handle */ +#ifdef MPI + int proc; + CCTK_INT info [3]; /* communication buffer for MPI */ +#endif + + + /* Get the handles for PUGH and IO extensions */ + pughGH = (pGH *) GH->extensions [CCTK_GHExtensionHandle ("PUGH")]; + + myproc = CCTK_MyProc (GH); + nprocs = CCTK_nProcs (GH); + + /* all IO procs determine the number of datasets in their checkpoint files */ + if (myproc == file_ioproc) { + + /* Get the number of sets */ + nDatasets = IOnDatasets (ifp); + if (verbose) + printf (" Input file has %d datasets\n", nDatasets); + + } + + /* In Cactus 3.x we had only datasets containing grid function data. + This distributed data was stored as one dataset per processor within + the group belonging to one IO processor. So there should be + nGF*ioproc_every datasets within each checkpoint file. + + This consistency condition is no longer true + because now there might be datasets containing a SCALAR grouptype. + These datasets are stored only from the IO processors, + and they are just distributed to the non-IO processors again + during recovery. + + if (nDatasets % file_ioproc_every != 0) + CCTK_WARN (0, "Number of datasets isn't a multiple of nioprocs"); + */ + + /* Now process the datasets. + All IO processors read the datasets from their checkpoint file + verify their contents and communicate them to the non-IO processors. */ + + /* At first the code for the IO processors ... */ + if (myproc == file_ioproc) { + + /* Seek here once to the beginning of the file, the file pointer + is advanced then implicitely by subsequent calls to IOreadInfo() */ + CACTUS_IEEEIO_ERROR (IOseek (ifp, 0)); + + /* Each IO processor loops over all available datasets, checks their + consistency and broadcasts them to the non-IO processors. */ + for (currentDataset = 0; currentDataset < nDatasets; currentDataset++) { + + /* read in the next dataset's attributes and verify them */ + if (GetCommonAttributes (GH, ifp, file_unchunked, &index, + >ype, &timelevel) < 0) { + CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, + "Ignoring dataset %d", currentDataset); + continue; + } + + /*** FIXME: process all group types ! ***/ + if (gtype != GROUP_GF && gtype != GROUP_SCALAR) { + CCTK_WARN (1, "Currently only restoring of GF and SCALAR datasets is supported"); + continue; + } + + /* Read in the data */ + if (verbose) { + char *fullname = CCTK_FullName (index); + + printf (" dataset %d: %s (timelevel %d)\n", currentDataset, + fullname, timelevel); + free (fullname); + } + + if (file_ioproc_every == 1) + CACTUS_IEEEIO_ERROR ( + IOread (ifp, CCTK_VarDataPtrI (GH, timelevel, index))); +#ifdef MPI + else { + int npoints; + void *buffer; + int chunkdims [3], *chunkorigin; + int element_size, mpi_type; + + switch (CCTK_VarTypeI (index)) { + case CCTK_VARIABLE_CHAR: + element_size = sizeof (CCTK_CHAR); mpi_type = PUGH_MPI_CHAR; + break; + case CCTK_VARIABLE_INT: + element_size = sizeof (CCTK_INT); mpi_type = PUGH_MPI_INT; + break; + case CCTK_VARIABLE_REAL: + element_size = sizeof (CCTK_REAL); mpi_type = PUGH_MPI_REAL; + break; + case CCTK_VARIABLE_COMPLEX: + element_size = sizeof (CCTK_COMPLEX); + mpi_type = pughGH->pugh_mpi_complex; + break; + default: + CCTK_WARN (1, "Unsupported datatype"); + continue; + } + + /* read my own data directly into data, + read others data into buffer and communicate it */ + if (! file_unchunked || gtype == GROUP_SCALAR) + CACTUS_IEEEIO_ERROR ( + IOread (ifp, CCTK_VarDataPtrI (GH, timelevel, index))); + else { + chunkdims [0] = pughGH->rnsize [file_ioproc][0]; + chunkdims [1] = pughGH->rnsize [file_ioproc][1]; + chunkdims [2] = pughGH->rnsize [file_ioproc][2]; + chunkorigin = pughGH->lb [file_ioproc]; + + CACTUS_IEEEIO_ERROR (IOreadChunk (ifp, chunkdims, chunkorigin, + CCTK_VarDataPtrI (GH, timelevel, index))); + } + + /* read data for non-IO processors */ + if (gtype == GROUP_SCALAR) { + npoints = 1; + buffer = CCTK_VarDataPtrI (GH, timelevel, index); + } else { + /* allocate memory for the biggest chunk */ + npoints = pughGH->rnpoints [file_ioproc + 1]; + for (proc = 2; proc < file_ioproc_every; proc++) + if (npoints < pughGH->rnpoints [file_ioproc + proc]) + npoints = pughGH->rnpoints [file_ioproc + proc]; + buffer = malloc (npoints * element_size); + } + + for (proc = file_ioproc + 1; + proc < file_ioproc + file_ioproc_every && proc < nprocs; + proc++) { + + if (gtype != GROUP_SCALAR) { + + if (! file_unchunked) { + /* Also increment dataset counter here !!! */ + currentDataset++; + + if (GetChunkAttributes (GH, ifp, index) < 0) { + CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, + "Ignoring chunk in dataset %d", currentDataset+1); + continue; + } + + CACTUS_IEEEIO_ERROR (IOread (ifp, buffer)); + } else { + chunkdims [0] = pughGH->rnsize [proc][0]; + chunkdims [1] = pughGH->rnsize [proc][1]; + chunkdims [2] = pughGH->rnsize [proc][2]; + chunkorigin = pughGH->lb [proc]; + + CACTUS_IEEEIO_ERROR ( + IOreadChunk (ifp, chunkdims, chunkorigin, buffer)); + } + + npoints = pughGH->rnpoints [proc]; + } + + /* and finally send the index and the data */ + info [0] = index; info [1] = timelevel; info [2] = npoints; + CACTUS_MPI_ERROR (MPI_Send (info, 3, PUGH_MPI_INT, proc, + STARTUPBASE, pughGH->PUGH_COMM_WORLD)); + CACTUS_MPI_ERROR (MPI_Send (buffer, npoints, mpi_type, proc, + STARTUPBASE, pughGH->PUGH_COMM_WORLD)); + + } + + /* free allocated chunk */ + if (gtype != GROUP_SCALAR) + free (buffer); + + } /* reading data for file_ioproc_every processors */ +#endif + + } /* end of loop over all datasets */ + +#ifdef MPI + /* Finally an invalid variable index is communicated + to indicate completion to the non-IO processors. */ + info [0] = -1; + for (proc = 1; proc < file_ioproc_every; proc++) + CACTUS_MPI_ERROR (MPI_Send (info, 3, PUGH_MPI_INT, proc + file_ioproc, + STARTUPBASE, pughGH->PUGH_COMM_WORLD)); +#endif + + } else { + + /* And here the code for non-IO processors: */ +#ifdef MPI + int npoints; + int mpi_type; + MPI_Status ms; + + /* They don't know how many datasets there are, because the IO processors + could skip some on the fly during their consistency checks. + The IO Processor sends the index of the variable to be processed next. + So, all non-IO processors execute a loop where the termination condition + is when an invalid index was received. + */ + while (1) { + /* receive the next variable index from the IO processor */ + CACTUS_MPI_ERROR (MPI_Recv (info, 3, PUGH_MPI_INT, file_ioproc, + STARTUPBASE, pughGH->PUGH_COMM_WORLD, &ms)); + index = info [0]; timelevel = info [1]; npoints = info [2]; + + /* check for termination condition */ + if (index < 0) + break; + + switch (CCTK_VarTypeI (index)) { + case CCTK_VARIABLE_CHAR: mpi_type = PUGH_MPI_CHAR; break; + case CCTK_VARIABLE_INT: mpi_type = PUGH_MPI_INT; break; + case CCTK_VARIABLE_REAL: mpi_type = PUGH_MPI_REAL; break; + case CCTK_VARIABLE_COMPLEX: mpi_type = pughGH->pugh_mpi_complex; break; + default: + CCTK_WARN (1, "Unsupported datatype"); + continue; + } + + /* receive following data from my IO processor */ + CACTUS_MPI_ERROR (MPI_Recv (CCTK_VarDataPtrI (GH, timelevel, index), + npoints, mpi_type, file_ioproc, + STARTUPBASE, pughGH->PUGH_COMM_WORLD, &ms)); + } +#endif + } + + return (0); + + USE_CCTK_PARAMETERS + +} + +/************************* local routines ********************************/ + /* local routine getDatasetAttributes() reads in the next dataset's attributes and verifies them: @@ -41,16 +342,14 @@ static char *rcsid = "$Id$"; - ntimelevels - sizes (rank, dimensions) according to chunking mode - If there is a mismatch a warning (warning level 2) is printed and value of 1 + If there is a mismatch a warning (warning level 2) is printed and value of -1 is returned to indicate that this dataset should be ignored. If successful, the global variable index, the group type and the timelevel - to restore are stored in {*index, *gtype, *timelevel}, and 0 is returned. - - Currently only restoring of CCTK_VARIABLE_REAL variables is supported. + to restore are stored in {*index, *grouptype, *timelevel}, and 0 is returned. */ -int GetCommonAttributes (cGH *GH, IOFile ifp, int unchunked, int *index, - int *grouptype, int *timelevel) +static int GetCommonAttributes (cGH *GH, IOFile ifp, int unchunked, int *index, + int *grouptype, int *timelevel) { int i, flag; int atype; @@ -61,7 +360,6 @@ int GetCommonAttributes (cGH *GH, IOFile ifp, int unchunked, int *index, int result; char *groupname; char fullname [512], groupname_stored [512]; - char msg [160]; /* read the next dataset's info from the file */ @@ -69,100 +367,104 @@ int GetCommonAttributes (cGH *GH, IOFile ifp, int unchunked, int *index, CACTUS_IEEEIO_ERROR (result); if (result == 0) { CCTK_WARN (1, "Can't read dataset info"); - return (1); + return (-1); } /* retrieve the name attribute */ i = IOreadAttributeInfo (ifp, "name", &atype, &asize); if (i < 0 || atype != FLEXIO_CHAR || asize >= sizeof (fullname)) { CCTK_WARN (2, "Can't read name attribute"); - return (1); + return (-1); } CACTUS_IEEEIO_ERROR (IOreadAttribute (ifp, i, fullname)); /* check if there is a matching variable */ *index = CCTK_VarIndex (fullname); if (*index < 0) { - sprintf (msg, "No matching variable found for '%s'", fullname); - CCTK_WARN (2, msg); - return (1); + CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, + "No matching variable found for '%s'", fullname); + return (-1); } /* read and verify the group name */ i = IOreadAttributeInfo (ifp, "groupname", &atype, &asize); if (i < 0 || atype != FLEXIO_CHAR || asize >= sizeof (groupname_stored)) { - sprintf (msg, "Can't read groupname attribute of '%s'", fullname); - CCTK_WARN (2, msg); - return (1); + CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, + "Can't read groupname attribute of '%s'", fullname); + return (-1); } CACTUS_IEEEIO_ERROR (IOreadAttribute (ifp, i, groupname_stored)); groupname = CCTK_GroupNameFromVarI (*index); if (! CCTK_Equals (groupname_stored, groupname)) { - sprintf (msg, "Groupnames don't match for '%s'", fullname); - CCTK_WARN (2, msg); - return (1); + CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, + "Groupnames don't match for '%s'", fullname); + return (-1); } free (groupname); /* read the group type */ i = IOreadAttributeInfo (ifp, "grouptype", &atype, &asize); if (i < 0 || atype != FLEXIO_INT4 || asize != 1) { - sprintf (msg, "Can't read grouptype attribute for '%s'", fullname); - CCTK_WARN (2, msg); - return (1); + CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, + "Can't read grouptype attribute for '%s'", fullname); + return (-1); } CACTUS_IEEEIO_ERROR (IOreadAttribute (ifp, i, &grouptype_stored)); /* read the number of timelevels */ i = IOreadAttributeInfo (ifp, "ntimelevels", &atype, &asize); if (i < 0 || atype != FLEXIO_INT4 || asize != 1) { - sprintf (msg, "Can't read ntimelevels attribute for '%s'", fullname); - CCTK_WARN (2, msg); - return (1); + CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, + "Can't read ntimelevels attribute for '%s'", fullname); + return (-1); } CACTUS_IEEEIO_ERROR (IOreadAttribute (ifp, i, &numtimelevels_stored)); /* read the timelevel to restore */ i = IOreadAttributeInfo (ifp, "timelevel", &atype, &asize); if (i < 0 || atype != FLEXIO_INT4 || asize != 1) { - sprintf (msg, "Can't read timelevel attribute for '%s'", fullname); - CCTK_WARN (2, msg); - return (1); + CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, + "Can't read timelevel attribute for '%s'", fullname); + return (-1); } CACTUS_IEEEIO_ERROR (IOreadAttribute (ifp, i, &timelevel_stored)); - *timelevel = timelevel_stored; + *timelevel = (int) timelevel_stored; /* verify group type, variable type, dims, sizes and ntimelevels */ if (CCTK_GroupData (CCTK_GroupIndex (groupname_stored), &groupdata) != 0) { - sprintf (msg, "Could not get group info for '%s'", fullname); - CCTK_WARN (2, msg); - return (1); + CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, + "Could not get group info for '%s'", fullname); + return (-1); } if (groupdata.grouptype != grouptype_stored) { - sprintf (msg, "Group types don't match for '%s'", fullname); - CCTK_WARN (2, msg); - return (1); + CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, + "Group types don't match for '%s'", fullname); + return (-1); } if (groupdata.numtimelevels != numtimelevels_stored) { - sprintf (msg, "Number of timelevels don't match for '%s'", fullname); - CCTK_WARN (2, msg); - return (1); + CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, + "Number of timelevels don't match for '%s'", fullname); + return (-1); } /* The CCTK variable type defines do not correlate with the IEEEIO defines so compare them explicitely here. - Up to now CCTK knows only REALs, but COMPLEX types aren't supported - anyway by IOFlexIO. */ - if ((vartype_stored == FLEXIO_REAL && groupdata.vartype == CCTK_VARIABLE_REAL) || - (vartype_stored == FLEXIO_INT && groupdata.vartype == CCTK_VARIABLE_INT) || - (vartype_stored == FLEXIO_CHAR && groupdata.vartype == CCTK_VARIABLE_CHAR)) { -#if 0 - || (vtype_stored == FLEXIO_COMPLEX && groupdata.vartype == CCTK_VARIABLE_COMPLEX)) { -#endif + FlexIO doesn't have an explicite FLEXIO_COMPLEX datatype + so FLEXIO_REAL is used instead. This means we can do only a weak test - + and check whether a given FLEXIO_REAL type matches with + either a CCTK_VARIABLE_REAL or CCTK_VARIABLE_COMPLEX variable. */ + if ((vartype_stored == FLEXIO_REAL && + groupdata.vartype == CCTK_VARIABLE_REAL) || + (vartype_stored == FLEXIO_INT && + groupdata.vartype == CCTK_VARIABLE_INT) || + (vartype_stored == FLEXIO_CHAR && + groupdata.vartype == CCTK_VARIABLE_CHAR) || + (vartype_stored == FLEXIO_REAL && + groupdata.vartype == CCTK_VARIABLE_COMPLEX)) { /* everything is okay */ } else { - sprintf (msg, "Variable types don't match for '%s'", fullname); - CCTK_WARN (2, msg); - return (1); + CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, + "Variable types don't match for '%s'", fullname); + return (-1); } /* verify the dims and sizes */ @@ -194,14 +496,15 @@ int GetCommonAttributes (cGH *GH, IOFile ifp, int unchunked, int *index, break; } if (flag) { - sprintf (msg, "Variable sizes don't match for '%s'", fullname); - CCTK_WARN (2, msg); - return (1); + CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, + "Variable sizes don't match for '%s'", fullname); + return (-1); } if (! CCTK_QueryGroupStorageI (GH, CCTK_GroupIndexFromVarI (*index))) { - CCTK_WARN (2, "Can't read into variable with no storage"); - return (1); + CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, + "Can't read into '%s': no storage assigned", fullname); + return (-1); } *grouptype = groupdata.grouptype; @@ -215,7 +518,7 @@ int GetCommonAttributes (cGH *GH, IOFile ifp, int unchunked, int *index, It verifies via the name attribute that this chunk belongs to the current variable given by its index. */ -int GetChunkAttributes (cGH *GH, IOFile ifp, int index) +static int GetChunkAttributes (cGH *GH, IOFile ifp, int index) { int i; int atype; @@ -223,7 +526,6 @@ int GetChunkAttributes (cGH *GH, IOFile ifp, int index) int result; int vtype_stored, rank_stored, dims_stored [MAXDIM]; char fullname [512]; - char msg [160]; /* read the next dataset's info from the file */ @@ -231,285 +533,23 @@ int GetChunkAttributes (cGH *GH, IOFile ifp, int index) CACTUS_IEEEIO_ERROR (result); if (result == 0) { CCTK_WARN (1, "Can't read dataset info"); - return (1); + return (-1); } /* retrieve the name attribute */ i = IOreadAttributeInfo (ifp, "name", &atype, &asize); if (i < 0 || atype != FLEXIO_CHAR || asize >= sizeof (fullname)) { CCTK_WARN (2, "Can't read name attribute"); - return (1); + return (-1); } CACTUS_IEEEIO_ERROR (IOreadAttribute (ifp, i, fullname)); /* check if there is a matching variable */ if (index != CCTK_VarIndex (fullname)) { - sprintf (msg, "No matching variable found for '%s'", fullname); - CCTK_WARN (2, msg); - return (1); - } - - return (0); -} - - /*@@ - @routine IOFlexIO_RestoreIEEEIOfile - @date Fri Jun 19 09:19:48 1998 - @author Tom Goodale - @desc - Reads in data from an open IEEEIO file. - Code was originally in StartupReader. - @enddesc - @calls - @calledby - @history - @hauthor Gabrielle Allen @hdate Oct 17 1998 - @hdesc Changed logic so that cactus stops if any of the dimensions of the - input file and the current cactus run differ. - @hauthor Thomas Radke @hdate May 05 1999 - @hdesc Added parameter unchunked - @endhistory - -@@*/ -int IOFlexIO_RestoreIEEEIOfile (cGH *GH, IOFile ifp, int file_ioproc, - int file_ioproc_every, int file_unchunked) -{ - DECLARE_CCTK_PARAMETERS - int index, gtype; - int myproc, nprocs; - int nDatasets, currentDataset; - int timelevel; /* current timelevel to be restored */ - pGH *pughGH; /* PUGH extension handle */ - char msg [512]; /* just a message buffer */ -#ifdef MPI - int proc; - CCTK_INT info [2]; /* communication buffer for MPI */ -#endif - - - /* Get the handles for PUGH and IO extensions */ - pughGH = (pGH *) GH->extensions [CCTK_GHExtensionHandle ("PUGH")]; - - myproc = CCTK_MyProc (GH); - nprocs = CCTK_nProcs (GH); - - /* all IO procs determine the number of datasets in their checkpoint files */ - if (myproc == file_ioproc) { - - /* Get the number of sets */ - nDatasets = IOnDatasets (ifp); - if (verbose) - printf (" Input file has %d datasets\n", nDatasets); - - } - - /* In Cactus 3.x we had only datasets containing grid function data. - This distributed data was stored as one dataset per processor within - the group belonging to one IO processor. So there should be - nGF*ioproc_every datasets within each checkpoint file. - - This consistency condition is no longer true - because now there might be datasets containing a SCALAR grouptype. - These datasets are stored only from the IO processors, - and they are just distributed to the non-IO processors again - during recovery. - - if (nDatasets % file_ioproc_every != 0) - CCTK_WARN (0, "Number of datasets isn't a multiple of nioprocs"); - */ - - /* Now process the datasets. - All IO processors read the datasets from their checkpoint file - verify their contents and communicate them to the non-IO processors. */ - - /* At first the code for the IO processors ... */ - if (myproc == file_ioproc) { - - /* Seek here once to the beginning of the file, the file pointer - is advanced then implicitely by subsequent calls to IOreadInfo() */ - CACTUS_IEEEIO_ERROR (IOseek (ifp, 0)); - - /* Each IO processor loops over all available datasets, checks their - consistency and broadcasts them to the non-IO processors. */ - for (currentDataset = 0; currentDataset < nDatasets; currentDataset++) { - - /* read in the next dataset's attributes and verify them */ - if (GetCommonAttributes (GH, ifp, file_unchunked, &index, >ype, &timelevel)) { - sprintf (msg, "Ignoring dataset %d", currentDataset); - CCTK_WARN (1, msg); - } - - /*** FIXME: process all group types ! ***/ - else if (gtype != GROUP_GF && gtype != GROUP_SCALAR) { - CCTK_WARN (1, "Currently only restoring of GF and SCALAR datasets is supported"); - } - - /* Read in the data */ - else { - - if (verbose) { - char *varname = CCTK_FullName (index); - - printf (" dataset %d: %s (timelevel %d)\n", currentDataset, - varname, timelevel); - free (varname); - } - - if (file_ioproc_every == 1) - CACTUS_IEEEIO_ERROR (IOread (ifp, GH->data [index][timelevel])); -#ifdef MPI - else { - int npoints; - void *buffer; - int chunkdims [3], *chunkorigin; - int element_size, mpi_type; - - switch (CCTK_VarTypeI (index)) { - case CCTK_VARIABLE_CHAR: - element_size = sizeof (CCTK_CHAR); mpi_type = PUGH_MPI_CHAR; - break; - case CCTK_VARIABLE_INT: - element_size = sizeof (CCTK_INT); mpi_type = PUGH_MPI_INT; - break; - case CCTK_VARIABLE_REAL: - element_size = sizeof (CCTK_REAL); mpi_type = PUGH_MPI_REAL; - break; - case CCTK_VARIABLE_COMPLEX: - CCTK_WARN (1, "Restoring of complex datatypes not yet supported"); - continue; - default: - CCTK_WARN (1, "Unknown datatype in IOFlexIO_RestoreIEEEIOfile"); - continue; - } - - /* read my own data directly into data, - read others data into buffer and communicate it */ - if (! file_unchunked || gtype == GROUP_SCALAR) - CACTUS_IEEEIO_ERROR (IOread (ifp, GH->data [index][timelevel])); - else { - chunkdims [0] = pughGH->rnsize [file_ioproc][0]; - chunkdims [1] = pughGH->rnsize [file_ioproc][1]; - chunkdims [2] = pughGH->rnsize [file_ioproc][2]; - chunkorigin = pughGH->lb [file_ioproc]; - - CACTUS_IEEEIO_ERROR (IOreadChunk (ifp, chunkdims, chunkorigin, - GH->data [index][timelevel])); - } - - /* read data for non-IO processors */ - if (gtype == GROUP_SCALAR) { - npoints = 1; - buffer = GH->data [index][timelevel]; - } else { - /* allocate memory for the biggest chunk */ - npoints = pughGH->rnpoints [file_ioproc + 1]; - for (proc = 2; proc < file_ioproc_every; proc++) - if (npoints < pughGH->rnpoints [file_ioproc + proc]) - npoints = pughGH->rnpoints [file_ioproc + proc]; - buffer = malloc (npoints * element_size); - } - - for (proc = file_ioproc + 1; - proc < file_ioproc + file_ioproc_every && proc < nprocs; - proc++) { - - if (gtype != GROUP_SCALAR) { - - if (! out3D_unchunked) { - /* Also increment dataset counter here !!! */ - currentDataset++; - if (GetChunkAttributes (GH, ifp, index)) { - sprintf (msg, "Ignoring chunk in dataset %d", - currentDataset+1); - CCTK_WARN (1, msg); - continue; - } - - CACTUS_IEEEIO_ERROR (IOread (ifp, buffer)); - } else { - chunkdims [0] = pughGH->rnsize [proc][0]; - chunkdims [1] = pughGH->rnsize [proc][1]; - chunkdims [2] = pughGH->rnsize [proc][2]; - chunkorigin = pughGH->lb [proc]; - - CACTUS_IEEEIO_ERROR (IOreadChunk (ifp, chunkdims, chunkorigin, - buffer)); - } - - npoints = pughGH->rnpoints [proc]; - } - - /* and finally send the index and the data */ - info [0] = index; info [1] = timelevel; - CACTUS_MPI_ERROR (MPI_Send (info, 2, PUGH_MPI_INT, proc, - STARTUPBASE, pughGH->PUGH_COMM_WORLD)); - CACTUS_MPI_ERROR (MPI_Send (buffer, npoints, mpi_type, proc, - STARTUPBASE, pughGH->PUGH_COMM_WORLD)); - - } - - if (gtype != GROUP_GF) - free (buffer); - } -#endif - } /* reading data for file_ioproc_every processors */ - - } /* end of loop over all datasets */ - -#ifdef MPI - /* Finally an invalid variable index is communicated - to indicate completion to the non-IO processors. */ - info [0] = -1; - for (proc = 1; proc < file_ioproc_every; proc++) - CACTUS_MPI_ERROR (MPI_Send (info, 2, PUGH_MPI_INT, proc + file_ioproc, - STARTUPBASE, pughGH->PUGH_COMM_WORLD)); -#endif - - } else { - - /* And here the code for non-IO processors: */ -#ifdef MPI - int mpi_type; - MPI_Status ms; - - /* They don't know how many datasets there are, because the IO processors - could skip some on the fly during their consistency checks. - The IO Processor sends the index of the variable to be processed next. - So, all non-IO processors execute a loop where the termination condition - is when an invalid index was received. - */ - while (1) { - /* receive the next variable index from the IO processor */ - CACTUS_MPI_ERROR (MPI_Recv (info, 2, PUGH_MPI_INT, file_ioproc, - STARTUPBASE, pughGH->PUGH_COMM_WORLD, &ms)); - index = info [0]; timelevel = info [1]; - - /* check for termination condition */ - if (index < 0) - break; - - switch (CCTK_VarTypeI (index)) { - case CCTK_VARIABLE_CHAR: mpi_type = PUGH_MPI_CHAR; break; - case CCTK_VARIABLE_INT: mpi_type = PUGH_MPI_INT; break; - case CCTK_VARIABLE_REAL: mpi_type = PUGH_MPI_REAL; break; - case CCTK_VARIABLE_COMPLEX: - CCTK_WARN (1, "Restoring of complex datatypes not yet supported"); - continue; - default: - CCTK_WARN (1, "Unknown datatype in IOFlexIO_RestoreIEEEIOfile"); - continue; - } - - /* receive following data from my IO processor */ - CACTUS_MPI_ERROR (MPI_Recv (GH->data [index][timelevel], pughGH->npoints, - mpi_type, file_ioproc, - STARTUPBASE, pughGH->PUGH_COMM_WORLD, &ms)); - } -#endif + CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, + "No matching variable found for '%s'", fullname); + return (-1); } return (0); - - USE_CCTK_PARAMETERS - } |