Arrays

As discussed in Section 5.4, SIDL supports both normal and raw arrays (i.e., r-arrays). Normal SIDL arrays can be used by any supported language; whereas, r-arrays are restricted to numeric types and use in languages such as C, C++, and Fortran. This subsection starts with a discussion normal and generic arrays before proceeding with an example of the interfaces for r-arrays.

The normal SIDL array API is available in a module for creating, destroying, and accessing array elements and meta-data for normal arrays. More information on the API can be found in Subsection 5.4. For sidl.SIDLException, the array module -- called sidl_SIDLException_array -- is defined in sidl_SIDLException_array.F90. The derived type for a SIDL array is named after the class, interface, or basic type that it holds and the dimension of the array. For sidl.SIDLException, the array derived types are named sidl_SIDLException_1d, sidl_SIDLException_2d, sidl_SIDLException_3d, $\ldots$ up to sidl_SIDLException_7d. For basic types, they are treated as sidl.dcomplex, sidl.double, sidl.fcomplex, etc. Each of these derived types has a 64-bit integer to hold an opaque pointer.

NOTE$:$ Normal Fortran 90 arrays or normal SIDL arrays can be used when calling a Fortran 90 method, but they cannot be mixed.

Derived types for SIDL types dcomplex, double, fcomplex, float, int, and long have pointers to arrays of the appropriate type and dimension that facilitate direct access to array elements. For example, the derived type for 2d and 3d arrays of doubles is$:$


  use sidl
  type sidl_double_2d
    sequence
    integer (kind=sidl_arrayptr) :: d_array
    real (kind=sidl_double), pointer, &
      dimension(:,:) :: d_data
  end type sidl_double_2d

  type sidl_double_3d
    sequence
    integer (kind=sidl_arrayptr) :: d_array
    real (kind=sidl_double), pointer, &
      dimension(:,:,:) :: d_data
  end type sidl_double_3d

For the other types, the array API must be used to access elements. In this case, the array can be accessed with the F90 array pointer d_data just like any other F90 array. However, the F90 built-in methods allocate or deallocate on d_data must not be used. Instead, SIDL functions, createCol, createRow, create1d, create2dRow, or create2dCol, must be used to create a new array. These SIDL routines initialize d_data to refer to the data allocated in d_array.

NOTE$:$ create1d, create2dRow, and create2dCol create arrays whose lower index is 0 not 1. To create arrays with a lower index of 1, createCol or createRow must be used.

Software packages like LINPACK or BLAS can be called, but the stride should be checked to make sure the array is suitably packed. Using stride(i) will provide the distance between elements in dimension i. A value of 1 means elements are packed densely. Negative stride values are possible and, when an array is sliced, the resulting array might not even have one densely packed dimension.

As discussed in Section 5.4, the type of a generic array is not specified. As a result, Fortran 90 represents generic arrays as the derived type sidl__array as defined in the sidl_array_type module. (Note the use of a two underscore separator.) The following subroutines, defined in the sidl_array_array module, apply to generic arrays$:$ addRef, deleteRef, dimen, type, isColumnOrder, isRowOrder, is_null, no_null, set_null, lower, upper, length, stride, and smartCopy.

Finally, SIDL r-arrays are passed to and from methods as normal Fortran 90 arrays. Index variables do not need to be included because the values are determined from the Fortran 90 array extents in each dimension. For example, the client-side interface for solve -- introduced in Section 5.4 -- behaves as if it is a Fortran 90 function with the following overloaded interface$:$


  private :: solve_1s, solve_2s
  interface solve
    module procedure solve_1s, solve_2s
  end interface

  recursive subroutine solve_1s(self, A, x, exception)
    implicit none
    ! in num.Linsol self
    type(num_Linsol_t) , intent(in) :: self
    ! in array<double,2,column-major> A
    type(sidl_double_2d) , intent(in) :: A
    ! inout array<double,column-major> x
    type(sidl_double_1d) , intent(inout) :: x
    ! out sidl.BaseInterface exception
    type(sidl_BaseInterface_t) , intent(out) :: exception
  end subroutine solve_1s

  recursive subroutine solve_2s(self, A, x, exception)
    implicit none
    ! in num.Linsol self
    type(num_Linsol_t) , intent(in) :: self
    ! in rarray<double,2> A(m,n)
    real (kind=sidl_double) , intent(in), dimension(:, :) :: A
    ! inout rarray<double> x(n)
    real (kind=sidl_double) , intent(inout), dimension(:) :: x
    ! out sidl.BaseInterface exception
    type(sidl_BaseInterface_t) , intent(out) :: exception
    ! in int m
    integer (kind=sidl_int) :: m
    ! in int n
    integer (kind=sidl_int) :: n
  end subroutine solve_2s

The server-side interface, shown below, is similar.


recursive subroutine num_Linsol_solve_mi(self, A, x, m, n, exception)
  use sidl
  use sidl_BaseInterface
  use sidl_RuntimeException
  use num_Linsol
  use sidl_double_array
  use num_Linsol_impl
  ! DO-NOT-DELETE splicer.begin(num.Linsol.solve.use)
  ! Insert-Code-Here {num.Linsol.solve.use} (use statements)
  ! DO-NOT-DELETE splicer.end(num.Linsol.solve.use)
  implicit none
  type(num_Linsol_t) :: self ! in
  integer (kind=sidl_int) :: m ! in
  integer (kind=sidl_int) :: n ! in
  type(sidl_BaseInterface_t) :: exception ! out
  real (kind=sidl_double), dimension(0:m-1, 0:n-1) :: A ! in
  real (kind=sidl_double), dimension(0:n-1) :: x ! inout

! DO-NOT-DELETE splicer.begin(num.Linsol.solve)
! Insert-Code-Here {num.Linsol.solve} (solve method)
! DO-NOT-DELETE splicer.end(num.Linsol.solve)
end subroutine num_Linsol_solve_mi

NOTE$:$ The lower index of each dimension of every incoming array is always zero.



babel-1.4.0
users_guide Last Modified 2008-10-16

http://www.llnl.gov/CASC/components
components@llnl.gov