// URI: bk://mpib.bkbits.net/mpib-dev
// SIDL interface for MPI
// MPIB is a language independent binding for the MPI standard interface.
// It allows a user to compile once with the client binding in the language
// of choice, and then dynamically load different implementations using the
// SIDL loading mechanism.
// We are shooting for a full implementation of MPI 1.2, but there are a few things missing:
// ------------------------------------------------------------------------------------------------
// Missing Feature | Reason
// ------------------------------------------------------------------------------------------------
// Communicator topologies | Laziness
// Buffered communication | Need some representation of the buffer (use SIDL arrays?)
// Convert error handling to exceptions | Laziness
// MPI user operators | Must locate a C binding to the submitted SIDL interface
// All I/O functions | Probably belong in a separate MPI-IO package
// ------------------------------------------------------------------------------------------------
package MPIB {
    // This default implementation is provided with MPIB. It allows the
    // user to build with any MPI implementation having a conforming C binding.
    //
    // Note that all classes which represent opaque MPI objects implement the
    // AccessOpauqe interface, so that the underlying object may be retrieved.
    package
Default {
        class
Base implements MPIB.Base {}
        class Object implements MPIB.Object {}
        class DefaultComms extends ObjectimplementsDefaultComms {}
        class Comm extends ObjectimplementsMPIB.Comm, MPIB.AccessOpaque {}
        class DefaultDatatypes extends ObjectimplementsDefaultDatatypes {}
        class Datatype extends ObjectimplementsMPIB.Datatype, MPIB.AccessOpaque {}
        class DefaultGroups extends ObjectimplementsDefaultGroups {}
        class Group extends ObjectimplementsMPIB.Group, MPIB.AccessOpaque {}
        class DefaultOps extends ObjectimplementsDefaultOps {}
        class Op extends ObjectimplementsMPIB.Op, MPIB.AccessOpaque {}
        class CollectiveRequests extends ObjectimplementsMPIB.CollectiveRequests {}
        class Request extends ObjectimplementsMPIB.Request, MPIB.AccessOpaque {}
        class Status extends ObjectimplementsMPIB.Status, MPIB.AccessOpaque {}
        class Info extends ObjectimplementsMPIB.Info, MPIB.AccessOpaque {}
    }
    // The opaque MPI objects of two components are from different MPIs
    class Incompatible extends SIDL.BaseException {}
    // The given key was not found
    class KeyError extends SIDL.BaseException {}
    // Possible results of opaque object comparison
    enum CompareResult {IDENT, CONGRUENT, SIMILAR, UNEQUAL};
    // The Base interface is intended to encapsulate the state of a
    // running MPI implementation. All the static data and methods
    // now belong to Base, so that we might have several different
    // MPI implementations running at once.
    interface
Base extends SIDL.ProjectState {
        stringGet_processor_name();
        void
Get_version(out int ver, out int subver);
        int
Keyval_create(in opaque extra_state);
        void
Keyval_free(in int key_val);
        double
Wtime();
        double
Wtick();
        
DefaultCommscomm();
        
DefaultDatatypesdatatype();
        
DefaultGroupsgroup();
        
DefaultOpsop();
        
CollectiveRequestsrequest();
        int
ANY_SOURCE();
        int
ANY_TAG();
        int
PROC_NULL();
        string
getCompareResultString(in CompareResult value);
    }
    // This is the base interface for any opaque object in MPI. It provides
    // a way to retrieve the "implementation" context from any object.
    interface Object {
        
BasegetBase();
        void
setBase(in Base base);
    }
    // The default communicators provided by MPI
    interface DefaultComms extends Object {
        CommSELF();
        
CommWORLD();
    }
    // The Comm interface replaces MPI_Comm
    interface
Comm extends Object {
        intsize();
        int
rank();
        
CompareResultcompare(in Comm comm2);
        stringget_name();
        void
set_name(in string name);
        void
Barrier();
        
Commdup();
        void
Send(in opaque data, in int count, in Datatype dtype, inint dest, inint tag);
        RequestSend_init(in opaque data, in int count, in Datatype dtype, inint dest, inint tag);
        voidSsend(in opaque data, in int count, in Datatype dtype, inint dest, inint tag);
        RequestSsend_init(in opaque data, in int count, in Datatype dtype, inint dest, inint tag);
        voidRsend(in opaque data, in int count, in Datatype dtype, inint dest, inint tag);
        RequestRsend_init(in opaque data, in int count, in Datatype dtype, inint dest, inint tag);
        RequestIsend(in opaque data, in int count, in Datatype dtype, inint dest, inint tag);
        RequestIrsend(in opaque data, in int count, in Datatype dtype, inint dest, inint tag);
        RequestIssend(in opaque data, in int count, in Datatype dtype, inint dest, inint tag);
        StatusSendrecv(in opaque data, in int count, in Datatype dtype, inint dest, inint tag, inopaque rdata, inint rcount, inDatatype rdtype, inint rsrc, inint rtag);
        StatusSendrecv_replace(in opaque data, in int count, in Datatype dtype, inint dest, inint tag, inint rsrc, inint rtag);
        StatusRecv(in opaque data, in int count, in Datatype dtype, inint src, inint tag);
        RequestIrecv(in opaque data, in int count, in Datatype dtype, inint src, inint tag);
        RequestRecv_init(in opaque data, in int count, in Datatype dtype, inint src, inint tag);
        voidPack(in opaque data, in int count, in Datatype dtype, inopaque output, inint outcount, inoutint position);
        voidUnpack(in opaque data, in int count, inout int position, in opaque output, in int outcount, in Datatype dtype);
        intPack_size(in int count, in Datatype dtype);
        voidGather(in opaque sendbuf, in int sendcount, in Datatype sendtype, inopaque recvbuf, inint recvcount, inDatatype recvtype, inint root);
        voidGatherv(in opaque sendbuf, in int sendcount, in Datatype sendtype, inopaque recvbuf, in array<int> recvcounts, in array<int> displs, inDatatype recvtype, inint root);
        voidAllgather(in opaque sendbuf, in int sendcount, in Datatype sendtype, inopaque recvbuf, inint recvcount, inDatatype recvtype);
        voidAllgatherv(in opaque sendbuf, in int sendcount, in Datatype sendtype, inopaque recvbuf, in array<int> recvcounts, in array<int> displs, inDatatype recvtype);
        voidAlltoall(in opaque sendbuf, in int sendcount, in Datatype sendtype, inopaque recvbuf, inint recvcount, inDatatype recvtype);
        voidAlltoallv(in opaque sendbuf, in array<int> sendcounts, in array<int> sdispls, in Datatype sendtype, inopaque recvbuf, in array<int> recvcounts, in array<int> rdispls, inDatatype recvtype);
        voidScatter(in opaque sendbuf, in int sendcount, in Datatype sendtype, inopaque recvbuf, inint recvcount, inDatatype recvtype, inint root);
        voidScatterv(in opaque sendbuf, in array<int> sendcount, in array<int> displs, in Datatype sendtype, inopaque recvbuf, inint recvcount, inDatatype recvtype, inint root);
        voidAllreduce(in opaque sendbuf, in opaque recvbuf, in int count, in Datatype datatype, inOp op);
        voidReduce(in opaque sendbuf, in opaque recvbuf, in int count, in Datatype datatype, inOp op, inint root);
        voidReduce_scatter(in opaque sendbuf, in opaque recvbuf, in array<int> recvcounts, in Datatype datatype, inOp op);
        voidScan(in opaque sendbuf, in opaque recvbuf, in int count, in Datatype datatype, inOp op);
        voidAttr_delete(in int keyval);
        opaque
Attr_get(in int keyval, out bool flag);
        opaque
Attr_put(in int keyval, in opaque attr_value);
        void
Bcast(in opaque buffer, in int count, in Datatype datatype, inint root);
        Groupgroup();
        
Groupremote_group();
        int
remote_size();
        
Commsplit(in int color, in int key);
        bool
test_inter();
        bool
Iprobe(in int source, in int tag, out Status status);
        StatusProbe(in int source, in int tag);
        void
Abort(in int errorcode);
        
Commcreate(in Group group);
        CommIntercomm_create(in int local_leader, in Comm peer_comm, inint remote_leader, inint tag);
        CommIntercomm_merge(in int high);
        void
Send_char(in array<char> data, in int dest, in int tag);
        void
Send_int(in array<int> data, in int dest, in int tag);
        void
Send_double(in array<double> data, in int dest, in int tag);
        void
Send_dcomplex(in array<dcomplex> data, in int dest, in int tag);
        
StatusRecv_char(inout array<char> data, in int src, in int tag);
        
StatusRecv_int(inout array<int> data, in int src, in int tag);
        
StatusRecv_double(inout array<double> data, in int src, in int tag);
        
StatusRecv_dcomplex(inout array<dcomplex> data, in int src, in int tag);
        void
Bcast_char(inout array<char> data, in int root);
        void
Bcast_int(inout array<int> data, in int root);
        void
Bcast_double(inout array<double> data, in int root);
        void
Bcast_dcomplex(inout array<dcomplex> data, in int root);
    }
    // The default data types provided by MPI
    interface
DefaultDatatypes extends Object {
        DatatypeINT();
        
DatatypeDOUBLE();
        
DatatypeSTRING();
        
DatatypeSHORT();
        
DatatypeLONG();
        
DatatypeLONGLONG();
        
DatatypeFLOAT();
        
DatatypeCOMPLEX();
        
DatatypeDCOMPLEX();
        
DatatypePACKED();
        void
commit(in Datatype dtype);
        voidfree(in Datatype dtype);
        Datatypecontiguous(in int count, in Datatype dtype);
        Datatypedarray(in int size, in int rank, in int ndims, in array<int> gsizes, in array<int> distribs, in array<int> dargs, in array<int> psizes, in int order, in Datatype dtype);
        Datatypehindexed(in int count, in array<int> blocklens, in array<long> indices, in Datatype dtype);
        Datatypehvector(in int count, in int blocklen, in long stride, in Datatype dtype);
        Datatypeindexed(in int count, in array<int> blocklens, in array<int> indices, in Datatype dtype);
        Datatypeindexed_block(in int count, in int blocklen, in array<int> displacements, in Datatype dtype);
        Datatypestructure(in int count, in array<int> blocklens, in array<long> indices, in array<Datatype> dtypes);
        Datatypesubarray(in int ndims, in array<int> sizes, in array<int> subsizes, in array<int> starts, in int order, in Datatype dtype);
        Datatypevector(in int count, in int blocklen, in int stride, in Datatype dtype);
    }
    // The Datatype interface replaces MPI_Datatype
    interface Datatype extends Object {
        intsize();
        long
extent();
        void
get_contents(out array<int> integers, out array<long> addresses, out array<Datatype> datatypes);
    }
    // The default groups provided by MPI
    interface DefaultGroups extends Object {
        GroupEMPTY();
    }
    // The Group interface replaces MPI_Group
    interface
Group extends Object {
        CompareResultcompare(in Group group2);
        Groupdifference(in Group group2);
        Groupexcl(in array<int> ranks);
        
Groupincl(in array<int> ranks);
        
Grouprange_excl(in array<int, 2> ranks);
        
Grouprange_incl(in array<int, 2> ranks);
        
Groupintersection(in Group group2);
        Groupunionc(in Group group2);
        intrank();
        int
size();
        array<int>
translate(in array<int> ranks, in Group group2);
    }
    // The default operators provided by MPI
    interface DefaultOps extends Object {
        OpSUM();
        
OpMAX();
        
OpMIN();
        
OpPROD();
        
OpLAND();
        
OpBAND();
        
OpLOR();
        
OpBOR();
        
OpLXOR();
        
OpBXOR();
        
OpMINLOC();
        
OpMAXLOC();
    }
    // The Op interface replaces MPI_Op
    interface
Op extends Object {}
    interface CollectiveRequests extends Object {
        voidStartall(in array<Request> requests);
        boolTestall(in array<Request> requests, out array<Status> statuses);
        voidTestsome(in array<Request> requests, out array<int> indices, out array<Status> statuses);
        boolTestany(in array<Request> requests, outint index, outStatus status);
        voidWaitall(in array<Request> requests, out array<Status> statuses);
        voidWaitany(in array<Request> requests, outint index, outStatus status);
        voidWaitsome(in array<Request> requests, out array<int> indices, out array<Status> statuses);
    }
    // The Request interface replaces MPI_Request
    interface Request extends Object {
        voidCancel();
        void
Start();
        bool
Test(out Status status);
        StatusWait();
    }
    // The Status interface replaces MPI_Status
    interface
Status extends Object {
        intGet_count(in Datatype dtype);
        intGet_elements(in Datatype dtype);
        voidset_elements(in Datatype dtype, inint count);
        intGet_source();
        int
Get_tag();
        bool
Test_cancelled();
        void
set_cancelled(in bool isCancelled);
    }
    // The Info interface replaces MPI_Info
    interface
Info extends Object {
        voiddelete_key(in string key);
        
Infodup();
        string
get(in string key) throws KeyError;
        intget_nkeys();
        string
get_nthkey(in int n);
        void
set(in string key, in string value);
    }
    // If components use legacy code which requires the raw MPI objects, they can
    // cast the various MPIB objects to the AccessOpaque interface and then extract
    // out the underlying MPI object.
    //
    // WARNING: The legacy code MUST be compiled with exactly the same version of MPI as MPIB.
    interface
AccessOpaque {
        opaque
getOpaque() throws Incompatible;
        voidsetOpaque(in opaque value) throws Incompatible;
    }
}