You are not logged in. Click here to log in.

Application Lifecycle Management

Search In Project

Search inClear

Tags:  not added yet

OMS Arrays

This document introduces the syntax and semantics of Arrays in OMS and provides use examples.

General

An OMS array represents a wrapper object for java native arrays. Any array consists of two major components
  1. The typed array interface which allows access by array indexes using in a certain layout. Using indexes array elements can be accessed.
  2. The array store represents the data store for the content in a layout independent manner. The store implementation may depend on the intended use of the array. If the array should be mapped to native code, the store implementation is actually a java.nio.ByteBuffer.
  • OMS Arrays are always Attribute objects, no primitive array types are used such as double[], or float[],.. .
  • There is a generic OMS Array class for each basic data type
  • An array object has a fixed shape which is specified at compile time and cannot be changed at runtime.
  • The length of the array dimensions can be set to be static or dynamic. If the array is static, a length is specified at compile time; the array dimension length is set to this size at runtime and cannot be changed.
    If a dimension is dynamic, its length is set to 0 at runtime. It needs to be allocated.
  • Specification of array dimension happens using the @oms.dim meta data annotation only.
  • A component will never instantiate the Array object, however it may allocate the array content according to its shape if the array is dynamic.

Array type Mapping:

Java array base type OMS type
float (4byte) Attribute.FloatArray
double (8byte) Attribute.DoubleArray
boolean (1byte) Attribute.BooleanArray
int (4byte) Attribute.IntegerArray

Examples

Declaring a dynamic 1D float array

This declares a one dimensional array of doubles, which lengths is not set. The dimension is named d
/** Array example
 * @oms.dim d
 */
Attribute.FloatArray  arr;
Note: if the @oms.dim info is missing the array will be a 1D array per default.

Declaring a dynamic 2D double array

This declares a two dimensional array of doubles, which lengths is not set. The dimension is named x and y
/** Array example
 * @oms.dim x,y
 */
Attribute.DoubleArray  arr;
Note: Different dimensions are specified only in the meta data sections, All using the same array class.

Declaring a static 1D float array

This declares a two dimensional array of doubles, which length is set to 10. The dimension is named x.
/** Array example
 * @oms.dim x:10
 */
Attribute.FloatArray  arr;
Note: Such an array usually maps to a FORTRAN array, which is statically allocated. Therefore any change in the length would cause an improper access to memory at the FORTRAN level.

Getting the rank of an array.

This declares a two dimensional dynamic array of floats. The number of dimensions is two, the lengths of the dimensions are both zero since it is not allocated yet. The rank of that array is two.
/** Array example
 * @oms.dim x,y
 */
Attribute.FloatArray  arr;
...
int rank = arr.getRank();  // 2

Getting the actual dimension lengths.

This declares a two dimensional dynamic array of floats. The number of dimensions is two, the lengths of the dimensions are both zero since it is not allocated yet.
/** Array example
 * @oms.dim x,y
 */
Attribute.FloatArray  arr;
...
int[] dims = arr.getDims();
System.out.println(dims.length);   // ouput: 2
System.out.println(dims[0]);   // ouput: 0
System.out.println(dims[1]);   // output: 0

The second example shows the same code for a static array:

/** Array example
 * @oms.dim x:2,y:3
 */
Attribute.FloatArray  arr;
...
int[] dims = arr.getDims();
System.out.println(dims.length);   // ouput: 2
System.out.println(dims[0]);   // ouput: 2
System.out.println(dims[1]);   // output: 3

Allocating a dynamic array

/** Array example
 * @oms.dim x,y
 */
Attribute.FloatArray  arr;
...
int[] dims = arr.getDims();
System.out.println(dims.length);   // ouput: 2
System.out.println(dims[0]);   // ouput: 0
System.out.println(dims[1]);   // output: 0

arr.allocate(new int[] {5,6});
System.out.println(dims.length);   // ouput: 2
System.out.println(dims[0]);   // ouput: 5
System.out.println(dims[1]);   // output: 6

Note: If the number of dimensions used in the allocate() call is different from the one specified in the @oms.dim section, an IllegalArgumentException is thrown. If the array is static, the allocate() call throws an IllegalAccessException

Accessing Array Elements

/** Array example
 * @oms.dim x:2, y:3
 */
