138#if !defined(__MPI_ATTRIBUTES_LANGUAGE_EXTENSION__)
140 + full_qualified_name
141 +
"""::Datatype = MPI_DATATYPE_NULL;
145[[clang::map_mpi_datatype]]
147 + full_qualified_name
148 +
"""::getForkDatatype() {
153[[clang::map_mpi_datatype]]
155 + full_qualified_name
156 +
"""::getGlobalCommunciationDatatype() {
161[[clang::map_mpi_datatype]]
163 + full_qualified_name
164 +
"""::getJoinDatatype() {
169[[clang::map_mpi_datatype]]
171 + full_qualified_name
172 +
"""::getBoundaryExchangeDatatype() {
177[[clang::map_mpi_datatype]]
179 + full_qualified_name
180 +
"""::getMultiscaleDataExchangeDatatype() {
185[[clang::map_mpi_datatype]]
187 + full_qualified_name
188 +
"""::freeForkDatatype() {
189 if (Datatype != MPI_DATATYPE_NULL){
190 MPI_Type_free(&Datatype);
191 Datatype = MPI_DATATYPE_NULL;
196[[clang::map_mpi_datatype]]
198 + full_qualified_name
199 +
"""::freeGlobalCommunciationDatatype() {
200 if (Datatype != MPI_DATATYPE_NULL){
201 MPI_Type_free(&Datatype);
202 Datatype = MPI_DATATYPE_NULL;
207[[clang::map_mpi_datatype]]
209 + full_qualified_name
210 +
"""::freeJoinDatatype() {
211 if (Datatype != MPI_DATATYPE_NULL){
212 MPI_Type_free(&Datatype);
213 Datatype = MPI_DATATYPE_NULL;
218[[clang::map_mpi_datatype]]
220 + full_qualified_name
221 +
"""::freeBoundaryExchangeDatatype() {
222 if (Datatype != MPI_DATATYPE_NULL){
223 MPI_Type_free(&Datatype);
224 Datatype = MPI_DATATYPE_NULL;
229[[clang::map_mpi_datatype]]
231 + full_qualified_name
232 +
"""::freeMultiscaleDataExchangeDatatype() {
233 if (Datatype != MPI_DATATYPE_NULL){
234 MPI_Type_free(&Datatype);
235 Datatype = MPI_DATATYPE_NULL;
241 + full_qualified_name
242 +
"""::getSenderRank() const {
243 return _senderDestinationRank;
249 + full_qualified_name
250 +
"""::initDatatype() {
251 #if !defined(__MPI_ATTRIBUTES_LANGUAGE_EXTENSION__)
253 + full_qualified_name
256 int NumberOfAttributes = 0;
261 if i._is_static
or i._is_const_static
or i._is_constexpr
or i._is_const:
265 result += construct_ifdef_string(i.ifdefs)
266 result +=
" NumberOfAttributes++;\n#endif \n"
268 result +=
" NumberOfAttributes++;\n"
271 MPI_Datatype* subtypes = new MPI_Datatype[NumberOfAttributes];
272 int* blocklen = new int[NumberOfAttributes];
273 MPI_Aint* disp = new MPI_Aint[NumberOfAttributes];
279 if i._is_static
or i._is_const_static
or i._is_constexpr
or i._is_const:
283 result += construct_ifdef_string(i.ifdefs)
284 for ii
in i.get_native_MPI_type():
285 result +=
" subtypes[counter] = " + ii[0] +
";\n"
286 result +=
" blocklen[counter] = " + str(ii[1]) +
";\n"
287 result +=
" counter++;\n"
292 MPI_Aint baseFirstInstance;
293 MPI_Aint baseSecondInstance;
294 MPI_Get_address( &instances[0], &baseFirstInstance );
295 MPI_Get_address( &instances[1], &baseSecondInstance );
301 if i._is_static
or i._is_const_static
or i._is_constexpr
or i._is_const:
306 result += construct_ifdef_string(i.ifdefs)
307 for ii
in i.get_first_plain_C_attribute():
308 result +=
" MPI_Get_address( &(instances[0]."
310 result +=
"), &disp[counter] );\n"
311 result +=
" counter++;\n"
317 MPI_Aint offset = disp[0] - baseFirstInstance;
318 MPI_Aint extent = baseSecondInstance - baseFirstInstance - offset;
319 for (int i=NumberOfAttributes-1; i>=0; i--) {
320 disp[i] = disp[i] - disp[0];
324 MPI_Datatype tmpType;
325 errorCode += MPI_Type_create_struct( NumberOfAttributes, blocklen, disp, subtypes, &tmpType );
326 errorCode += MPI_Type_create_resized( tmpType, offset, extent, &Datatype );
327 errorCode += MPI_Type_commit( &Datatype );
328 errorCode += MPI_Type_free( &tmpType );
329 if (errorCode) std::cerr << "error constructing MPI datatype in " << __FILE__ << ":" << __LINE__ << std::endl;
336 // invoke routine once to trigger lazy initialisation
339 getBoundaryExchangeDatatype();
340 getMultiscaleDataExchangeDatatype();
341 getGlobalCommunciationDatatype();
347 + full_qualified_name
348 +
"""::shutdownDatatype() {
349 #if !defined(__MPI_ATTRIBUTES_LANGUAGE_EXTENSION__)
352 freeBoundaryExchangeDatatype();
353 freeMultiscaleDataExchangeDatatype();
354 freeGlobalCommunciationDatatype();
356 MPI_Datatype type = Datatype;
357 MPI_Type_free( &type );
363 + full_qualified_name
364 +
"""::send(const """
365 + full_qualified_name
366 +
"""& buffer, int destination, int tag, MPI_Comm communicator ) {
367 MPI_Send( &buffer, 1, Datatype, destination, tag, communicator);
372 + full_qualified_name
374 + full_qualified_name
375 +
"""& buffer, int source, int tag, MPI_Comm communicator ) {
377 MPI_Recv( &buffer, 1, Datatype, source, tag, communicator, &status);
378 buffer._senderDestinationRank = status.MPI_SOURCE;
383 + full_qualified_name
386 + full_qualified_name
390 std::function<void()> startCommunicationFunctor,
391 std::function<void()> waitFunctor,
392 MPI_Comm communicator
394 MPI_Request sendRequestHandle;
396 MPI_Isend( &buffer, 1, Datatype, destination, tag, communicator, &sendRequestHandle );
397 MPI_Test( &sendRequestHandle, &flag, MPI_STATUS_IGNORE );
398 startCommunicationFunctor();
401 MPI_Test( &sendRequestHandle, &flag, MPI_STATUS_IGNORE );
407 + full_qualified_name
410 + full_qualified_name
414 std::function<void()> startCommunicationFunctor,
415 std::function<void()> waitFunctor,
416 MPI_Comm communicator
419 MPI_Request receiveRequestHandle;
421 MPI_Irecv( &buffer, 1, Datatype, source, tag, communicator, &receiveRequestHandle );
422 MPI_Test( &receiveRequestHandle, &flag, &status );
423 startCommunicationFunctor();
426 MPI_Test( &receiveRequestHandle, &flag, &status );
428 buffer._senderDestinationRank = status.MPI_SOURCE;