146#if !defined(__MPI_ATTRIBUTES_LANGUAGE_EXTENSION__)
148 + full_qualified_name
149 +
"""::Datatype = MPI_DATATYPE_NULL;
153[[clang::map_mpi_datatype]]
155 + full_qualified_name
156 +
"""::getForkDatatype() {
161[[clang::map_mpi_datatype]]
163 + full_qualified_name
164 +
"""::getGlobalCommunciationDatatype() {
169[[clang::map_mpi_datatype]]
171 + full_qualified_name
172 +
"""::getJoinDatatype() {
177[[clang::map_mpi_datatype]]
179 + full_qualified_name
180 +
"""::getBoundaryExchangeDatatype() {
185[[clang::map_mpi_datatype]]
187 + full_qualified_name
188 +
"""::getMultiscaleDataExchangeDatatype() {
193[[clang::map_mpi_datatype]]
195 + full_qualified_name
196 +
"""::freeForkDatatype() {
197 if (Datatype != MPI_DATATYPE_NULL){
198 MPI_Type_free(&Datatype);
199 Datatype = MPI_DATATYPE_NULL;
204[[clang::map_mpi_datatype]]
206 + full_qualified_name
207 +
"""::freeGlobalCommunciationDatatype() {
208 if (Datatype != MPI_DATATYPE_NULL){
209 MPI_Type_free(&Datatype);
210 Datatype = MPI_DATATYPE_NULL;
215[[clang::map_mpi_datatype]]
217 + full_qualified_name
218 +
"""::freeJoinDatatype() {
219 if (Datatype != MPI_DATATYPE_NULL){
220 MPI_Type_free(&Datatype);
221 Datatype = MPI_DATATYPE_NULL;
226[[clang::map_mpi_datatype]]
228 + full_qualified_name
229 +
"""::freeBoundaryExchangeDatatype() {
230 if (Datatype != MPI_DATATYPE_NULL){
231 MPI_Type_free(&Datatype);
232 Datatype = MPI_DATATYPE_NULL;
237[[clang::map_mpi_datatype]]
239 + full_qualified_name
240 +
"""::freeMultiscaleDataExchangeDatatype() {
241 if (Datatype != MPI_DATATYPE_NULL){
242 MPI_Type_free(&Datatype);
243 Datatype = MPI_DATATYPE_NULL;
249 + full_qualified_name
250 +
"""::getSenderRank() const {
251 return _senderDestinationRank;
257 + full_qualified_name
258 +
"""::initDatatype() {
259 #if !defined(__MPI_ATTRIBUTES_LANGUAGE_EXTENSION__)
261 + full_qualified_name
264 int NumberOfAttributes = 0;
269 if i._is_static
or i._is_const_static
or i._is_constexpr
or i._is_const:
273 result += construct_ifdef_string(i.ifdefs)
274 result +=
" NumberOfAttributes++;\n#endif \n"
276 result +=
" NumberOfAttributes++;\n"
279 MPI_Datatype* subtypes = new MPI_Datatype[NumberOfAttributes];
280 int* blocklen = new int[NumberOfAttributes];
281 MPI_Aint* disp = new MPI_Aint[NumberOfAttributes];
287 if i._is_static
or i._is_const_static
or i._is_constexpr
or i._is_const:
291 result += construct_ifdef_string(i.ifdefs)
292 for ii
in i.get_native_MPI_type():
293 result +=
" subtypes[counter] = " + ii[0] +
";\n"
294 result +=
" blocklen[counter] = " + str(ii[1]) +
";\n"
295 result +=
" counter++;\n"
300 MPI_Aint baseFirstInstance;
301 MPI_Aint baseSecondInstance;
302 MPI_Get_address( &instances[0], &baseFirstInstance );
303 MPI_Get_address( &instances[1], &baseSecondInstance );
309 if i._is_static
or i._is_const_static
or i._is_constexpr
or i._is_const:
314 result += construct_ifdef_string(i.ifdefs)
315 for ii
in i.get_first_plain_C_attribute():
316 result +=
" MPI_Get_address( &(instances[0]."
318 result +=
"), &disp[counter] );\n"
319 result +=
" counter++;\n"
325 MPI_Aint offset = disp[0] - baseFirstInstance;
326 MPI_Aint extent = baseSecondInstance - baseFirstInstance - offset;
327 for (int i=NumberOfAttributes-1; i>=0; i--) {
328 disp[i] = disp[i] - disp[0];
332 MPI_Datatype tmpType;
333 errorCode += MPI_Type_create_struct( NumberOfAttributes, blocklen, disp, subtypes, &tmpType );
334 errorCode += MPI_Type_create_resized( tmpType, offset, extent, &Datatype );
335 errorCode += MPI_Type_commit( &Datatype );
336 errorCode += MPI_Type_free( &tmpType );
337 if (errorCode) std::cerr << "error constructing MPI datatype in " << __FILE__ << ":" << __LINE__ << std::endl;
344 // invoke routine once to trigger lazy initialisation
347 getBoundaryExchangeDatatype();
348 getMultiscaleDataExchangeDatatype();
349 getGlobalCommunciationDatatype();
355 + full_qualified_name
356 +
"""::shutdownDatatype() {
357 #if !defined(__MPI_ATTRIBUTES_LANGUAGE_EXTENSION__)
360 freeBoundaryExchangeDatatype();
361 freeMultiscaleDataExchangeDatatype();
362 freeGlobalCommunciationDatatype();
364 MPI_Datatype type = Datatype;
365 MPI_Type_free( &type );
371 + full_qualified_name
372 +
"""::send(const """
373 + full_qualified_name
374 +
"""& buffer, int destination, int tag, MPI_Comm communicator ) {
375 MPI_Send( &buffer, 1, Datatype, destination, tag, communicator);
380 + full_qualified_name
382 + full_qualified_name
383 +
"""& buffer, int source, int tag, MPI_Comm communicator ) {
385 MPI_Recv( &buffer, 1, Datatype, source, tag, communicator, &status);
386 buffer._senderDestinationRank = status.MPI_SOURCE;
391 + full_qualified_name
394 + full_qualified_name
398 std::function<void()> startCommunicationFunctor,
399 std::function<void()> waitFunctor,
400 MPI_Comm communicator
402 MPI_Request sendRequestHandle;
404 MPI_Isend( &buffer, 1, Datatype, destination, tag, communicator, &sendRequestHandle );
405 MPI_Test( &sendRequestHandle, &flag, MPI_STATUS_IGNORE );
406 startCommunicationFunctor();
409 MPI_Test( &sendRequestHandle, &flag, MPI_STATUS_IGNORE );
415 + full_qualified_name
418 + full_qualified_name
422 std::function<void()> startCommunicationFunctor,
423 std::function<void()> waitFunctor,
424 MPI_Comm communicator
427 MPI_Request receiveRequestHandle;
429 MPI_Irecv( &buffer, 1, Datatype, source, tag, communicator, &receiveRequestHandle );
430 MPI_Test( &receiveRequestHandle, &flag, &status );
431 startCommunicationFunctor();
434 MPI_Test( &receiveRequestHandle, &flag, &status );
436 buffer._senderDestinationRank = status.MPI_SOURCE;