![]() |
SFB 376 - Project A2The DIstributed VAriables Library |
[diva_init] reserves local memory for the simulated global memory on every processor. The amount of memory reserved can be controlled by a commandline parameter passed to the program. For example "ccsrun 1221 hello.exe -mem_size 1024" means that 1024 KB will be reserved for the global memory on every processor. If DIVA is running in an MPI environment, and MPI is not yet initialized, [diva_init] also initializes MPI and passes [*argc] and [*argv] to the MPI initialization function.
[diva_term] should be called by every processor at the end of a DIVA session. It synchronizes the complete system and releases all recources allocated by [diva_init], e.g., all allocated system buffers and spawned system threads. The user should ensure that all allcocated global variables and all generated groups (except for [DIVA_ALL] and [DIVA_SINGLE]) of a process have been released before it calls [diva_term].
If the corresponding [diva_init] call has initialized MPI, [diva_term] finalizes MPI.
The example program hello.c illustrates how these functions are used.
The function returns a handle for the created variable. This handle can be viewed as logical pointer to the variable. In the following we usually identify a global variable with its handle, i.e., "global variable [var]" means "the global variable associated with handle [var]".
The function has to be called by all processes which are members of the group [group]. For instance, if the group is [DIVA_ALL] then all processes have to call this function simultanously. Note that, for performance reasons, this function does not (necessarily) synchronize the calling processes. Thus, the processes must synchronized by barrier synchronizations before accessing the created variables.
In order to create a global variable by a single processor, this function can be called with group [DIVA_SINGLE]. Of course, then the global variable is known only by one processor. However, this processor can communicate the handle to other processors, which then also can access the respective global variable.
[diva_free] releases the global variable [var]. The function should be called by the processes which are members of [group]. It is in the users responsibility that all pending accesses to the global variable complete before [diva_free] is called.
These functions are illustrated in the example program hello.c.
[diva_write] writes the memory block pointed to by [buffer] into the global variable [var]. [diva_read] reads the global variable [var]. The content of [var] is copied into the local buffer pointed to by [buffer].
[diva_write] and [diva_read] are blocking, that means the calling thread is suspended until the respective read or write access is completed.
The example program hello.c illustrates how these function are used.
[diva_iwrite] writes the memory block pointed to by [buffer] into the global variable [var]. [diva_iread] reads the global variable [var]. The content of [var] is copied into the local buffer pointed to by [buffer]. A call to [diva_wait] returns when the read or write access corresponding to [request] is completed.
A call to [diva_test] returns 1 if the read or write access corresponding to [request] is completed, otherwise it returns 0.
The example program hello_nblock.c illustrates how the nonblocking access to variables can be used.
For instance, if diva_sync is called with parameter [DIVA_ALL], then each process in the system has to wait at a barrier until all processes have reached this barrier.
The example program hello.c illustrates how these barrier synchronizations work.
With [diva_slock] (soft lock) the calling process tries to obtain a lock on the respective variable. If the corresponding variable is not locked then this call locks the variable. If the variable is locked by another process the calling process is suspended until the lock is released, but the variable is not (!) locked. If the lock can not be realized, because another process has locked the variable, the function returns 0, otherwise it returns 1.
With [diva_unlock] a locked variable can be released by the process which locked it. All waiting accesses to the variable will be waked up.
The example program hello_lock.c illustrates the lock mechanism.
The function [diva_new_group] allows to generate new groups. In particular, it partitions the group associated with [old_group] into disjoint subgroups, one for each value of color. Each of the subgroups contains all processes of the same color.
The function must be called by any process of [old_group]. Besides to the group generation, the function synchronizes all processes in [old_group].
[diva_free_group] releases a group created with [diva_new_group]. The example program hello_groups.c illustrates the generation and release of groups.
[diva_init_func] announces a global operation to the system and returns
a func_id. The parameter [data_size] specifies the size of the operands
the operator works on. The second parameter is a pointer to the operator
function. This function, which has to be defined by the user, expects two
pointers to the input-datablocks. The result of the operation has to be
copied to the first datablock.
The user has to make sure that [diva_init_func] has been called on
every processor before the respective function is executed via [diva_exec_func].
[diva_exec_func] computes the global operation on the given operands. Every process of the specified group has to call [diva_exec_func], passing a pointer to his operand and the correct func_id to the function. After execution [operand] points to the result of the operation. The example program hello_op.c illustrates the use of [diva_init_func] and [diva_exec_func].
Garbage Collection Mechanism
[diva_id] returns the id of the calling process. The processes are always numbered from 0 to [diva_nprocs] - 1.