The SIDL specification for the CDriver component can
be found in the file
. The
implementation of this component (in the C programming language) can be
found at
$STUDENT_SRC/components/sidl/arraydrivers.sidl in the
two files $STUDENT_SRC/components/arrayDrivers/c/arrayDrivers_CDriver_Impl.c and
arrayDrivers_CDriver_Impl.h. Component implementation
details include details of component/framework interaction that should be
now familiar, and will not be discussed further in this exercise. We will
focus on the handling of different types of SIDL arrays in the
go method.
Raw arrays (and vectors) are used as arguments in the call to
mulMatVec. Note that multidimensional SIDL
raw arrays are always assumed to use column-major
storage. This requirement necessitates special treatment when calling
methods that use SIDL raw arrays as arguments from languages that
follow a default raw-major array storage order (C and C++). The caller
may choose to alter the memory layout of the array argument throughout
its entire lifetime, or alternatively perform a matrix transpose
operation on “native” arrays before and after every call
to a SIDL method that uses raw arrays. In the example presented here,
we have chosen to adopt column-major storage throughout the lifetime
of the raw array argument A, as shown in the
initialization code shown below
/* _ _ _ _ _ _
* | 1.0 4.0 | | 1.0 | | 3.0 |
* A = | 2.0 5.0 | v1 = | 2.0 | sda1 = | 4.0 |
* | 3.0 6.0 | - - | 5.0 |
* - - - -
*
* Note that A needs to be stored in column-major order to make
* the call using SIDL raw arrays
*/
value = 0.0;
for (i = 0; i <= m; i++){
for (j = 0; j <= n; j++){
A[i*n+j] = (value += 1.0);
}
}
When making a call to a SIDL method that has SIDL raw arrays
arguments, the dimensions of those arrays must be explicitly included
in the argument list in the SIDL specification. No special
“wrapping” of native arrays is needed to make a call
using SIDL raw arrays arguments. This can be seen in the call to the
mulMatVec method.
retval = arrayop_LinearOp_mulMatVec(linopPort, alpha, A, v1, y, m , n, &throwaway_excpt);
if (retval != 0){
fprintf(stderr, "Error:: %s:%d: Error in call to mulMatVec() \n",
__FILE__, __LINE__);
return(-1);
}
The requirement to use column-major memory layout is one of the restrictions imposed by Babel to allow for the use of raw arrays. See the Babel User Guide for the complete list.
SIDL “normal” arrays are implemented in the Babel runtime, with bindings in all Babel supported languages. SIDL normal arrays provided a more flexible array representation, with the ability to directly access the underlying array memory in languages that support this capability (C, C++, F90, and F77). In Python, there are situations where arrays must be copied when passing in and out, but direct access is used wherever the Numerical Python package will allow. In Java, arrays are accessed using the Java Native Interface. More information on SIDL normal arrays can be found in the Babel User Guide.
In this exercise, the method addVec uses SIDL
normal arrays (sda1, and
sda2). The SIDL specification of the
addVec method designates sda1 as
an input argument, therefore it needs to be created (more
specifically, associated with memory) on the caller side before the
call is made. The Babel runtime provides array manipulation bindings
in Babel supported languages (except Python, which uses
Numeric Python arrays). The one-dimensional, SIDL
double array sda1 is created
using the following code
sda1 = sidl_double__array_create1d(m);
if (!sda1){
fprintf(stderr, "Error:: %s:%d: Error creating sda1.\n",
__FILE__, __LINE__);
return(-1);
}
The Babel runtime C binding contains macros that allow direct access
to underlying SIDL array memory and properties (dimensions, strides,
etc.), without having to go through the standard
set() and get() methods. One
such macro is used in this example to access the underlying memory of
SIDL array sda1
sda1_data = sidlArrayAddr1(sda1, 0);
for (value =0.0, i = 0; i <= m; i++){
sda1_data[i] = (double) i + 3.0 ;
}
Other macros are used in the loop that prints the result returned in the
SIDL out array sda2, after the call
to addVec.
printf("Result2 = ");
for ( i = sidlLower(sda2, 0); i <= sidlUpper(sda2, 0); i++){
printf("%.2f ", sidlArrayElem1(sda2,i));
}
printf("\n");
Direct access to underlying SIDL array memory is also available in the Babel SIDL array binding in F77, F90, and C++. Example of such use is available in the discussion in Section 7.3, “Linear Array Operations Components”.