Methoddocs
Overview
Since the way transport methods function varies considerably, the interface
between ADIOS and the individual transports is richly interactive. Fortunately,
because ADIOS has a relatively simple end user API, the number of interation
points are modest. The short of it:
When the transport is selected in the XML, it is called with the opportunity
to create a private data structure. Then, with each call made at the end user
level that requires data manipulation and a few others mainly useful for
asynchronous routines, a call is made to the transport to handle/process the
data. Each transport can either rely on the provided functionality for things
like encoding/decoding or they can do it themselves fully.
<p>
Below is a list of the various C functions that are expected to be implemented
for every transport method. At a minimum, these functions will either call a
standard implementation or they can just perform no operation. Where the
method is in each name, it is expected a standardized transport method
specific simple name will be used instead. This will facilitate easy integration
into ADIOS. For an example of a standard, fully featured implementation, please
refer to the adios_mpi.c file containing the individual MPI method routines.
Transport Method Functions
void <a href="#init">adios_<i>method</i>_init</a> (const char * parameters, void ** method);
void <a href="#open">adios_<i>method</i>_open</a> (struct adios_file_struct * fd);
void <a href="#write">adios_<i>method</i>_write</a> (struct adios_file_struct * fd
,struct adios_field_struct * f
,void * data
);
void <a href="#write_get_buffer">adios_<i>method</i>_write_get_buffer</a> (struct adios_file_struct * fd
,struct adios_field_struct * f
,unsigned long long * size
,void ** buffer
);
void <a href="#read">adios_<i>method</i>_read</a> (struct adios_file_struct * fd
,struct adios_field_struct * f
,void * buffer
);
void <a href="#close">adios_<i>method</i>_close</a> (struct adios_file_struct * fd);
void <a href="#finalize">adios_<i>method</i>_finalize</a> (int mype, void * method_data);
void <a href="#end_iteration">adios_<i>method</i>_end_iteration</a> (void * method_data);
void <a href="#start_calculation">adios_<i>method</i>_start_calculation</a> (void * method_data);
void <a href="#stop_calculation">adios_<i>method</i>_stop_calculation</a> (void * method_data);
Function Details
void adios_method_init (const char * parameters, void ** method);
- parameters [IN] - the parameter string specified in the XML
- method [OUT] - a pointer for private data storage available during other calls to the method
<p> When a method is selected in the XML via naming it in the method attribute of the method element, this function is called to initialize the method. This will be called each time the method is specified in the XML so that each use of the method can be initialized separately. If there are any cross-usage settings necessary, it is the job of the transport method implementer to handle these details.
void adios_method_open (struct adios_file_struct * fd);
- fd [IN] - the full knowledge about the datatype being manipulated for write/read/append
For all 3 types of open operations (write, read, append), this call will be made for the transport method to initialize itself. The contents of the adios_file_struct contains the path, filename, mode, and other paramaters to determine how to perform the open properly.
void adios_method_write (struct adios_file_struct * fd ,struct adios_field_struct * f ,void * data );
- fd [IN] - the full knowledge about the datatype being manipulated for
- f [IN] - the field to be written
- data [IN] - the buffer of data to be written
For each call in the source code to adios_write, this call will be made to give the transport method the opportunity to do any particular handling of the data. The most important of these operations is to check the copy-on-write flag to know whether or not it is safe to hold a copy of the pointer or if some other means of perserving the data is necessary.
void adios_method_write_get_buffer (struct adios_file_struct * fd ,struct adios_field_struct * f ,unsigned long long * size ,void ** buffer );
- fd [IN] - the full knowledge about the datatype being manipulated for
- f [IN] - the field to be written
- size [IN] - the size required
- buffer [OUT] - the buffer to write into
This function gives the end user the ability to obtain a buffer into which they can write data for output. It is assumed that the end user knows how to convert the allocated pointer into something the host language can support. The purpose of this functionality is to provide a mechanism to avoid an additional copy of a temporary variable by having the transport method allocate some space that can be directly used to send the data downstream to storage or other processing.
void adios_method_read (struct adios_file_struct * fd ,struct adios_field_struct * f ,void * buffer );
- fd [IN] - the full knowledge about the datatype being manipulated for
- f [IN] - the field to be written
- buffer [IN] - the buffer to write the read data into
Specify the buffer into which to place the data of a data item being read.
void adios_method_close (struct adios_file_struct * fd);
- fd [IN] - the full knowledge about the datatype being manipulated for
Perform the close operation on a file stream (no matter the mode).
void adios_method_finalize (int mype, void * method_data);
- mype [IN] - my process id
- method_data [IN] - the method data created during the init call
When the code is being shutdown, this is called to give the transport method the opportunity to perform any graceful shutdown/cleanup operation. The addition of the process id is to make it easier to keep this to just a particular process if so desired.
void adios_method_end_iteration (void * method_data);
- method_data [IN] - the method data created during the init call
This is primarily intended for asynchronous methods to give them some feedback about how quickly the data in the buffers needs to be evacuated to be able to keep up with the running code. The hint in the XML states how many iterations should be used at most to evacuate a datatype. This call will give pacing information to the transport method.
void adios_method_start_calculation (void * method_data);
- method_data [IN] - the method data created during the init call
For asynchronous transport methods, it is important to schedule the communication phases to overlap with the primarily calculation phases of the code. This call indicates that the end user has determined that from this point until the end_calculation call the code will be essentially not using the network. This is the opportunity to use the bandwidth as much as possible.
void adios_method_stop_calculation (void * method_data);
- method_data [IN] - the method data created during the init call
For asynchronous transport methods, it is important to schedule the communication phases to overlap with the primarily calculation phases of the code. This call indicates that the end user has determined that it is no longer safe to use the network extensively because the main calculation phase of the code has completed.
Notes for Implementers
Several topics of specific importance to implementers are discussed in detail below.
Memory Management
Managing memory effectively and according to the contract specified in the XML file is crucial. The XML file specifies the maximum amount of memory the code programmer has allocated for IO purposes. It is essential that no transport method exceed that total for fear that users will abandon ADIOS in its entirety due to a sloppy implementation. It is acceptable to allocate a little memory for private use (think 10s of KB rather than anything approaching 1 MB). To handle allocating memory across all transport methods employed on a single code, a couple of memory "allocation" functions have been provided:
unsigned long long <a href="#buffer_alloc">adios_method_buffer_alloc</a> (unsigned long long size); int <a href="#buffer_free">adios_method_buffer_free</a> (unsigned long long size);
unsigned long long adios_method_buffer_alloc (unsigned long long size);
- size [IN] - the number of bytes requested
- return value [OUT] - the number of bytes allowed
When some memory is needed by a transport method, it is imperative to call this function to get an allocation of memory bytes from the pool available to ADIOS. This DOES NOT actually allocate any memory, but instead it lets ADIOS know that the transport method needs size bytes of memory. The return value is the number of bytes the transport method is allowed to use. This will be some number up to the size requested. If there is memory available, as much as is available up to the requested amount will be provided. Once this call has been made, no matter what value is returned, that memory is considered owned and allocated by the calling transport method. If that is not sufficient for some reason, it is imperative to free that memory for some other transport method to use by calling adios_method_buffer_free.
int adios_method_buffer_free (unsigned long long size);
- size [IN] - the number of bytes requested
Once memory is no longer needed, in addition to performing any deallocation operation within the transport method, it is imperative to tell ADIOS that
it is no longer being used and is available for other transport methods' use.