mirror of
https://github.com/nwchemgit/nwchem.git
synced 2026-07-27 21:55:30 -04:00
559 lines
21 KiB
TeX
559 lines
21 KiB
TeX
|
|
The NWChem {\tt util} directory is a dumping ground for all sorts of useful
|
|
things, some of which have been described elsewhere. Here are the rest.
|
|
|
|
\subsection{Printing utilities}
|
|
|
|
\subsubsection{{\tt util\_print\_centered}}
|
|
\begin{verbatim}
|
|
subroutine util_print_centered(unit, string, center, ounder)
|
|
integer unit [input]
|
|
character*(*) string [input]
|
|
integer center [input]
|
|
logical ounder [input]
|
|
\end{verbatim}
|
|
Write the string to speficied Fortran unit centered about the given
|
|
column. If {\tt ounder} is \TRUE then the string is underlined.
|
|
|
|
\subsubsection{{\tt banner}}
|
|
\begin{verbatim}
|
|
subroutine banner(unit, string, char, top, bot, sides)
|
|
integer unit [input]
|
|
character*(*) string [input]
|
|
character*(1) char [input]
|
|
logical top, bot, sides [input]
|
|
\end{verbatim}
|
|
Write the string to specified Fortran unit flush against the left
|
|
margin, optionally enclosing the top/bottom/sides with a box constructed
|
|
from the given character. At some point this routine should be renamed
|
|
\verb+util_banner+.
|
|
|
|
\subsubsection{{\tt output}}
|
|
\begin{verbatim}
|
|
subroutine output (z, rowlow, rowhi, collow, colhi,
|
|
rowdim, coldim, nctl)
|
|
double precision z(rowdim, coldim)
|
|
integer rowlow, rowhi, collow, colhi, rowdim, coldim, nctl
|
|
\end{verbatim}
|
|
{\tt Output} is a classic routine that prints non-zero rows of a
|
|
double precision matrix in formatted form with numbered rows
|
|
and columns. The arcane input is as follows;
|
|
\begin{itemize}
|
|
\item {\tt z} --- matrix to be printed
|
|
\item {\tt rowlow} --- row number at which output is to begin
|
|
\item {\tt rowhi} --- row number at which output is to end
|
|
\item {\tt collow} --- column number at which output is to begin
|
|
\item {\tt colhi} --- column number at which output is to end
|
|
\item {\tt rowdim} --- number of rows in the matrix
|
|
\item {\tt coldim} --- number of columns in the matrix
|
|
\item {\tt nctl} --- carriage control flag; 1 for single space 2 for
|
|
double space 3 for triple space --- only 1 looks any good.
|
|
\end{itemize}
|
|
Two examples might help. To print {\tt z(3:6,8:12)}
|
|
\begin{verbatim}
|
|
double precision z(n,m)
|
|
call output(z, 3, 6, 8, 12, n, m, 1)
|
|
\end{verbatim}
|
|
To print {\tt x(3:12)}
|
|
\begin{verbatim}
|
|
double precision x(n)
|
|
call output(x, 3, 12, 1, 1, n, 1, 1)
|
|
\end{verbatim}
|
|
|
|
\subsection{Error Routines}
|
|
|
|
\subsubsection{{\tt errquit}}
|
|
\label{errquit}
|
|
\begin{verbatim}
|
|
subroutine errquit(string, status)
|
|
character*(*) string
|
|
integer status
|
|
\end{verbatim}
|
|
All fatal errors should result in a call to this routine, which prints
|
|
out the string and status value to both standard error and standard
|
|
output and attempts to kill all parallel processes and to tidy any
|
|
allocated system resources (e.g., system V shared memory). The integer
|
|
status may be any non-zero integer that has some meaning to the
|
|
programmer.
|
|
|
|
\subsection{Parallel Communication}
|
|
|
|
\subsubsection{{\tt util\_char\_ga\_brdcst}}
|
|
\begin{verbatim}
|
|
subroutine util_char_ga_brdcst(type, string, originator)
|
|
integer type [input]
|
|
character*(*) string [input/output]
|
|
integer originator [input]
|
|
\end{verbatim}
|
|
The standard broadcast routine {\tt ga\_brdcst} does not work portably
|
|
with Fortran character strings for which this routine should be used
|
|
instead. The string is broadcast from process \verb+originator+ to all other
|
|
processes. Type is the standard message type or tag. All processes
|
|
should execute the same call and there is an implied weak
|
|
synchronization (i.e., no process can complete this statement until at
|
|
least process \verb+originator+ has reached it).
|
|
|
|
\subsubsection{{\tt fcsnd} and {\tt fcrcv}}
|
|
\begin{verbatim}
|
|
subroutine fcsnd(type, string, node, sync)
|
|
subroutine fcrcv(type, string, slen, nodeselect, nodefrom, sync)
|
|
\end{verbatim}
|
|
Similarly, the basic point-to-point message-passing routines do not
|
|
work portably with Fortran character strings. Here are routines that
|
|
work only with character strings. Refer to the standard TCGMSG
|
|
documentation for details on the other arguments.
|
|
|
|
\subsection{Naming Files}
|
|
|
|
The length of a file name can be large and also system depenedent.
|
|
The parameter \verb+NW_MAX_PATH_LEN+ is defined in \verb+util.fh+ to
|
|
enable a portable definition. Use it as follows
|
|
\begin{verbatim}
|
|
#include "util.fh"
|
|
character*(nw_max_path_len) filename
|
|
\end{verbatim}
|
|
|
|
For easy management by a use of NWChem, and so that multiple jobs can
|
|
run without interaction in the same directory tree, all files should
|
|
by default have a common prefix (specified on the {\tt START},
|
|
{\tt RESTART}, or {\tt CONTINUE} directive). In addition, files need to be routed to the
|
|
correct directory (scratch or permanent) and parallel files need the
|
|
process number appended to the name. Routines (should) exist to do
|
|
all of these things individually, but one master routine does it all
|
|
for you --- wow!
|
|
|
|
\subsubsection{{\tt util\_file\_name}}
|
|
|
|
\begin{verbatim}
|
|
subroutine util_file_name(stub, oscratch, oparallel, name)
|
|
character*(*) stub ! [input] stub name for file
|
|
logical oscratch ! [input] T=scratch, F=permanent
|
|
logical oparallel ! [input] T=append .<nodeid>
|
|
character*(*) name ! [output] full filename
|
|
\end{verbatim}
|
|
|
|
This routine prepends the common file prefix (specified on the {\tt
|
|
START}, {\tt RESTART}, or {\tt CONTINUE} directive) and directory (scratch or
|
|
permanent) and appends the process number for parallel files. For
|
|
example
|
|
\begin{verbatim}
|
|
call util_file_name('movecs', .false., .false., name)
|
|
\end{verbatim}
|
|
might result in \verb+name+ being set to
|
|
\verb+/msrc/home/d3g681/c60.movecs+ (i.e., having the name of the
|
|
permanent directory and the file prefix prepended onto the stub).
|
|
|
|
Another example,
|
|
\begin{verbatim}
|
|
call util_file_name('khalf', .true., .true., name)
|
|
\end{verbatim}
|
|
might yield \verb+/scratch/h2o.khalf.99+ (i.e., having the name
|
|
of the scratch directory and the file prefix prepended and the process
|
|
number appended).
|
|
|
|
\subsubsection{{\tt util\_file\_prefix}}
|
|
\begin{verbatim}
|
|
subroutine util_file_prefix(name, fullname)
|
|
character*(*) name [input]
|
|
character*(*) fullname [output]
|
|
\end{verbatim}
|
|
{\em This routine is superceded for most purposes by}\
|
|
\verb+util_file_name()+.
|
|
|
|
By default all filenames should be prefixed
|
|
with the \verb+file_prefix+ which is the argument presented to the
|
|
\verb+START+, \verb+RESTART+, or \verb+CONTINUE+ directive in the input. This is most
|
|
simply accomplished by calling this routine which returns in
|
|
\verb+fullname+ the value of \verb+file_prefix+ followed (with no
|
|
intervening characters) by the contents of \verb+name+.
|
|
|
|
\subsubsection{{\tt util\_pname}}
|
|
\begin{verbatim}
|
|
subroutine util_pname(name, pname)
|
|
character*(*) name [input]
|
|
character*(*) pname [output]
|
|
\end{verbatim}
|
|
{\em This routine is superceded for most purposes by}\
|
|
\verb+util_file_name()+.
|
|
|
|
Construct a unique parallel name by appending the process number after
|
|
the stub name. E.g., \verb+fred.0001+, \verb+fred.0002+, \ldots. The
|
|
number of leading zeroes are adjusted so that there are none in front
|
|
of the highest numbered processor. This is useful for generating
|
|
names for files, but is probably superseded by the exclusive access
|
|
files in CHEMIO (see Section \ref{sec:ChemIO}.)
|
|
|
|
\subsection{Sequential Fortran Files}
|
|
|
|
\subsubsection{{\tt util\_flush}}
|
|
\begin{verbatim}
|
|
subroutine util_flush(unit)
|
|
integer unit [input]
|
|
\end{verbatim}
|
|
If possible, flush the Fortran output buffers associated with the
|
|
specified unit. Note that this is generally required in order for
|
|
output to be visible during the course of a calculation and thus
|
|
should be called after most write operations to standard output.
|
|
Also, on some machines it is a fatal error to flush a unit on which no
|
|
output has been performed thus care must be taken to ensure that
|
|
writes and flushes are paired --- e.g., it is wrong to have all
|
|
processes flush unit six when only process zero has written output.
|
|
|
|
\subsubsection{{\tt sread} and {\tt swrite}}
|
|
\begin{verbatim}
|
|
subroutine sread(unit, a, n)
|
|
integer unit [input]
|
|
double precision a(n) [output]
|
|
integer n [input]
|
|
|
|
subroutine swrite(unit, a, n)
|
|
integer unit [input]
|
|
double precision a(n) [input]
|
|
integer n [input]
|
|
\end{verbatim}
|
|
Read/write an array of {\tt double} {\tt precision} words from the given Fortran
|
|
unit (variable record length, binary file). These routines are
|
|
valuable to avoid inefficient implied {\tt DO} loops and also to
|
|
circumvent system limitations on record lengths (e.g., some Cray
|
|
systems). The I/O operations are internally chopped into 0.25~Mbyte
|
|
chunks.
|
|
|
|
\subsection{Parallel file operations}
|
|
|
|
\subsubsection{{\tt begin\_seq\_output}, {\tt write\_seq}, and {\tt end\_seq\_output}}
|
|
\begin{verbatim}
|
|
subroutine begin_seq_output()
|
|
|
|
subroutine write_seq(unit, text)
|
|
integer unit [input]
|
|
character*(*) text [input]
|
|
|
|
subroutine end_seq_output()
|
|
\end{verbatim}
|
|
These routines support sequential (i.e., ordered) formatted output
|
|
from all parallel processes. A call to \verb+begin_seq_output+
|
|
indicates the start of a section of sequentialized output. This can
|
|
be followed by any number of calls to \verb+write_seq+, which {\em
|
|
must} be followed by calling \verb+end_seq_output+. All output will
|
|
be sent to node 0 and written there in order of increasing node
|
|
number.
|
|
|
|
{\em All nodes must participate in all calls of a sequential output section}.
|
|
|
|
Because we have to declare a fixed length string, it is possible for
|
|
some transmissions to be truncated. In practice, however, we choose
|
|
something rather longer than typical line lengths and it should not be
|
|
a serious problem.
|
|
|
|
Observe that the specified unit is the Fortran unit on node zero, not
|
|
that of the invoking node!
|
|
|
|
\subsection{Data packing and unpacking}
|
|
\begin{verbatim}
|
|
subroutine util_pack_16(nunpacked, packed, unpacked)
|
|
integer nunpacked [input]
|
|
integer packed(*) [output]
|
|
integer unpacked(nunpacked) [input]
|
|
|
|
subroutine util_unpack_16(nunpacked, packed, unpacked)
|
|
integer nunpacked [input]
|
|
integer packed(*) [input]
|
|
integer unpacked(nunpacked) [output]
|
|
|
|
subroutine util_pack_8(nunpacked, packed, unpacked)
|
|
integer nunpacked [input]
|
|
integer packed(*) [output]
|
|
integer unpacked(nunpacked) [input]
|
|
|
|
subroutine util_unpack_8(nunpacked, packed, unpacked)
|
|
integer nunpacked [input]
|
|
integer packed(*) [input]
|
|
integer unpacked(nunpacked) [output]
|
|
\end{verbatim}
|
|
These routines pack/unpack unsigned eight bit (0--255) or sixteen bit
|
|
(0--65535) integers to/from standard Fortran integers. The number of
|
|
unpacked numbers {\em must} be a multiple of the number of values that
|
|
fit into a single Fortran integer. On 32 bit machines this is four
|
|
eight-bit values and two sixteen-bit values. On 64 bit machines these
|
|
numbers are eight and four respectively. The number of values that
|
|
can be packed per integer can be computed in a machine
|
|
independent fashion using MA
|
|
\begin{verbatim}
|
|
npacked_per_int = ma_sizeof(mt_int, 1, mt_byte) /
|
|
n_bytes_per_value
|
|
\end{verbatim}
|
|
under the assumption that the word length is an exact multiple of the
|
|
value length.
|
|
|
|
\subsection{Checksums}
|
|
|
|
Checksums are useful for rapid comparison and validation of data, such
|
|
as digital signatures for verification of important messages, or, more
|
|
relevant to us, to determine if input and disk resident restart data
|
|
are still consistent. The checksum routines provided here are
|
|
wrappers around the RSA implementation of the RSA Data Security, Inc.
|
|
MD5 Message-Digest Algorithm. It is the reference implementation for
|
|
internet RFC 1321, The MD5 Message-Digest Algorithm, and as such has
|
|
been extensively tested and there are no restrictions placed upon its
|
|
distribution or export. License is granted by RSA to make and use
|
|
derivative works provided that such works are identified as "derived
|
|
from the RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all
|
|
material mentioning or referencing the derived work. Consider this
|
|
done. The unmodified network posting is included in md5.txt for
|
|
reference.
|
|
|
|
\begin{quote}
|
|
MD5 is probably the strongest checksum algorithm most people will need
|
|
for common use. It is conjectured that the difficulty of coming up
|
|
with two messages having the same message digest is on the order of
|
|
$2^{64}$ operations, and that the difficulty of coming up with any
|
|
message having a given message digest is on the order of $2^{128}$
|
|
operations.
|
|
\end{quote}
|
|
|
|
The checksums are returned (through the NWChem interface) as character
|
|
strings containing a 32 character hexadecimal representation of the
|
|
128 bit binary checksum. This form loses no information, may be
|
|
readily compared with single statements of standard C/F77, is easily
|
|
printed, and does not suffer from byte ordering problems. The
|
|
checksum depends on both the value and order of data, and thus
|
|
differing numerical representations, floating-point rounding
|
|
behaviour, and byte ordering, make the checksum of all but simple text
|
|
data usually machine dependent unless great care is taken when moving
|
|
data between machines. The Fortran test program merely tests the
|
|
Fortran interface. For a more definitive test of MD5 make
|
|
\verb+mddriver+ and execute it with the \verb+-x+ option, comparing
|
|
output with that in \verb+md5.txt+.
|
|
|
|
\subsubsection{Checksum C and Fortran interface}
|
|
|
|
C routines should include \verb+checksum.h+ for prototypes.
|
|
There is no Fortran header file since there are no functions.
|
|
|
|
The checksum of a contiguous block of data may be generated with
|
|
\begin{verbatim}
|
|
call checksum_simple(len, data, sum)
|
|
\end{verbatim}
|
|
--- to get more sophisticated see below and have a look at \verb+ftest.F+.
|
|
|
|
\begin{verbatim}
|
|
C: void checksum_init(void);
|
|
F77: subroutine checksum_init()
|
|
\end{verbatim}
|
|
|
|
Initialize the internal checksum. \verb+checksum_update()+ may then
|
|
be called repeatedly. The result does NOT depend on the number
|
|
of calls to \verb+checksum_update()+ - e.g., the checksum of an array
|
|
element-by-element is the same as the checksum of all elements
|
|
(in the same order) at once.
|
|
|
|
\begin{verbatim}
|
|
C: void checksum_update(int len, const void *buf)
|
|
F77: subroutine checksum_update(len, buf)
|
|
integer len ! [input] length in bytes
|
|
<anything but character> buf(*) ! [input] data to sum
|
|
\end{verbatim}
|
|
|
|
Update the internal checksum with \verb+len+ bytes of data from the
|
|
location pointed to by buf. Fortran may use the MA routines
|
|
for portable conversion of lengths into bytes.
|
|
|
|
\begin{verbatim}
|
|
F77: subroutine checksum_char_update(buf)
|
|
character*(*) buf ! [input] data to sum
|
|
\end{verbatim}
|
|
|
|
Same as \verb+checksum_update()+ but only for Fortran character strings
|
|
(trailing blanks are included).
|
|
|
|
\begin{verbatim}
|
|
C: void checksum_final(char sum[33])
|
|
F77: subroutine checksum_final(sum)
|
|
character*32 sum ! [output] checksum
|
|
\end{verbatim}
|
|
|
|
Finish generating the checksum and return the checksum value
|
|
as a C (null terminated) or Fortran character string.
|
|
|
|
\begin{verbatim}
|
|
C: void checksum_simple(int len, const void *buf, char sum[33]);
|
|
F77: subroutine checksum_simple(len, buf, sum)
|
|
integer len ! [input] length in bytes
|
|
<anything but character> buf(*) ! [input] data to sum
|
|
character*32 sum ! [output] checksum
|
|
\end{verbatim}
|
|
|
|
Convenience routine when checksumming a single piece of data.
|
|
Same as:
|
|
\begin{verbatim}
|
|
call checksum_init()
|
|
call checksum_update(len, buf)
|
|
call checksum_final(sum)
|
|
\end{verbatim}
|
|
|
|
\begin{verbatim}
|
|
F77: subroutine checksum_char_simple(buf, sum)
|
|
character*(*) buf ! [input] data to sum
|
|
character*32 sum ! [output] checksum
|
|
\end{verbatim}
|
|
|
|
Same as \verb+checksum_simple()+ but only for Fortran character strings
|
|
(trailing blanks are included).
|
|
|
|
|
|
\subsection{Source version information}
|
|
|
|
\subsubsection{{\tt util\_version}}
|
|
\begin{verbatim}
|
|
subroutine util_version
|
|
\end{verbatim}
|
|
By default this routine does nothing since it is expensive to
|
|
construct. If you execute the command {\tt make version} in the
|
|
{\tt util} directory then all configured source files will be
|
|
processed to generate a copy \verb+util_version+ which when called
|
|
will printout the name and version information of all source files,
|
|
organized by module. Of course, you'll also have to relink.
|
|
|
|
\subsection{Times and dates}
|
|
|
|
\subsubsection{{\tt util\_cpusec}}
|
|
\begin{verbatim}
|
|
double precision function util_cpusec()
|
|
\end{verbatim}
|
|
This function returns the cputime in seconds from the start of the
|
|
process. On some systems this number will be the same as the wall
|
|
time. The resolution and call overhead will also vary. This routine
|
|
should provide the most accurate cputime. On nearly all systems the
|
|
clocks are not synchronized between processes.
|
|
|
|
\subsubsection{{\tt util\_wallsec}}
|
|
\begin{verbatim}
|
|
double precision function util_wallsec()
|
|
\end{verbatim}
|
|
Routine to return wall clock seconds since the start of execution. On
|
|
nearly all systems the clocks are not synchronized between processes.
|
|
Resolution will also vary.
|
|
|
|
\subsubsection{{\tt util\_date}}
|
|
\begin{verbatim}
|
|
subroutine util_date(date)
|
|
character*(*) date [output]
|
|
\end{verbatim}
|
|
Routine to return to Fortran the current date in the same format as the
|
|
standard C routine {\tt ctime()}. Note that there are 26 characters
|
|
in this format and a fatal error will result if the argument {\tt
|
|
date} is too small.
|
|
|
|
\subsection{System operations and information}
|
|
|
|
\subsubsection{{\tt util\_hostname}}
|
|
\begin{verbatim}
|
|
subroutine util_hostname(name)
|
|
character*(*) name [output]
|
|
\end{verbatim}
|
|
Returns in {\tt name} the hostname of the machine. A fatal error
|
|
results if {\tt name} is too small to hold the result --- 256
|
|
characters should suffice.
|
|
|
|
\subsubsection{{\tt util\_file\_unlink}}
|
|
\begin{verbatim}
|
|
subroutine util_file_unlink(filename)
|
|
character*(*) filename [input]
|
|
\end{verbatim}
|
|
The calling process executes the \verb+unlink()+ system call to delete
|
|
the file. If the file does not exist then it quietly returns. If the
|
|
file exists and the unlink fails then it aborts calling
|
|
\verb+ga_error()+.
|
|
|
|
\subsubsection{{\tt util\_file\_copy}}
|
|
\begin{verbatim}
|
|
subroutine util_file_copy(input, output)
|
|
character*(*) input [input]
|
|
character*(*) output [input]
|
|
\end{verbatim}
|
|
The calling process copies the named input file to the named output
|
|
file. All errors are fatal.
|
|
|
|
\subsubsection{{\tt util\_system}}
|
|
\begin{verbatim}
|
|
integer function util_system(command)
|
|
character*(*) command [input]
|
|
\end{verbatim}
|
|
The calling processes execute the UNIX system call \verb+system()+
|
|
with \verb+command+ as an argument. This executes \verb+command+
|
|
inside the Bourne shell. Returned is the completion code of the
|
|
command (typically 0 on success). If this functionality is not
|
|
supported on a given machine then a non-zero value (1) is returned.
|
|
|
|
\subsection{C to Fortran interface}
|
|
|
|
\subsubsection{{\tt string\_to\_fortchar} and {\tt
|
|
fortchar\_to\_string}}
|
|
\begin{verbatim}
|
|
#ifdef CRAY
|
|
#include "fortran.h"
|
|
int string_to_fortchar(_fcd f, int flen, char *buf);
|
|
int fortchar_to_string(_fcd f, int flen, char *buf,
|
|
const int buflen);
|
|
#else
|
|
int string_to_fortchar(char *f, int flen, char *buf);
|
|
int fortchar_to_string(const char *f, int flen, char *buf,
|
|
const int buflen);
|
|
#endif
|
|
\end{verbatim}
|
|
These C callable routines automate the tricky conversion of C
|
|
null-terminated character strings to Fortran character strings
|
|
(\verb+string_to_fortchar+) and vice versa
|
|
(\verb+fortchar_to_string+). The Cray interface is
|
|
complicated by their use of character descriptors. We describe the
|
|
non-Cray interface.
|
|
\begin{itemize}
|
|
\item {\tt f} --- a pointer to the Fortran character string
|
|
\item {\tt flen} --- the length of the Fortran string (i.e., number of
|
|
storage locations in bytes)
|
|
\item {\tt buf} --- pointer to the C character string
|
|
\item {\tt buflen} --- the size of buf (i.e., number of bytes in the
|
|
buffer).
|
|
\end{itemize}
|
|
In converting to C format, strings are stripped of trailing blanks and
|
|
terminated with a null-character. In converting to Fortran format, the
|
|
null character is removed and the Fortran string padded on the right
|
|
with blanks.
|
|
|
|
|
|
\subsection{Debugging aids}
|
|
|
|
\subsubsection{{\tt ieeetrap}}
|
|
|
|
\subsection{Miscellaneous BLAS-like operations}
|
|
|
|
dabsmax.F --- to be removed
|
|
|
|
dabssum.F --- to be removed
|
|
|
|
rsg.f --- Eispack diagonalization routine --- should use Lapack
|
|
equivalent instead
|
|
|
|
|
|
\subsubsection{Initializing arrays --- {\tt dfill} and {\tt ifill}}
|
|
|
|
\begin{verbatim}
|
|
subroutine dfill(n, s, x, ix)
|
|
integer n ! [input] No. of elements to initialize
|
|
double precision s ! [input] Value to set each element to
|
|
double precision x(*) ! [output] Array to initialize
|
|
integer ix ! [input] Stride between elements
|
|
|
|
subroutine ifill(n, i, m, im)
|
|
integer n ! [input] No. of elements to initialize
|
|
integer i ! [input] Value to set each element to
|
|
integer m(*) ! [output] Array to initialize
|
|
integer im ! [input] Stride between elements
|
|
\end{verbatim}
|
|
|
|
Initialize \verb+n+ elements of the array \verb+x(*)+ to the value
|
|
\verb+s+. The stride between elements is specified by \verb+ix+ which
|
|
should be specified as one for contiguous data. Routine
|
|
\verb+ifill()+ should be used for integer data.
|
|
|
|
|