Lib-DVM interface description (contents) | Part 1 (1-5) |
Part 2 (6-7) |
Part 3 (8-11) |
Part 4 (12-13) |
Part 5 (14-15) |
Part 6 (16-18) |
Part 7 (19) |
created: february, 2001 | - last edited 03.05.01 - |
16.1 Analogies to functions of C language standard library
All functions discussed below is intended for usage for input/output of the replicated variables (all copies of each variable are equal). The implementaôion of these functions is based on the execution of the standard C functions on the processor, called "I/O processor". The result (if one exists) of the functions is sent to all the processors. For example, the execution of the function dvm_prinf results in single printing from the I/O processor. The execution of the function printf results in multiple printing from each processor. It is possible to determine if the current processor is I/O processor with the help of the function tstio_ (see section 17.6).
Note, that it is possible to use in the user program the I/O functions of the standard C language library (ANSI), which have no corresponding functions in the list below and have no undesirable effect of multiple executions.
16.1.1. High level input/output functions
ANSI:
void | dvm_clearerr | (DVMFILE *StreamPtr); |
int | dvm_fclose | (DVMFILE *StreamPtr); |
int | dvm_feof | (DVMFILE *StreamPtr); |
int | dvm_ferror | (DVMFILE *StreamPtr); |
int | dvm_fflush | (DVMFILE *StreamPtr); |
int | dvm_fgetc | (DVMFILE *StreamPtr); |
int | dvm_fgetpos | (DVMFILE *StreamPtr, fpos_t *PosPtr); |
char | *dvm_fgets | (char *StringPtr, int n, DVMFILE *StreamPtr); |
DVMFILE | *dvm_fopen | (const char *FileNamePtr, const char TypePtr); |
int | dvm_fprintf | (DVMFILE *StreamPtr, const char *FormatPtr [, Argument, ... ]); |
void | dvm_void_fprintf | (DVMFILE *StreamPtr, const char *FormatPtr [, Argument, ... ]); |
int | dvm_fputc | (int c, DVMFILE *StreamPtr); |
int | dvm_fputs | (const char *StringPtr, DVMFILE *StreamPtr); |
int | dvm_fread | (void *BufferPtr, size_t Size, size_t Count, DVMFILE *StreamPtr); |
DVMFILE | *dvm_freopen | (const char *FileNamePtr, const char *TypePtr, DVMFILE *StreamPtr); |
int | dvm_fscanf | (DVMFILE *StreamPtr, const char *FormatPtr [, ArgumentPtr, ... ]); |
int | dvm_fseek | (DVMFILE *StreamPtr, long Offset, int Origin); |
int | dvm_fsetpos | (DVMFILE *StreamPtr, const fpos_t *PosPtr); |
long | dvm_ftell | (DVMFILE *StreamPtr); |
int | dvm_fwrite | (const void *BufferPtr, size_t Size, size_t Count, DVMFILE *StreamPtr); |
int | dvm_getc | (DVM_FILE *StreamPtr); |
int | dvm_getchar | (void); |
char | *dvm_gets | (char *BufferPtr); |
int | dvm_printf | (const char *FormatPtr, ... ); |
void | dvm_void_printf | (const char *FormatPtr, ... ); |
int | dvm_putc | (int c, DVMFILE *StreamPtr); |
int | dvm_putchar | (int c); |
int | dvm_puts | (char const *StringPtr); |
void | dvm_rewind | (DVMFILE *StreamPtr); |
int | dvm_scanf | (const char *FormatPtr [, ArgumentPtr, ... ]); |
void | dvm_setbuf | (DVMFILE *StreamPtr, char *BufferPtr); |
int | dvm_setvbuf | (DVMFILE *StreamPtr, char *BufferPtr, int Type, int Size); |
DVMFILE | *dvm_tmpfile | (void); |
int | dvm_ungetc | (int c, DVMFILE *StreamPtr); |
int | dvm_vfprintf | (DVMFILE *StreamPtr, const char *FormatPtr, va_list ArgList); |
void | dvm_void_vfprintf | (DVMFILE *StreamPtr, const char *FormatPtr, va_list ArgList); |
int | dvm_vprintf | (const char *FormatPtr, va_list ArgList); |
void | dvm_void_vprintf | (const char *FormatPtr, va_list ArgList); |
BORLAND-C & MICROSOFT-C:
int | dvm_fgetchar | (void); |
int | dvm_fputchar | (int c); |
BORLAND-C:
int | dvm_vfscanf | (DVMFILE *StreamPtr,
const char *FormatPtr, va_list ArgList); |
int | dvm_vscanf | (const char *FormatPtr, va_list ArgList); |
In the functions above to specify standard streams the following pointers can be used:
DVMFILE *DVMSTDIN | - | standard input stream; |
DVMFILE *DVMSTDOUT | - | standard output stream; |
DVMFILE *DVMSTDERR | - | standard error stream; |
DVMFILE *DVMSTDAUX | - | standard com port; |
DVMFILE *DVMSTDPRN | - | standard printer port. |
Note 1. The distinction (in the realization) between the functions dvm_void_printf, dvm_void_fprintf, dvm_void_vprintf, dvm_void_vfprintf are the functions dvm_printf, dvm_fprintf, dvm_vprintf, dvm_vfprintf is that the I/O processor does not send the return values of the functions printf, fprintf, vprintf and vfprintf to another processors, i.e. their is difference in the execution time. The full analogues of the standard functions printf, fprintf, vprintf and vfprintf are the functions dvm_printf, dvm_fprintf, dvm_vprintf and dvm_.
Note2. The functions dvm_fread and dvm_fwrite can be used to read/write the distributed array. In this case, the BufferPtr pointer has to point to the header of the distributed array. The size of the array element is assumed to be equal to *TypeSizePtr (that is value used at the array creation with the function crtda_), not Size. The number of the elements to read/write is assumed to be equal to the minimum of Count*Size/(*TypeSizePtr) and the number of the elements in the distributed array (also see the description of the functions dvm_dfread and dvm_dfwrite in sections 16.2 and 16.3).
Distributed array, specified in dvm_fread and dvm_fwrite function call must be mapped on the processor system, all elements of which must belong to the current processor system.
Note 3. Access to standard stdaux (stdprn) stream using DVMSTDAUX (DVMSTDPRN) pointer is possible only if Run-Time System was compiled with defined compilation variable _DVM_STDAUX_ (_DVM_STDPRN_).
16.1.2 Low lewel I/O functions
BORLAND-C & MICROSOFT-C & PORTLAND GROUP-C:
int | dvm_close | (DVMHANDLE *HandlePtr); |
int | dvm_fstat | (DVMHANDLE *HandlePtr, struct stat *BufferPtr); |
long | dvm_lseek | (DVMHANDLE *HandlePtr, long Offset, int Origin); |
DVMHANDLE | *dvm_open | (const char *FileNamePtr, int OFlag, int Pmode); |
int | dvm_read | (DVMHANDLE *HandlePtr, char *BufferPtr, unsigned int Count); |
int | dvm_write | (DVMHANDLE *HandlePtr, const void *BufferPtr, unsigned int Count); |
To access to standard I/O streams in low level I/O functions the following pointers may be used:
DVMSTREAM0 | - | standard input stream; |
DVMSTREAM1 | - | standard output stream; |
DVMSTREAM2 | - | standard error stream; |
DVMSTREAM3 | - | standard com port; |
DVMSTREAM4 | - | standard printer port |
16.1.3 Operations with directories and files
ANSI:
int | dvm_remove | (const char *FileNamePtr); |
int | dvm_rename | (const char *OldNamePtr, const char NewNamePtr); |
char | *dvm_tmpnam | (char *FileNamePtr); |
BORLAND-C & MICROSOFT-C & PORTLAND GROUP-C:
int | dvm_access | (const char *FileNamePtr, int Mode); |
int | dvm_stat | (const char *FileName, struct stat *BufferPtr); |
int | dvm_unlink | (const char *FileNamePtr); |
Note. A user program can use low level I/O functions and the functions dvm_access and dvm_stat only in the case, if C compiler library contains corresponding functions. To use low level input/output functions Run-Time System and user program should be compiled with defined compilation variable _DVM_LLIO_. To link function dvm_access (dvm_stat) the compilation should be done with defined variable _ACCESS_FUN_ (_STRUCT_STAT_).
When working in WINDOWS+MPI+MICROSOFT_C (WINDOWS+MICROSOFT_C) environment to link all functions above Run-Time System and user ðrogram must be compiled with defined compilation variable _WIN_MPI_ (_DVM_MSC_).
16.2 Reading from file to sub-array of distributed array
long DisArrRead( | DVMFILE long long long long |
*StreamPtr, ArrayHeader[], InitIndexArray[], LastIndexArray[], StepArray[] ); |
*StreamPtr | - | the input file descriptor. | |
ArrayHeader | - | the header of the distributed array. | |
InitIndexArray | - | array, which i-th element is the initial value of the index variable of the (i+1)-th dimension of the distributed array. | |
LastIndexArray | - | array, which i-th element ] is the last value of the index variable of the (i+1)-th dimension of the distributed array. | |
- | array, which i-th element is the step value for the index variable of the (i+1)-th dimension of the distributed array. |
The function reads the sub-array of the distributed array. This sub-array is determined by the following set of the index corteges:
{I_{1} Î M_{1}
: I_{1 }=
InitIndexArray[0] +
StepArray[0] *P_{1 }} ´
. . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
{ I_{k} Î M_{k}:
I_{k} =
InitIndexArray[k-1] + StepArray[k-1]*P_{k }}
´
. . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . .
{ I_{n} Î M_{n}:
I_{n} =
InitIndexArray[n-1] + StepArray[n-1]*P_{n }}
,
where:
´ | - | symbol of Cartesian product; |
n | - | rank of the distributed array; |
I_{k} | - | index variable of the k-th dimension of the distributed array. |
0 £ P_{k }£ (LastIndexArray[k-1] - InitIndexArray[k-1] + 1) / StepArray[k-1].
The subarray to be read is a block (stretched, if at least one StepArray[i] is not equal to 1).
The reading is executed until the exhaustion of the source elements. The elements are copied in the order, according to the C language discipline of allocating of the elements in the memory, that is the right index is changed more faster then the left one. If the initial value of the index by some dimension of the tárget array is greater or equal to its last value, then the index of this dimension is not changed during copy operation. Note, that Run-Time System considers the last index value of any dimension as a minimum of the defined value in the function call and the real size of this dimension minus 1.
To use a full scope of the target array without requesting the size of the object by some dimension (see section 17.2), Run-Time System supposes that the value of the initial index value can be equal to -1. In that case, the initial index value is supposed to be equal to zero, the step be equal to 1, and the last index value be equal to the size of the dimension minus 1.
The function returns the number of the copied elements.
long dvm_dfread ( | long long DVMFILE |
ArrayHeader[], Count, *StreamPtr ); |
ArrayHeader | - | the header of the distributed array. | ||
Count | - | the number of the elements to read. | ||
*StreamPtr | - | the descriptor of the input file. |
The function dvm_dfread reads no more than Count of the first elements of the distributed array (in order of allocation this array in memory). If Count is greater then zero the number of the copied elements is supposed to be minimum of Count and the real number of the elements in the distributed array. If Count is a negative number then the function reads the distributed array entirely.
The function returns the number of the copied elements.
16.3 Writing sub-array of distributed array to file
long DisArrWrite( | DVMFILE long long long long |
*StreamPtr, ArrayHeader[], InitIndexArray[], LastIndexArray[], StepArray[] ); |
*StreamPtr | - | the descriptor of the output file. |
ArrayHeader | - | the header of the distributed array. |
InitIndexArray | - | array, which i-th element is the initial value of the index variable of the (i+1)-th dimension of the distributed array. |
LastIndexArray | - | array, which i-th element ] is the last value of the index variable of the (i+1)-th dimension of the distributed array. |
StepArray | - | array, which i-th element is the step value for the index variable of the (i+1)-th dimension of the distributed array. |
The functions writes the sub-array of the distributed array. This sub-array is determined by the following set of the index corteges:
{ I_{1} Î M_{1}:
I_{1 }=
InitIndexArray[0] +
StepArray[0] *P_{1 }} ´
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.
{ I_{k} Î M_{k}:
I_{k} =
InitIndexArray[k-1] + StepArray[k-1]*P_{k }}
´
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.
{ I_{n} Î M_{n}:
I_{n} =
InitIndexArray[n-1] + StepArray[n-1]*P_{n }}
,
where:
x | - | symbol of Cartesian product; |
n | - | rank of the distributed array; |
I_{k} | - | index variable of the k-th dimension of the distributed array. |
0 £ P_{k }£ (LastIndexArray[k-1] - InitIndexArray[k-1] + 1) / StepArray[k-1].
The subarray to be coped is a block (stretched, if at least one StepArray[i] is not equal to 1).
The writing is executed until the exhaustion of the source elements. The elements are copied in the order, according to the C language discipline of allocating of the elements in the memory, that is the right index is changed more faster then the left one. If the initial value of the index by some dimension of the source array is greater or equal to its last value, then the index of this dimension is not changed during copy operation. Note, that Run-Time System considers the last index value of any dimension as a minimum of the defined value in the function call and the real size of this dimension minus 1.
To use a full scope of the source array without requesting of the size of the object by some dimension (see section 17.2), Run-Time System supposes that the value of the initial index value can be equal to -1. In that case, the initial index value is supposed to be equal to zero, the step is equal to 1, and the last index value is equal to the size of the dimension minus 1.
The function returns the number of the copied elements.
long dvm_dfwrite( | long long DVMFILE |
ArrayHeader[], Count, *StreamPtr ); |
ArrayHeader | - | the header of the distributed array. | ||
Count | - | the number of the elements to be copied. | ||
*StreamPtr | - | the descriptor of the output file. |
The function dvm_dfwrite writes no more than Count of the first elements of the distributed array (in order of allocation this array in memory). If Count is greater then zero the number of the copied elements is supposed to be minimum of Count and the real number of the elements in the distributed array. If Count is a negative number then the function writes the distributed array entirely.
The function returns the number of the copied elements.
Note 1. Distributed array, specified in dvm_dfread, DisArrRead, dvm_dfwrite and DisArrWrite function call must be mapped on the processor system, all elements of which must belong to the current processor system.
Note 2. The first Count elements in order of the memory allocation are not a block in common case and can be described in the following way. Let decomposition of the number Count by the dimension weights of the distributed array is
where:
n | - | rank of the distributed array; |
K_{i} | - | decomposition coefficient of i-th dimension (0 £ K_{i} £ Size_{i} -1 , Size_{i} - size of i-th dimension); |
W_{i} | - | weight of i-th dimension. |
Then first Count elements may be represented as the following union of blocks:
Therefore reading (writing) the first Count elements of the distributed array by the function dvm_dfread (dvm_dfwrite) is equivalent to sequential reading (writing) existing blocks B_{1}, ... , B_{n} using the function DisArrRead (DisArrWrite) (the block B_{m} exists, if K_{m} is not equal to zero).
17.1 Requesting size of object
long getrnk_(ObjectRef *ObjectRefPtr);
The function getrnk_ returns the rank of the object, defined by the reference *ObjectRefPtr.
The following entities can be used as objects:
If the reference *ObjectRefPtr is not a reference to any of the mentioned above objects, then the function returns zero.
For the map (of array or abstract machine representation) the rank of the object, that is the source for the map, is returned.
17.2 Requesting size of object dimension
long getsiz_( | ObjectRef long |
*ObjectRefPtr, *AxisPtr ); |
The function returns the size of the dimension *AxisPtr of the object, defined by the reference *ObjectRefPtr.
The following entities can be used as objects:
The size of the distributed array dimension is equal to
ceil( (LastIndex - InitIndex + 1) / Step ) ,
where:
InitIndex | initial value of the index variable of the parallel loop for the dimension *AxisPtr; |
LastIndex | last value of the index variable of the parallel loop for the dimension *AxisPtr; |
Step | step of the index variable of the parallel loop for the dimension *AxisPtr; |
ceil | a function to get the least integer, not less than value of its argument. |
If *AxisPtr = 0, the size of the object (product of sizes of all dimensions) is returned.
If the reference *ObjectRefPtr is not a reference to any of the mentioned above objects, then the function returns zero.
long locsiz_( | ObjectRef long |
*ObjectRefPtr, *AxisPtr ); |
The function locsiz_ is similar to the function getsiz_, but it returns the local size of dimension *AxisPtr (or the local size of the object), i.e. the size of the object part, mapped on the current processor. If the object is a processor system, then the values, returned by the functions getsiz_ and locsiz_ are the same.
Note, that a local size of the object, having no a local part on the current processor, is equal to zero.
17.3 Requesting if object is distributed array
long tstda_ (ObjectRef *ObjectRefPtr);
The function tstda_ allowes to determine whether the object, specified by the reference *ObjectRefPtr, is a distributed array.
The following values are returned:
0 - the object is not a
distributed array;
1 - the object is a distributed
array;
2 - the object is a fully
replicated distributed array.
17.4 Requesting size of distributed array element
long getlen_ (long ArrayHeader[]);
ArrayHeader - header of the distributed array.
The function getlen_ returns the size in bytes of element of specified distributed array in bytes.
long delobj_(ObjectRef *ObjectRefPtr);
*ObjectRefPtr - reference to the deleted object.
It is possible to use the followings as an object:
The object can be deleted by delobj_ function only if it was created in the current subtask and in the current program block (or its sub-block) (see sections 8 and 10).
The function returns zero.
17.6 Requesting whether current processor is I/O processor
long tstio_(void);
The function returns 1 if the current processor is the I/O processor and returns zero in another case.
17.7 Sending memory areas of I/O processor
long srmem_( | long AddrType long |
*MemoryCountPtr, StartAddrArray[], LengthArray[] ); |
*MemoryCountPtr | - | the number of the sent areas of the memory. | ||
StartAddrArray | - | array, which i-th element is the start address of (i+1)-th area (adjusted to AddrType type). | ||
LengthArray | - | array, which i-th element is the size of the (i+1)-th area (in bytes). |
The function srmem_ sends the memory areas of the I/O processor to another processors. During this operation the I/O processor sends the data, and the other processors receive the data. The number of the parameters in the arrays LenghtArray and StartAddrArray has to be equal to *MemoryCountPtr. The length of the each sent area has not to exceed the maximum of the positive integer (LengthArray[i] (unsigned int)-1 >> 1).
The function returns zero.
To transform an address acceptable for the function srmem_, Run-Time System has the function
AddrType dvmadr_(void *VarPtr);
This function is intended for usage in Fortran.
The following functions can be also used for Fortran variables of different types:
AddrType | getash_ | (void *VarPtr); |
AddrType | getai_ | (void *VarPtr); |
AddrType | getal_ | (void *VarPtr); |
AddrType | getaf_ | (void *VarPtr); |
AddrType | getad_ | (void *VarPtr); |
AddrType | getac_ | (void *VarPtr); |
AddrType | getach_ | (void *VarPtr, long StrLength); |
These functions are similar to the function dvmadr_ (parameter VarPtr is the address of text string, and StrLength is its size, formed by Fortran compiler).
The functions srmem_ and dvmadr_ (getash_, getai_, getal_, getaf_, getad_, getac_, getach_) can be used for implementation of input/output operations.
18 Using Run-Time System in Fortran language
To coordinate allocation of the arrays in the memory, (along the columns in the Fortran , and along the rows in the C) inverse order of specifying the array indexes (in comparison with the order in the C ) is required. In addition, in this document it is supposed that the initial array index value is equal to zero, that is conformed to the C language. In the Fortran language this index is equal to 1.
Data types (except C base types, DVMFILE* and DVMHANDLE*) used in Run-Time System functions are defined as "unsigned long". They can be used only in assignment operators and as actual parameters in function and subroutine calls.
Each C base type, used in Run-Time System function calls, must have equivalent representation as some construction of Fortran language. Checking correctness of C base data type in Fortran is implemented by the representation size using the function
void tpcntr_( | long AddrType AddrType long long |
*ElmNumberPtr, FirstAddrArray[], NextAddrArray[], TypeLengthArray[], TypeCodeArray[] ); |
*ElmNumberPtr | - | a number of elements, specified in FirstAddrArray, NextAddrArray, TypeLengthArray and TypeCodeArray arrays. | ||
FirstAddrArray, NextAddrArray | - |
arrays, which i-th elements contain addresses of two adjacent elements of the type with TypeCodeArray[i] number (in Fortran representation). | ||
TypeLengthArray | - | array, which i-th element contains supposed size of the type with TypeCodeArray[i] number. | ||
TypeCodeArray | - | array, which contains numbers (codes) of C data types to be checked. |
The function tpcntr_ assumes the following numeration of C types:
If while executing tpcntr_ function it will be detected, that the length of data of the type with TypeCodeArray[i] number is not equal to the difference (NextAddrArray[i] – FirstAddrArray[i]) or TypeLengthArray[i] value, the user program is terminated with diagnostics, which contains:
The tpcntr_ function call must precede Run-Time System initialization from Fortran program by linit_ function (see section 2).
Example.
integer
getac,
getash, getai, getal, getaf, getad, linit
integer
dvm
integer
faddr(8), naddr(8), tlen(8), tcode(8)
integer
tint(2)
logical
tlog(2)
character*1
tchar (2)
real
tfloat
(2)
double precision tdouble (2)
integer*2
tint2
(2)
integer*4
tint4 (2)
integer*8
tint8
(2)
C Initialization of arrays with addresses of adjacent elements of the same type
faddr(1) = getai (tint(1))
naddr(1) = getai (tint(2))
faddr(2) = getal (tlog(1))
naddr(2) = getal (tlog(2))
faddr(3) = getaf (tfloat(1))
naddr(3) = getaf (tfloat(2))
faddr(4) = getad (tdouble(1))
naddr(4) = getad (tdouble(2))
faddr(5) = getach (tchar(1))
naddr(5) = getach (tchar(2))
faddr(6) = getash (tint2(1))
naddr(6) = getash (tint2(2))
faddr(7) = getai (tint4(1))
naddr(7) = getai (tint4(2))
faddr(8) = getai (tint8(1))
naddr(8) = getai (tint8(2))
C Initialization of array with supposed sizes of checked types
tlen(1) = 4
tlen(2) = 4
tlen(3) = 4
tlen(4) = 8
tlen(5) = 1
tlen(6) = 2
tlen(7) = 4
tlen(8) = 8
C Initialization of arrays with numbers of checked types
tcode(1) = 1
tcode(2) = 1
tcode(3) = 3
tcode(4) = 4
tcode(5) = 5
tcode(6) = 6
tcode(7) = 1
tcode(8) = 2
C Checking data types
call tpcntr (8, faddr, naddr, tlen, tcode)
C Run-Time System initialization
dvm = linit (0)