Attribute.FloatArray  arr;
...
int[] dims = arr.getDims();
assert dims.length==1 : "Invalid dimensions for arr";
for(int i = 0; i<dims[0]; i++) {
  for(int j = 0; j<dims[1]; j++) {
    // printing out the existing Value
    System.out.println(Element "+i+","+j+ arr.getValue(i,j);
    // setting the value
    arr.setValue(i,j, 10 + i+ j);
  }
}
  

Accessing the Array Store

The following code accesses an array's store and computes the mean of all elements. Note that this code works for all array access code which not depends on a certain array layout.
/** Array example
 * @oms.dim x:2, y:3
 */
Attribute.FloatArray  arr;
...
Array.Store store = arr.getStore();    

System.out.println(store.size())  // 6
float sum = 0;
for(int i = 0; i<store.size(); i++) {
  sum += store.getDouble(i);
}
System.out.println("Mean: " + sum/store.size());
  

Notes:

  • There is clear distinction between the dimension rank (or shape) and the dimension lengths. As someone might notice there is no way in the OMS API that you can change the shape of an array programmatically. What should be the use case? There is none. Code is always written against a certain array shape.
  • OMS Arrays are not dynamic regarding their layout, they are mutable to the length of their dimension only. In other words: You cannot change a one dimensional array into a two dimensional array, but you can change the length of any array dimension; that's what dynamic means.
  • Static arrays as proposed are not allowing for any change at all, even dimension lengths are fixed! Reason: They are mapped to static allocated FORTRAN array.

Array API


/** Array Attribute.
 *
 * @author  Ian Schneider
 * @author  Olaf David
 */
public interface Array extends Attribute {
    
    /** Get the store which is implementing the array.
     * @return a non-null ArrayStore
     */
    Store getStore();
    
    /** Get the dimensions of this array. Short cut for calling getShape
     * and extracting the length of each Dimension.
     * @return a non-null array of integers describing the dimensions of this
     *         array.
     */
    int[] getDims();
    
    /** Get the rank of an array. This call is more efficient than <code>getDims().length</code>
     *  even it does provide the same answer.
     * @return the rank of this array
     */
    int getRank();
    
    /** Get the dimensions of this array.
     * @return a non-null array of Dimensions describing the dimensions of this
     *         array.
     */
    Dimension[] getShape();
    
    /** (Re)Allocate the ArrayStore physical resources.
     * @param dims the dimensions to allocate the array with.
     * @throws IllegalArgumentException if the dimensionality does not match
     *         that of this Arrays type.
     */
    void allocate(int[] dims);
    
    /** Allow the array to decode a multi-dimensional index to an absolute index.
     * @param an array specifying the index to decode
     * @return the absolute index derived from the multi-dimensional.
     * @throws IllegalArgumentException if the dimensionality does not match
     *         that of this Arrays type.
     */
    int getLocation(int[] index);
    
    
    /** Array Dimension
     */
    interface Dimension {

        /** Length of the array */
        int getLength();
        
        /** Get the dimension name
         */
        java.lang.String getName();
    }
        
    /** Array Store.
     *
     *  An Array store represents the backend storage for any array.
     */
    interface Store {
        
        /** Get the size of the array store
         */
        int size();
        
        /** Get the back end. This should be a ByteBuffer object.
         */
        public Object getBackend();
        
        int getInteger(int i);
        double getDouble(int i);
        float getFloat(int i);
        short getShort(int i);
        boolean getBoolean(int i);
        java.lang.String getString(int i);
        
        void set(int i, int value);
        void set(int i, double value);
        void set(int i, float value);
        void set(int i, short value);
        void set(int i, boolean value);
        void set(int i, java.lang.String value);
    }    
}


    /** Double Array Attribute
     */
    public interface DoubleArray extends Array {
        javax.units.Unit getUnit();
        
        double getValue(int index1);
        double getValue(int index1, int index2);
        double getValue(int index[]);
        
        void   setValue(int index1, double value);
        void   setValue(int index1, int index2, double value);
        void   setValue(int index[], double value);
    }
    
    /** Float array attribute
     */
    public interface FloatArray extends Array {
        
        /** Get the unit of the float
         */
        javax.units.Unit getUnit();
        
        /** Get the value at a certain index.
         */
        float getValue(int index[]);
        float getValue(int i);
        float getValue(int i, int j);
        
        /** Set the value at a certain index
         */
        void setValue(int index[], float value);
        void setValue(int i, float value);
        void setValue(int i, int j,float value);
    }
    
    /** Integer array Attribute
     */
    public interface IntegerArray extends Array {
        
        /** Get the value at a certain index
         */
        int getValue(int index[]);
        int getValue(int i);
        int getValue(int i, int j);
        
        /** Set the value at a certain index
         */
        void setValue(int index[], int value);
        void setValue(int i, int value);
        void setValue(int i, int j,int value);
    }
    
    /** Boolean Array Attribute.
     */
    public interface BooleanArray extends Array {
        
        /** Get the value at a certain index
         */
        boolean getValue(int index[]);
        boolean getValue(int i);
        boolean getValue(int i, int j);
        
        /** Set the value at a certain index
         */
        void setValue(int i, boolean value);
        void setValue(int i, int j,boolean value);
        void setValue(int index[], boolean value);
    }