#ifndef MOC_H_ #define MOC_H_ #include #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_*/