aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortradke <tradke@ebee0441-1374-4afa-a3b5-247f3ba15b9a>2000-01-20 10:26:23 +0000
committertradke <tradke@ebee0441-1374-4afa-a3b5-247f3ba15b9a>2000-01-20 10:26:23 +0000
commitd58e1c47d498896b0c1f208724c7d138abce6349 (patch)
tree167737d22f870e26ef4188196f87dc2df90f2b9c
parentaac197b92353ee71641fc4c9ec874a60704a14d5 (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.c684
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,
+ &gtype, &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, &gtype, &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
-
}