Date: Wed, 26 Mar 2003 11:05:06 -0500 From: Robert Edwards Subject: Draft QIO/C++ header file. Change in semantics All, I've attached the first pass at a C++ header file for QIO. I've not included the "v" versions in this pass. The code includes into a trivial file and even compiles! Note, there are several things I want to change semantically in the QIO standard. Most importantly, at the *top* level I (still) want to impose a stream view. What this practically means is that there is no random-access of files. I've not heard reasons for it and having random-access breaks possible implementations. So, at the *top* level for QDP there is // No seeking possible class QDPReader{ // a constructor and other stuff ... // Skip reading this record. Can only skip forward // which is logically equiv. to read and discard int skipRecord(); // Read record int read(MetaReader& recXML, QDPType& f); }; // No record skipping/seeking possible class QDPWriter{ // constructor and other stuff ... // Write a record int write(const MetaWriter& rexXML, const QDPType& f); }; At the LRL level, I'm willing to concede a seek of sorts is required. The only case I heard justifying this is for parallel FS writing/reading. So, at LRL I want to change to class LRLReader { // Constructor and other functions ... // From beginning of record, skip reading some bytes // Logically equiv to read and discard int skipBytes(size_t nbytes); }; class LRLWriter { // Constructor and other functions ... // From beginning of record, skip forward some bytes int skipBytes(size_t nbytes); }; Robert --------------040601030409070608000808 Content-Type: text/plain; name="qio.h" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="qio.h" // $Id$ // Forward declarations template class multi1d; // 1D array container template class QDPType; // QDP++ field types class MetaReader; class MetaWriter; //! Call back function-object for mapping a QLA object to a site level QDP object /*! * Copies all the needed data for the site at the specified * coordinate coords to the buffer "buf" of size "size". The * data has to be presented in the standard file layout order for * the resulting "QLA" datatype. */ struct QLAFactory { void operator()(char *buf, const multi1d& coords); }; //------------------------------------------------------------------------------- // QDP Level function calls //! Reader class QDPReader { public: /** * \param serialparallel is "QDP_SERIAL" or "QDP_PARALLEL". If the * architecture does not support parallel reads/writes * the mode reverts to serial. */ QDPReader(MetaReader& fileXML, char *filename, int serialparallel); //! Reads a physics record containing a single QDP field. template int read(MetaReader& recXML, QDPType& field); //! For peeking at the physics record metadata, but not reading the binary data. /*! Reads the record XML and then backs up to the beginning of the record. */ int peekMetaData(MetaReader& recXML); //! Skip reading this record int skipRecord(); //! Close the file int close(); }; //! Writer class QDPWriter { public: /** * \param serialparallel is "QDP_SERIAL" or "QDP_PARALLEL". If the * architecture does not support parallel reads/writes * the mode reverts to serial. * * \param mode is "QDP_CREATE", "QDP_APPEND", or "QDP_TRUNCATE" */ QDPWriter(const MetaReader& fileXML, char *filename, int serialparallel, int mode); //! Writes a physics record containing a single QDP field. template int write(const MetaReader& recXML, const QDPType& field); //! Close the file int close(); }; //------------------------------------------------------------------------------- // QIO Level function calls //! Reader class QIOReader { public: /** * \param serialparallel is "QDP_SERIAL" or "QDP_PARALLEL". If the * architecture does not support parallel reads/writes * the mode reverts to serial. */ QIOReader(MetaReader& fileXML, char *filename, int serialparallel); //! Reads a physics record /*! The factory functions provide access to QDP site level objects */ template int read(MetaReader& recXML, const QLAFactory& f); //! For peeking at the physics record metadata, but not reading the binary data. /*! Reads the record XML and then backs up to the beginning of the record. */ int peekMetaData(MetaReader& recXML); //! Skip reading this record int skipRecord(); //! Close the file int close(); }; //! Writer class QIOWriter { public: /** * \param serialparallel is "QDP_SERIAL" or "QDP_PARALLEL". If the * architecture does not support parallel reads/writes * the mode reverts to serial. * * \param mode is "QDP_CREATE", "QDP_APPEND", or "QDP_TRUNCATE" */ QIOWriter(const MetaReader& fileXML, char *filename, int serialparallel, int mode); //! Writes a physics record containing a single QDP field. /*! The factory functions provide access to QDP site level objects */ template int write(const MetaReader& recXML, const QLAFactory& f); //! Close the file int close(); }; //------------------------------------------------------------------------------- // Data Management Layer //! DML stream for reading from a QDP object class DMLReader { public: /** * \param sp for serial or parallel file I/O * \param vf for multidump or single file I/O */ DMLReader(const QLAFactory& f, int sp, int vf); //! Returns the max number of sites any node has to write/read to/from int numberSites() const; /*! * Returns the list of site coordinates to be read by this node. * The site coordinates are linearized according to a convention. * "site" is an "int". This might be useful for consistency checking * with the multidump format. */ void nodeSiteList(multi1d& list) const; // ?????? /*! * Returns the list of site coordinates in the order written by all * nodes. This information is inserted into the private record XML for * nonlexicographic site ordering. */ void fullSiteList(multi1d& list) const; // ?????? //! The "QDPstream" functions. /*! * Transfers data between the buffer and the field. "Next" refers * to the order in which data is arranged on the current node. * Return indicates status - e.g. end of data. */ int getNext(char *buf); /*! * Generate the global checksum for the data transferred. * Cleans up. Checks that no data was left unprocessed. * Status returned as int. */ int closeGet(); //! Return checksum computed on reading int checkSum() const; }; //! DML stream for writing into a QDP object class DMLWriter { public: /** * \param sp for serial or parallel file I/O * \param vf for multidump or single file I/O */ DMLWriter(const QLAFactory& f, int sp, int vf); //! Returns the max number of sites any node has to write/read to/from int numberSites() const; /*! * Returns the list of site coordinates to be written by this node. * The site coordinates are linearized according to a convention. * "site" is an "int". This might be useful for consistency checking * with the multidump format. */ void nodeSiteList(multi1d& list) const; /*! * Returns the list of site coordinates in the order written by all * nodes. This information is inserted into the private record XML for * nonlexicographic site ordering. */ void fullSiteList(multi1d& list) const; //! The "QDPstream" functions. /*! * Transfers data between the buffer and the field. "Next" refers * to the order in which data is arranged on the current node. * Return indicates status - e.g. end of data. */ int putNext(char *buf); /*! * Generate the global checksum for the data transferred. * Cleans up. Checks that no data was left unprocessed. * Status returned as int. */ int closePut(); //! Return checksum computed on writing int checkSum() const; }; //------------------------------------------------------------------------------- // Logical Record Layer typedef char * DIME_tag; //! Logical Record Level reader class LRLReader { public: //! Constructor LRLReader(char *filename) {open(filename);} //! Real constructor /*! Positions at first record */ int open(char *filename); //! Go to next record int nextRecord(); //! Skip record /*! Logically opens and consumes reading a record. Positions to next record */ int skipRecord(); //! Open a record /*! \param tag We might want to use this tag for consistency checking */ int openRecord(DIME_tag tag); //! From beginning of record, skips to byte offset int skipBytes(size_t nskip); /** * LRL reads the next size bytes into the buffer from the specified * record. Returns the number of bytes read. LRL does not read * past the end of the record. Multinode reads are simply * passed through to the OS, so they are supported if the * OS supports it. */ size_t readBytes(char *buf, size_t size); //! Close record int closeRecord(); //! Close file int close(); }; //! Logical Record Level writer class LRLWriter { public: //! Constructor LRLWriter(char *filename, int mode) {open(filename,mode);} //! Real constructor /*! mode = LRL_CREATE, LRL_APPEND, LRL_TRUNCATE */ int open(char *filename, int mode); //! Open a record /*! \param size Number of bytes in this record (for DIME) * \param tag We might want to use this tag for consistency checking. */ int openRecord(size_t size, DIME_tag tag); //! From beginning of record, skips to byte offset int skipBytes(size_t nskip); /** * LRL writes the next size bytes into the buffer from the specified * record. Returns the number of bytes written. LRL does not write * past the end of the record. Multinode writes are simply * passed through to the OS, so they are supported if the * OS supports it. */ int writeBytes(char *buf, size_t size); //! Close record int closeRecord(); //! Close file int close(); };