The process of mapping one of an NDF's array components for access may be performed using the routine NDF_MAP. For instance:
INTEGER PNTR( 1 ), EL
...
CALL NDF_MAP( INDF, 'Data', '_REAL', 'READ', PNTR, EL, STATUS )
will map an NDF's data component as an array of `_REAL' (i.e. single-precision) values so that the calling routine can `READ' them. NDF_MAP returns an integer pointer to the mapped values via its PNTR argument and a count of the number of array elements which were mapped via its EL argument. (PNTR is actually a 1-dimensional integer array, so the pointer value in this example will be returned in its first element.)
An application can access the mapped values as if they were a Fortran array of real numbers by passing the pointer to a subroutine. On computers which support it, this should be done using the %VAL facility (see below). Afterwards, access is relinquished by unmapping the NDF component using the routine NDF_UNMAP. The following illustrates the process:
INTEGER PNTR( 1 ), EL
REAL SUM
...
CALL NDF_MAP( INDF, 'Data', '_REAL', 'READ', PNTR, EL, STATUS )
CALL SUMIT( EL, %VAL( PNTR( 1 ) ), SUM )
CALL NDF_UNMAP( INDF, 'Data', STATUS )
...
END
SUBROUTINE SUMIT( EL, ARRAY, SUM )
INTEGER EL, I
REAL ARRAY( EL ), SUM
SUM = 0.0
DO 1 I = 1, EL
SUM = SUM + ARRAY( I )
1 CONTINUE
END
Here, the call to NDF_MAP maps the NDF's data component and returns a
pointer to the mapped values.
This pointer is passed to the subroutine SUMIT using %VAL, where it
appears as a normal Fortran real array with EL elements.
SUMIT can then access the mapped values, in this case summing them, before
it returns.
Finally NDF_UNMAP is called to unmap the data component, thereby
releasing the resources that were used.
In the above example, the array was treated as if it were 1-dimensional, since its actual dimensionality was not important. This is sometimes the case, but if the shape of the array is significant, then a call to a routine such as NDF_DIM would be used to obtain the necessary dimension size information, which would then be passed to the subroutine which accesses the mapped values, for instance:
INTEGER PNTR( 1 ), EL, DIM( 2 ), NDIM
REAL SUM
...
CALL NDF_MAP( INDF, 'Data', '_REAL', 'READ', PNTR, EL, STATUS )
CALL NDF_DIM( INDF, 2, DIM, NDIM, STATUS )
CALL SUMIT( DIM( 1 ), DIM( 2 ), %VAL( PNTR( 1 ) ), SUM )
CALL NDF_UNMAP( INDF, 'Data', STATUS )
...
END
In this case, the routine SUMIT would declare the array to have the appropriate shape, and access it accordingly, as follows:
SUBROUTINE SUMIT( NX, NY, ARRAY, SUM )
INTEGER NX, NY, I
REAL ARRAY( NX, NY ), SUM
SUM = 0.0
DO 2 J = 1, NY
DO 1 I = 1, NX
SUM = SUM + ARRAY( I, J )
1 CONTINUE
2 CONTINUE
END
The routine NDF_MAP will also accept a list of component names and will map all of them in the same way (i.e. with the same type and mapping mode). Pointers to each mapped array will be returned via the PNTR argument, which must have sufficient elements to accommodate the returned values. The following shows how both the data and variance components of an NDF might be mapped for access, passed to a subroutine DOIT for processing, and then unmapped:
INTEGER PNTR( 2 ), EL
...
CALL NDF_MAP( INDF, 'Data,Variance', '_REAL', 'READ', PNTR, EL, STATUS )
CALL DOIT( EL, %VAL( PNTR( 1 ) ), %VAL( PNTR( 2 ) ), STATUS )
CALL NDF_UNMAP( INDF, 'Data,Variance', STATUS )
...
Note how NDF_UNMAP is also provided with a list of components to unmap. An alternative would be to specify a component name of `*', which would cause NDF_UNMAP to unmap all components which had previously been mapped using the specified NDF identifier.