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.
\newline
Currently supported datatypes are 
\begin{itemize}
\item Contiguous - Contiguous datatype constructs a typemap consisting of the
replication of a datatype into contiguous locations. 
\item Vector - Vector datatype allows replication of a datatype into locations 
that consist of equally spaced blocks.
\item 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.
\item Indexed - The Indexed datatype allows one to specify a noncontiguous data
layout where displacements between successive blocks need not be equal.
\item HIndexed - Similar to Indexed except that displacement can be arbitrary
number of bytes.
\item Struct - This is the most general type constructor. It allows each block
to consist of replications of different datatypes.
\end{itemize}

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.\\
\vspace*{0.1in}
DDT library provides following functionality.\\
- First, a pool of datatypes should be created, by calling new {\tt DDT()}.
\newline
- new data types can be created by calling {\tt newContiguous()}, {\tt 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.
\newline
- \kw{DDT\_datatype} can be retrieved using {\tt getType()} function of DDT. Previously
created index needs to be passed to this function.
\newline
- To copy non-contiguous bytes based on a data type, serialize funtion needs to
be called on \kw{DDT\_Datatype}. 
\newline
- Also, {\tt getSize()}, {\tt getExtent()} functions can be used to get size and extent of a
datatype.

\begin{alltt}
//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.

//When needed to do the reverse, keep dir = -1
\end{alltt}
Following datatype constants are supported.\\
{\em Primitive Datatypes:}
\newline
\kw{DDT\_DOUBLE}, \kw{DDT\_INT}, \kw{DDT\_FLOAT}, \kw{DDT\_COMPLEX}, \kw{DDT\_LOGICAL}, \kw{DDT\_CHAR}, \kw{DDT\_BYTE},\kw{DDT\_PACKED},  \kw{DDT\_SHORT}, \kw{DDT\_LONG}, \kw{DDT\_UNSIGNED\_CHAR}, \kw{DDT\_UNSIGNED\_SHORT}, \kw{DDT\_UNSIGNED}, \kw{DDT\_UNSIGNED\_LONG}, \kw{DDT\_LONG\_DOUBLE}   
{\em Derived Datatypes:}
\newline
\kw{DDT\_CONTIGUOUS}, \kw{DDT\_VECTOR}, \kw{DDT\_HVECTOR}, \kw{DDT\_INDEXED}, \kw{DDT\_HINDEXED}, \kw{DDT\_STRUCT} \\
\vspace*{0.1in}
DDT library provides following interface
- To create new datatypes. 
\begin{alltt}
class DDT \{
	public:
	void newContiguous(int count, DDT\_Type  oldType, DDT\_Type* newType);
	void newVector(int count, int blocklength, int stride, DDT\_Type oldtype, 
			  DDT\_Type* newtype) ;
	void newHVector(int count, int blocklength, int stride, DDT\_Type oldtype, 
			   DDT\_Type* newtype);
	void newIndexed(int count, int* arrbLength, int* arrDisp , DDT\_Type oldtype, DDT\_Type* newtype);
	void newHIndexed(int count, int* arrbLength, int* arrDisp , DDT\_Type oldtype, DDT\_Type* newtype);
	void newStruct(int count, int* arrbLength, int* arrDisp , DDT\_Type *oldtype, DDT\_Type* newtype);
\}
\end{alltt}

- To Use the derived datatype. 
\begin{alltt}
class DDT_Datatype \{
	public:
	virtual int getSize();
	virtual int getExtent();
	virtual int serialize(char* userdata, char* buffer, int num, int dir);
\}
\end{alltt}


{\em Examples of Derived Datatype}
\begin{itemize}
\item Contiguous -

If oldType is a derived datatype struct consisting a char and a double,
\begin{alltt}
	ddt->newContiguous(5, oldType, \&newType1) ; 
\end{alltt}
	creates a contiguous datatype which has
    {char, double, char, double, char, double, char double, char double }

\item Vector and HVector -
To select alternate elements from each row and to select alternate rows in a 
5 X 5 2-D array of doubles.
\begin{alltt}
	ddt->newVector(3,1,2, DDT\_DOUBLE, \&oneSlice) ;
\end{alltt}
    This will give a row in which alternate elements are selected.
\begin{alltt}
	ddt->newHVector(3, 1, 5*sizeof(double), oneSlice, \&twoSlice) ; 
\end{alltt}
	This will give three rows each of type oneSlice.

\item Indexed -

To select 2, 3, 4 blocks of Integer spaced 4,5,6 blocks in a given 1-D array of
integers.
    blength[3] = { 2, 3, 4 } ;
	stride[3]  = { 4, 5, 6 } ;

\begin{alltt}
	ddt->Indexed(1, blength, stride, MPI\_INT, \&newArray);
\end{alltt}

\item HIndexed -

To select 2, 3, 4 blocks of Integer spaced 4,5,6 bytes in a given 1-D array of
integers.
    blength[3] = { 2, 3, 4 } ;
	stride[3]  = { 4, 5, 6 } ;

\begin{alltt}
	ddt->HIndexed(1, blength, stride, MPI\_INT, \&newArray);
\end{alltt}

In Indexed datatype, displacements will be 4, 5 and 6  multiples of int, 
while in HIndexed, displacements will  be 4, 5 and 6 bytes.
\end{itemize}
