The cheetah_core interface is the the core set of C routines that handle moving bits between contexts and invoking appropriate operations there. The fundamental operations are:
void cheetah_core_setup(int *argc, int ***argv)
The user passes a pointer to the arguments to the function main, and the library parses the arguments to pull out the information it needs. The only guaranteed command line argument for this to parse is -np #, for the number of contexts.The teardown function is:
void cheetah_core_finalize()
This does a barrier to wait for all contexts to reach this point, then it gets rid of the parallelism. After this function is called, no other cheetah_core functions can be used. Whether all of the contexts but one have actually been destroyed at this point or not is implementation dependent.
int cheetah_core_ncontexts()
Return the total number of contexts that have been started up.
int cheetah_core_mycontext()
A unique identifier for this context in the range [0..ncontexts()-1].
In the current implementation, doorbells are just integers. A thread safe implementation would substitute a doorbell that can be incremented safely from multiple threads simultaneously.The intended use of a doorbell is that a series of asynchronous operations are begun with a given doorbell. Each increments ("rings") the doorbell at an appropriate time. The rest of the code can then wait until the doorbell reaches a given value to be sure that all of the asynchronous operations have completed.
void cheetah_core_put(int context, void *remote, void *local, int length, int *local_bell, int *remote_bell)
context: The integer (as from cheetah_core_mycontext()) identifier for the remote context.It is important to keep in mind that no synchronization is guaranteed by this function before writing the remote data. You can think of this as an interface to a DMA engine, and all synchronization has to be performed outside of this call.
remote: A pointer valid in the remote context for where to put the buffer.
local: A pointer valid in this context for where to get the buffer.
length: The length in bytes of the buffer.
local_bell: The local bell. This bell is rung (in the current context) when the buffer on this side can be reused.
remote_bell: The remote bell. This bell is rung (in the remote context) when that context can use the destination buffer.
void cheetah_core_get(int context, void *remote, void *local, int length, int *local_bell, int *remote_bell)
context: The integer (as from cheetah_core_mycontext()) identifier for the remote context.It is important to keep in mind that no synchronization is guaranteed by this function before writing the remote data. You can think of this as an interface to a DMA engine, and all synchronization has to be performed outside of this call.
remote: A pointer valid in the remote context for where to get the buffer.
local: A pointer valid in this context for where to put the buffer.
length: The length in bytes of the buffer.
local_bell: The local bell. This bell is rung (in the current context) when the buffer on this side can be used.
remote_bell: The remote bell. This bell is rung (in the remote context) when that context can reuse the source buffer.
void cheetah_core_register(int tag, void (*handler)(int who, int tag, void* buffer, int length) )
tag: The tag the user will use to indicate this function.
handler: The function pointer to associate with this tag. The same function can be registered with multiple tags. The arguments to this function are:who: The context that issued the ainvoke
tag: The tag that was used to call this function.
buffer: The buffer of data the user supplied in the ainvoke.
length: The length in bytes of the buffer.
void cheetah_core_ainvoke(int context, int tag, void *buffer, int length, int *local_bell)
context: The context in which the function should be executed.The handler function could perform an arbitrary computation (including calling other cheetah functions), and it is the user's responsibility to ensure that the handler returns sufficiently rapidly that the system does not hang.
tag: The function to be invoked.
buffer: The buffer of data to pass to the handler in the remote context.
length: The length in bytes of the buffer.
local_bell: The bell to ring when the local buffer can be reused.
No synchronization is done before calling the handler in the remote context, so if the user's code has to do any synchronization, it must either ensure it calls the ainvoke at a legal time, or inside of the function being called it much check for any synchronization conditions.
The handler function should not free the buffer pointer it is given, and neither may it capture a pointer to the buffer. The system is allowed to free the buffer upon the return of the handler.
void cheetah_core_poll()The poll call takes no arguments. It potentially has side effects in that it could perform a get (which could ring a local bell), a put (which could deposit memory locally and possibly ring a local bell), or an ainvoke (which could do an arbitrary computation).
cheetah_core_wait(int *bell, int value)
bell: The bell we're waiting for.
value: The value the bell should get to. It returns when the *bell >= value.
void cheetah_core_barrier()