public static unsafe extern int MPI_Address(IntPtr location, out MPI_Aint address);
public static unsafe extern int MPI_Type_extent(MPI_Datatype datatype, out MPI_Aint extent);
public static unsafe extern int MPI_Type_struct(int count, int[] array_of_blocklengths, MPI_Aint[] array_of_displacements, MPI_Datatype[] array_of_types, out MPI_Datatype newtype);
public static unsafe extern int MPI_Type_hindexed(int count, int[] array_of_blocklengths, MPI_Aint[] array_of_displacements, MPI_Datatype oldtype, out MPI_Datatype newtype);
public static unsafe extern int MPI_Type_hvector(int count, int blocklength, MPI_Aint stride, MPI_Datatype oldtype, out MPI_Datatype newtype);
public static extern unsafe int MPI_Alloc_mem(MPI_Aint size, MPI_Info info, out IntPtr baseptr);
/// <summary> /// Builds a new MPI datatype by using reflection on the given type. /// </summary> private static MPI_Datatype BuildDatatype(Type type) { // Try to build an MPI datatype using reflection, and return that value. FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); int[] blocklens = new int[fields.Length]; MPI_Aint[] indices = new MPI_Aint[fields.Length]; MPI_Datatype[] types = new MPI_Datatype[fields.Length]; int actualLength = 0; // Walk the fields of the data structure, computing offsets and types // for the MPI datatype foreach (FieldInfo field in fields) { // Only include non-static, serialized fields if (!field.IsStatic && !field.IsNotSerialized) { Type fieldType = field.FieldType; // The type stored in the field int fieldLength = 1; // Number of elements in this field. > 1 only for "fixed" fields // Handle "fixed" arrays in structures, such as: // // struct Dimensions // { // public unsafe fixed float values[11]; // } // // .NET 2.0 uses a synthesized type whose name contains "__FixedBuffer" for this // field. The type itself has size = sizeof(float)*11, and contains a field // named "FixedElementType", whose type is "float". if (fieldType.Name.Contains("__FixedBuffer")) { // Dig out the inner field FieldInfo innerField = fieldType.GetFields()[0]; // Determine the number of elements fieldLength = Marshal.SizeOf(fieldType) / Marshal.SizeOf(innerField.FieldType); // Pull out the type of the fixed array fieldType = innerField.FieldType; } // Find the field's MPI datatype MPI_Datatype fieldDatatype = GetDatatype(fieldType); if (fieldDatatype == Unsafe.MPI_DATATYPE_NULL) { // There is no MPI datatype for this field, so we cannot build a // datatype for this struct. Note this failure and return. return(Unsafe.MPI_DATATYPE_NULL); } // Compute the offset of this field int fieldOffset = (int)Marshal.OffsetOf(type, field.Name); // Record this field blocklens[actualLength] = fieldLength; indices[actualLength] = new IntPtr(fieldOffset); types[actualLength] = fieldDatatype; ++actualLength; } } // Create the MPI datatype MPI_Datatype datatype; unsafe { // Build the MPI datatype as a "structure" int errorCode = Unsafe.MPI_Type_struct(actualLength, blocklens, indices, types, out datatype); if (errorCode != Unsafe.MPI_SUCCESS) { throw Environment.TranslateErrorIntoException(errorCode); } // Commit the newly-constructed MPI datatype errorCode = Unsafe.MPI_Type_commit(ref datatype); if (errorCode != Unsafe.MPI_SUCCESS) { throw Environment.TranslateErrorIntoException(errorCode); } } return(datatype); }