Array Data Pointers

Release 4 and later of SmartArrays provides a means for .NET and C++ programmers to access the data in an SmArray object  This facility is not available in SmartArrays for Java because the Java language has no pointer facility. 

Using Array Data Pointers in .NET

In SmartArrays for .NET, the address of the data in an SmArray object is exposed by four attributes of the SmArray object.

C# Attribute Use
DataPtrByte An unsafe byte pointer to the array data
DataPtrChar An unsafe char pointer to the array data
DataPtrInt An unsafe int pointer to the array data
DataPtrDouble An unsafe double pointer to the array data

These provide access to the insides of arrays of appropriate types. Each ensures that the array is of the appropriate type. For example, DataPtrInt only works on arrays of type dtInt, for any other type of array it returns zero. Boolean arrays can be accessed one byte at a time via DataPtrByte; bits in a dtBoolean array are stored from high-order bit to low-order bit. Complex number arrays are stored internally as successive pairs of doubles, so DataPtrDouble can be used. No way is provided to access dtString, dtNested, or dtMixed data, as these arrays contain values that can be understood only inside the SmartArrays engine.

Used with appropriate care, these pointers allow data values in an array to be read or written at full speed, without incurring the overhead associated with SmArray method calls.  They can let you achieve major performance improvements in situations where scalar-oriented custom logic needs to be applied to data in SmArray objects.

Working with SmArray data pointers does not require the C# fixed statement facility (which temporarily pins managed objects to their location in memory) because SmartArrays data is outside the scope of .NET memory management. As currently implemented, SmartArrays keeps its data blocks at a stable location for the lifespan of the array. The .NET instances of class SmArray do not need to be pinned because they hold only the handle that identifies an array to the engine.

To Use Array Data Pointers in Your .NET Project

The C# compiler must be called with the /unsafe switch to enable the use of unsafe code.  In Visual Studio, you can set this in the Configuration Properties for the project by setting Allow Unsafe Code Blocks to true.

Examples

C# Example:

// Work with the contents of an SmArray as a unsafe int[] array.

// For example: replace each value in an array with its square

SmArray v = SmArray.sequence( 1000 );

unsafe {

    int* vdata = v.DataPtrInt;

    // now vdata can be used like an int[]

    int vcount = v.getCount();

    for ( int i=0; i<vcount; i++ )

        vdata[i] *= vdata[i];

}

v.show();

0 1 4 9 16 25 36 ...

 


Using Array Data Pointers in C++

In SmartArrays for C++, the data is exposed a public method of class SmArray 

C++ Method Use
void* getDataPtr() A pointer to the array data
int* getDataPtrInt() A pointer to the array data in an integer type array
char* getDataPtrChar() A pointer to the array data in a dtByte type array
wchar* getDataPtrWChar() A pointer to the double byte array data in a dtChar type array
double* getDataPtrDouble() A pointer to the array data in a dtDouble type array

 

These methods return a pointer to the array's data values. getDataPtr() returns a void*, which you can cast to the appropriate type based on array's internal data type. The type-specific methods are preferable because they enforce the array type. For example, getDataPtrInt() will throw an SA_CANNOT_CONVERT exception if the array is not integer type.   The usage and guidelines are the same as those described above for .NET

Examples

C++ Example:

// Work with the contents of an SmArray as an int[] array.

// For example: replace each value in an array with its square

SmArray v = SmArray::sequence( 1000 );

int* vdata = v.getDataPtrInt();

// now vdata can be used like an int[]

int vcount = v.getCount();

for ( int i=0; i<vcount; i++ )

    vdata[i] *= vdata[i];

v.show();

0 1 4 9 16 25 36 ...