\label{sec:rtdb}

The run time data base is the parameter and information repository for
the independent modules (e.g., SCF, RIMP2) comprising NWChem.
This approach is similar in spirit to the GAMESS
dumpfile or the Gaussian checkpoint file.  The only way modules can
share data is via the database or via files, the names of which are stored in
the database (and may have default values).  Information is stored
directly in the database as typed arrays, each of which is described by
\begin{enumerate}
\item a name, which is a simple string of ASCII characters (e.g., 
      \verb+"reference energies"+),
\item the type of the data (real, integer, logical, or character), 
\item the number of data items, and
\item the actual data (an array of items of the specified type).
\end{enumerate}

A database is simply a file and is opened by name. Usually there is
just one database per calculation, though multiple databases may be
open at any instant.  

By default, access to all open databases occur in parallel, meaning
that
\begin{itemize}
\item all processes must participate in any read/write of any database
  and any such operation has an implied synchronization
\item writes to the database write the data associated with process
  zero but the correct status of the operation is returned to all
  processes
\item reads from the database read the data named by process zero and
  broadcast the data to all processes, checking dimensions and types
  of provided arrays
\end{itemize}

Alternatively, database operations can occur sequentially.  This means
that
only process zero can read/write the database, and this happens
  with no communication or synchronization with other processes.
Any read/write operations by any process other than process zero is
  an error.

Usually, all processes will want the same data at the same time from
the database, and all processes will want to know of the success or
failure of operations.  This is readily done in the default parallel
mode.  An exception to this is during the reading of input.
Usually, only process zero will read the input and needs to store the
data directly into the database without involving the other processes.
This is done using sequential mode.

The following subsections contain a detailed listing of the C and Fortran API.  
Programs using RTDB routines must include the appropriate header file; 
{\tt rtdb.fh} for Fortran, or {\tt rtdb.h} for C.   These files define the return
types for all rtdb functions.  In addition, {\tt rtdb.fh} specifies the 
following parameters 
\begin{itemize}
\item {\tt rtdb\_max\_key} --- an integer parameter that defines the maximum
  length of a character string key
\item {\tt rtdb\_max\_file} --- an integer parameter that defines the maximum
  length of a file name
\end{itemize}
The Fortran routines return logical values; \TRUE  on success, \FALSE 
on failure.  The C routines return integers; 1 on success, or 0 on failure.
All \verb+rtdb_*+ functions are also mirrored by routines \verb+rtdb_par_*+
in which process 0 performs the operation and all other processes
are broadcast the result of a read and discard writes.

\subsection{Functions to Control Access to the Runtime Database}

The functions that control opening, closing, writing to and reading information
from the runtime database are described in this section.


\subsubsection{{\tt rtdb\_parallel}}

C routine:

\begin{verbatim}
  int rtdb_parallel(const int mode)
\end{verbatim}


Fortran routine:

\begin{verbatim}
  logical function rtdb_parallel(mode)
  logical mode              [input]
\end{verbatim}
This function sets the parallel access mode of all databases to {\tt mode} and returns the
previous setting. If {\tt mode} is true then accesses are in parallel, otherwise they are
sequential.

\subsubsection{{\tt rtdb\_open}}

C routine:

\begin{verbatim}
  int rtdb_open(const char *filename, const char *mode, int *handle)
\end{verbatim}


Fortran routine:

\begin{verbatim}
  logical function rtdb_open(filename, mode, handle)
  character *(*) filename   [input]
  character *(*) mode       [input]
  integer handle            [output]
\end{verbatim}
This function opens a database.  It requires the following arguments:
\begin{itemize}
\item    {\tt Filename} --- path to file associated with the data base
\item    {\tt mode} --- specify initial condition of data base
\begin{itemize}
\item {\tt new} ---  Open only if it does not exist already
\item {\tt old} ---  Open only if it does exist already
\item {\tt unknown} --- Create a new database or open the existing database {\tt Filename} (preserving contents)
\item {\tt empty} --- Create a new database or open the existing database {\tt Filename} (deleting contents)
\item {\tt scratch} --- Create a new database or open the existing database {\tt Filename} (deleting contents)
                         that will be automatically deleted upon closing.  Note that items
                         cached in memory are not written to disk when this mode is specified.
\end{itemize}
\item {\tt handle} --- returns an integer handle which must be used in all future
  references to the database
\end{itemize}

\subsubsection{{\tt rtdb\_close}}

C routine:

\begin{verbatim}
  int rtdb_close(const int handle, const char *mode)
\end{verbatim}


Fortran routine:

\begin{verbatim}
  logical function rtdb_close(handle, mode)
  integer handle            [input]
  character*(*) mode        [input]
