diff --git a/MPI/CustomUnsafe.cs b/MPI/CustomUnsafe.cs new file mode 100644 index 0000000..3ce52f2 --- /dev/null +++ b/MPI/CustomUnsafe.cs @@ -0,0 +1,2614 @@ +/* Copyright (C) 2007 The Trustees of Indiana University + * + * Use, modification and distribution is subject to the Boost Software + * License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * Authors: Douglas Gregor + * Andrew Lumsdaine + * + * This file provides an interface to the native C MPI from within C#, + * exposing all of the various functions and constants that are part + * of MPI. Since the MPI standard provides an API and not an ABI, the + * contents of this file are tied specifically to Microsoft's MPI + * implementation, MS-MPI, for which this file can be used in 32- or + * 64-bit Windows environments without any additional customization, + * built with the provided Visual Studio projects. + * + * For all other environments and MPI implementations, the data types + * and constants must be changed to suit the environment. These + * changes occur in three places. First, each of the MPI.NET source + * files contains a block of MPI data type definitions that are + * controlled by various preprocessor defines (e.g., + * MPI_HANDLES_ARE_POINTERS); the configure script will select the + * appropriate set of defines when it runs. Second, when using the + * configure script, this file will be translated at build time into + * CustomUnsafe.cs by Unsafe.pl. This Perl script parses mpi.h, then + * updates the constants in this file to reflect the constants + * provided by the MPI implementation. This process may also involve + * creating a small C shared library that helps map some additional + * constants into C# (see the generated cbridge.c and its library, + * libmpinet). Finally, the configure script generates a file + * MPI.dll.config, which is a Mono-specific file that remaps some of + * the DLL and MPI names to platform-specific versions. This file is + * also generated by the configure script. + */ +using System; +using System.Runtime.InteropServices; + +namespace MPI +{ + // MPI data type definitions +#if MPI_HANDLES_ARE_POINTERS + using MPI_Aint = IntPtr; + using MPI_Comm = IntPtr; + using MPI_Datatype = IntPtr; + using MPI_Errhandler = IntPtr; + using MPI_File = IntPtr; + using MPI_Group = IntPtr; + using MPI_Info = IntPtr; + using MPI_Op = IntPtr; + using MPI_Request = IntPtr; + using MPI_User_function = IntPtr; + using MPI_Win = IntPtr; +#else + using MPI_Aint = IntPtr; + using MPI_Comm = Int32; + using MPI_Datatype = Int32; + using MPI_Errhandler = Int32; + using MPI_File = IntPtr; + using MPI_Group = Int32; + using MPI_Info = Int32; + using MPI_Op = Int32; + using MPI_Request = Int32; + using MPI_User_function = IntPtr; + using MPI_Win = Int32; +#endif + + /// + /// Direct, low-level interface to the system MPI library. + /// + /// + /// + /// This low-level interface provides direct access to the unmanaged + /// MPI library provided by the system. It is by nature unsafe, and + /// should only be used by programmers experienced both in the use + /// of MPI from lower-level languages (e.g., C, Fortran) and with an + /// understanding of the interaction between managed and unmanaged + /// code, especially those issues that pertain to memory + /// pinning/unpinning. + /// + /// A second use of the Unsafe class is purely for documentation reasons. Each member of the + /// Unsafe class corresponds to an entity in the standard, C MPI, and the documentation of each member + /// of Unsafe will point to the corresponding functionality within MPI.NET. Programmers already familiar + /// with the Message Passing Interface in C can use the Unsafe class as a reference to better understand + /// how to apply their knowledge of C MPI to MPI.NET programs. + /// + public unsafe class Unsafe + { + + // I did not manage to modify the Unsafe.pl script to cater for replacing OPAL_* constants. I resort to the following to get by: + // taken from /usr/lib/openmpi/include/mpi.h in the Debian openmpi-dev package + public const int OPAL_MAX_PROCESSOR_NAME = 256; + public const int OPAL_MAX_ERROR_STRING = 256; + +#if MPICH2 + private const string MPI_DLL = "mpich2.dll"; +#else + private const string MPI_DLL = "msmpi.dll"; +#endif + + /// + /// Low-level representation of the status of an MPI communication operation. + /// + /// + /// This structure is used internally by MPI.NET, and most users will instead see the MPI.NET version + /// of the message-status class, . Unless you are interacting directly with the + /// low-level MPI interface (which is not typically recommended), use instead. + /// + [StructLayout(LayoutKind.Sequential)] + public struct MPI_Status + { + public int MPI_SOURCE; + public int MPI_TAG; + public int MPI_ERROR; + internal int _cancelled; + internal UIntPtr _ucount; + } + + #region Predefined communicators + /// + /// Predefined communicator containing all of the MPI processes. See . + /// + public static readonly MPI_Comm MPI_COMM_WORLD = mpinet_MPI_COMM_WORLD(); + + /// + /// Predefined communicator containing only the calling process. See . + /// + public static readonly MPI_Comm MPI_COMM_SELF = mpinet_MPI_COMM_SELF(); + + /// + /// Predefined communicator representing "no communicator". In the higher-level interface, this + /// is represented by a null object. + /// + public static readonly MPI_Comm MPI_COMM_NULL = mpinet_MPI_COMM_NULL(); + #endregion + + #region Built-in data types + /// + /// A single character. There is no equivalent to this type in C# or .NET. + /// + public static readonly MPI_Datatype MPI_CHAR = mpinet_MPI_CHAR(); + + /// + /// A single, signed character. This is equivalent to the sbyte type + /// in C# and the System.SByte type in .NET. + /// + public static readonly MPI_Datatype MPI_SIGNED_CHAR = mpinet_MPI_SIGNED_CHAR(); + + /// + /// A single, unsigned character. There is no equivalent to this type in C# or .NET. + /// + public static readonly MPI_Datatype MPI_UNSIGNED_CHAR = mpinet_MPI_UNSIGNED_CHAR(); + + /// + /// A single byte. This is equivalent to the byte type + /// in C# and the System.Byte type in .NET. + /// + public static readonly MPI_Datatype MPI_BYTE = mpinet_MPI_BYTE(); + + /// + /// A single, wide character. The equivalent is char in C# and System.Char in .NET. + /// + public static readonly MPI_Datatype MPI_WCHAR = mpinet_MPI_WCHAR(); + + /// + /// A signed short integer. This is equivalent to the short type in C# and + /// System.Int16 in .NET. + /// + public static readonly MPI_Datatype MPI_SHORT = mpinet_MPI_SHORT(); + + /// + /// An unsigned short integer. This is equivalent to the ushort type in C# and + /// System.UInt16 in .NET. + /// + public static readonly MPI_Datatype MPI_UNSIGNED_SHORT = mpinet_MPI_UNSIGNED_SHORT(); + + /// + /// A signed integer. This is equivalent to the int type in C# and + /// System.Int32 in .NET. + /// + public static readonly MPI_Datatype MPI_INT = mpinet_MPI_INT(); + + /// + /// An unsigned integer. This is equivalent to the uint type in C# and + /// System.UInt32 in .NET. + /// + public static readonly MPI_Datatype MPI_UNSIGNED = mpinet_MPI_UNSIGNED(); + + /// + /// A long signed integer. There is no equivalent in C# or .NET, because the 64-bit + /// integer in C# and .NET is mapped to . + /// + public static readonly MPI_Datatype MPI_LONG = mpinet_MPI_LONG(); + + /// + /// A long unsigned integer. There is no equivalent in C# or .NET, because the 64-bit + /// unsigned integer in C# and .NET is mapped to . + /// + public static readonly MPI_Datatype MPI_UNSIGNED_LONG = mpinet_MPI_UNSIGNED_LONG(); + + /// + /// A single-precision floating-point value. The equivalent is float in C# + /// and System.Single in .NET. + /// + public static readonly MPI_Datatype MPI_FLOAT = mpinet_MPI_FLOAT(); + + /// + /// A double-precision floating-point value. The equivalent is double in C# + /// and System.Double in .NET. + /// + public static readonly MPI_Datatype MPI_DOUBLE = mpinet_MPI_DOUBLE(); + + /// + /// An extended-precision floating-point value. There is no equivalent in C# or .NET. + /// + public static readonly MPI_Datatype MPI_LONG_DOUBLE = mpinet_MPI_LONG_DOUBLE(); + + /// + /// A long long signed integer. The equivalent is long in C# and + /// System.Int64 in .NET. This is a synonym for . + /// + public static readonly MPI_Datatype MPI_LONG_LONG_INT = mpinet_MPI_LONG_LONG_INT(); + + /// + /// A long long unsigned integer. The equivalent is ulong in C# and + /// System.UInt64 in .NET. + /// + public static readonly MPI_Datatype MPI_UNSIGNED_LONG_LONG = mpinet_MPI_UNSIGNED_LONG_LONG(); + + /// + /// A long long signed integer. The equivalent is long in C# and + /// System.Int64 in .NET. This is a synonym for . + /// + public static readonly MPI_Datatype MPI_LONG_LONG = mpinet_MPI_LONG_LONG(); + + /// + /// A special data type used to indicate data that has been packed with . + /// This type is only used by the lowest-level MPI operations. The .NET equivalent is the + /// type. + /// + public static readonly MPI_Datatype MPI_PACKED = mpinet_MPI_PACKED(); + + /// + /// A special datatype value that indicates "no datatype". + /// + public static readonly MPI_Datatype MPI_DATATYPE_NULL = mpinet_MPI_DATATYPE_NULL(); + #endregion + + #region Comparison constants + /// + /// Constant used in comparisons of MPI objects to denote that two objects are identical. + /// See . + /// + public const int MPI_IDENT = 0; + + /// + /// Constant used in comparisons of MPI objects to denote that two objects are congruent, + /// meaning that the objects act the same way but are not identical. + /// See . + /// + public const int MPI_CONGRUENT = 1; + + /// + /// Constant used in comparisons of MPI objects to denote that two objects are similar, + /// but assign different ranks to each of the processes. + /// See . + /// + public const int MPI_SIMILAR = 2; + + /// + /// Constant used in comparisons of MPI objects to denote that two objects are completely + /// different. + /// See . + /// + public const int MPI_UNEQUAL = 3; + #endregion + + /// + /// A special marker used for the "buf" parameter to point-to-point operations + /// and some collectives that indicates that the derived datatype contains absolute + /// (rather than relative) addresses. The use of MPI_BOTTOM is not recommended. + /// This facility is unused in C# and .NET. + /// + public static unsafe IntPtr MPI_BOTTOM = new IntPtr(0); + + /// + /// Special value for the source or dest argument to any communication operation, + /// which indicates that the communication is a no-op. Not supported in MPI.NET. + /// + public const int MPI_PROC_NULL = -2 ; + + /// + /// Special value used for Intercommunicator collective operations which indicates the root + /// process for a collective operation. + /// + public const int MPI_ROOT = -4 ; + + /// + /// Constant used to indicate that the MPI_Status argument of an MPI + /// operation will be ignored. + /// + public static readonly MPI_Status* MPI_STATUS_IGNORE = ((MPI_Status *) 0); + + /// + /// Constant used to indicate that the array of MPI_Status arguments + /// to an MPI operation will be ignored. + /// + public static readonly MPI_Status* MPI_STATUSES_IGNORE = ((MPI_Status *) 0); + + /// + /// An empty group containing no processes. See . + /// + public static readonly MPI_Group MPI_GROUP_EMPTY = mpinet_MPI_GROUP_EMPTY(); + + /// + /// A constant used to indicate the "null" group of processes. Corresponds to a null . + /// + public static readonly MPI_Group MPI_GROUP_NULL = mpinet_MPI_GROUP_NULL(); + + /// + /// A special info key used to indicate that no extra information is being + /// passed into a routine. + /// + public static readonly MPI_Info MPI_INFO_NULL = mpinet_MPI_INFO_NULL(); + + /// + /// "Undefined" value used to identify when a rank is not a part of a group. + /// See . + /// + public const int MPI_UNDEFINED = -32766 ; + + /// + /// A constant used to indicate whether a communicator has a Cartesian topology. + /// + public const int MPI_CART = 1 ; + + /// + /// A constant used to indicate whether a communicator has a Graph topology. + /// + public const int MPI_GRAPH = 2 ; + + #region Datatype constructors + /// + /// Creates a new datatype from a contiguous block of values + /// of the same type. Not used by MPI.NET. + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Type_contiguous(int count, MPI_Datatype oldtype, out MPI_Datatype newtype); + + /// + /// Creates a new datatype from a strided block of values of + /// the same type. Not used by MPI.NET. + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Type_vector(int count, int blocklength, int stride, MPI_Datatype oldtype, out MPI_Datatype newtype); + + /// + /// Creates a new datatype from a strided block of values of + /// the same type. Not used by MPI.NET. + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Type_hvector(int count, int blocklength, MPI_Aint stride, MPI_Datatype oldtype, out MPI_Datatype newtype); + + /// + /// Creates a new datatype from discontiguous blocks of values + /// of the same type. Not used by MPI.NET. + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Type_indexed(int count, int[] array_of_blocklengths, int[] array_of_displacements, MPI_Datatype oldtype, out MPI_Datatype newtype); + + /// + /// Creates a new datatype from discontiguous blocks of values + /// of the same type. Not used by MPI.NET. + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + 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); + + /// + /// Creates a new datatype from a structure containing + /// discontiguous blocks of different types. + /// This is the most general type constructor, and is used by + /// the to + /// create MPI datatypes from .NET value types. + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + 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); + #endregion + + #region Pack and unpack + /// + /// Packs (serializes) data into a byte buffer. This serialized representation can be transmitted via MPI + /// with the datatype and unpacked with . Serialization + /// in MPI.NET is automatic, so this routine is very rarely used. + /// + /// + /// Pointer to the input buffer, containing values with the MPI datatype + /// . + /// + /// The number of values in . + /// The MPI datatype of the values in . + /// + /// A pointer to the buffer of bytes into which we will be packing the serialized representation + /// of the data in . + /// + /// The size (in bytes) of . + /// + /// A pointer to the position (in bytes) into where the packed data + /// will be written. This position will be updated to the next available position in the buffer + /// once the serialized data has been written. + /// + /// The communicator over which the packed data will be sent. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Pack(IntPtr inbuf, int incount, MPI_Datatype datatype, IntPtr outbuf, int outsize, ref int position, MPI_Comm comm); + + /// + /// Unpacks (deserializes) data from a byte buffer. The serialized representation will have been + /// packed by and (possibly) transmitted via MPI using the datatype + /// . Serialization in MPI.NET is automatic, so this routine is very + /// rarely used. + /// + /// A pointer to the buffer of bytes that will be unpacked. + /// The number of bytes in . + /// + /// A pointer to the position (in bytes) inside the buffer from which data will be unpacked. + /// This position will be updated to reflect the position of the next value in the buffer + /// after the data has been unpacked. + /// + /// + /// A pointer to the buffer where the unpacked data will be written. This buffer contains + /// values whose MPI datatype is . + /// + /// Number of values that will be stored into . + /// The type of data in . + /// + /// The communicator for which the packing was performed (and which may have been used to transmit the + /// serialized data). + /// + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Unpack(IntPtr inbuf, int insize, ref int position, IntPtr outbuf, int outcount, MPI_Datatype datatype, MPI_Comm comm); + + /// + /// Determine the maximum amount of space that packing values with the + /// MPI datatype will require. This routine is useful for allocating + /// buffer space when packing data with . + /// + /// + /// The number of elements of type to be packed. + /// + /// The type of data to be packed. + /// The communicator over which the packed data would be transmitted. + /// + /// A pointer to an integer. This integer will receive the maximum number of bytes required to + /// pack the data. However, it is possible that when calling , fewer bytes + /// will be required to pack the actual data. + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Pack_size(int incount, MPI_Datatype datatype, MPI_Comm comm, out int size); + #endregion + + #region Address and extent functions + /// + /// Converts a pointer into an address for use with MPI. In many cases, this operation is simply a + /// cast from the pointer's value to an integer. + /// + /// A pointer to the memory whose address will be returned. + /// + /// A pointer to the integer address value that will be replaced with the address pointed to + /// by . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Address(IntPtr location, out MPI_Aint address); + + /// + /// Determines the extent of the datatype. + /// + /// The datatype to query. + /// Receives the extent of . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Type_extent(MPI_Datatype datatype, out MPI_Aint extent); + + /// + /// Computes the size of a datatype. + /// + /// The MPI datatype. + /// + /// Pointer to an integer, which will be assigned the size of the data type (in bytes). + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Type_size(MPI_Datatype datatype, out int size); + #endregion + + #region Commit and free + /// + /// Completes creation of an MPI datatype. This routine will be called + /// automatically when the MPI datatype is being generated via reflection + /// in . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Type_commit(ref MPI_Datatype datatype); + + /// + /// Frees an MPI datatype. + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Type_free(ref MPI_Datatype datatype); + #endregion + + #region Group accessors + /// + /// Determine the number of processes in a group. See . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Group_size(MPI_Group group, out int size); + + /// + /// Determine the rank of the calling process in a group. See . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Group_rank(MPI_Group group, out int rank); + + /// + /// Translate the ranks of processes in one group into those processes' corresponding + /// ranks in another group. See . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Group_translate_ranks (MPI_Group group1, int n, int[] ranks1, MPI_Group group2, int[] ranks2); + + /// + /// Compare two groups. See . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Group_compare(MPI_Group group1, MPI_Group group2, out int result); + #endregion + + #region Group constructors + /// + /// Retrieve the group associated with a communicator. See . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Comm_group(MPI_Comm comm, out MPI_Group group); + + /// + /// Create a group from the union of two groups. See . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Group_union(MPI_Group group1, MPI_Group group2, out MPI_Group newgroup); + + /// + /// Create a group from the intersection of two groups. See . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Group_intersection(MPI_Group group1, MPI_Group group2, out MPI_Group newgroup); + + /// + /// Create a group from the difference of two groups. See . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Group_difference(MPI_Group group1, MPI_Group group2, out MPI_Group newgroup); + + /// + /// Create a subgroup containing the processes with specific ranks in an existing group. + /// See . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Group_incl(MPI_Group group, int n, int[] ranks, out MPI_Group newgroup); + + /// + /// Create a subgroup containing all processes in existing group except those specified. + /// See . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Group_excl(MPI_Group group, int n, int[] ranks, out MPI_Group newgroup); + + /// + /// Create a subgroup of processes in a group, based on a set of (first, last, stride) rank triples. + /// Note: this precise functionality is not exposed directly in the normal MPI layer; however, the + /// same semantics can be attained with . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Group_range_incl(MPI_Group group, int n, int[] ranges, out MPI_Group newgroup); + + /// + /// Create a subgroup of processes containing all of the processes in the source group except those described + /// by one of th provided(first, last, stride) rank triples. + /// Note: this precise functionality is not exposed directly in the normal MPI layer; however, the + /// same semantics can be attained with . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Group_range_excl(MPI_Group group, int n, int[] ranges, out MPI_Group newgroup); + #endregion + + #region Group destructors + /// + /// Frees a group. This routine will be invoked automatically by + /// or the finalizer for . + /// + /// + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Group_free(ref MPI_Group group); + #endregion + + #region Communicator accessors + /// + /// Determines the number of processes in the communicator. See . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Comm_size(MPI_Comm comm, out int size); + + /// + /// Determines the rank of the calling process in the communicator. See . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Comm_rank(MPI_Comm comm, out int rank); + + /// + /// Compare two communicators. See . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Comm_compare(MPI_Comm comm1, MPI_Comm comm2, out int result); + #endregion + + #region Communicator constructors + /// + /// Duplicates a communicator, creating a new communicator with the same processes and ranks + /// as the original. See . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Comm_dup(MPI_Comm comm, out MPI_Comm comm_out); + + /// + /// Creates a new communicator from a subgroup of the processes in an existing communicator. + /// See . + /// + /// + /// The existing communicator, from which the new communicator will be created. + /// + /// + /// A group specifying zero or more processes in the communicator . + /// + /// + /// A pointer that points to the newly-created communicator, which will contain all of + /// the processes in the group. The order of the processes in this new communicator will + /// be the same as the order of those processes in the original communicator. + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Comm_create(MPI_Comm comm, MPI_Group group, out MPI_Comm newcomm); + + /// + /// Splits a communicator into several new communicators, based on the colors provided. + /// See . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Comm_split(MPI_Comm comm, int color, int key, out MPI_Comm newcomm); + + /// + /// Creates a new Cartesian communicator from another + /// communicator. See . + /// + /// + /// Existing communicator from which the new communicator will be created. + /// + /// + /// Number of dimensions for Cartesian communicator's grid to have. + /// + /// + /// Array to specify sizes in each dimension. + /// + /// + /// Array of logical values (0s and 1s) indicating whether grid should be periodic in each dimension + /// (i.e. if the last communicator and the first in each dimension are directly connected). + /// + /// + /// Logical value indicating whether ranks may be reordered or not. + /// + /// + /// Output parameter for new communicator. + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Cart_create(MPI_Comm comm, int ndims, int* dims, int* periods, int reorder, MPI_Comm* newcomm); + + /// + /// Create a lesser dimensional grid from an existing + /// Cartesian communicator. See . + /// + /// + /// The existing communicator. + /// + /// + /// A logical array indicating whether a dimension in the existing should be kept (1) or dropped (0). + /// + /// + /// The new communicator. + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Cart_sub(MPI_Comm comm, int* remain_dims, MPI_Comm* newcomm); + + /// + /// Create a topological communicator with a graph topology, + /// where any rank can be connected to any other rank. See + /// . + /// + /// + /// An existing Intracommunicator to use to create the new communicator. + /// + /// + /// The number of nodes the graph will have. + /// + /// + /// An array indicating the starting index in of the edges for each vertex. + /// + /// + /// An array of edge targets, indexed by . + /// + /// + /// Logical indicating whether ranks can be reordered. + /// + /// + /// The new communicator. + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Graph_create(MPI_Comm comm, int nnodes, int* index, int* edges, int reorder, MPI_Comm *newComm); + + #endregion + + #region Communicator destructors + /// + /// Frees a communicator. This routine will be invoked automatically by + /// or the finalizer for . + /// + /// The communicator to free. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Comm_free(ref MPI_Comm comm); + #endregion + + #region Communicator attributes + /// + /// Delegate describing a low-level MPI function used to copy attribute values from a communicator + /// when the communicator is being duplicated. + /// + /// + /// This function will + /// be defined automatically by MPI.NET when a new is created, and will vary + /// depending on the type of the attribute and on the requested . + /// + /// The communicator being duplicated. + /// The attribute's key value. + /// + /// The extra state associated with the attribute, provided by the user + /// in . + /// + /// + /// The attribute value in the communicator to be duplicated. + /// + /// + /// A pointer to the attribute value that will be copied into the + /// new communicator. The attribute value will be no larger than an IntPtr. + /// The user only needs to set this value if the attribute will be copied, + /// as determined by flag. + /// + /// + /// Set this to a non-zero value to indicate that the attribute should + /// be copied. + /// + public delegate int MPI_Copy_function(MPI_Comm comm, int keyval, IntPtr extra_state, IntPtr attribute_val_in, + IntPtr attribute_val_out, out int flag); + + /// + /// Delegate describing a low-level MPI function that takes care of de-allocating + /// an attribute when it is deleted from a communicator (or the communicator itself + /// is freed). + /// + /// + /// + /// Often used when the attribute's value is a pointer to some per-communicator + /// data, and the pointer needs to be freed. This function will be defined automatically + /// by MPI.NET when a new is created, and will vary + /// depending on the type of the attribute and on the requested . + /// + /// The communicator. + /// The attribute being removed from the communicator. + /// The value of this attribute in the communicator. + /// + /// The extra state provided by the user in . + /// + public delegate int MPI_Delete_function(MPI_Comm comm, int keyval, IntPtr attribute_val, IntPtr extra_state); + + /// + /// Special key value that indicates an invalid key. + /// + public const int MPI_KEYVAL_INVALID = -1 ; + + /// + /// Special "null" copy function that indicates that an attribute should not be copied. + /// + public static readonly MPI_Copy_function MPI_NULL_COPY_FN = mpinet_MPI_NULL_COPY_FN(); + + /// + /// Special "null" deletion function that indicates that no delete function should + /// be called when an attribute is removed from a communicator. + /// + public static readonly MPI_Delete_function MPI_NULL_DELETE_FN = mpinet_MPI_NULL_DELETE_FN(); + + /// + /// Creates a new MPI attribute that can be attached to communicators. This routine is + /// automatically involved by MPI.NET when a new is created. + /// See + /// + /// + /// The function used to copy the attribute when a communicator is + /// duplicated. + /// + /// + /// The function used to delete the attribute when it is removed + /// from a communicator. + /// + /// + /// Will receive a new integer that identifies this attribute. + /// + /// + /// A user-defined pointer that includes extra information to be + /// passed to the copy and delete functions. This pointer can + /// be used to store more information about the attribute itself. + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static extern unsafe int MPI_Keyval_create(MPI_Copy_function copy_fn, MPI_Delete_function delete_fn, out int keyval, IntPtr extra_state); + + /// + /// Frees an attribute with the given key value. The user must ensure that + /// this attribute has been deleted from all communicators before calling + /// this routine. This operation is performed by . + /// + /// The attribute's key value. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static extern unsafe int MPI_Keyval_free(ref int keyval); + + /// + /// Sets the value of an attribute on a communicator. Attributes in MPI.NET are + /// handled through the class, an instance of which is associated + /// with each communicator. + /// + /// The communicator. + /// The attribute to set. + /// The new value to place into the communicator. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static extern unsafe int MPI_Attr_put(MPI_Comm comm, int keyval, IntPtr attribute_val); + + /// + /// Retrieves the value of an attribute on a communicator. Attributes in MPI.NET are + /// handled through the class, an instance of which is associated + /// with each communicator. + /// + /// The communicator. + /// The attribute to get. + /// + /// Will receive the value stored for this attribute on this + /// communicator, if one exists. The result is only valid + /// if is non-zero. + /// + /// + /// Will receive a boolean value stating whether the attribute is stored + /// with this communicator. + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static extern unsafe int MPI_Attr_get(MPI_Comm comm, int keyval, IntPtr attribute_val, out int flag); + + /// + /// Deletes an attribute stored on the communicator. Attributes in MPI.NET are + /// handled through the class, an instance of which is associated + /// with each communicator. + /// + /// The communicator. + /// The attribute to delete. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static extern unsafe int MPI_Attr_delete(MPI_Comm comm, int keyval); + #endregion + + #region Intercommunicator accessors + /// + /// Determine whether a communicator is an intercommunicator. In MPI.NET, intercommunicators + /// will have type . + /// + /// The communicator. + /// + /// Pointer to a flag, which will be set to a non-zero value if + /// is an intercommunicator. + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Comm_test_inter(MPI_Comm comm, out int flag); + + /// + /// Determines the number of processes in the remote group of an intercommunicator. + /// See . + /// + /// The intercommunicator. + /// + /// Will receive the number of processes in the remote group of + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Comm_remote_size(MPI_Comm comm, out int size); + + /// + /// Retrieves the remote group from an intercommunicator. + /// See . + /// + /// The intercommunicator. + /// + /// Will receive the group containing all of the processes in the remote group + /// of . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Comm_remote_group(MPI_Comm comm, out MPI_Group group); + + /// + /// Create a new intercommunicator from two disjoint intracommunicators. + /// See . + /// + /// The local communicator. + /// The leader of the local communicator. + /// + /// Communicator that bridges the intercommunicators, allowing the leaders to communicate. + /// + /// + /// The rank of the remote group's leader within . + /// + /// Tag used for communication to create the intercommunicator. + /// Will receive the new intercommunicator. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Intercomm_create(MPI_Comm local_comm, int local_leader, MPI_Comm bridge_comm, int remote_leader, int tag, out MPI_Comm newintercomm); + + /// + /// Merge the two groups in an intercommunicator into a single intracommunicator. + /// See + /// + /// The intercommunicator. + /// + /// Whether this group of processes has the higher ranks in the resuling intercommunicator. + /// + /// The resulting intracommunicator. + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Intercomm_merge(MPI_Comm intercomm, int high, out MPI_Comm newintracomm); + #endregion + + #region Cartesian communicator methods + /// + /// Gets the number of dimensions in the Cartesian communicator. + /// See . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Cartdim_get(MPI_Comm comm, int* result); + + /// + /// Retrieves the primary topological information on a Cartesian communicator: the number of dimensions, + /// the size in each dimension, the periodicity in each dimension. Also gives the coordinates of the + /// calling process. See , + /// , and . + /// + /// + /// The communicator. + /// + /// + /// The number of dimensions. + /// + /// + /// Output parameter for size of each dimension. Should be as long as . + /// + /// + /// Output parameter for periodicity in each dimension. 0 for false, 1 for true. Should be as long as . + /// + /// + /// Output parameter for coordinates of calling process. Should be as long as . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Cart_get(MPI_Comm comm, int ndims, int* dims, int* periods, int* coords); + + /// + /// Determines the rank of a process in the Cartesian communicator given its coordinates. + /// See . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Cart_rank(MPI_Comm comm, int* coords, int* rank); + + /// + /// Determines the coordinates of a process given its rank in the Cartesian communicator. + /// See . + /// + /// + /// The communicator. + /// + /// + /// The rank of the process in the Cartesian communicator. + /// + /// + /// Length of + /// + /// + /// Output parameter. + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Cart_coords(MPI_Comm comm, int rank, int maxdims, int* coords); + + /// + /// Calculates the necessary source and destination ranks for shifting data over the + /// Cartesian communicator. See . + /// + /// + /// The communicator. + /// + /// + /// An integer specifying which of the dimensions along which to shift. + /// + /// + /// How far to shift (negative values means "downward," positive values "upward"). + /// + /// + /// Output parameter for rank to receive from. + /// + /// + /// Output parameter for rank to send to. + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Cart_shift(MPI_Comm comm, int direction, int disp, int* rank_source, int* rank_dest); + + /// + /// Returns a recommended configuration for a new Cartesian grid. + /// See . + /// + /// + /// The existing communicator. + /// + /// + /// The number of dimensions for the Cartesian grid. + /// + /// + /// An array of length indicating the size of the grid in each dimension. + /// + /// + /// A logical array of length indicating whether the grid is periodic in any given dimension. + /// + /// + /// The new rank of the calling process. + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Cart_map(MPI_Comm comm, int ndims, int* dims, int* periods, out int newrank); + + /// + /// Find out the communicator topology. In MPI.NET, one queries the communicator's topology by + /// looking at the type, e.g., , , or + /// . + /// + /// + /// The communicator. + /// + /// + /// Value indicating communicator topology; one of MPI_CART, MPI_GRAPH, or MPI_UNDEFINED (if the communicator + /// has no topology). + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Topo_test(MPI_Comm comm, out int status); + + #endregion + + #region Graph communicator methods + /// + /// Retrieve the dimensions of a Graph communicator. See + /// and . + /// + /// + /// The communicator. + /// + /// + /// Output parameter for the number of nodes in the graph. + /// + /// + /// Output parameter for the number of edges in the graph. + /// + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Graphdims_get(MPI_Comm comm, out int nnodes, out int nedges); + + /// + /// Retrieve the index and edges arrays used to create the graph communicator. See + /// and . + /// + /// + /// The communicator. + /// + /// + /// The size of . + /// + /// + /// The size of + /// + /// + /// Output array in which to store the index array. + /// + /// + /// Output array in which to store the edges array. + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Graph_get(MPI_Comm comm, int maxindex, int maxedges, int* index, int* edges); + + /// + /// Retrieve the number of neighbors of a node. See + /// and . + /// + /// + /// The communicator. + /// + /// + /// The rank of the node of interest. + /// + /// + /// Output parameter to store the number of neighbors. + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Graph_neighbors_count(MPI_Comm comm, int rank, out int nneighbors); + + + /// + /// Retrieve a list of the neighbors of a node. See + /// and . + /// + /// + /// The communicator. + /// + /// + /// The rank of the node of interest. + /// + /// + /// The size of . + /// + /// + /// Output array to store the list of neighbors. + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Graph_neighbors(MPI_Comm comm, int rank, int maxneighbors, int* neighbors); + + /// + /// Returns a recommended configuration for a new Graph communicator. + /// See . + /// + /// + /// The existing communicator. + /// + /// + /// The number of nodes to assume. + /// + /// + /// An index array to use (where the semantics is the same as for . + /// + /// + /// An array of edges as for the constructor . + /// + /// + /// The new rank of the calling process. + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Graph_map(MPI_Comm comm, int nnodes, int* index, int* edges, out int newrank); + #endregion + + + /// + /// Suggest a shape for a new Cartesian communicator, given the number of dimensions. + /// See . + /// + /// + /// The number of nodes the grid will contain. + /// + /// + /// The number of dimensions the grid will have. + /// + /// + /// An array indicating the size in each dimension. Any nonzero entries will be left + /// alone; only 0 values will be changed to shape the grid. + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Dims_create(int nnodes, int ndims, int *dims); + + #region Startup + /// + /// Initializes MPI. This routine must be called before any other MPI routine. + /// It will be invoked by the constructor. + /// + /// The number of arguments in . + /// + /// A pointer to an array of C-style strings containing all of + /// the command-line arguments. + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Init(ref int argc, ref byte **argv); + + /// + /// Finalizes (shuts down) MPI. This routine must be called before exiting the + /// program. It will be invoked by . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Finalize(); + + /// + /// Determine whether MPI has already been initialized. See . + /// + /// Will be set to a non-zero value if the MPI environment has been initialized. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Initialized(out int flag); + + /// + /// Determine whether MPI has already been finalized. See . + /// + /// Will be set to a non-zero value if the MPI environment has been finalized. + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Finalized(out int flag); + + /// + /// Aborts the current MPI program. See + /// and . + /// + /// The communicator that will be used to abort the program. + /// The error code to be returned from the MPI process. + /// This routine does not return. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Abort(MPI_Comm comm, int errcode); + #endregion + + #region Threading + /// + /// Indicates that the MPI program is single-threaded. See . + /// + public const int MPI_THREAD_SINGLE = 0; + /// + /// Indicates that the MPI program is multi-threaded, but all MPI operations will be called + /// from the main thread. See . + /// + public const int MPI_THREAD_FUNNELED = 1; + /// + /// Indicates that the MPI program is multi-threaded, but only one thread will call into MPI + /// at any given time. See . + /// + public const int MPI_THREAD_SERIALIZED = 2; + /// + /// Indicates that the MPI program is multi-threaded, and any thread can call into MPI + /// at any time. See . + /// + public const int MPI_THREAD_MULTIPLE = 3; + + /// + /// Initializes the MPI library with thread support. This operation subsumes . + /// See . + /// + /// Pointer to the number of arguments passed on the command line. + /// Pointer to the command-line arguments (array of C-style strings). + /// + /// The threading level required by the caller, which must be one of the MPI_THREAD_* + /// constants. + /// + /// + /// Returns the actual threading level that the MPI implementation is providing, which will be + /// one of the MPI_THREAD_* constants. + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Init_thread(ref int argc, ref byte **argv, int required, out int provided); + + /// + /// Determine whether the calling thread is the main MPI thread (that called + /// or . See . + /// + /// Returns whether the calling thread is the main thread. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Is_thread_main(out int flag); + + /// + /// Determine the level of threading support provided by the MPI library. + /// See . + /// + /// Returns one of the MPI_THREAD_* constants. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Query_thread(out int provided); + #endregion + + #region Predefined keys + /// + /// Predefined attribute key that can be used to determine the maximum + /// tag value that users are allowed to provide to a communication + /// request. + /// See . + /// + public const int MPI_TAG_UB = 0; + + /// + /// Predefined attribute key that can be used to determine the rank of + /// the host process associated with . + /// If there is no host, the result will be . + /// See . + /// + public const int MPI_HOST = 1; + + /// + /// Predefined attribute key that can be used to determine the rank of + /// the process than can perform I/O via the language-standard I/O + /// mechanism. If every process can provided language-standard I/O, the + /// resulting value will be ; if no process + /// can support language-standard I/O, the result will be + /// . + /// See . + /// + public const int MPI_IO = 2; + + /// + /// Predefined attribute key that can be used to determine whether the + /// clocks (accessed via ) are synchronized + /// across all processes. + /// See . + /// + public const int MPI_WTIME_IS_GLOBAL = 3; + #endregion + + /// + /// The maximum length of the string returned by . + /// + public const int MPI_MAX_PROCESSOR_NAME = OPAL_MAX_PROCESSOR_NAME ; + + /// + /// Retrieve the name of the processor or compute node that is currently executing. + /// See . + /// + /// + /// Pointer to an array of bytes that will, on return, contain the name of + /// the currenly executing processor. If the processor name requires more + /// than * ASCII characters, only the first + /// * characters will be written. To be sure that you + /// will always get the full processor name, should + /// refer to at least characters. + /// + /// + /// A pointer to the number of bytes in the processor name. On input, this is + /// the number of bytes that refers to. When this + /// function returns, this will point to the number of bytes in the actual name. + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Get_processor_name(byte[] name, ref int len); + + #region Error handling + /// + /// The maximum number of characters that can occur in an error string returned from + /// . + /// + public const int MPI_MAX_ERROR_STRING = OPAL_MAX_ERROR_STRING ; + + /// + /// Error value indicating no error. + /// + public const int MPI_SUCCESS = 0; + + /// + /// Error class indicating an invalid buffer pointer. + /// + public const int MPI_ERR_BUFFER = 1; + + /// + /// Error class indicating an invalid count argument. + /// + public const int MPI_ERR_COUNT = 2; + + /// + /// Error class indicating an invalid data type argument. + /// + public const int MPI_ERR_TYPE = 3; + + /// + /// Error class indicating an invalid tag argument. + /// + public const int MPI_ERR_TAG = 4; + + /// + /// Error class indicating an invalid communicator. + /// + public const int MPI_ERR_COMM = 5; + + /// + /// Error class indicating an invalid rank. + /// + public const int MPI_ERR_RANK = 6; + + /// + /// Error class indicating an invalid root. + /// + public const int MPI_ERR_ROOT = 8; + + /// + /// Error class indicating that a message was truncated on receive. + /// + public const int MPI_ERR_TRUNCATE = 15; + + /// + /// Error class indicating an invalid group argument. + /// + public const int MPI_ERR_GROUP = 9; + + /// + /// Error class indicating an invalid operation argument. + /// + public const int MPI_ERR_OP = 10; + + /// + /// Error class indicating an invalid request argument. + /// + public const int MPI_ERR_REQUEST = 7; + + /// + /// Error class indicating an invalid topology for a communicator argument. + /// + public const int MPI_ERR_TOPOLOGY = 11; + + /// + /// Error class indicating an invalid dimension argument (for cartesian communicators). + /// + public const int MPI_ERR_DIMS = 12; + + /// + /// Error class indicating an invalid argument. + /// + public const int MPI_ERR_ARG = 13; + + /// + /// Error class indicating an error that is know, but not described by other MPI + /// error classes. + /// + public const int MPI_ERR_OTHER = 16; + + /// + /// Error class indicating that an unkown error occurred. + /// + public const int MPI_ERR_UNKNOWN = 14; + + /// + /// Error class indicating that an internal error occurred in the MPI implementation. + /// + public const int MPI_ERR_INTERN = 17; + + /// + /// Error class indicating that the actual error code is in the status argument. + /// + public const int MPI_ERR_IN_STATUS = 18; + + /// + /// Error class indicating that a request is still pending. + /// + public const int MPI_ERR_PENDING = 19; + + /// + /// Error class indicating an invalid file handle argument. + /// + public const int MPI_ERR_FILE = 30; + + /// + /// Error class indicating that permission was denied when accessing a file. + /// + public const int MPI_ERR_ACCESS = 20; + + /// + /// Error class indicating that the amode argument passed to MPI_File_open is invalid. + /// + public const int MPI_ERR_AMODE = 21; + + /// + /// Error class indicating an invalid file name. + /// + public const int MPI_ERR_BAD_FILE = 23; + + /// + /// Error class indicating that the file already exists. + /// + public const int MPI_ERR_FILE_EXISTS = 28; + + /// + /// Error class indicating that the file is already in use. + /// + public const int MPI_ERR_FILE_IN_USE = 29; + + /// + /// Error class indicating that there is not enough space for the file. + /// + public const int MPI_ERR_NO_SPACE = 41; + + /// + /// Error class indicating that no such file exists. + /// + public const int MPI_ERR_NO_SUCH_FILE = 42; + + /// + /// Error class indicating an I/O error. + /// + public const int MPI_ERR_IO = 35; + + /// + /// Error class indicating that the file is read-only. + /// + public const int MPI_ERR_READ_ONLY = 45; + + /// + /// Error class indicating that an error occurred in a user-supplied data conversion function. + /// + public const int MPI_ERR_CONVERSION = 25; + + /// + /// Error class indicating that conversion functions could not be registered because a conversion + /// function has already been registered for this data representation identifier. + /// + public const int MPI_ERR_DUP_DATAREP = 27; + + /// + /// Error class indicating that an unsupported data representation was passed to MPI_FILE_SET_VIEW. + /// + public const int MPI_ERR_UNSUPPORTED_DATAREP = 51; + + /// + /// Error class indicating an invalid info argument. + /// + public const int MPI_ERR_INFO = 34; + + /// + /// Error class indicating an invalid info key. + /// + public const int MPI_ERR_INFO_KEY = 31; + + /// + /// Error class indicating an invalid info value. + /// + public const int MPI_ERR_INFO_VALUE = 33; + + /// + /// Error class indicating that the requested info key is not defined. + /// + public const int MPI_ERR_INFO_NOKEY = 32; + + /// + /// Error class indicating that an attempt has been made to look up a service + /// name that has not been published. + /// + public const int MPI_ERR_NAME = 38; + + /// + /// Error class indicating that no memory is available when trying to allocate + /// memory with MPI_Alloc_mem. + /// + public const int MPI_ERR_NO_MEM = 39; + + /// + /// Error class indicating that a collective argument is not the same on all processes, + /// or collective routines were called in a different order. + /// + public const int MPI_ERR_NOT_SAME = 40; + + /// + /// Error class indicating that a named port does not exist or has been closed. + /// + public const int MPI_ERR_PORT = 43; + + /// + /// Error class indicating that the user's quota has been exceeded. + /// + public const int MPI_ERR_QUOTA = 44; + + /// + /// Error class indicating that an attempt to unpublish a service + /// name that has already been unpublished or never was published. + /// + public const int MPI_ERR_SERVICE = 48; + + /// + /// Error class indicating that an attempt to spawn a process has failed. + /// + public const int MPI_ERR_SPAWN = 50; + + /// + /// Error class indicating that an operation is unsupported. + /// + public const int MPI_ERR_UNSUPPORTED_OPERATION = 52; + + /// + /// Error class indicating an invalid window argument. + /// + public const int MPI_ERR_WIN = 53; + + /// + /// Error class indicating an invalid base argument. + /// + public const int MPI_ERR_BASE = 24; + + /// + /// Error class indicating an invalid locktype argument. + /// + public const int MPI_ERR_LOCKTYPE = 37; + + /// + /// Error class indicating an invalid attribute key. + /// + public const int MPI_ERR_KEYVAL = 36; + + /// + /// Error class indicating that there were conflicting accesses within a window. + /// + public const int MPI_ERR_RMA_CONFLICT = 46; + + /// + /// Error class indicating that RMA calls were incorrectly synchronized. + /// + public const int MPI_ERR_RMA_SYNC = 47; + + /// + /// Error class indicating an invalid size argument. + /// + public const int MPI_ERR_SIZE = 49; + + /// + /// Error class indicating an invalid displacement argument. + /// + public const int MPI_ERR_DISP = 26; + + /// + /// Error class indicating an invalid assert argument. + /// + public const int MPI_ERR_ASSERT = 22; + + /// + /// The last valid error code for a predefined error class. + /// + public const int MPI_ERR_LASTCODE = 54; + + /// + /// Predefined error handler that indicates that the MPI program should be terminated + /// if an error occurs. This is the default error handler in the low-level MPI, which + /// is overridden by MPI.NET. + /// + public static readonly MPI_Errhandler MPI_ERRORS_ARE_FATAL = mpinet_MPI_ERRORS_ARE_FATAL(); + + /// + /// Predefined error handler that indicates that the MPI routine that detected an error + /// should return an error code. MPI.NET uses this error handler to translate MPI + /// errors into program exceptions. + /// + public static readonly MPI_Errhandler MPI_ERRORS_RETURN = mpinet_MPI_ERRORS_RETURN(); + + /// + /// Predefined error handler that represents "no" error handler. + /// + public static readonly MPI_Errhandler MPI_ERRHANDLER_NULL = mpinet_MPI_ERRHANDLER_NULL(); + + /// + /// Creates a new MPI error handler from a user function. Attaching this error handler + /// to a communicator will invoke the user error handler when an error occurs. + /// This feature is not supported in MPI.NET; instead, MPI.NET installs its own error + /// handler that translates MPI errors into .NET exceptions. + /// + /// The user's function. + /// The newly-created error handler. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Errhandler_create(IntPtr function, out MPI_Errhandler errhandler); + + /// + /// Set the error handler for a given communicator. This feature is not supported in MPI.NET; + /// instead, MPI.NET installs its own error handler that translates MPI errors into .NET exceptions. + /// + /// The communicator. + /// The error handler. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Errhandler_set(MPI_Comm comm, MPI_Errhandler errhandler); + + /// + /// Retrieve the error handler for a given communicator. This feature is not supported in MPI.NET; + /// instead, MPI.NET installs its own error handler that translates MPI errors into .NET exceptions. + /// + /// The communicator. + /// The error handler attached to the communicator. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Errhandler_get(MPI_Comm comm, out MPI_Errhandler errhandler); + + /// + /// Free a user-defined error handler that was created with . + /// This feature is not supported in MPI.NET; instead, MPI.NET installs its own error handler + /// that translates MPI errors into .NET exceptions. + /// + /// + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Errhandler_free(ref MPI_Errhandler errhandler); + + /// + /// Retrieves an error string corresponding to the given MPI error code. Used internally by + /// MPI.NET to provide an error string in MPI.NET exceptions. + /// + /// The error code. + /// Byte array that will be filled with a string describing the error. + /// Returns the number of elements placed into the buffer . + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Error_string(int errorcode, byte[] text, ref int resultlen); + + /// + /// Maps an MPI error code into an error class. Error classes describe (in general) what kind of + /// error occurred, and can be used to provide better information to the user. The MPI_ERR_* constants + /// give the various error classes present in MPI. Used internally by MPI.NET. + /// + /// The error code returned from MPI. + /// Set to the error class + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Error_class(int errorcode, out int errorclass); + #endregion + + #region Point-to-point communication + /// + /// Predefined value for the "source" parameter to MPI receive or probe operations, + /// which indicates that a message from any process may be matched. + /// See . + /// + public const int MPI_ANY_SOURCE = -1 ; + + /// + /// Predefined value for the "tag" parameter to MPI receive or probe operations, + /// which indicates that a message with any tag may be matched. + /// See . + /// + public const int MPI_ANY_TAG = -1 ; + + /// + /// Send a message to another process within the communicator. + /// See . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Send(IntPtr buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm); + + /// + /// Receive a message from another process within the communicator. + /// See . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Recv(IntPtr buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, out MPI_Status status); + + /// + /// Simultaneously send and receive a message from another process within the communicator. + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Sendrecv(IntPtr sendbuf, int sendcount, MPI_Datatype senddatatype, int dest, int sendtag, + IntPtr recvbuf, int recvcount, MPI_Datatype recvdatatype, int source, int recvtag, MPI_Comm comm, out MPI_Status status); + + /// + /// Determine whether a particular communication operation was cancelled. + /// See . + /// + /// Status object + /// Will be set to a non-zero value if the communnication was cancelled. + /// Error code. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Test_cancelled(ref MPI_Status status, out int flag); + + /// + /// Determine the number of elements transmitted by a communication operation. + /// See . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Get_count(ref MPI_Status status, MPI_Datatype datatype, out int count); + #endregion + + #region Predefined reduce operations + /// + /// Compute the maximum value via an MPI reduction operation. + /// See . + /// + public static readonly MPI_Op MPI_MAX = mpinet_MPI_MAX(); + + /// + /// Compute the minimum value via an MPI reduction operation. + /// See . + /// + public static readonly MPI_Op MPI_MIN = mpinet_MPI_MIN(); + + /// + /// Compute the sum via an MPI reduction operation. + /// See + /// + public static readonly MPI_Op MPI_SUM = mpinet_MPI_SUM(); + + /// + /// Compute the product via an MPI reduction operation. + /// See + /// + public static readonly MPI_Op MPI_PROD = mpinet_MPI_PROD(); + + /// + /// Compute the logical AND via an MPI reduction operation. + /// See + /// + public static readonly MPI_Op MPI_LAND = mpinet_MPI_LAND(); + + /// + /// Compute the bitwise AND via an MPI reduction operation. + /// See + /// + public static readonly MPI_Op MPI_BAND = mpinet_MPI_BAND(); + + /// + /// Compute the logical OR via an MPI reduction operation. + /// See + /// + public static readonly MPI_Op MPI_LOR = mpinet_MPI_LOR(); + + /// + /// Compute the bitwise OR via an MPI reduction operation. + /// See + /// + public static readonly MPI_Op MPI_BOR = mpinet_MPI_BOR(); + + /// + /// Compute the logical exclusive OR via an MPI reduction operation. + /// There is no high-level operation corresponding to this predefined + /// MPI reduction. + /// + public static readonly MPI_Op MPI_LXOR = mpinet_MPI_LXOR(); + + /// + /// Compute the bitwise exclusive OR via an MPI reduction operation. + /// See + /// + public static readonly MPI_Op MPI_BXOR = mpinet_MPI_BXOR(); + + /// + /// Compute the minimum value and location of that value via + /// an MPI reduction operation. There is no high-level operation + /// corresponding to this predefined MPI reduction. + /// + public static readonly MPI_Op MPI_MINLOC = mpinet_MPI_MINLOC(); + + /// + /// Compute the maximum value and location of that value via + /// an MPI reduction operation. There is no high-level operation + /// corresponding to this predefined MPI reduction. + /// + public static readonly MPI_Op MPI_MAXLOC = mpinet_MPI_MAXLOC(); + + /// + /// Placeholder operation that indicates "no operation". + /// + public static readonly MPI_Op MPI_OP_NULL = mpinet_MPI_OP_NULL(); + #endregion + + #region Non-blocking point-to-point communication + /// + /// Constant that indicates a "null" MPI request, meaning that there is no such request. + /// + public static readonly MPI_Request MPI_REQUEST_NULL = mpinet_MPI_REQUEST_NULL(); + + /// + /// An immediate (non-blocking) point-to-point send. + /// See . + /// + /// Buffer of data to send. + /// The number of elements in . + /// The type of data in . + /// Rank of the destination process. + /// Tag used to transmit this data. + /// Communicator through which this data will be sent. + /// Receives a request object that can be used to query this communication. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Isend(IntPtr buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, out MPI_Request request); + + /// + /// A non-blocking receive that posts the intent to receive a value. The actual receive will be + /// completed when the corresponding request is completed. + /// See . + /// + /// Buffer that will receive message data. + /// Number of elements in . + /// Type of data stored in . + /// Rank of the processor that will initiate this message, or . + /// Message tag used to identify the message, or . + /// Communicator through which the message will be sent. + /// Receives a request object that can be used to query this communication. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Irecv(IntPtr buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, out MPI_Request request); + + /// + /// Wait until the given request has completed. See . + /// + /// Request object. + /// Will receive the status of the completed operation. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Wait(ref MPI_Request request, out MPI_Status status); + + /// + /// Test whether the given request has completed. See . + /// + /// Request object. + /// Will be set to a non-zero value if the request has completed. + /// Will receive the status of the completed operation. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Test(ref MPI_Request request, out int flag, out MPI_Status status); + + /// + /// Free the resources associated with a request. + /// + /// The request that will be freed. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Request_free(ref MPI_Request request); + + /// + /// Waits until any of the given MPI requests completes before returning. + /// See . + /// + /// The number of requests in . + /// An array of MPI request objects. + /// Receives the index of the request that completed. + /// Receives the status of the completed request. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Waitany(int count, MPI_Request[] array_of_requests, out int index, out MPI_Status status); + + /// + /// Test whether any of the MPI requests has completed. + /// See . + /// + /// The number of requests in . + /// An array of MPI request objects. + /// Receives the index of the request that completed (if is non-zero). + /// Will be set to a non-zero value if a request has completed. + /// Receives the status of the completed request (if is non-zero). + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Testany(int count, MPI_Request[] array_of_requests, out int index, out int flag, out MPI_Status status); + + /// + /// Wait until all of the given MPI requests have completed before returning. + /// See . + /// + /// The number of requests (and statuses). + /// An array of MPI request objects to be completed. + /// An array of MPI status objects, to be filled in by the completed requests. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Waitall(int count, MPI_Request* array_of_requests, MPI_Status[] array_of_statuses); + + /// + /// Test whether all of the given MPI requests have been completed. + /// See . + /// + /// The number of requests (and statuses). + /// An array of MPI request objects to be completed. + /// Will be set to a non-zero value if all requests have completed. + /// An array of MPI status objects, to be filled in by the completed requests (if is non-zero). + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Testall(int count, MPI_Request* array_of_requests, out int flag, MPI_Status[] array_of_statuses); + + /// + /// Wait until some MPI requests have completed, then provide a list of all of the requests that have completed. + /// See . + /// + /// The number of requests in . + /// The array of requests to be completed. + /// Receives the number of requests that have been completed. + /// + /// An array that will receive the indices into of the + /// completed requests. + /// + /// + /// Array containing the completed status information that corresponds to the completed + /// requests whose indices are in . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Waitsome(int incount, MPI_Request[] array_of_requests, + out int outcount, int[] array_of_indices, MPI_Status[] array_of_statuses); + + /// + /// Providing a list of all of the requests that have completed, without waiting for any + /// requests to complete. See . + /// + /// The number of requests in . + /// The array of requests to be completed. + /// Receives the number of requests that have been completed. + /// + /// An array that will receive the indices into of the + /// completed requests. + /// + /// + /// Array containing the completed status information that corresponds to the completed + /// requests whose indices are in . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Testsome(int incount, MPI_Request[] array_of_requests, + out int outcount, int[] array_of_indices, MPI_Status[] array_of_statuses); + #endregion + + #region Probe and cancel + /// + /// Test whether a message is available. See . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Iprobe(int source, int tag, MPI_Comm comm, out int flag, out MPI_Status status); + + /// + /// Wait until a message is available. See . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Probe(int source, int tag, MPI_Comm comm, out MPI_Status status); + + /// + /// Cancel an outstanding MPI communication request. See . + /// + /// The request to be cancelled. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Cancel(ref MPI_Request request); + #endregion + + #region Environment Inquiry + /// + /// Returns a floating point number of seconds, since some time in the past + /// See . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern double MPI_Wtime(); + + /// + /// Returns a resolution of , in seconds. + /// See . + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern double MPI_Wtick(); + #endregion + + #region Collective communication + /// + /// Perform a parallel reduction operation that summarizes the results from the input provided + /// by all of the processes in the communicator. Semantically, this is equivalent to an + /// to an arbitrary root followed by an from + /// that process. + /// See + /// + /// + /// Buffer containing the "outgoing" values contributed by the calling process to the reduction operation. + /// + /// + /// Buffer that will receive the results of the parallel reduction. + /// + /// + /// The number of elements in and . + /// + /// + /// The type of data in and . + /// + /// + /// The MPI reduction operation to use, which may be one of the predefined reduction operations + /// or a user-defined operation created with . + /// + /// + /// The communicator over which the reduction will occur. + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Allreduce(IntPtr sendbuf, IntPtr recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm); + + /// + /// Gather the values provided by each process into an array containing the contributions of all + /// of the processes. This operation is equivalent to a to an arbitrary + /// root followed by an from that root. + /// See + /// + /// Buffer containing the values that will be sent from this process. + /// The number of elements to send. + /// The datatype describing the send buffer. + /// Buffer that will contain all of the values contributed by every process. + /// The number of elements to receive from each process. + /// The type of data that will be stored in the receive buffer. + /// The communicator over which data will be gathered. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Allgather(IntPtr sendbuf, int sendcount, MPI_Datatype sendtype, + IntPtr recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm); + + /// + /// Gather the values provided by each process into an array containing the contributions of all + /// of the processes. This operation differs from in that it + /// permits different processes to provide a different number of elements to be gathered. + /// See + /// + /// Buffer containing the values that will be sent from this process. + /// The number of elements to send. + /// The datatype describing the send buffer. + /// Buffer that will contain all of the values contributed by every process. + /// + /// An array whose ith element is the number of elements to be received from the process + /// with rank i. + /// + /// + /// An array whose ith element is the offset (in ) at which the + /// data from process i should be placed. + /// + /// The type of data that will be stored in the receive buffer. + /// The communicator over which data will be gathered. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Allgatherv(IntPtr sendbuf, int sendcount, MPI_Datatype sendtype, + IntPtr recvbuf, int[] recvcounts, int[] displs, MPI_Datatype recvtype, MPI_Comm comm); + + /// + /// Transmits data from every process in a communicator to every other process in the communicator. + /// Similar to , except that each process can send different data to + /// every other process. To send a different amount of data to each process, use + /// or . + /// See . + /// + /// + /// Buffer containing the data to send from this process. The ith position in this buffer + /// contains the data that will be sent to the process with rank i. + /// + /// The number of elements to send to each process. + /// The type of data stored in . + /// + /// Buffer that will receive data sent from other processes to this process. + /// + /// + /// The number of elements that will be received from each process. + /// + /// The type of data stored in . + /// The communicator used for collective communication. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Alltoall(IntPtr sendbuf, int sendcount, MPI_Datatype sendtype, + IntPtr recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm); + + /// + /// Transmits data from every process in a communicator to every other process in the communicator. + /// Similar to , except that each process can send different data to + /// every other process. If all of your processes send the same amount of data to each other, use + /// the simpler ; if you need the data sent to different processes to + /// have different datatypes, use . + /// See . + /// + /// + /// Buffer containing the data to send from this process. The ith position in this buffer + /// contains the data that will be sent to the process with rank i. + /// + /// + /// An array whose ith element contains the number of elements to be send to the process with + /// rank i. + /// + /// + /// An array whose ith element contains the offsets into where the + /// data destined for the process with rank i begins. + /// + /// The type of data in . + /// + /// Buffer that will receive data sent from other processes to this process. + /// + /// + /// An array whose jth element contains the number of elements that will be received from the + /// process with rank j. + /// + /// + /// An array whose jth element contains the offset into where the + /// data received from the process with rank j begins. + /// + /// The type of data in . + /// The communicator used for collective communication. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Alltoallv(IntPtr sendbuf, int[] sendcounts, int[] sdispls, MPI_Datatype sendtype, + IntPtr recvbuf, int[] recvcounts, int[] rdispls, MPI_Datatype recvtype, MPI_Comm comm); + + /// + /// Transmits data from every process in a communicator to every other process in the communicator. + /// Similar to , except that each process can send different data to + /// every other process. If all of your processes send the same amount of data to each other, use + /// the simpler ; if the volume of data sent to each process can be different + /// but all of the data has the same type, use . + /// See . + /// + /// + /// Buffer containing the data to send from this process. The ith position in this buffer + /// contains the data that will be sent to the process with rank i. + /// + /// + /// An array whose ith element contains the number of elements to be send to the process with + /// rank i. + /// + /// + /// An array whose ith element contains the offsets into where the + /// data destined for the process with rank i begins. + /// + /// + /// An array whose ith element contains the type of data that will be sent to rank i. + /// + /// + /// Buffer that will receive data sent from other processes to this process. + /// + /// + /// An array whose jth element contains the number of elements that will be received from the + /// process with rank j. + /// + /// + /// An array whose jth element contains the offset into where the + /// data received from the process with rank j begins. + /// + /// + /// An array whose jth element contains the type of data that will be received from the process + /// with rank j. + /// + /// The communicator used for collective communication. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Alltoallw(IntPtr sendbuf, int[] sendcnts, int[] sdispls, MPI_Datatype[] sendtypes, + IntPtr recvbuf, int[] recvcnts, int[] rdispls, MPI_Datatype[] recvtypes, MPI_Comm comm); + + /// + /// A synchronization barrier where no processor leaves the barrier until all processors have entered the barrier. + /// See . + /// + /// The communicator whose processes will be synchronized. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static extern int MPI_Barrier(MPI_Comm comm); + + /// + /// Broadcast a value from the root process to every process within the communication. + /// + /// See . + /// + /// + /// Pointer to the data that will be broadcast. At the root, this buffer will be + /// read; in all other processes, the buffer will be written. + /// + /// The number of elements that points to. + /// The type of data stored in the . + /// The rank of the root processor, from which the data will be broadcast. + /// The communicator over which the data will be transmitted. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Bcast(IntPtr buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm); + + /// + /// Performs a partial exclusive reduction on the data, returning the result from combining the data provided + /// by the first P-1 processes to the process with rank P. + /// See + /// + /// Buffer containing the data to contribute to the reduction. + /// Buffer that will receive the result of combining the first Rank values. + /// Number of values in and . + /// The type of data in and . + /// The reduction operation used to combine values. + /// The communicator over which the communication will occur. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Exscan(IntPtr sendbuf, IntPtr recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm); + + /// + /// Gather the values provided by each process into an array containing the contributions of all + /// of the processes. This routine differs from in that the results + /// are gathered to only the "root" process, which is identified by its + /// in the communicator. + /// See + /// + /// Buffer containing the values that will be sent from this process. + /// The number of elements to send. + /// The datatype describing the send buffer. + /// + /// Buffer that will contain all of the values contributed by every process. + /// This argument is only significant at the root. + /// + /// + /// The number of elements to receive from each process. + /// This argument is only significant at the root. + /// + /// + /// The type of data that will be stored in the receive buffer. + /// This argument is only significant at the root. + /// + /// The rank of the "root" process. + /// The communicator over which data will be gathered. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Gather(IntPtr sendbuf, int sendcount, MPI_Datatype sendtype, + IntPtr recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm); + + /// + /// Gather the values provided by each process into an array containing the contributions of all + /// of the processes. This routine differs from in that the results + /// are gathered to only the "root" process, which is identified by its + /// in the communicator. + /// See + /// + /// Buffer containing the values that will be sent from this process. + /// The number of elements to send. + /// The datatype describing the send buffer. + /// + /// Buffer that will contain all of the values contributed by every process. + /// This argument is only significant at the root. + /// + /// + /// An array whose ith element is the number of elements to receive from process i. + /// This argument is only significant at the root. + /// + /// + /// An array whose ith element contains the displacement (into ) at + /// which the data from process i will be placed. This argument is only significant at the root. + /// + /// + /// The type of data that will be stored in the receive buffer. + /// This argument is only significant at the root. + /// + /// The rank of the "root" process. + /// The communicator over which data will be gathered. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Gatherv(IntPtr sendbuf, int sendcount, MPI_Datatype sendtype, + IntPtr recvbuf, int[] recvcounts, int[] displs, MPI_Datatype recvtype, int root, MPI_Comm comm); + + /// + /// Perform a parallel reduction operation that summarizes the results from the data contributed + /// by all of the processes in a communicator. Unlike , the results + /// of this operation are returned only to the process whose rank is equivalent to + /// , i.e., the "root" process. + /// See + /// + /// + /// Buffer containing the "outgoing" values contributed by the calling process to the reduction operation. + /// + /// + /// Buffer that will receive the results of the parallel reduction. This argument is + /// only significant at the root. + /// + /// + /// The number of elements in and . + /// + /// + /// The type of data in and . + /// + /// + /// The MPI reduction operation to use, which may be one of the predefined reduction operations + /// or a user-defined operation created with . + /// + /// + /// Identifies the root process (which will receive the intermediate of the reduction) by + /// its rank in the communicator . + /// + /// + /// The communicator over which the reduction will occur. + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Reduce(IntPtr sendbuf, IntPtr recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm); + + /// + /// The equivalent of a followed by a , performing a + /// reduction on the data provided in and then scattering those results + /// to all of the processes. See . + /// + /// Buffer containing the data to be reduced. + /// Buffer that will receive this process's results. + /// + /// An array whose ith element gives the number of results that will go to the process with rank i. + /// + /// The type of data in and . + /// The operation used to combine each element in . + /// The communicator over which this collective will operate. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Reduce_scatter(IntPtr sendbuf, IntPtr recvbuf, int[] recvcounts, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm); + + /// + /// Performs a partial reduction on the data, returning the result from combining the data provided + /// by the first P processes to the process with rank P. + /// See + /// + /// Buffer containing the data to contribute to the reduction. + /// Buffer that will receive the result of combining the first Rank values. + /// Number of values in and . + /// The type of data in and . + /// The reduction operation used to combine values. + /// The communicator over which the communication will occur. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Scan(IntPtr sendbuf, IntPtr recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm); + + /// + /// Scatters data from one process (the "root" process) to all of the processes in a communicator, + /// with different parts of the data going to different processes. + /// See . + /// + /// + /// Buffer containing the data to be sent. Only significant at the root process. + /// + /// + /// The number of elements to send to each process. Only significant at the root process. + /// + /// + /// The type of data in . Only significant at the root process. + /// + /// A buffer that will receive the calling process's part of the data. + /// The number of elements to receive. + /// The type of data to receive. + /// The rank of the "root" process, which supplies the data. + /// The communicator over which the data will be scattered. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Scatter(IntPtr sendbuf, int sendcount, MPI_Datatype sendtype, + IntPtr recvbuf, int recvcount, MPI_Datatype rectype, int root, MPI_Comm comm); + + /// + /// Scatters data from one process (the "root" process) to all of the processes in a communicator, + /// with different parts of the data going to different processes. Unlike , + /// different processes may receive different amounts of data. + /// See . + /// + /// + /// Buffer containing the data to be sent. Only significant at the root process. + /// + /// + /// An array whose ith element contains the number of elements to send to process i. + /// Only significant at the root process. + /// + /// + /// An array whose ith element contains the offset (into ) + /// if the data to be sent to process i. Only significant at the root process. + /// + /// + /// The type of data in . Only significant at the root process. + /// + /// A buffer that will receive the calling process's part of the data. + /// The number of elements to receive. + /// The type of data to receive. + /// The rank of the "root" process, which supplies the data. + /// The communicator over which the data will be scattered. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Scatterv(IntPtr sendbuf, int[] sendcounts, int[] displs, MPI_Datatype sendtype, + IntPtr recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm); + + /// + /// Creates an MPI operation that invokes a user-provided function. The MPI operation + /// can be used with various reduction operations. MPI.NET provides support for user-defined + /// operations via the class. + /// + /// A pointer to the user-defined function. + /// Whether this function is commutative. + /// Receives the newly-created MPI operation. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Op_create(MPI_User_function function, int commute, out MPI_Op op); + + /// + /// Frees an MPI operation created via . MPI.NET will automatically + /// manage any operations it creates via when the corresponding + /// object is disposed of or finalized. + /// + /// The operation to be freed. + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static unsafe extern int MPI_Op_free(ref MPI_Op op); + #endregion + + #region Memory allocator + /// + /// Attempts to allocate (unmanaged) memory from MPI. This memory must be + /// manually freed with a call to . + /// This routine is used automatically by the to + /// allocate memory when serializing or de-serializing objects within MPI.NET. + /// + /// The number of bytes to allocate. + /// + /// Provides extra information to the MPI implementation that may + /// help it allocate memory for a specific reason or from a specific + /// memory pool. + /// + /// + /// Will receive a pointer to the newly-allocated memory. + /// + /// + /// if memory is successfully allocated, + /// if no memory is available. + /// + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static extern unsafe int MPI_Alloc_mem(MPI_Aint size, MPI_Info info, out IntPtr baseptr); + + /// + /// Frees memory allocated with . + /// This routine is used automatically by the to + /// allocate memory when serializing or de-serializing objects within MPI.NET. + /// + /// The pointer provided by . + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static extern unsafe int MPI_Free_mem(IntPtr ptr); + #endregion + + #region Helper operations and classes + /// + /// Converts the intermediate of an MPI_*_compare operation into a enum value. + /// + public static Comparison ComparisonFromInt(int result) + { + switch (result) + { + case MPI_IDENT: + return Comparison.Identical; + + case MPI_CONGRUENT: + return Comparison.Congruent; + + case MPI_SIMILAR: + return Comparison.Similar; + + case MPI_UNEQUAL: + return Comparison.Unequal; + + default: + throw new InvalidOperationException("MPI internal error: Invalid comparison result"); + } + } + #endregion + + #region Process Management +#if PROCESS_CREATION_PRESENT + + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static extern unsafe int MPI_Comm_spawn(byte* command, byte** argv, int maxprocs, MPI_Info info, int root, MPI_Comm comm, out MPI_Comm intercomm, out int[] array_of_errorcodes); + + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static extern unsafe int MPI_Comm_spawn(byte* command, byte** argv, int maxprocs, MPI_Info info, int root, MPI_Comm comm, out MPI_Comm intercomm, int* array_of_errorcodes); + + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static extern unsafe int MPI_Comm_get_parent(out MPI_Comm comm); + + [DllImport(MPI_DLL, CallingConvention = CallingConvention.StdCall)] + public static extern unsafe int MPI_Comm_spawn_multiple(int count, ref byte* array_of_commands, ref byte** array_of_argv, ref int array_of_maxprocs, ref MPI_Info array_of_info, int root, MPI_Comm comm, out MPI_Comm intercomm, out int array_of_errorcodes); + + + //public byte** MPI_ARGV_NULL = (byte**)0; + //public byte** MPI_ARGVS_NULL = (byte**)0; + //public int* MPI_ERRCODES_IGNORE = (int*)0; +#endif + #endregion + + // CBridge Customizations Follow + [DllImport("mpinet")] public static unsafe extern MPI_Comm mpinet_MPI_COMM_WORLD(); + + [DllImport("mpinet")] public static unsafe extern MPI_Comm mpinet_MPI_COMM_SELF(); + + [DllImport("mpinet")] public static unsafe extern MPI_Comm mpinet_MPI_COMM_NULL(); + + [DllImport("mpinet")] public static unsafe extern MPI_Datatype mpinet_MPI_CHAR(); + + [DllImport("mpinet")] public static unsafe extern MPI_Datatype mpinet_MPI_SIGNED_CHAR(); + + [DllImport("mpinet")] public static unsafe extern MPI_Datatype mpinet_MPI_UNSIGNED_CHAR(); + + [DllImport("mpinet")] public static unsafe extern MPI_Datatype mpinet_MPI_BYTE(); + + [DllImport("mpinet")] public static unsafe extern MPI_Datatype mpinet_MPI_WCHAR(); + + [DllImport("mpinet")] public static unsafe extern MPI_Datatype mpinet_MPI_SHORT(); + + [DllImport("mpinet")] public static unsafe extern MPI_Datatype mpinet_MPI_UNSIGNED_SHORT(); + + [DllImport("mpinet")] public static unsafe extern MPI_Datatype mpinet_MPI_INT(); + + [DllImport("mpinet")] public static unsafe extern MPI_Datatype mpinet_MPI_UNSIGNED(); + + [DllImport("mpinet")] public static unsafe extern MPI_Datatype mpinet_MPI_LONG(); + + [DllImport("mpinet")] public static unsafe extern MPI_Datatype mpinet_MPI_UNSIGNED_LONG(); + + [DllImport("mpinet")] public static unsafe extern MPI_Datatype mpinet_MPI_FLOAT(); + + [DllImport("mpinet")] public static unsafe extern MPI_Datatype mpinet_MPI_DOUBLE(); + + [DllImport("mpinet")] public static unsafe extern MPI_Datatype mpinet_MPI_LONG_DOUBLE(); + + [DllImport("mpinet")] public static unsafe extern MPI_Datatype mpinet_MPI_LONG_LONG_INT(); + + [DllImport("mpinet")] public static unsafe extern MPI_Datatype mpinet_MPI_UNSIGNED_LONG_LONG(); + + [DllImport("mpinet")] public static unsafe extern MPI_Datatype mpinet_MPI_LONG_LONG(); + + [DllImport("mpinet")] public static unsafe extern MPI_Datatype mpinet_MPI_PACKED(); + + [DllImport("mpinet")] public static unsafe extern MPI_Datatype mpinet_MPI_DATATYPE_NULL(); + + [DllImport("mpinet")] public static unsafe extern MPI_Group mpinet_MPI_GROUP_EMPTY(); + + [DllImport("mpinet")] public static unsafe extern MPI_Group mpinet_MPI_GROUP_NULL(); + + [DllImport("mpinet")] public static unsafe extern MPI_Info mpinet_MPI_INFO_NULL(); + + [DllImport("mpinet")] public static unsafe extern MPI_Copy_function mpinet_MPI_NULL_COPY_FN(); + + [DllImport("mpinet")] public static unsafe extern MPI_Delete_function mpinet_MPI_NULL_DELETE_FN(); + + [DllImport("mpinet")] public static unsafe extern MPI_Errhandler mpinet_MPI_ERRORS_ARE_FATAL(); + + [DllImport("mpinet")] public static unsafe extern MPI_Errhandler mpinet_MPI_ERRORS_RETURN(); + + [DllImport("mpinet")] public static unsafe extern MPI_Errhandler mpinet_MPI_ERRHANDLER_NULL(); + + [DllImport("mpinet")] public static unsafe extern MPI_Op mpinet_MPI_MAX(); + + [DllImport("mpinet")] public static unsafe extern MPI_Op mpinet_MPI_MIN(); + + [DllImport("mpinet")] public static unsafe extern MPI_Op mpinet_MPI_SUM(); + + [DllImport("mpinet")] public static unsafe extern MPI_Op mpinet_MPI_PROD(); + + [DllImport("mpinet")] public static unsafe extern MPI_Op mpinet_MPI_LAND(); + + [DllImport("mpinet")] public static unsafe extern MPI_Op mpinet_MPI_BAND(); + + [DllImport("mpinet")] public static unsafe extern MPI_Op mpinet_MPI_LOR(); + + [DllImport("mpinet")] public static unsafe extern MPI_Op mpinet_MPI_BOR(); + + [DllImport("mpinet")] public static unsafe extern MPI_Op mpinet_MPI_LXOR(); + + [DllImport("mpinet")] public static unsafe extern MPI_Op mpinet_MPI_BXOR(); + + [DllImport("mpinet")] public static unsafe extern MPI_Op mpinet_MPI_MINLOC(); + + [DllImport("mpinet")] public static unsafe extern MPI_Op mpinet_MPI_MAXLOC(); + + [DllImport("mpinet")] public static unsafe extern MPI_Op mpinet_MPI_OP_NULL(); + + [DllImport("mpinet")] public static unsafe extern MPI_Request mpinet_MPI_REQUEST_NULL(); + + } +} diff --git a/MPI/cbridge.c b/MPI/cbridge.c new file mode 100644 index 0000000..abe1b6c --- /dev/null +++ b/MPI/cbridge.c @@ -0,0 +1,58 @@ +/* Copyright (C) 2007, 2008 The Trustees of Indiana University + * + * Use, modification and distribution is subject to the Boost Software + * License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * This file was automatically generated from Unsafe.cs by Unsafe.pl. + * Edit at your own risk. + * + * Authors: Douglas Gregor + * Andrew Lumsdaine + */ +#include + +MPI_Comm mpinet_MPI_COMM_WORLD() { return MPI_COMM_WORLD; } +MPI_Comm mpinet_MPI_COMM_SELF() { return MPI_COMM_SELF; } +MPI_Comm mpinet_MPI_COMM_NULL() { return MPI_COMM_NULL; } +MPI_Datatype mpinet_MPI_CHAR() { return MPI_CHAR; } +MPI_Datatype mpinet_MPI_SIGNED_CHAR() { return MPI_SIGNED_CHAR; } +MPI_Datatype mpinet_MPI_UNSIGNED_CHAR() { return MPI_UNSIGNED_CHAR; } +MPI_Datatype mpinet_MPI_BYTE() { return MPI_BYTE; } +MPI_Datatype mpinet_MPI_WCHAR() { return MPI_WCHAR; } +MPI_Datatype mpinet_MPI_SHORT() { return MPI_SHORT; } +MPI_Datatype mpinet_MPI_UNSIGNED_SHORT() { return MPI_UNSIGNED_SHORT; } +MPI_Datatype mpinet_MPI_INT() { return MPI_INT; } +MPI_Datatype mpinet_MPI_UNSIGNED() { return MPI_UNSIGNED; } +MPI_Datatype mpinet_MPI_LONG() { return MPI_LONG; } +MPI_Datatype mpinet_MPI_UNSIGNED_LONG() { return MPI_UNSIGNED_LONG; } +MPI_Datatype mpinet_MPI_FLOAT() { return MPI_FLOAT; } +MPI_Datatype mpinet_MPI_DOUBLE() { return MPI_DOUBLE; } +MPI_Datatype mpinet_MPI_LONG_DOUBLE() { return MPI_LONG_DOUBLE; } +MPI_Datatype mpinet_MPI_LONG_LONG_INT() { return MPI_LONG_LONG_INT; } +MPI_Datatype mpinet_MPI_UNSIGNED_LONG_LONG() { return MPI_UNSIGNED_LONG_LONG; } +MPI_Datatype mpinet_MPI_LONG_LONG() { return MPI_LONG_LONG; } +MPI_Datatype mpinet_MPI_PACKED() { return MPI_PACKED; } +MPI_Datatype mpinet_MPI_DATATYPE_NULL() { return MPI_DATATYPE_NULL; } +MPI_Group mpinet_MPI_GROUP_EMPTY() { return MPI_GROUP_EMPTY; } +MPI_Group mpinet_MPI_GROUP_NULL() { return MPI_GROUP_NULL; } +MPI_Info mpinet_MPI_INFO_NULL() { return MPI_INFO_NULL; } +MPI_Copy_function * mpinet_MPI_NULL_COPY_FN() { return MPI_NULL_COPY_FN; } +MPI_Delete_function * mpinet_MPI_NULL_DELETE_FN() { return MPI_NULL_DELETE_FN; } +MPI_Errhandler mpinet_MPI_ERRORS_ARE_FATAL() { return MPI_ERRORS_ARE_FATAL; } +MPI_Errhandler mpinet_MPI_ERRORS_RETURN() { return MPI_ERRORS_RETURN; } +MPI_Errhandler mpinet_MPI_ERRHANDLER_NULL() { return MPI_ERRHANDLER_NULL; } +MPI_Op mpinet_MPI_MAX() { return MPI_MAX; } +MPI_Op mpinet_MPI_MIN() { return MPI_MIN; } +MPI_Op mpinet_MPI_SUM() { return MPI_SUM; } +MPI_Op mpinet_MPI_PROD() { return MPI_PROD; } +MPI_Op mpinet_MPI_LAND() { return MPI_LAND; } +MPI_Op mpinet_MPI_BAND() { return MPI_BAND; } +MPI_Op mpinet_MPI_LOR() { return MPI_LOR; } +MPI_Op mpinet_MPI_BOR() { return MPI_BOR; } +MPI_Op mpinet_MPI_LXOR() { return MPI_LXOR; } +MPI_Op mpinet_MPI_BXOR() { return MPI_BXOR; } +MPI_Op mpinet_MPI_MINLOC() { return MPI_MINLOC; } +MPI_Op mpinet_MPI_MAXLOC() { return MPI_MAXLOC; } +MPI_Op mpinet_MPI_OP_NULL() { return MPI_OP_NULL; } +MPI_Request mpinet_MPI_REQUEST_NULL() { return MPI_REQUEST_NULL; }