Patch for more versatile "assigns" on Cray Computers
Problem:
-------
The implementation with "ffopens" allows only to pass a simple "assign"
parameter (namely the option following -F to determine the buffer
structure). For those who like to fiddle around with ALL assign
options (to determine the partitions and reserved block sizes and so
on) for optimization, I added some additional lines to libsrc/ffio.c.
Implementation:
------------
Here is a patch to netCDF version 3.4 for users of Cray Supercomputers
(tested for T3E only but it should run on all Unicos machines supplying the
fast flexible I/O (ffio) scheme, especially the Fortran ASSIGN
command).Instead of using the ffopens-command the Fortran ASSIGN
command is called to pass the options. To provide full compatabilty an
extra environment variable called NETCDF_XFFIOSPEC ist introduced and
appended to the parameters of the assign command. Schematically:
assign -F $NETCDF_FFIOSPEC $NETCDF_XFFIOSPEC
Extra functionality:
--------------
Now there is an extra environment variable called "NETCDF_XFFIOSPEC"
which holds additional options to the assign command. For
compatibility reasons the -F option is still passed via
"NETCDF_FFIOSPEC". This seems a bit complicated but it assures
that even the not patched programms (including ncdump and ncgen) will
work without errors.
Example (bourne shell grammer):
------------------------
Type
NETCDF_FFIOSPEC="cachea:8:350"
NETCDF_XFFIOSPEC="-p 0:1 -d 100"
and run a (patched) netCDF-programm. Then when reading or writing a
file it will use 350 asynchronous Buffers of 8 * 512kwords size each
AND place it only on partitions 0 and 1 of the (respectively designed)
file system, changing partitions every 100 Blocks (512kwords each).
Note:
The cited NETCDF_FFIOSPEC yielded a factor 1/10 in execution time for
a programm that randomly accessed a netCDF file (array rearrangements).
To apply the patch:
---------------
1) write the block between --------start and --------end into a file
(preferably patch_ffio)
1) walk down to netcdf-3.4/src/libsrc
2) faint hearted people make a copy of the original (recommended)
3) type: "patch patch ffio.c ffio.c path_of_ffio/patch_ffio" (symbolically)
4) recompile netCDF, ncgen and ncdump
Patch (context patch) follows:
--------start
*** ffio.c.orig Thu Mar 12 10:08:00 1998
--- ffio.c Thu Mar 12 17:23:05 1998
***************
*** 16,21 ****
--- 16,23 ----
#include <ffio.h>
#include <unistd.h>
#include <string.h>
+ /* Insertion by O. R. Heudecker, AWI-Bremerhaven 12.3.98 (1 line)*/
+ #include <fortran.h>
#include "ncio.h"
#include "fbits.h"
***************
*** 477,487 ****
{
ControlString="bufa:336:2";
}
!
if(fIsSet(ioflags, NC_NOCLOBBER))
fSet(oflags, O_EXCL);
! fd = ffopens(path, oflags, 0666, 0, &stat, ControlString);
if(fd < 0)
{
status = errno;
--- 479,513 ----
{
ControlString="bufa:336:2";
}
! /* Insertion by Olaf Heudecker, AWI-Bremerhaven, 12.8.1998
! to allow more versatile FFIO-assigns */
! /* begin new */
! {
! char assignstr[128];
! char emptystr=' ';
! char *xtra_assign;
! xtra_assign = getenv("NETCDF_XFFIOSPEC");
! if(xtra_assign == NULL)
! {
! xtra_assign=&emptystr;
! }
! if (strlen(ControlString)+strlen(xtra_assign)+21 > 127) {
! /* Error: AssignCommand too long */
! status=E2BIG;
! goto unwind_new;
! }
! sprintf(assignstr,"assign -F %s %s f:%s",ControlString,
! xtra_assign,path);
! /* printf("1 assignstr=>%s<\n",assignstr); */
! /* Aufruf der Fortran-Routine assign von C aus */
! ASSIGN(_cptofcd(assignstr,strlen(assignstr)));
! }
! /* end new */
if(fIsSet(ioflags, NC_NOCLOBBER))
fSet(oflags, O_EXCL);
! /* Orig: fd = ffopens(path, oflags, 0666, 0, &stat, ControlString); */
! fd = ffopen(path, oflags, 0666, 0, &stat);
if(fd < 0)
{
status = errno;
***************
*** 559,566 ****
{
ControlString="bufa:336:2";
}
! fd = ffopens(path, oflags, 0, 0, &stat, ControlString);
if(fd < 0)
{
status = errno;
--- 585,618 ----
{
ControlString="bufa:336:2";
}
+ /* Insertion by Olaf Heudecker, AWI-Bremerhaven, 12.8.1998
+ to allow more versatile FFIO-assigns */
+ /* begin new */
+ {
+ char assignstr[128];
+ char emptystr=' ';
+ char *xtra_assign;
+ xtra_assign = getenv("NETCDF_XFFIOSPEC");
+ if(xtra_assign == NULL)
+ {
+ xtra_assign=&emptystr;
+ }
+ if (strlen(ControlString)+strlen(xtra_assign)+21 > 127) {
+ /* Error: AssignCommand too long */
+ status=E2BIG;
+ goto unwind_new;
+ }
+ sprintf(assignstr,"assign -F %s %s f:%s",ControlString,
+ xtra_assign,path);
+ /* printf("2 assignstr=>%s<\n",assignstr); */
+ /* Aufruf der Fortran-Routine assign von C aus */
+ ASSIGN(_cptofcd(assignstr,strlen(assignstr)));
+ }
+ /* end new */
! /* Orig: fd = ffopens(path, oflags, 0, 0, &stat, ControlString); */
! fd = ffopen(path, oflags, 0, 0, &stat);
!
if(fd < 0)
{
status = errno;
--------end
Have fun
Olaf R. Heudecker