\end{verbatim}
This function closes a database. It requires the following arguments:
\begin{itemize}
\item {\tt handle} --- unique handle created when the database was first opened
\item {\tt mode} --- specifies the fate of the information in the database after closing;
\begin{itemize}
\item {\tt keep} ---    Preserve the data base file to enable restart
\item {\tt delete} ---  Delete the data base file, freeing all resources
\end{itemize}
\end{itemize}
When closing a database file that has been opened with the {\tt rtdb\_open} argument
{\tt mode} specified as {\tt scratch}, the value for {\tt mode} for the function
{\tt rtdb\_close} is automatically set to {\tt delete}.  Database files needed for
restart must not be opened as {\tt scratch} files.

\subsubsection{{\tt rtdb\_put}}

C routine:

\begin{verbatim}
  int rtdb_put(const int handle, const char *name, const int ma_type,
               const int nelem, const void *array)
\end{verbatim}


Fortran routine:

\begin{verbatim}
  logical function rtdb_put(handle, name, ma_type, nelem, array)
  integer handle            [input]
  character *(*) name       [input]
  integer ma_type           [input]
  integer nelem             [input]
  <ma_type>                 [input]
  nelem                     [input]
  array                     [input]
\end{verbatim}
This function inserts an entry into the database, replacing the previous entry.
It requires the following arguments:
\begin{itemize}
\item {\tt handle} --- unique handle created when the database was first opened
\item {\tt name} --- entry name of data array to be put into the database (null-terminated character string)
\item {\tt ma\_type} --- MA type of the entry
\item {\tt nelem} --- number of elements of the given type
\item {\tt array} --- array of length {\tt nelem} containing data to be inserted
\end{itemize}

\subsubsection{{\tt rtdb\_get}}

C routine:

\begin{verbatim}
  int rtdb_get(const int handle, const char *name, const int ma_type,
               const int nelem, void *array)
\end{verbatim}


Fortran routine:

\begin{verbatim}
  logical function rtdb_get(handle, name, ma_type, nelem, array)
  integer handle            [input]
  character *(*) name       [input]
  integer ma_type           [input]
  integer nelem             [input]
  <ma_type>                 [output]
  nelem                     [output]
  array                     [output]
\end{verbatim}
This function gets an entry from the data base. It requires the following arguments:
\begin{itemize}
\item {\tt handle} --- unique handle created when the database was first opened
\item {\tt name} --- entry name of data array to get from the database (null-terminated character string)
\item {\tt ma\_type} --- MA type of the entry (which must match entry type in the database)
\item {\tt nelem} --- size of array in units of {\tt ma\_type}
\item {\tt array} --- buffer of length {\tt nelem} defined by calling routine to store the returned data
\end{itemize}

\subsubsection{{\tt rtdb\_cput} and {\tt rtdb\_cget}}

\begin{verbatim}
  logical function rtdb_cput(handle, name, nelem, buf)
  integer handle            [input]
  character *(*) name       [input]
  character *(*) buf        [input]

  logical function rtdb_cget(handle, name, nelem, buf)
  integer handle            [input]
  character *(*) name       [input]
  character *(*) buf        [output]
\end{verbatim}
These functions are Fortran routines to provide put/get functionality for character
variables.  The functions have identical argument lists, the only difference between them is that for
{\tt rtdb\_cput}, the specified character data is put into the database, and for 
{\tt rtdb\_cget} the data is copied from the database.  The arguments are as follows;

