DDT (Derived Data Types) provides a simple way to create user defined datatypes.
With standard datatypes such as int, double, char one can use a contiguous
memory space. Often it is desirable to use data that is not homogeneous such
as structure or that is not contiguous in memory such as some selection in
array. This library allows The user to define derived datatypes, that specify
more general data layouts. These derived datatypes can then be used in a
similar way as basic datatypes.
Some examples where user might want to use derived datatypes are: using only
upper tringle of a matrix, using only elements in alternate rows and columns
in a 2D array.
It might be cumbersome to program it in user code every time it is needed.
DDT library provides a simple and convinient way to create such datatypes, find out their lengths and extents.
Currently supported datatypes are
Contiguous - Contiguous datatype constructs a typemap consisting of the
replication of a datatype into contiguous locations.
Vector - Vector datatype allows replication of a datatype into locations
that consist of equally spaced blocks.
HVector - Similar to Vector except that it allows a stride which consists
of an arbitrary number of bytes as opposed to stride being multiple of block
size in Vector.
Indexed - The Indexed datatype allows one to specify a noncontiguous data
layout where displacements between successive blocks need not be equal.
HIndexed - Similar to Indexed except that displacement can be arbitrary
number of bytes.
Struct - This is the most general type constructor. It allows each block
to consist of replications of different datatypes.
Derived datatypes can be constructed from basic datatypes as well as derived
data types. For example, a Struct datatype can be made of contiguous, vector datatypes.
DDT library provides following functionality.
- First, a pool of datatypes should be created, by calling new DDT().
- new data types can be created by calling newContiguous(), newVector() etc
functions of DDT which will give an integer index for a datatype. This index
can be used later to refer to this derived datatype. Creating a datatype just
initializes the type, extent, size of a datatype. It does not copy buffers.
- DDT_datatype can be retrieved using getType() function of DDT. Previously
created index needs to be passed to this function.
- To copy non-contiguous bytes based on a data type, serialize funtion needs to
be called on DDT_Datatype.
- Also, getSize(), getExtent() functions can be used to get size and extent of a
datatype.
//file test.C
#include "ddt.h"
myDDT = new DDT((void*)0);
DDT_Type newType1, newType2 ;
//Create a new contiguous datatype which will copy the given buffer (in this
// case, int) count times in a new buffer
myDDT->newContiguous(count, DDT_INT, &newType1) ;
//Create a new vector datatype which will copy count elements of type DDT_DOUBLE
// with length blocklength, spaced stride apart in the original buffer.
myDDT->newVector(count, blocklength, stride, DDT_DOUBLE, newtype);
//newType1 and newType2 can be used for further refering to contiguous and
//vector type of datatype.
// Create a new buffer with characteristics specified while creating
// the new datatype.
DDT_DataType *ddt = myDDT->getType(newType1);
ddt->serialize(buf1, buf2, size, dir);
// dir = 1, specifies that data is copied from buf1 to buf2, buf1 being old
// buffer and buf2 being the new buffer which should contains only the
// selected data.