Functions | |
int | MB_Env_Init (void) |
Initialises the libmboard environment. | |
int | MB_Env_Finalise (void) |
Finalises the libmboard environment. | |
int | MB_Env_Initialised (void) |
Indicates whether MB_Env_Init() has been called successfully. | |
int | MB_Env_Finalised (void) |
Indicates whether MB_Env_Finalise() has been called. | |
int | MB_Create (MBt_Board *mb_ptr, size_t msgsize) |
Instantiates a new Message Board object. | |
int | MB_SetAccessMode (MBt_Board mb, int MODE) |
Sets access mode of the Message Board. | |
int | MB_SetSyncPattern (MBt_Board mb, unsigned int *sync_matrix) |
Sets sync pattern of the Message Board. | |
int | MB_AddMessage (MBt_Board mb, void *msg) |
Adds a message to the Message Board. | |
int | MB_Clear (MBt_Board mb) |
Clears the Message Board. | |
int | MB_Delete (MBt_Board *mb_ptr) |
Deletes a Message Board. | |
int | MB_Iterator_Create (MBt_Board mb, MBt_Iterator *itr_ptr) |
Creates a new Iterator for accessing messages in board mb . | |
int | MB_Iterator_CreateSorted (MBt_Board mb, MBt_Iterator *itr_ptr, int(*cmpFunc)(const void *msg1, const void *msg2)) |
Creates a new Iterator for accessing sorted messages in board mb . | |
int | MB_Iterator_CreateFiltered (MBt_Board mb, MBt_Iterator *itr_ptr, int(*filterFunc)(const void *msg, const void *params), void *filterFuncParams) |
Creates a new Iterator for accessing a selection of messages in board mb . | |
int | MB_Iterator_CreateFilteredSorted (MBt_Board mb, MBt_Iterator *itr_ptr, int(*filterFunc)(const void *msg, const void *params), void *filterFuncParams, int(*cmpFunc)(const void *msg1, const void *msg2)) |
Instantiates a new Iterator for accessing a sorted selection of messages in board mb . | |
int | MB_Iterator_Delete (MBt_Iterator *itr_ptr) |
Deletes an Iterator. | |
int | MB_Iterator_GetMessage (MBt_Iterator itr, void **msg_ptr) |
Returns next available message from Iterator. | |
int | MB_Iterator_Rewind (MBt_Iterator itr) |
Rewinds an Iterator. | |
int | MB_Iterator_Randomise (MBt_Iterator itr) |
Randomises the order of entries in an Iterator. | |
int | MB_SyncStart (MBt_Board mb) |
Synchronises the content of the board across all processes. | |
int | MB_SyncTest (MBt_Board mb, int *flag) |
Inspects the completion status of a board synchronisation. | |
int | MB_SyncComplete (MBt_Board mb) |
Completes the synchronisation of a board. | |
int | MB_Filter_Create (MBt_Filter *fh_ptr, int(*filterFunc)(const void *msg, int pid)) |
Creates a filter object. | |
int | MB_Filter_Assign (MBt_Board mb, MBt_Filter fh) |
Assigns a filter handle to a message board. | |
int | MB_Filter_Delete (MBt_Filter *fh_ptr) |
Deallocates a registered function. | |
int | MB_IndexMap_Create (MBt_IndexMap *im_ptr, const char *name) |
Instantiates a new Index Map object. | |
int | MB_IndexMap_Delete (MBt_IndexMap *im_ptr) |
Deletes an Index Map. | |
int | MB_IndexMap_AddEntry (MBt_IndexMap im, int value) |
Adds an entry into the Index Map. | |
int | MB_IndexMap_Sync (MBt_IndexMap im) |
Distributes/gathers the map content across/from all processors. | |
int | MB_IndexMap_MemberOf (MBt_IndexMap im, int pid, int value) |
Query the map to determine if a value exists on a particular processor. |
Routines to create and use Message Boards
MB_Env_Init | ( | void | ) |
Initialises the libmboard environment.
This routine must be called before any other libmboard routines (apart for MB_Env_Initialised() and MB_Env_Finalised()). It launches the communication thread and initialises all internal data structures required by the library.
The libmboard environment should be initialised only once, and never re-initialised once it has been finalised (using MB_Env_Finalise()).
Possible return codes:
MB_Env_Finalise | ( | void | ) |
Finalises the libmboard environment.
This should be the last libmboard routine called within a program (apart for MB_Env_Initialised() and MB_Env_Finalised()). It deallocates all internal data structures and terminates the communication thread.
It is erroneous to finalise the environment while there are pending board synchronisations, i.e. all MB_SyncStart() must be completed with a matching MB_SyncComplete() (or successful MB_SyncTest()).
Possible return codes:
MB_Env_Initialised | ( | void | ) |
Indicates whether MB_Env_Init() has been called successfully.
This routine will return MB_SUCCESS if the environment has been initialised, or MB_ERR_ENV otherwise.
Possible return codes:
MB_Env_Finalised | ( | void | ) |
Indicates whether MB_Env_Finalise() has been called.
This routine will return MB_SUCCESS if the environment has been finalised, or MB_ERR_ENV otherwise.
Possible return codes:
MB_Create | ( | MBt_Board * | mb_ptr, | |
size_t | msgsize | |||
) |
Instantiates a new Message Board object.
[out] | mb_ptr | Address of Message Board handle |
[in] | msgsize | Size of message that this Message Board will be used for |
Creates a new board for storing messages of size msgsize
and returns a handle to the board via mb_ptr
.
In the parallel debug version, this routine is blocking and will return when all processes have issued and completed the call. This effectively synchronises all processes. It is the users' responsibility to ensure that all processes issue the call (with the same values of msgsize
) to prevent deadlocks.
If this routine returns with an error, mb_ptr
will be set to MB_NULL_MBOARD.
Possible return codes:
msgsize
is invalid)Usage example:
/* Datatype for message */ typedef struct { double x; double y; int value; } MyMessageType; /* some function somewhere */ void func_harimau(void) { int rc; MBt_Board myboard; /* create the message board */ rc = MB_Create(&myboard, sizeof(MyMessageType)); if ( rc != MB_SUCCESS ) { fprintf(stderr, "Message board creation failed!\n"); /* check valur of rc to determine reason of failure. Handle error */ /* don't continue if error can't be handled */ exit(1); } /* .... more code .... */ }
MB_SetAccessMode | ( | MBt_Board | mb, | |
int | MODE | |||
) |
Sets access mode of the Message Board.
[in] | mb | Message Board handle |
[in] | MODE | Access mode identifier |
Sets the access mode of the board to allow the board synchronisation process to be optimised.
This routine is collective and must be called on all MPI processes. The mode applies only to the calling MPI process hence can be set to a different value on different processes.
When a non-readable mode is set, all MB_Iterator_*
() will be disabled. Similarly, when a non-writeable mode is set, MB_AddMessage() will be disabled.
MB_MODE_READWRITE is the default mode of all newly created boards.
The following MODE
values can be used:
This routine can only be called when the message board is empty and not locked.
Possible return codes:
is
null or invalid, or MODE
is invalid)mb
is locked by another process)Usage example: (to be included)
MB_SetSyncPattern | ( | MBt_Board | mb, | |
unsigned int * | sync_matrix | |||
) |
Sets sync pattern of the Message Board.
[in] | mb | Message Board handle |
[in] | sync_matrix | Integer array representing board communication matrix |
Sets the access pattern of the board to allow the board synchronisation process to be optimised.
This routine is collective and must be called on all MPI processes. However, only the master node (MPI rank == 0) needs to provide a valid sync_matrix
. The sync_matrix
parameter will be ignored on all other nodes.
The sync_matrix
array must be an element count equal to the square of the number of nodes. It is the users responsibility to provide a non-NULL sync_matrix
which points to an array of apropriate size.
sync_matrix
is provided by the master node, the routine may terminate or return errorneously, leaving the other nodes waiting for further instrustions from the master node hence causing a deadlock.The sync_matrix
will be processed as an NxN matrix (where N is the number of nodes), whereby the row i
will represent the amount of communication from all node to node i
. A zero value will indicate no communication.
When a node does not read from any proc including itself (all zeros in row i
), it will be set to a non-reader and all MB_Iterator_*
() routines will be disabled.
Similarly, when a node does not send to any other proc including itself, (add zeros in column i
) it will be set to a non-writer and MB_AddMessage() will be disabled.
This routine can only be called when the message board is empty and not locked.
Possible return codes:
is
null or invalid, or sync_matrix
is null)mb
is locked by another process)Usage example: (to be included)
MB_AddMessage | ( | MBt_Board | mb, | |
void * | msg | |||
) |
Adds a message to the Message Board.
[in] | mb | Message Board handle |
[in] | msg | Address of the message to be added |
Messages added to the board must be of the size specified during the creation of the board. Adding messages of a different size may not cause an error code to be returned, but will lead to unexpected behavior and possible segmentation faults.
The message data addressed by msg
is cloned and stored in the message board. Users are free to modify, reuse, or deallocate their copy of the message after this routine has completed.
It this routine returns with an error, the access mode of mb
will remain unchanged.
Possible return codes:
mb
is null or invalid)mb
is locked by another process)Usage example:
/* some function somewhere */ void func_kucing(void) { int rc; MBt_Board myboard; myMessageType staticMsg; myMessageType dynamicMsg; /* create board to store myMessageType messages */ rc = MB_Create(&myboard, sizeof(myMessageType)); /* create messages to add to board */ staticMsg.value = 200; dynamicMsg = (myMessageType *)malloc(sizeof(myMessageType)); dynamicMsg->value = 100; if ( MB_AddMessage(myboard, (void *)&staticMsg) != MB_SUCCESS ) { fprintf(stderr, "Error adding message to board\n"); /* check valur of rc to determine reason of failure. Handle error */ /* don't continue if error can't be handled */ exit(1); } if ( MB_AddMessage(myboard, (void *)dynamicMsg) != MB_SUCCESS ) { fprintf(stderr, "Error adding message to board\n"); /* check valur of rc to determine reason of failure. Handle error */ /* don't continue if error can't be handled */ exit(1); } /* it is safe to modify message memory once it has been added to the board. * Value in the board will not be modified. */ staticMsg.value = 42; /* it is safe to deallocate message memory once it has been added to message board */ free(dynamicMsg); /* ... more code ... */ }
MB_Clear | ( | MBt_Board | mb | ) |
Clears the Message Board.
[in] | mb | Message Board handle |
Deletes all messages from the board. The board can be reused for adding more messages of the same type.
Once a board is cleared, all Iterators associated with the board is no longer valid and has to be recreated. It is the users' responsibility to ensure that invalidated Iterators are never used.
MB_Clear() can be asked not to deallocate memory. The allocated memory will then be reuse when the board is later populated. This therefore increases the amount of memory used by the simulation in exchange for a shorter runtime. This can ge done by setting the following environment variable: MBOARD_MEMPOOL_RECYCLE=1
Possible return codes:
mb
is null or invalid)mb
is locked by another process)Usage example:
/* some function somewhere */ void func_semut(void) { MBt_Board myboard; /* board created */ rc = MB_Create(&myboard, sizeof(myMessageType)); /* .... more code that uses the board .... */ /* clear the board */ if ( MB_Clear(myboard) != MB_SUCCESS ) { fprintf(stderr, "Could not clear message board\n"); /* check valur of rc to determine reason of failure. Handle error */ /* don't continue if error can't be handled */ exit(1); } /* ... board can be reused here ... */ /* Don't forget to delete the board when done */ }
MB_Delete | ( | MBt_Board * | mb_ptr | ) |
Deletes a Message Board.
[in,out] | mb_ptr | Address of Message Board handle |
Upon successful deletion, the handle referenced by mb_ptr
will be set to MB_NULL_MBOARD.
If an error occurs, this routine will return an error code, and mb_ptr
will remain unchanged.
If a null board (MB_NULL_MBOARD) is given, the routine will return immediately with MB_SUCCESS
Once a board is deleted, all Iterators associated with the board is no longer valid. It is the users' responsibility to ensure that invalidated Iterators are never used.
Possible return codes:
mb
is invalid)mb
is locked by another process)Usage example:
/* some function somewhere */ void func_belut(void) { MBt_Board myboard; /* board created */ rc = MB_Create(&myboard, sizeof(myMessageType)); /* .... more code that uses the board .... */ /* when done, delete the board */ if ( MB_Delete(&myboard) != MB_SUCCESS ) { fprintf(stderr, "Could not delete message board\n"); /* check valur of rc to determine reason of failure. Handle error */ /* don't continue if error can't be handled */ exit(1); } /* ... more code ... */ }
MB_Iterator_Create | ( | MBt_Board | mb, | |
MBt_Iterator * | itr_ptr | |||
) |
Creates a new Iterator for accessing messages in board mb
.
[in] | mb | Message Board handle |
[out] | itr_ptr | Address of Iterator Handle |
Upon successful creation of the Iterator, the routine returns a handle to the Iterator via itr_ptr
.
Attempts to create an Iterator against a null board (MB_NULL_MBOARD) will result in an MB_ERR_INVALID error.
If this routine returns with an error, itr_ptr
will remain unchanged.
Possible return codes:
mb
is null or invalid)mb
is locked by another process)Usage example:
/* some function somewhere */ void func_siput(void) { MBt_Board myboard; MBt_Iterator iterator; /* .... more code that creates and populate myboard .... */ rc = MB_Iterator_Create(myboard, &iterator); if ( rc != MB_SUCCESS ) { fprintf(stderr, "Error while creating Iterator\n"); /* check valur of rc to determine reason of failure. Handle error */ /* don't continue if error can't be handled */ exit(1); } /* iterator ready to be used */ /* ... more code ... */ }
MB_Iterator_CreateSorted | ( | MBt_Board | mb, | |
MBt_Iterator * | itr_ptr, | |||
int(*)(const void *msg1, const void *msg2) | cmpFunc | |||
) |
Creates a new Iterator for accessing sorted messages in board mb
.
[in] | mb | Message Board handle |
[out] | itr_ptr | Address of Iterator Handle |
[in] | cmpFunc | Pointer to user-defined comparison function |
Creates a new Iterator for accessing messages in board mb
, and returns a handle to the iterator via itr_ptr
. This Iterator will allow users to retrieve ordered messages from mb
without modifying the board itself.
The user-defined comparison function (cmpFunc
) must return an integer less than, equal to, or greater than zero if the first message is considered to be respectively less than, equal to, or greater than the second. In short:
0 if (msg1 == msg2)
< 0 if (msg1 < msg2)
> 0 if (msg1 > msg2)
If two members compare as equal, their order in the sorted Iterator is undefined.
Attempts to create an Iterator against a null board (MB_NULL_MBOARD) will result in an MB_ERR_INVALID error.
If this routine returns with an error, itr_ptr
will remain unchanged.
Possible return codes:
mb
is null or invalid)mb
is locked by another process)Usage example:
/* our message datatype */ typedef struct { int id; double price; double value; } myMessageType; /* to be used for sorting myMessageType based on 'price' */ int mycmp(const void *msg1, const void *msg2) { myMessageType *m1, *m2; /* cast messages to proper type */ m1 = (myMessageType*)msg1; m2 = (myMessageType*)msg2; if (m1->price == m2->price) { return 0; } else if (m1->price > m2->price) { { return 1; } else { return -1; } } /* some function somewhere */ void func_siamang(void) { MBt_Iterator iterator; /* assuming myboard has been created and populated */ rc = MB_Iterator_CreateSorted(myboard, &iterator, &mycmp); if ( rc != MB_SUCCESS ) { fprintf(stderr, "Error while creating Sorted Iterator\n"); /* check valur of rc to determine reason of failure. Handle error */ /* don't continue if error can't be handled */ exit(1); } /* ... more code ... */ }
MB_Iterator_CreateFiltered | ( | MBt_Board | mb, | |
MBt_Iterator * | itr_ptr, | |||
int(*)(const void *msg, const void *params) | filterFunc, | |||
void * | filterFuncParams | |||
) |
Creates a new Iterator for accessing a selection of messages in board mb
.
[in] | mb | Message Board handle |
[out] | itr_ptr | Address of Iterator Handle |
[in] | filterFunc | Pointer to user-defined filter function |
[in] | filterFuncParams | Pointer to input data that will be passed into filterFunc |
Creates a new Iterator for accessing messages in board mb
, and returns a handle to the iterator via itr_ptr
. This Iterator will allow users to retrieve a filtered selection of messages from mb
without modifying the board itself.
The user-defined filter function (filterFunc
) must return 0
if a message is to be rejected by the filter, or 1
if it is to be accepted.
The filterFuncParam
argument allows users to pass on additional information to filterFunc
(see example code below). Users may useNULL
in place of filterFuncParam
if filterFunc
does not require additional information.
Attempts to create an Iterator against a null board (MB_NULL_MBOARD) will result in an MB_ERR_INVALID error.
If this routine returns with an error, itr_ptr
will remain unchanged.
Possible return codes:
mb
is null or invalid)mb
is locked by another process)Usage example:
/* our message datatype */ typedef struct { int id; double price; double value; } myMessageType; /* parameter datatype for myFilter */ typedef struct { double minPrice; double maxPrice; } myFilterParams; /* to be used for filtering myMessageType */ int myFilter(const void *msg, const void *params) { myMessageType *m; myFilterParams *p; /* cast data to proper type */ m = (myMessageType*)msg; p = (myFilterParams*)params; if (m1->price > p->maxPrice) { return 0; /* reject */ } else if (m1->price < p->minPrice) { { return 0; /* reject */ } else { return 1; /* accept */ } } /* some function somewhere */ void func_monyet(void) { MBt_Iterator iterator; myFilterParam params; /* assuming myboard has been created and populated */ params.minPrice = 10.5; params.maxPrice = 58.3; rc = MB_Iterator_CreateFiltered(myboard, &iterator, &myFilter, ¶ms); if ( rc != MB_SUCCESS ) { fprintf(stderr, "Error while creating Filtered Iterator\n"); /* check valur of rc to determine reason of failure. Handle error */ /* don't continue if error can't be handled */ exit(1); } /* ... more code ... */ }
MB_Iterator_CreateFilteredSorted | ( | MBt_Board | mb, | |
MBt_Iterator * | itr_ptr, | |||
int(*)(const void *msg, const void *params) | filterFunc, | |||
void * | filterFuncParams, | |||
int(*)(const void *msg1, const void *msg2) | cmpFunc | |||
) |
Instantiates a new Iterator for accessing a sorted selection of messages in board mb
.
[in] | mb | Message Board handle |
[out] | itr_ptr | Address of Iterator Handle |
[in] | filterFunc | Pointer to user-defined filter function |
[in] | filterFuncParams | Pointer to input data that will be passed into filterFunc |
[in] | cmpFunc | Pointer to user-defined compariosn function |
Creates a new Iterator for accessing messages in board mb
, and returns a handle to the iterator via itr_ptr
. This Iterator will allow users to retrieve a filtered selection of ordered messages from mb
without modifying the board itself.
The user-defined filter function (filterFunc
) must return 0
if a message is to be rejected by the filter, or 1
if it is to be accepted.
The filterFuncParam
argument allows users to pass on additional information to filterFunc
(see example code below). Users may useNULL
in place of filterFuncParam
if filterFunc
does not require additional information.
The user-defined comparison function (cmpFunc
) must return an integer less than, equal to, or greater than zero if the first message is considered to be respectively less than, equal to, or greater than the second. In short:
0 if (msg1 == msg2)
< 0 if (msg1 < msg2)
> 0 if (msg1 > msg2)
Attempts to create an Iterator against a null board (MB_NULL_MBOARD) will result in an MB_ERR_INVALID error.
If this routine returns with an error, itr_ptr
will remain unchanged.
Possible return codes:
mb
is null or invalid)mb
is locked by another process)Usage example:
/* our message datatype */ typedef struct { int id; double price; double value; } myMessageType; /* parameter datatype for myFilter */ typedef struct { double minPrice; double maxPrice; } myFilterParams; /* to be used for filtering myMessageType */ int myFilter(const void *msg, const void *params) { myMessageType *m; myFilterParams *p; /* cast data to proper type */ m = (myMessageType*)msg; p = (myFilterParams*)params; if (m1->price > p->maxPrice) { return 0; /* reject */ } else if (m1->price < p->minPrice) { { return 0; /* reject */ } else { return 1; /* accept */ } } /* to be used for sorting myMessageType based on 'price' */ int mycmp(const void *msg1, const void *msg2) { myMessageType *m1, *m2; /* cast messages to proper type */ m1 = (myMessageType*)msg1; m2 = (myMessageType*)msg2; if (m1->price == m2->price) { return 0; } else if (m1->price > m2->price) { { return 1; } else { return -1; } } /* some function somewhere */ void func_beruk(void) { MBt_Iterator iterator; myFilterParam params; /* assuming myboard has been created and populated */ params.minPrice = 10.5; params.maxPrice = 58.3; rc = MB_Iterator_CreateFilteredSorted(myboard, &iterator, &myFilter, ¶ms, &mycmp); if ( rc != MB_SUCCESS ) { fprintf(stderr, "Error while creating Filtered+Sorted Iterator\n"); /* check valur of rc to determine reason of failure. Handle error */ /* don't continue if error can't be handled */ exit(1); } /* ... more code ... */ }
MB_Iterator_Delete | ( | MBt_Iterator * | itr_ptr | ) |
Deletes an Iterator.
[in,out] | itr_ptr | Address of Iterator Handle |
Upon successful deletion, the handle referenced by itr_ptr
will be set to MB_NULL_ITERATOR.
If an error occurs, itr_ptr
will remain unchanged.
If a null Iterator (MB_NULL_ITERATOR) is passed in, the routine will return immediately with MB_SUCCESS
Possible return codes:
itr
is invalid)Usage example:
/* some function somewhere */ void func_lipan(void) { MBt_Board myboard; MBt_Iterator iterator; /* .... more code that creates and populate myboard .... */ rc = MB_Iterator_Create(myboard, &iterator); /* .... more code .... */ rc = MB_Iterator_Delete(&iterator); if ( rc != MB_SUCCESS ) { fprintf(stderr, "Unable to delete Iterator\n"); /* check valur of rc to determine reason of failure. Handle error */ /* don't continue if error can't be handled */ exit(1); } /* ... more code ... */ }
MB_Iterator_GetMessage | ( | MBt_Iterator | itr, | |
void ** | msg_ptr | |||
) |
Returns next available message from Iterator.
[in] | itr | Iterator Handle |
[out] | msg_ptr | Address where pointer to message will be written to |
After a successful call to the routine, msg_ptr
will be assigned with a pointer to a newly allocated memory block containing the message data. It is the user's responsibility to free the memory associated with the returned msg.
When there are no more messages to return, msg_ptr
will be assigned with NULL
and the routine shall complete with the MB_SUCCESS return code.
Any attempts to retrieve a message from a null Iterator (MB_NULL_ITERATOR) will result in an MB_ERR_INVALID error.
In the event of an error, msg will be assigned NULL
and the routine shall return with an appropriate error code.
Possible return codes:
itr
is null of invalid)Usage example:
/* some function somewhere */ void func_ayam(void) { int rc; MyMessageType *msg = NULL; MBt_Iterator iterator; /* assuming myboard has been created and populated */ /* create and iterator myBoard */ MB_Iterator_Create(myBoard, &iterator); rc = MB_Iterator_GetMessage(iterator, (void **)&msg); while (msg) /* loop till end of Iterator */ { do_something_with_message(msg); free(msg); /* free allocated message */ /* get next message from iterator */ rc = MB_Iterator_GetMessage(iterator, (void **)&msg); if (rc != MB_SUCCESS) { fprintf(stderr, "Oh no! Error while traversing iterator.\n"); /* check valur of rc to determine reason of failure. Handle error */ /* don't continue if error can't be handled */ exit(1); } } }
MB_Iterator_Rewind | ( | MBt_Iterator | itr | ) |
Rewinds an Iterator.
[in] | itr | Iterator Handle |
Resets the internal counters such that the next MB_Iterator_GetMessage() call on the given Iterator will obtain the first message in the list (or NULL
if the Iterator is empty).
Rewinding a null Iterator (MB_NULL_ITERATOR) will result in an MB_ERR_INVALID error.
Possible return codes:
itr
is null or invalid)Usage example:
/* some function somewhere */ void func_itik(void) { MyMessageType *msg1, *msg2; MBt_Iterator iterator; /* assuming myboard has been created and populated */ /* create and iterator myBoard */ MB_Iterator_Create(myBoard, &iterator); /* get a message */ MB_Iterator_GetMessage(iterator, (void *)msg1); /* rewind the iterator */ MB_Iterator_Rewind(iterator); /* get another message */ MB_Iterator_GetMessage(iterator, (void *)msg2); /* msg1 and msg2 will be pointers to different blocks of data, but * both blocks will contain the same data */ /* ... more ... */ free(msg1); free(msg2); }
MB_Iterator_Randomise | ( | MBt_Iterator | itr | ) |
Randomises the order of entries in an Iterator.
[in] | itr | Iterator Handle |
Apart from randomising the order of entries in the Iterator, this routine will also reset the internal counters leading to an effect similar to that of MB_Iterator_Rewind().
Randomising a null Iterator (MB_NULL_ITERATOR) will result in an MB_ERR_INVALID error.
Possible return codes:
itr
is null or invalid)Usage example:
/* some function somewhere */ void func_angsa(void) { MyMessageType *msg1, *msg2, *msg3, *msg4; MBt_Iterator iterator; /* assuming myboard has been created and populated */ /* create and iterator myBoard */ MB_Iterator_Create(myBoard, &iterator); /* ... fill up board ... */ /* get messages */ MB_Iterator_GetMessage(iterator, (void *)msg1); MB_Iterator_GetMessage(iterator, (void *)msg2); MB_Iterator_GetMessage(iterator, (void *)msg3); MB_Iterator_GetMessage(iterator, (void *)msg4); /* ... more ... */ /* .... process messages .... */ free(msg1); free(msg2); free(msg3); free(msg4); /* randomise the iterator (rewind was done automatically) */ MB_Iterator_Randomise(iterator); /* messages should now be returned in a randomised order */ MB_Iterator_GetMessage(iterator, (void *)msg1); MB_Iterator_GetMessage(iterator, (void *)msg2); MB_Iterator_GetMessage(iterator, (void *)msg3); MB_Iterator_GetMessage(iterator, (void *)msg4); /* ... more ... */ free(msg1); free(msg2); free(msg3); free(msg4); }
MB_SyncStart | ( | MBt_Board | mb | ) |
Synchronises the content of the board across all processes.
[in] | mb | Message Board Handle |
This is a non-blocking routine which returns immediately after locking the message board and intialising the synchronisation process. The board should not be modified, cleared, or deleted until the synchronisation process is completed using MB_SyncComplete() (or until MB_SyncTest() results in a MB_TRUE flag).
In the serial version, this routine will do nothing apart from locking the message board.
Synchronisation of a null board (MB_NULL_MBOARD) is valid, and will return immediately with MB_SUCCESS
Possible return codes:
mb
is invalid)mb
is locked by another process)Usage example:
int rc; int flag; MBt_Board myboard; myMessageType staticMsg; /* .... more code .... */ rc = MB_Create(&myboard, sizeof(myMessageType)); /* .... more code .... */ /* create messages to add to board */ staticMsg.value = 200; if ( MB_AddMessage(myboard, (void *)&staticMsg) != MB_SUCCESS ) { fprintf(stderr, "Error adding message to board\n"); /* check valur of rc to determine reason of failure. Handle error */ /* don't continue if error can't be handled */ exit(1); } if ( MB_SyncStart(myboard) != MB_SUCCESS ) { fprintf(stderr, "Unable to begin synchronisation\n"); /* check valur of rc to determine reason of failure. Handle error */ /* don't continue if error can't be handled */ exit(1); } /* check if synchronisation has completed */ MB_SyncTest(myboard, &flag); if (flag == MB_TRUE) { printf("synchronisation has completed\n"); /* a successful call to MB_SyncTest would already complete * the communication and unlock the board. MB_SyncComplete() * is not needed. */ process_message_board(); } else { printf("synchronisation still in progress\n"); do_something_else_first(); if ( MB_SyncComplete(myboard) != MB_SUCCESS ) /* wait till sync done */ { fprintf(stderr, "Unable to begin synchronisation\n"); /* check valur of rc to determine reason of failure. Handle error */ /* don't continue if error can't be handled */ exit(1); } process_message_board(); } /* .... rest of program .... */
MB_SyncTest | ( | MBt_Board | mb, | |
int * | flag | |||
) |
Inspects the completion status of a board synchronisation.
[in] | mb | Message Board Handle |
[out] | flag | address where return value will be written to |
This routine is non-blocking, and will return after setting the flag
value to either MB_TRUE or MB_FALSE depending on the synchronisation completion status.
If synchronisation has completed, the MB_TRUE flag is returned, and the board is unlocked. The synchronisation process is considered to be completed, and users no longer need to call MB_SyncComplete() on this board.
Testing a null board (MB_NULL_MBOARD) will always return with the MB_TRUE flag and MB_SUCCESS return code.
Testing a board that is not being synchronised is invalid, and will return with the MB_FALSE flag and MB_ERR_INVALID return code.
In the serial version, this routine will always return MB_TRUE as synchronisation is assumed to be completed immediately after it started.
Possible return codes:
mb
is invalid or not being synchronised)Usage example: see MB_SyncStart()
MB_SyncComplete | ( | MBt_Board | mb | ) |
Completes the synchronisation of a board.
[in] | mb | Message Board Handle |
This routine will block until the synchronisation of the board has completed. Upon successful execution of this routine, the board will be unlocked and ready for access.
In the serial version, this routine will do nothing apart from unlocking the message board.
Synchronisation of a null board (MB_NULL_MBOARD) is valid, and will return immediately with MB_SUCCESS
Completing synchronisation a board that is not being synchronised is invalid, and will return with the MB_ERR_INVALID error code.
Possible return codes:
mb
is invalid or not being synchronised)Usage example: see MB_SyncStart()
MB_Filter_Create | ( | MBt_Filter * | fh_ptr, | |
int(*)(const void *msg, int pid) | filterFunc | |||
) |
Creates a filter object.
[out] | fh_ptr | Address to write Filter Handle to |
[in] | filterFunc | Pointer to user-defined function |
Introduced in version 0.2.0.
Registers a filter function and returns a handle to the filter via ft_ptr
. The handle is unique to that function and is recognised across all processing nodes.
Registered filters can be assigned to message boards using MB_Filter_Assign() to act as a filtering mechanism when retrieving messages from remote nodes during a synchronisation. This reduces the number of messages that need to be transferred and stored on each node.
If this routine returns with an error, fh_ptr
will be set to :: MB_NULL_FILTER.
In the parallel debug version, this routine is blocking and will return when all processes have issued and completed the call. This effectively synchronises all processing nodes. It is the users' responsibility to ensure that all processing nodes issue the call (with the same values for filterFunc
) to prevent deadlocks.
Possible return codes:
filterFunc
is NULL)Usage example:
/* our message datatype */ typedef struct { int id; double price; double value; } myMessageType; /* to be used for filtering myMessageType */ int myFilter(const void *msg, int pid) { myMessageType *m; /* cast data to proper type */ m = (myMessageType*)msg; if (m->price < 0) return 0; /* reject */ else return 1; /* accept */ } /* some function somewhere */ void func_beruang(void) { int rc; MBt_Filter f_handle; /* register the function */ rc = MB_Fitler_Create(&f_handle, &myFilter); if ( rc != MB_SUCCESS ) { fprintf(stderr, "Error while creating filter\n"); /* check valur of rc to determine reason of failure. Handle error */ /* don't continue if error can't be handled */ exit(1); } /* assign function to board, assuming myboard has been created */ rc = MB_Filter_Assign(mboard, f_handle); if ( rc != MB_SUCCESS ) { fprintf(stderr, "Error while assigning filter to board\n"); /* check valur of rc to determine reason of failure. Handle error */ /* don't continue if error can't be handled */ exit(1); } /* ... more code that adds messages to myboard ... */ /* assign params for filtering messages during sync */ MB_SyncStart(myboard); /* you should check the return code */ do_something_else(); MB_SyncComplete(myboard); /* you should check the return code */ /* we should now have messages from other processing nodes, but * only those that passes the filter function myFilter() */ /* ... do stuff ... */ rc = MB_Filter_Delete(&f_handle); if ( rc != MB_SUCCESS ) { fprintf(stderr, "Error while deleting filter\n"); /* check valur of rc to determine reason of failure. Handle error */ /* don't continue if error can't be handled */ exit(1); } }
MB_Filter_Assign | ( | MBt_Board | mb, | |
MBt_Filter | fh | |||
) |
Assigns a filter handle to a message board.
[in] | mb | Message Board Handle |
[in] | fh | Filter Handle |
Introduced in version 0.2.0.
This routine assigns a registered filter to a Message Board. The associated filter function will act as a filtering mechanism when retrieving messages from remote nodes during a synchronisation. This reduces the number of messages that need to be transferred and stored on each node.
For efficiency, boards must be assigned with the same fh
on all MPI processes. It is left to the user to ensure that this is so.
fh
can be MB_NULL_FILTER, in which case mb
will be deassociated with any function that it was previously assigned with.
Possible return codes:
mb
is NULL or invalid, or fh
is invalid)mb
is locked by another process)Usage example: see MB_Filter_Create()
MB_Filter_Delete | ( | MBt_Filter * | fh_ptr | ) |
Deallocates a registered function.
[in,out] | fh_ptr | Address of Filter Handle |
Introduced in version 0.2.0.
The filter function associated with fh_ptr
will be deregistered, and fh_ptr
will be set to MB_NULL_FILTER.
Deleting a filter that is assigned to a board will result in an error if the board is synchronised. It is the users' responsibility to ensure that this does not happen.
If an invalid handle is give, the routine will end with MB_ERR_INVALID and fh_ptr
will not be modified.
If MB_NULL_FILTER is entered via fh_ptr
, the routine will end immediately with MB_SUCCESS.
Possible return codes:
fh_ptr
is NULL or invalid)Usage example: see MB_Filter_Create()
MB_IndexMap_Create | ( | MBt_IndexMap * | im_ptr, | |
const char * | name | |||
) |
Instantiates a new Index Map object.
[in] | name | Unique string identifying the map (max of 127 chars) |
[out] | im_ptr | Address of Index Map handle |
Introduced in version 0.2.0.
Creates a new Index Map and returns a handle to the map via im_ptr
.
name
should be a string that uniquely identifies the map and can contain up to 127 characters. If the given string is longer than 127 characters the routine will quit and return with MB_ERR_OVERFLOW.
In the parallel debug version, this routine is blocking and will return when all processes have issued and completed the call. This effectively synchronises all processes. It is the users' responsibility to ensure that all processes issue the call (in the same order if multiple maps are created).
If this routine returns with an error, im_ptr
will be set to MB_NULL_INDEXMAP.
Possible return codes:
name
already exists)name
is NULL)name
is too long)Usage example:
MBt_IndexMap map_id; /* our message datatype */ typedef struct { int recipient_id; double price; double value; } myMessageType; /* some function somewhere */ void func_itik(void) { int i, rc; /* create a map of agent IDs available on this processor */ rc = MB_IndexMap_Create(&map_id, "Agent ID"); assert(rc == MB_SUCCESS); /* loop thru local agents and add their IDs to map */ for (i = 0; i < agents_in_this_proc; i++) { rc = MB_IndexMap_AddEntry(map_id, agent[i].id); assert(rc == MB_SUCCESS); } /* map_id should now know which agents are in out local proc */ /* sync so it also knows which agents are in all remote procs */ rc = MB_IndexMap_Sync(map_id); assert(rc == MB_SUCCESS); /* map is not ready to be used in agent filter functions */ /* see filter_by_target_agents() */ /* .... other stuff ... */ /* Delete map when done */ rc = MB_IndexMap_Delete(&map_id); assert(rc == MB_SUCCESS); } /* example filter function that uses the IndexMap. This fucntion can * be registered using MB_Filter_Create() and assigned to boards * using MB_Filter_Assign() */ int filter_by_target_agents(const void *msg, int pid) { /* value of pid will be populated by the board sync mechanism * that runs the filter, and will contain the pid of the * target processor */ myMessageType *m = (myMessageType *)msg; if (MB_IndexMap_MemberOf(map_id, pid, m->recipient_id)) return 1; /*ok*/ else return 0; /* reject */ }
MB_IndexMap_Delete | ( | MBt_IndexMap * | im_ptr | ) |
Deletes an Index Map.
[in,out] | im_ptr | Address of Index Map handle |
Introduced in version 0.2.0.
Upon successful deletion, the handle referenced by im_ptr
will be set to MB_NULL_INDEXMAP.
If an error occurs, this routine will return an error code and im_ptr
will remain unchanged.
If a null board (MB_NULL_INDEXMAP) is given, the routine will return immediately with MB_SUCCESS
Possible return codes:
im
is invalid)Usage example: see MB_IndexMap_Create()
MB_IndexMap_AddEntry | ( | MBt_IndexMap | im, | |
int | value | |||
) |
Adds an entry into the Index Map.
[in] | im | Index Map handle |
[in] | value | Integer value of entry to add into the map |
Introduced in version 0.2.0.
Entry will be added to the local map. In the parallel version, this entry will be searchable on other processors after MB_IndexMap_Sync() is called.
Adding an entry that already exists will have no effect on the map and the routine will return successfully.
Possible return codes:
im
is null or invalid)Usage example: see MB_IndexMap_Create()
MB_IndexMap_Sync | ( | MBt_IndexMap | im | ) |
Distributes/gathers the map content across/from all processors.
[in] | im | Index Map handle |
Introduced in version 0.2.0.
In the serial library, this routine does nothing and returns immediately with MB_SUCCESS. It will however return with an appropriate error code if an invalid or null map is given.
In parallel, this routine is a blocking and collective operation. It is the users' responsibility to ensure that the routine is called on all processors to avoid deadlocks.
Contents of the map is distributed across all processors such that every processor will be able to determine if an entry exists in a map of any other processor using the MB_IndexMap_MemberOf() routine.
This routine should be called after all entries are added to the map (using MB_IndexMap_AddEntry()) and before and queries are made (using MB_IndexMap_MemberOf()).
Possible return codes:
im
is null or invalid)Usage example: see MB_IndexMap_Create()
MB_IndexMap_MemberOf | ( | MBt_IndexMap | im, | |
int | pid, | |||
int | value | |||
) |
Query the map to determine if a value exists on a particular processor.
[in] | im | Index Map handle |
[in] | pid | Target processor ID |
[in] | value | Value of entry to query for |
Introduced in version 0.2.0.
Returns MB_TRUE or MB_FALSE depending on whether value
exists in the map of processor with ID pid
.
MB_IndexMap_Sync() must be called on the map before this routine can be used.
In the serial library, pid
is ignored and the call to MB_IndexMap_Sync() is not compulsory but advisable.
Possible return codes:
value
exists in the specified map)value
does not exist in the specified map)pid
or im
is invalid or null)Usage example: see MB_IndexMap_Create()