\begin{itemize}
\item {\tt handle} --- unique handle created when the database was first opened
\item {\tt name} --- entry name of data array to get from the database (null-terminated character string)
\item {\tt buf} --- character variable to be put into the database (for {\tt rtdb\_cput}, or character
buffer in calling routine to store returned character data (for {\tt rtdb\_cget}.
\end{itemize}

\subsubsection{{\tt rtdb\_ma\_get}}

C routine:

\begin{verbatim}
  int rtdb_ma_get(const int handle, const char *name, int *ma_type,
                  int *nelem, int *ma_handle)
\end{verbatim}


Fortran routine:

\begin{verbatim}
  logical function rtdb_ma_get(handle, name, ma_type, nelem, ma_handle)
  integer handle            [input]
  character *(*) name       [input]
  integer ma_type           [output]
  integer nelem             [output]
  integer ma_handle         [output]
\end{verbatim}
This function returns the MA type, number of elements of that type, and the MA handle
of the entry specified.  (The MA handle is to memory
automatically allocated to hold the data read from the database.)  the function requires
the following arguments:

\begin{itemize}  
\item {\tt handle} --- unique handle created when the database was first opened
\item {\tt name} --- entry name of information to get from the database (null-terminated character string)
\item {\tt ma\_type} --- returns MA type of the entry in the database
\item {\tt nelem} --- returns number of elements of type {\tt ma\_type} in data
\item {\tt ma\_handle} --- returns MA handle to data
\end{itemize}


\subsubsection{{\tt rtdb\_get\_info}}

C routine:

\begin{verbatim}
  int rtdb_get_info(const int handle, const char *name, int *ma_type, 
                    int *nelem, char date[26])
\end{verbatim}


Fortran routine:

\begin{verbatim}
  logical function rtdb_get_info(handle, name, ma_type, nelem, date)
  integer handle            [input]
  character *(*) name       [input]
  integer ma_type           [output]
  integer nelem             [output]
  character*26 date         [output]
\end{verbatim}

This function queries the database to obtain the number of elements in the
specified entry, it's MA type, and the date of its insertion into the rtdb.
It requires the following arguments:

\begin{itemize}
\item {\tt handle} --- unique handle created when the database was first opened
\item {\tt name} --- entry name of data for which information is to be obtained
(null-terminated character string in
  C,  standard FORTRAN character constant or variable in FORTRAN)
\item {\tt ma\_type} --- returns MA type of the entry
\item {\tt nelem} --- returns number of elements of the given type
\item {\tt date} --- returns date of insertion (null-terminated
  character string or FORTRAN character variable)
\end{itemize}

\subsubsection{{\tt rtdb\_first} and {\tt rtdb\_next}}

C routines:

\begin{verbatim}
  int rtdb_first(const int handle, const int namelen, char *name)

  int rtdb_next(const int handle, const int namelen, char *name)
\end{verbatim}


Fortran routines:

\begin{verbatim}
  logical function rtdb_first(handle, name)
  integer handle            [input]
  character *(*) name       [output]

  logical function rtdb_next(handle, name)
  integer handle            [input]
  character *(*) name       [output]
\end{verbatim}
These routines enable iteration through the items in the database in
an effectively random order.  The function {\tt rtdb\_first} returns
the name of the first user-inserted entry in the datbase.  The function
{\tt rtdb\_next} returns the name of the user-inserted entry put into the
data base after the entry identified on the previous call to {\tt rtdb\_next}
(or the call to {\tt rtdb\_first}, on the first call to {\tt rtdb\_next}).

The arguments required for the C routines are as follows:

\begin{itemize}

\item {\tt handle} --- unique handle created when the database was first opened
\item {\tt namelen} ---  size of buffer in calling routine required to store {\tt name}
\item {\tt name} --- buffer to hold returned name of next (or first) entry in the database 
\end{itemize}

The Fortran routines require the same arguments for {\tt handle} and {\tt name}, but it is 
not necessary to define the length of the buffer required.

An example of the use of these functions in C is to count and print the name of all
entries  in the database.  The coding for this can be implemented as follows;

\begin{verbatim}
  char name[256];
  int n, status, rtdb;

  for (status=rtdb_first(rtdb, sizeof(name), name), n=0;
       status;
       status=rtdb_next(rtdb, sizeof(name), name), n++) 
    printf("entry %d has name '%s'\n", n, name);
\end{verbatim}

\subsubsection{{\tt rtdb\_delete}}

C routine:

\begin{verbatim}
  int rtdb_delete(const int handle, const char *name)
\end{verbatim}


Fortran routine:

\begin{verbatim}
  logical function rtdb_delete(handle, name)
  integer handle            [input]
  character *(*) name       [input]
\end{verbatim}
This function deletes an entry from the database. 
\begin{itemize}
\item {\tt handle} --- unique handle created when the database was first opened
\item {\tt name} --- entry name of data to delete from the database (null-terminated character string)
\end{itemize}
This function does not return any arguments.  The value the function itself returns as indicates
success or failure of the delete operation.  The function returns as
\begin{itemize}
\item 1 if key was present and successfully deleted
\item 0 if key was not present, or if an error occured
\end{itemize}

\subsubsection{{\tt rtdb\_print}}

C routine:

\begin{verbatim}
  int rtdb_print(const int handle, const int print_values)
\end{verbatim}


Fortran routine:

\begin{verbatim}
  logical function rtdb_print(handle, print_values)
  integer handle            [input]
  logical print_values      [input]
\end{verbatim}
This function prints the contents of the data base to {\tt STDOUT}.  It requires
the following arguments:
\begin{itemize}
\item {\tt handle} --- unique handle created when the database was first opened
\item {\tt print\_values} --- (boolean flag) if true, values as
  well as keys are printed out.
\end{itemize}
