diff options
Diffstat (limited to 'doc/html/UsingF77.html')
-rw-r--r-- | doc/html/UsingF77.html | 532 |
1 files changed, 532 insertions, 0 deletions
diff --git a/doc/html/UsingF77.html b/doc/html/UsingF77.html new file mode 100644 index 0000000..5118411 --- /dev/null +++ b/doc/html/UsingF77.html @@ -0,0 +1,532 @@ +<html> + <head> + <title>IEEEIO F77 Interface</title> + </head> + <body bgcolor="#F0F0F0"> + <table><tr> + <td><img src="Images/info.gif"></td> + <td><h1>Fortran77</h1></td> + </tr></table> + <hr> + <h1>Using the F77 Interface</h1> + To use the F77 interface you must link to <b>ieeeio.a</b> and + the C++ libraries using + <DL> + <DT><b>All machines except SGI Irix 6.4</b> + <DD>f77</code> <i>link_line_stuff</i> <code>-L$IEEE_DIRECTORY/lib + -lieeeio -lC -lc</code> + <DT><b>SGI machines running Irix 6.4</b> <i>(eg. O2k and + Octane)</i> + <DD>f77</code> <i>link_line_stuff</i> <code>-L$IEEE_DIRECTORY/lib + -lieeeio -lC -lCsup -lc</code> + </DL> + The <code>-lC</code> and <code>-lc</code> links in the C and C++ + libraries with the fortran libraries. Irix 6.4 also requires + <code>-lCsup</code> for reasons I do not know.<p> + + If you + also want HDF support you must also link with <b>libhdfio.a</b> and + the usual complement of HDF libraries using + <code>-L$HDF_DIRECTORY/lib -L$IEEE_DIRECTORY/lib -lhdfio + -lieeeio -lmfhdf -ldf -ljpeg -lz</code>. + <hr> + <h1>F77 Subroutines</h1> + <UL> + <LI><a href="#Opening">Opening and Closing Datafiles</a> + <LI><a href="#Writing">Writing Datasets</a> + <LI><a href="#Reading">Reading Datasets</a> + <LI><a href="#Seeking">Random Access to Datasets + <i>(Seeking)</i></a> + <LI><a href="#WriteAttribs">Writing Attributes</a> + <LI><a href="#ReadAttribs">Reading Attributes</a> + <LI><a href="#WriteAnn">Writing Annotations</a> + <LI><a href="#ReadAnn">Reading Annotations</a> + <LI><a href="#ReadWriteChunk">Writing and Reading in Chunks</a> + </UL> + + <hr> + <a name="Opening"><h2>Opening</h2></a> + Just like the familiar <b>FILE*</b> type for F77 stdio operations, all + IEEEIO operations require a file handle. The type of this handle is + INTEGER*8 (and 8-byte integer number). The ieee_open() and hdf_open() + routines are used to create this handle and the io_close() subroutine can + be used to close file handles of either type.<p> + <b>F77 Call Format</b><br> + <code>INTEGER*8 ieee_open(CHARACTER filename(*),CHARACTER accessmode(*))</code><br> + <code>INTEGER*8 ieee_openr(CHARACTER filename(*))</code><br> + <code>INTEGER*8 ieee_openw(CHARACTER filename(*))</code><br> + <code>INTEGER*8 ieee_opena(CHARACTER filename(*))</code><br> + <DL> + <DT><i>filename</i>: + <DD>The name of the IEEEIO data file to + open. The typical extension for these files is <i>.raw</i>. + <DT><i>accessmode</i> + <DD>This is the type of access for the file. You can either + pass an accesstype option to the function or use the + appropriately + named function for the type of access you desire. + <UL> + <LI><b>openr = 'READ'</b>:<i>Opens a file in read-only mode.</i> + <LI><b>openw = 'WRITE'</b>:<i>Opens a file in write-only mode. If the + file does not exist, it will be created. If it does exist, it will be + truncated.</i> + <LI><b>opena = 'APPEND'</b>: <i>Opens a file in read/write mode. The file + pointer is automatically placed at the end of the file for appending, + but random-access read operations are allowed as well.</i> + </UL> + </DL> + + After you open the file handle you can use the same set of + subroutines for operations on the file regardless of whether the + file is HDF or IEEEIO. The libraries manage all of this internally. So + the open step is the only thing that is important to differentiating + between your HDF and IEEEIO files. + There are plans, for example, to have a SocketIO system + that allows the data to be written out to a TCP socket instead of to a + file for real-time simulation-visualization systems. There are also + plans to use this interface to drive an existing Parallel IO + system.<p><br> + <pre> +c The file handles are INTEGER*8's + INTEGER*8 writer + INTEGER*8 reader +c open a file for writing + writer = ieee_openw('datafileout.raw') +c open an HDF file for writing + writer = hdf_openw('datafileout.raw') +c open HDF file for reading + reader = hdf_openr('datafilein.raw') +c open an IEEEIO file for reading + reader = ieee_openr('datafileout.raw') + </pre><p> + + You can test if the file was opened successfully using the + <b>io_isvalid()</b> function.<br> + <pre> + IF io_isvalid(infile).EQ.0 THEN + write(*) 'The file you specified does not exist or is not in a +readable format' + </pre><br> + + To close the file, you simply use io_close. + <pre> + INTEGER io_close(INTEGER*8 filehandle) + </pre> + + <hr> + <a name="Writing"><h2>Writing</h2></a> + To write data you simply use the method write(). + <p><b>F77 Call Format</b><br> + <code>INTEGER io_write(INTEGER*8 filehandle,INTEGER numbertype,INTEGER rank,INTEGER + dimensions(*),<i>type</i> data(*))</code> + <DL> + <DT><i>filehandle</i> + <DD>An open filehandle for the datafile. + <DT><i>numbertype</i>: + <DD>The type of the data being stored + <i>(<a href="DataTypes.html">datatype definition</a>)</i>. + It can be one of + <UL> + <LI><b>INT8=0</b><br><i>CHARACTER byte</i> + <LI><b>INT16=1</b><br><i>INTEGER*2 short integer</i> + <LI><b>INT32=2</b><br><i>INTEGER*4 standard integer</i> + <LI><b>INT64=3</b><br><i>INTEGER*8 long integer. (note: this is not + availible on the Intel/Windows platform)</i> + <LI><b>FLOAT32=4<br></b><i>REAL*4 32-bit single-precision IEEE + float</i> + <LI><b>FLOAT64=5<br></b><i>REAL*8 64-bit double-precision IEEE + float</i> + <LI><b>UINT8=6</b><br><i>unsigned character</i> + <LI><b>UINT16=7</b><br><i>unsigned INTEGER*2 short integer</i> + <LI><b>UINT32=8</b><br><i>unsigned INTEGER*4 standard integer</i> + <LI><b>UINT64=9</b><br><i>unsigned INTEGER*8 long + integer. (note: this is not availible on the + Intel/Windows platform)</i> + </UL> + <DT><i>rank</i> + <DD>Number of dimensions of the dataset + <DT><i>dimensions</i>: + <DD>An array of <i>rank</i> integers that give the dimensions of + the dataset + <DT><i>data</i>: + <DD>Your data array. + </DL> + + So to write a sample array of data. + <pre> + REAL*4 myarray(40,50,60) // our bogus data array + INTEGER i,rank + INTEGER dims(3) + rank=3 + dims(1)=40 + dims(2)=50 + dims(3)=60 +c this is because ieeeio assumes f77 order for data +c and c/c++ use exactly the opposite ordering for data +c in memory. +c create a outfile + INTEGER*8 writer,ieee_openw + writer = ieee_openw('datafile.raw') + DO i=0,ndatasets + . . . . computation . . . +c write a dataset + CALL io_write(writer,FLOAT32,rank,dims,myarray) + . . . . you can write as many datasets as you want + ENDDO +c then close the file + CALL io_close(writer) + </pre> + + <hr> + <a name="Reading"><h2>Reading Data</h2></a> + Reading is a two step process. First you get information on + the size and type of the data you intend to read. This allows + you to allocate an array of the proper size and type for the + reading. Then you actually read the data into a pre-allocated + array. The methods for this are <b>io_readInfo()</b> and + <b>io_read()</b>.<p> + <b>F77 Call Format</b><br> + <code>INTEGER io_readInfo(INTEGER*8 filehandle,INTEGER numbertype,INTEGER rank,INTEGER + dims(*),INTEGER maxdims)</code><p> + <DL> + <DT><i>filehandle</i> + <DD>A filehandle open for reading or appending. + <DT><i>numbertype</i>: + <DD>The type of the data being stored + <i>(<a href="DataTypes.html">datatype definition</a>)</i>. + It can be one of + <UL> + <LI><b>INT8=0</b><br><i>CHARACTER type</i> + <LI><b>INT16=1</b><br><i>INTEGER*2 short integer</i> + <LI><b>INT32=2</b><br><i>INTEGER*4 standard integer</i> + <LI><b>INT64=3</b><br><i>INTEGER*8 long integer. (note: this is not + availible on the Intel/Windows platform)</i> + <LI><b>FLOAT32=4<br></b><i>REAL*4 32-bit single-precision IEEE + float</i> + <LI><b>FLOAT64=5<br></b><i>REAL*8 64-bit double-precision IEEE + float</i> + <LI><b>UINT8=6</b><br><i>unsigned CHARACTER character</i> + <LI><b>UINT16=7</b><br><i>unsigned INTEGER*2 short integer</i> + <LI><b>UINT32=8</b><br><i>unsigned INTEGER*4 standard integer</i> + <LI><b>UINT64=9</b><br><i>unsigned INTEGER*8 long + integer. (note: this is not availible on the + Intel/Windows platform)</i> + </UL> + <DT><i>rank</i> + <DD>Number of dimensions of the dataset + <DT><i>dimensions</i>: + <DD>An array of <i>rank</i> integers that give the dimensions + of the dataset + <DT><i>maxdims</i>: + <DD>The maximum size of the dimensions array you given it. + This prevents array overruns if the dataset has more + dimensions than you were anticipating. It can be any positive + integer. + </DL> + This retrieves information about the datatype, rank, + and dimensions of the dataset to be retrieved. + By default the maximum size of the dimensions array is 3, + but you can set it to be larger.<p> + <b>F77 Call Format</b><br> + <code> + INTEGER io_read(INTEGER*8 filehandle,<i>sometype</i> data(*)) + </code><p> + This actually reads the dataset into the preallocated array + <i>data</i>.<p> + + Another useful utility function is io_sizeof() which returns the + number of bytes in a give IO datatype in manner analogous to the + standard C sizeof() operator. This may not be of consequence for most + f77 codes. + + So for instance, to read a simple dataset, you would do + <pre> + INTEGER rank + INTEGER numbertype + INTEGER dims(3) +c Note: The "PTR" is the architecture dependent definition of +c a dynamically-allocated memory handle. (my vary from system to +c system under F77. + PTR data + INTEGER*8 infile,ieee_openr + infile = ieee_openr('dataset.raw') + io_readInfo(infile,numbertype,rank,dims) +c OK, we are assuming a 3D IO::Float32 array, +c but you can be more sophisticated... +c Note: The "allocate" statement is a stand-in for +c your architecture dependent dynamic memory allocation function +c for your particular system. + data = allocate(io_nbytes(numbertype,rank,dims)) +c io_nbytes() is a convenience function.. you can just as easily use +c data = allocate(dims(1) * dims(2) * dims(3) * io_sizeof(numbertype)) + CALL io_read(infile,data) // read in the data + </pre><p> + + Since multiple datasets can be stored in a file, you can + retrieve them in the order they were written <i>(there is a <a + href="#Seeking">seek()</a> function that allows random access as + well)</i>. The method <b>io_readinfo()</b> implies reading the next + dataset stored in the file. The method <b>io_numdata()</b> tells how + many datasets are in a file. So typically if you want to read all + datasets in a file in order, you would use code similar to; + <pre> + INTEGER*8 infile,ieee_openr + infile = ieee_openr('dataset.raw') + ndatasets = io_numdata(infile) + DO i=1,ndatasets BEGIN + .....lots of code.... +c increments to next dataset + CALL io_readinfo(infile,numbertype,rank,dims) + .....more code.... + ENDDO + </pre> + + <hr> + <a name="Seeking"><h2>Random Access to Datasets + <i>(Seeking)</i></h2></a> + You can select specific datasets in a file using the seek() + method.<p> + <b>F77 Call Format</b> + <code>INTEGER io_seek(INTEGER*8 filehandle,INTEGER index)</code> + <DL> + <DT><i>filehandle</i>: + <DD>Handle to a file open for reading. + <DT><i>index</i>: + <DD>The index of the dataset you want to read from. This can + be any number from 0 to (number_of_datasets - 1). + </DL> + + <hr> + <a name="WriteAttribs"><h2>Writing Attributes</h2></a> + Attributes allow you to attach extra information to each + dataset stored in the file. Each attribute has a name and an + array of data (of any of the standard IO datatypes) stored with + it. These attributes can be retrieved by name or by integer + index in the order in which they were stored. A typical + attribute would typically be parameters that describe the grid + or the data like, 'origin' which would be the 3-vector of floats + which locates of the origin of a grid in 3-space. The method + used to write these attributes is <b>io_writeAttribute()</b>.<p> + <b>F77 Call Format</b><br> + <code> + INTEGER io_writeatt(INTEGER*8 filehandle,CHARACTER name(*),INTEGER numbertype,INTEGER + length,(some type) data(*)) + </code><p> + <DL> + <DT><i>filehandle</i> + <DD>An open filehandle for the datafile. + <DT><i>name</i>: + <DD>Name of the attribute (like 'origin' or 'coordinates') + <DT><i>numbertype</i>: + <DD>The type of the data array associated with the attribute + <i>(<a href="DataTypes.html">datatype definition</a>)</i> + <DT><i>length</i>: + <DD>The number of elements in the data array. + <DT><i>data</i>: + <DD>The attribute data. + </DL><p> + So to write an attribute named <i>origin</i> along with a + 3-vector float for the coordinates of the origin, you would use; + <pre> + REAL*4 origin(3) + origin(1)=5. + origin(2)=0.3 + origin(3)=0.5 +c and assuming the file is already open for writing +c the following attribute will be attached to the last +c written dataset. (you must have write data before adding attribs) + io_writeatt(writer,'origin',FLOAT32,3,origin) + </pre> + + <hr> + <a name="ReadAttribs"><h2>Reading Attributes</h2></a> + The attributes can be retrieved in the order they were written + or they can be retrieved by their name. To retrieve the + attributes in order, you would utilize the <b>io_numatt()</b> + method to determine how many attributes are attached, + <b>io_iattinfo()</b> to get the size and type of the + attribute based on its index (<i>use io_attinfo() to get size + and type for the attribute based on its name</i>), + and <b>io_readatt()</b> to read the attribute + data.<p> + <b>F77 Call Format</b><br> + <code>INTEGER io_numatt(INTEGER*8 filehandle)</code><p> + <DL> + <DT><i>filehandle</i> + <DD>An open filehandle for the datafile. + <DT><i>returnvalue</i>: + <DD>Number of attributes in the file + </DL><p> + <b>F77 Call Format</b><br> + <code>INTEGER io_iattinfo(INTEGER index,CHARACTER name(*),INTEGER + numbertype,INTEGER length,INTEGER maxnamelength) + </code> + <DL> + <DT><i>index</i>: + <DD>The index of the attribute which can be 0 to (nattributes-1) + <DT><i>name</i>: + <DD>A buffer in which the name of the attribute will be placed. + <DT><i>numbertype</i>: + <DD>The type of the attribute data + <i>(<a href="DataTypes.html">datatype definition</a>)</i> + <DT><i>length</i>: + <DD>The number of elements in the attribute data. + <DT><i>maxnamelength</i>:<DD>The maximum size of a name that can be + stored in the <b>name</b> buffer. It can be any positive integer. + </DL> + <p> + <b>F77 Call Format</b><br> + <code>INTEGER io_readatt(INTEGER*8 filehandle,INTEGER index,(sometype) data(*))</code> + <DL> + <DT><i>filehandle</i> + <DD>An open filehandle for the datafile. + <DT><i>index</i>: + <DD>The index of the attribute data to read + <DT><i>data</i>: + <DD>The array into which the attribute data is copied. + </DL> + So for example, to read the attributes in order, you can use + <pre> + INTEGER io_numatt + CHARACTER*128 name + INTEGER length,datatype + nattributes=io_numatt(infile) + DO i=0,nattributes + ... + CALL io_iattinfo(infile,i,name,&datatype,&length) + ... allocate some data for storage or put in preallocated data + CALL io_readatt(infile,i,data) + ENDDO + </pre><p> + + The attributes can also be retrieve by name. In fact, the is + the most likely way you will use the attibutes interface. The + <b>io_attinfo()</b> method is overloaded to allow retrieval by + name as + well. It returns the index of the attribute if one is found with a + matching name: it returns -1 if one is not found. + <p><b>F77 Call Format</b><br> + <code> + INTEGER io_attinfo(CHARACTER name(*),INTEGER numbertype,INTEGER + length) + </code> + <DL> + <DT><i>filehandle</i> + <DD>An open filehandle for the datafile. + <DT><i>returnvalue</i>: + <DD>The index of the attribute if found or -1 if no attribute with + matching name is found. + <DT><i>name</i>: + <DD>The name of the attribute to find. + <DT><i>numbertype</i>: + <DD>Returns the numbertype of the stored attribute data + <i>(<a href="DataTypes.html">datatype definition</a>)</i> + <DT><i>length</i>: + <DD>The length of the stored attribute data. + </DL> + So a typical use of this interface would be to find an attribute + named 'origin' and retrieve its data if it exists. + <pre> + INTEGER io_attinfo + index = io_attinfo(infile,'origin',datatype,length) + IF (index.LE.0) THEN +c the attribute exists + CALL io_readatt(infile,index,data) + ELSE + write (*) 'The attribute origin could not be found' + ENDIF + </pre> + + </pre> + + <hr> + <a name="WriteAnn"><h2>Writing Annotations</h2></a> + An annotation is a text string which can be used to + describe a dataset. To write an annotation, you use the + writeAnnotation() method.<p> + <b>F77 Call Format</b><br> + <code> + INTEGER io_writenote(INTEGER*8 filehandle,CHARACTER annotationtext(*),INTEGER length) + </code> + <DL> + <DT><i>filehandle</i> + <DD>An open filehandle for the datafile. + <DT><i>annotationtext</i>: + <DD>A character array of the annotation text + <DT><i>annotationlength</i> + <DD>The length of the character array + </DL> + The annotation will be attached to the last written dataset. + You can store more than one annotation per dataset and the + annotations can be of arbitrary length.<p> + + <hr> + <a name="ReadAnn"><h2>Reading Annotations</h2></a> + The annotations are stored in the order they are written. The + method <b>io_numnote()</b> is used to find out how many + attributes are attached to a dataset. The method + <b>io_readnoteinfo()</b> is used to find the length of the + annotation and <b>io_readnote()</b> reads the actual + annotation text.<p> + <b>F77 Call Format</b><br> + <code> + INTEGER io_numnote(INTEGER*8 filehandle) + </code> + <DL> + <DT><i>filehandle</i> + <DD>An open filehandle for the datafile. + <DT><i>returnvalue</i>: + <DD>Number of annotations attached to current dataset. + </DL><p> + <b>F77 Call Format</b><br><code> + io_readnoteinfo(INTEGER*8 filehandle,INTEGER index,INTEGER length) + </code> + <DL> + <DT><i>filehandle</i> + <DD>An open filehandle for the datafile. + <DT><i>index</i>: + <DD>Index of the annotations which can be 0 to (nannotations-1) + <DT><i>length</i>: + <DD>Length in characters of the annotation. This includes the + null-terminating character. + </DL> + + <hr> + <a name="ReadWriteChunk"><h2>Writing and Reading in Chunks</h2></a> + For distributed-memory programming paradigms like HPF, MPI, or + PVM, it is often not unfeasible to write data to disk in a + single operation. For this reason, a <i>chunking</i> interface + is provided which allows you to write data in blocks to the + disk.<p> + To begin a chunk writing operation, you must first reserve a + data chunk in the file. This is accomplished using <b>io_reservck()</b> + <b>F77 Call Format</b><br> + <code> + INTEGER io_reservck(INTEGER*8 filehandle,INTEGER datatype,INTEGER rank,INTEGER dims(*)) + </code><p> + Once space has been allocated in the datafile, you can write + blocks of data specified by their dimensions and origin using + <b>io_writeck()</b> + <b>F77 Call Format</b><br> + <code> + INTEGER io_writeck(INTEGER*8 filehandle,INTEGER dims(*),INTEGER origin(*),(sometype) data(*...)) + </code><p> + Likewise, it is possible to read chunks from the disk as + well. No special procedure is required to select a record to + read in chunks. Simply use <a href="#Reading">io_readinfo()</a> + to get the dimensions and + type of the dataset and then use <b>io_readck()</b> in place + of <b>io_read()</b> in order to read-in the data. + <b>F77 Call Format</b><br> + <code> + INTEGER io_readck(INTEGER*8 filehandle,INTEGER dims(*),INTEGER origin(*),(sometype) data(*...)) + </code><p> + <hr> + <address><a href="mailto:jshalf@suttung.aei-potsdam.mpg.de">John + Shalf</a></address> + <!-- Created: Mon Apr 7 12:52:52 MDT 1997 --> + <!-- hhmts start --> +Last modified: Thu Feb 4 22:02:39 CST 1999 +<!-- hhmts end --> + </body> +</html> |