Files
2017-10-26 19:57:24 +02:00

681 lines
18 KiB
C
Executable File

#ifndef MOC_H_
#define MOC_H_
#include <stdint.h>
#include "moc_datatype.h"
#include "moc_error_codes.h"
/**
* Indicates, in a receive, to accept a message with any tag value.
**/
#define MOC_ANY_TAG 1000
/**
* Reserved Tag for Broadcast-Messages (MOC_Bcast).
**/
#define MOC_BCAST_TAG 250
/**
* Specifies a rank that can be used to send or receive from no-one.
**/
#define MOC_PROC_NULL 1000
/**
* Indicates, in a receive, to accept a message from any source.
**/
#define MOC_ANY_SOURCE 1001
/**
* Maximum byte-count which can be transferred by one DMA-transfer.
**/
#define MAX_DMA_CALL_SIZE 16384
/**
* Maximum byte-count of a MOC-message. It's only the theoretical size, because
* practically the SPU's local-stores can only hold much fewer bytes.
**/
#define MAX_MOC_MESSAGE_SIZE 16777215
/**
* \internal
* \addtogroup internal_p2p_imm
**/
//@{
/**
* \internal
* @name Possible structures for MOC_Request.request_data.
**/
//@{
/**
* \internal
* Struct with information about a non-blocking DMA-Communication.
**/
typedef struct imoc_dma_request_struct
{
char *buffer;
void *target;
uint32_t size;
uint32_t remainder;
uint32_t dest;
uint32_t tag_id;
} imoc_dma_request;
/**
* \internal
* Struct with information about a non-blocking ISsend-Communication.
**/
typedef struct imoc_issend_request_struct
{
uint8_t mid;
uint8_t isFinished;
uint8_t source;
uint8_t tag;
uint32_t message_size;
} imoc_issend_request;
//@}
//@}
/**
* \addtogroup environment_error
*
* This section describes how errors are handled.
*
* Every function should return an integer if possible. This integer should be
* MOC_SUCCESS if the operation teminated successfully otherwise an error-code
* telling the reason of the error is returned.
**/
//@{
/**
* Maximal length of error-text.
**/
#define MOC_MAX_ERROR_STRING 255
/**
* Returns an error-text for a given error code.
*
* The error-text is already terminated by '\\0'.
*
* \param errorcode \b in Error code returned by an MPI routine
* \param string \b out Text that corresponds to the errorcode
* \param resultlen \b out Length of string
* \retval MOC_SUCCESS No error; MPI routine completed successfully.
* \retval MOC_ERR_ARG Invalid argument. Most likely an error-code out of range.
**/
int MOC_Error_string ( int errorcode, char *string, int *resultlen );
/**
* Converts an error code into an error class.
*
* \param errorcode \b in Error code returned by an MPI routine
* \param errorclass \b out Error class associated with errorcode
* \retval MOC_SUCCESS No error; MPI routine completed successfully.
* \retval MOC_ERR_COMM Invalid argument. Most likely an error-code out of range.
**/
int MOC_Error_class ( int errorcode, int *errorclass );
//@}
/**
* \addtogroup environment_information
*
* Functions to return some information about the execution environment and
* the MOC-implementation.
**/
//@{
/**
* Major version-number of this MOC-Implementation
**/
#define MOC_VERSION 0
/**
* Minor version-number of this MOC-Implementation
**/
#define MOC_SUBVERSION 9
/**
* The maximum length of the string returned by MOC_Get_processor_name.
**/
#define MOC_MAX_PROCESSOR_NAME 4
/**
* Gets the name of the processor.
*
* \note This function returns "SPU" if the calling process is running on a SPU otherwise
* it's running on the "PPU".
*
* \param name \b out Specifies the processor-type the calling process is runnning on
* \param resultlen \b out Length (in characters) of the name
* \retval MOC_SUCCESS No error; MPI routine completed successfully.
**/
int MOC_Get_processor_name ( char *name, int *resultlen);
/**
* Returns the major and minor version of this MOC-implementation.
*
* \note Can be called before MOC_Init and after MOC_Finalize.
*
* @param version \b out Major version of this MOC-implementation
* @param subversion \b out Minor version of this MOC-implementation
* @retval MOC_SUCCESS Function returned successfully
**/
int MOC_Get_version(int *version, int *subversion);
//@}
/**
* \addtogroup environment_startup
**/
//@{
/**
* @name PPU & SPU
**/
//@{
/**
* Terminates MPI execution environment.
*
* \note All processes must call this routine before exiting.
*
* \retval MOC_SUCCESS No error; MPI routine completed successfully.
**/
int MOC_Finalize (void);
//@}
//@}
/**
* \addtogroup p2p_status
*
* Receiving operations return a status-object holding information about
* the message.
*
* There are three Fields of the status-Struct which are predefined by the MPI-Standard:
* MOC_SOURCE gives the message-source, MOC_TAG gives the message-tag and MOC_ERROR gives
* an error-code (not implemented by MOC at the moment). To get the number of element the
* function \ref MOC_Get_count should be used.
**/
//@{
/**
* Structure holding information about a received message.
**/
typedef struct MOC_Status_struct
{
uint8_t MOC_SOURCE; /**< message-source */
uint8_t MOC_TAG; /**< message-tag */
int MOC_ERROR; /**< error-code */
int message_size; /**< message-size in byte (internal-variable) */
uint8_t mid; /**< message-ID (internal-variable) */
} MOC_Status; /**< */
/**
* Gets the number of received elements which is encoded in MOC_Status.
*
* @param status \b in status-object
* @param datatype \b in Type of received elements
* @param count \b out Number of received elements
* @retval MOC_SUCCESS No error; MPI routine completed successfully.
* @retval ... error-code
**/
int MOC_Get_count(MOC_Status *status, MOC_Datatype datatype, int *count);
//@}
/**
* \addtogroup comm_main
*
* \details
* Currently there is no support for creating and managing user-defined groups and
* communicators and probably never will be. The local storage of a SPU is very small
* and also the maximal number of nodes is limited to a small number and so there is
* doubt if the benefits will be greater than the overhead introduced by supporting
* user-defined groups and communicators.
*
* Only the predefined communicators \ref MOC_COMM_WORLD, \ref MOC_COMM_SELF and
* \ref MOC_COMM_NULL are available.
*
* The only operations which are currently implemented are \ref MOC_Comm_size and \ref
* MOC_Comm_rank.
**/
/**
* \addtogroup comm_mgt
*
* Funktions for managing communicators. Because of reasons already stated (see \ref comm_main)
* there is no support for user-defined communicators. So this section is limited to functions
* which return the size of a specific communicator or the rank of the calling process.
**/
//@{
/**
* Communicator-Handle.
*
* Masks the actual type which is used to encode the communicator.
* Char is used and therefore the maximum number of possible communicators is limited to 256.
* But because there are three predefined communicators (MPI_COMM_NULL, MPI_COMM_WORLD and
* MPI_COMM_SELF) only 253 user-defined communicators are possible.
**/
typedef int MOC_Comm;
/**
* Specifies a null communicator.
**/
#define MOC_COMM_NULL 0
/**
* Specifies a constant that contains all of the processes.
**/
#define MOC_COMM_WORLD 1
/**
* Specifies a constant that contains only the calling process.
**/
#define MOC_COMM_SELF 2
/**
* Determines the rank of the calling process in the communicator.
*
* \param comm \b in commicator-handle
* \param rank \b out rank of the calling process in group of comm
* \retval MOC_SUCCESS No error; MPI routine completed successfully.
* \retval MOC_ERR_COMM Invalid communicator. A common error is to use a null communicator in a call.
**/
int MOC_Comm_rank ( MOC_Comm comm, int *rank );
/**
* Determines the size of the group associated with a communictor.
*
* \param comm \b in commicator-handle
* \param size \b out number of processes in the group of comm
* \retval MOC_SUCCESS No error; MPI routine completed successfully.
* \retval MOC_ERR_COMM Invalid communicator. A common error is to use a null communicator in a call.
**/
int MOC_Comm_size ( MOC_Comm comm, int *size );
//@}
/**
* \addtogroup environment_timer
*
* Functions to measure time.
*
* On the PPU gettimeofday from time.h is used. On the SPU either also gettimeofday or the
* spu-timer-library is used depending on the configuration during compilation of the MOC-library.
* When gettimeofday is used on the SPU the time is global in the MOC-environment with the
* disadvantage that the SPU-threads get their times from the PPU using DMA causing inaccuracy and
* delays.
**/
//@{
/**
* Returns a floating-point number of seconds, representing elapsed wall-clock
* time since some time in the past.
*
* @return wall-clock time in seconds.
**/
double MOC_Wtime(void);
/**
* Returns the resolution of Moc_Wtime in seconds.
*
* @return resolution in seconds.
**/
double MOC_Wtick(void);
//@}
/**
* \addtogroup p2p_main
**/
//@{
/**
* Indicates, at which message-size \ref MOC_Send switches to synchronous send.
*/
#define MOC_SEND_TRESHOLD 4096
/**
* Performs a blocking standard mode send operation.
*
* \note This routine may block until the message is received.
*
* @param buf \b in Pointer to buffer where data is stored
* @param count \b in Number of elements to be send (not equal to actual byte-value)
* @param datatype \b in Type of elements to be send
* @param dest \b in Rank of receiving process
* @param tag \b in Tag of message
* @param comm \b in communicator of message
* @retval MOC_SUCCESS No error; MPI routine completed successfully.
* @retval ... error-code
**/
int MOC_Send(void* buf, int count, MOC_Datatype datatype, int dest, int tag, MOC_Comm comm);
/**
* Performs a blocking standard mode receive operation.
*
* \note This routine blocks until the message is received.
*
* @param buf \b inout Buffer into which data should be stored
* @param count \b in Number of elements in receive buffer (not equal to actual byte-value)
* @param datatype \b in Datatype of each receive buffer element
* @param source \b in Rank of source
* @param tag \b in Tag of message
* @param comm \b in Communicator of message
* @param status \b inout Object holding status-information (has to be allocated by user)
* @retval MOC_SUCCESS No error; MPI routine completed successfully.
* @retval ... error-code
**/
int MOC_Recv(void* buf, int count, MOC_Datatype datatype, int source, int tag,
MOC_Comm comm, MOC_Status *status);
/**
* Waits till a message is received and returns information without actually
* receiving the message.
*
* @param source \b in source of message
* @param tag \b in message-tag
* @param comm \b in communicator
* @param status \b out status-object holding information about message
* @retval MOC_SUCCESS No error; MPI routine completed successfully.
* @retval ... error-code
**/
int MOC_Probe(int source, int tag, MOC_Comm comm, MOC_Status *status);
/**
* Tests if a message is available and returns information without actually
* receiving the message.
*
* @param source \b in source of message
* @param tag \b in message-tag
* @param comm \b in communicator
* @param flag \b out boolean value telling if a message is available
* @param status \b out status-object holding information about message
* @retval MOC_SUCCESS No error; MPI routine completed successfully.
* @retval ... error-code
**/
int MOC_Iprobe(int source, int tag, MOC_Comm comm, int *flag, MOC_Status *status);
//@}
/**
* \addtogroup p2p_synch
**/
//@{
/**
* Performs a blocking synchronous mode send operation.
*
* \note This routine blocks until the message is received.
*
* @param buf \b in Pointer to buffer where data is stored
* @param count \b in Number of elements to be send (not equal to actual byte-value)
* @param datatype \b in Type of elements to be send
* @param dest \b in Rank of receiving process
* @param tag \b in Tag of message
* @param comm \b in communicator of message
* @retval MOC_SUCCESS No error; MPI routine completed successfully.
* @retval ... error-code
**/
int MOC_Ssend(void* buf, int count, MOC_Datatype datatype, int dest, int tag, MOC_Comm comm);
//@}
/**
* \addtogroup p2p_buffered
**/
//@{
/**
* Performs a blocking buffered mode send operation.
*
* \note This routine blocks until the send-buffer is free.
*
* @param buf \b in Pointer to buffer where data is stored
* @param count \b in Number of elements to be send (not equal to actual byte-value)
* @param datatype \b in Type of elements to be send
* @param dest \b in Rank of receiving process
* @param tag \b in Tag of message
* @param comm \b in communicator of message
* @retval MOC_SUCCESS No error; MPI routine completed successfully.
* @retval ... error-code
**/
int MOC_Bsend(void* buf, int count, MOC_Datatype datatype, int dest, int tag, MOC_Comm comm);
//@}
/**
* \addtogroup p2p_sendrecv
**/
//@{
/**
* Execute a blocking send and receive operation. Both send and receive use the same
* communicator, but possibly different tags. The send buffer and receive buffers may
* be disjoint, and may have different lengths and datatypes.
*
* @param sendbuf \b in Pointer to buffer where data is stored
* @param sendcount \b in Number of elements to be send (not equal to actual byte-value)
* @param sendtype \b in Type of elements to be send
* @param dest \b in Rank of receiving process
* @param sendtag \b in Tag of message to be send
*
* @param recvbuf \b inout Buffer into which data should be stored
* @param recvcount \b in Number of elements in receive buffer (not equal to actual byte-value)
* @param recvtype \b in Datatype of each receive buffer element
* @param source \b in Rank of source
* @param recvtag \b in Tag of message to be received
*
* @param comm \b in Communicator of message
* @param status \b inout Object holding status-information (has to be allocated by user)
*
* @retval MOC_SUCCESS No error; MPI routine completed successfully.
* @retval ... error-code
**/
int MOC_Sendrecv(void *sendbuf, int sendcount, MOC_Datatype sendtype, int dest,
int sendtag, void *recvbuf, int recvcount, MOC_Datatype recvtype,
int source, int recvtag, MOC_Comm comm, MOC_Status *status);
/**
* Execute a blocking send and receive. The same buffer is used both for the send
* and for the receive, so that the message sent is replaced by the message
* received.
*
* @param buf \b inout Pointer to buffer
* @param count \b in Number of elements (not equal to actual byte-value)
* @param datatype \b in Type of elements
*
* @param dest \b in Rank of receiving process
* @param sendtag \b in Tag of message to be send
*
* @param source \b in Rank of source
* @param recvtag \b in Tag of message to be received
*
* @param comm \b in Communicator of message
* @param status \b inout Object holding status-information (has to be allocated by user)
*
* @retval MOC_SUCCESS No error; MPI routine completed successfully.
* @retval ... error-code
**/
int MOC_Sendrecv_replace(void* buf, int count, MOC_Datatype datatype, int dest,
int sendtag, int source, int recvtag, MOC_Comm comm,
MOC_Status *status);
//@}
/**
* \addtogroup p2p_imm
**/
//@{
/**
* Communication-Request (Handle)
**/
typedef struct moc_request_struct
{
int request_type;
union
{
imoc_dma_request dma_data;
imoc_issend_request issend_request;
} request_data ;
} MOC_Request /**< Communication-Request (Handle) */;
/**
* Performs a non-blocking standard mode send operation.
*
* \note This routine returns as soon as possible.
*
* @param buf \b in Pointer to buffer where data is stored
* @param count \b in Number of elements to be send (not equal to actual byte-value)
* @param datatype \b in Type of elements to be send
* @param dest \b in Rank of receiving process
* @param tag \b in Tag of message
* @param comm \b in communicator of message
* @param request \b out communication request (handle)
* @retval MOC_SUCCESS No error; MPI routine completed successfully.
* @retval ... error-code
**/
int MOC_ISend(void* buf, int count, MOC_Datatype datatype, int dest, int tag, MOC_Comm comm,
MOC_Request *request);
/**
* Performs a non-blocking synchronous mode send operation.
*
* \note This routine returns as soon as possible (After the message-envelope has
* been written into the receiver's message-queue).
*
* @param buf \b in Pointer to buffer where data is stored
* @param count \b in Number of elements to be send (not equal to actual byte-value)
* @param datatype \b in Type of elements to be send
* @param dest \b in Rank of receiving process
* @param tag \b in Tag of message
* @param comm \b in communicator of message
* @param request \b out communication request (handle)
* @retval MOC_SUCCESS No error; MPI routine completed successfully.
* @retval ... error-code
**/
int MOC_ISsend(void* buf, int count, MOC_Datatype datatype, int dest, int tag, MOC_Comm comm,
MOC_Request *request);
/**
* Tests, if a non-blocking communication has been completed.
*
* @param request \b in Communication-Request (Handle)
* @param flag \b out true, if communication-request has been completed
* @param status \b out Object holding status-information
* @retval MOC_SUCCESS No error; MPI routine completed successfully.
* @retval ... error-code
**/
int MOC_Test(MOC_Request *request, int *flag, MOC_Status *status);
/**
* Wait till a non-blocking communication has been completed.
*
* @param request \b in Communication-Request (Handle)
* @param status \b out Object holding status-information
* @retval MOC_SUCCESS No error; MPI routine completed successfully.
* @retval ... error-code
**/
int MOC_Wait(MOC_Request *request, MOC_Status *status);
//@}
/**
* \addtogroup broadcast
**/
//@{
/**
* Broadcasts a message from the process with rank "root" to all other processes of the group.
*
* \note The broadcast-message can also be received by a MOC_Recv using MOC_BCAST_TAG.
*
* @param buffer \b inout starting address of buffer
* @param count \b in number of elements to be send or received
* @param datatype \b in Type of elements to be send or received
* @param root \b in rank of the process who sends the broadcast-message
* @param comm \b in communicator of message
**/
int MOC_Bcast(void* buffer, int count, MOC_Datatype datatype, int root, MOC_Comm comm );
/**
* Blocks the caller until all processes in the communicator have called it; that is, the
* call returns at any process only after all members of the communicator have entered the
* call.
*
* @param comm \b in communicator of message
* @retval MOC_SUCCESS No error; MPI routine completed successfully.
* @retval ... error-code
**/
int MOC_Barrier(MOC_Comm comm );
//@}
#endif /*MOC_H_*/