Parallel 2D smoothing data using PABLO.
The example is the parallel version of PABLO_example_00003.
In order to perform the smoothing procedure in parallel, ghost elements and data communications towards them are needed. Now ghost quadrants and ghost data are not only instantiated, as in example 00003, but actually used to perform smoothing across process borders.
The user data communication interfaces are based on the Couriously Recurrent Template Pattern. The user has to implement a specification of the interface by writing a derived class. In the files PABLO_userDataComm.hpp and PABLO_userDataComm.tpp an example of this specification is given in the case of user data stored in a POD container similar to the STL vector.
The class in PABLO_userDataComm.hpp is an example of user specification of the data communication interface based on the Curiously Recurrent Template Pattern. The user has to implement his interface class(es) in order to define how his data have to be written and read in the communication buffer. These classes have to be derived from the template base class bitpit::DataCommInterface using as template argument value the derived class. Like this,
The choice of the members of the class is completely up to the user and they have to be useful to access both internal and ghost data container. In the example user data datatype is given as template parameter in order to pass any container similar to the STL vector.
In any case, the user must at least implement all the methods reported in this example:
size_t fixedsize()
method: this method is automatically called by the manager and it is intended to define the constant size of the data to be communicated per grid element. If all the element of the grid communicate the same size of data, this method must return a value different from zero and equal to the number of byte to be communicated for every element. Otherwise, it must return zero and the different data size for each element must be specified by the size method size_t size(const uint32_t e)
method: this method is automatically called by the manager and it is intended to define the variable size of the data to be communicated of every grid element. In order to make the manager use this method, the fixedsize method has to return zero. Implementing this method, the user can pass the manager the specific data size to be communicated for the element e. [in] | index | of the internal element to be communicated. |
void gather(Buffer& buff, const uint32_t e)
method: this method is automatically called by the manager and it is intended to write user data to the char communication buffer. The user has to specify in its implementation the way data can be written in the char buffer. The manager provide the user with a buffer and a stream insertion (<<) operator in order to simply write POD data in the buffer. The user has to define the way his data can be written in the buffer by decomposing them in POD data and by using the stream insertion (<<) operator to store them in the buffer. In this example we suppose that data is a container of POD data having the random access operator. [in] | e | index of the internal element to be communicated. |
[in] | buff | is the char buffer used to communicate user data. |
void scatter(Buffer& buff, const uint32_t e)
method: this method is automatically called by the manager and it is intended to read user data from the char communication buffer and store them in the ghost data container. The user has to specify in its implementation the way data can be read from the char buffer. The manager provide the user with a buffer and its stream extraction (>>) operator in order to simply read POD data from the buffer. The user has to define the way his data can be read from the buffer by decomposing them in POD data and by using the buffer stream extraction (>>) operator to take them from the buffer and to store them in the ghost data container. In this example we suppose that ghostData is a container of POD data having the random access operator. [in] | e | index of the ghost element to be communicated. |
[in] | buff | is the char buffer used to communicate user data. The user has not to take care of the buffer, but its method write and read. These methods are intended to write/read POD data to/fromthe buffer. |
UserDataComm(Data& data_, Data& ghostdata_)
the constructor method: this method has to be called by the user in his application code. The user is free to implement his constructors as he wants, but he must guarantee the access to the internal and ghost data. In the code of this example application, pay attention to the use of the interface
To run: ./PABLO_example_00006
To see the result visit: PABLO website