OpenMP pragmas inside WALBERLA_FOR_ALL_CELLS_ macros are broken
I'm currently trying to put a #pragma omp critical
into a loop created by one of the WALBERLA_FOR_ALL_CELLS_*
macros. Unfortunately, the preprocessor puts the pragma into the completely wrong place.
Here's a short code sample that exhibits the issue:
#include "field/iterators/IteratorMacros.h"
#include "field/Field.h"
#include <vector>
using namespace walberla;
int blah(Field<real_t, 1> * field)
{
std::vector<real_t> data;
WALBERLA_FOR_ALL_CELLS_XYZ( field,
_Pragma("omp critical")
data.push_back(field->get(x,y,z));
);
}
And after preprocessing, that becomes
using namespace walberla;
int blah(Field<real_t, 1> * field)
{
std::vector<real_t> data;
#pragma omp critical
{ (void(0)); const ::walberla::cell_idx_t xSize__ = ::walberla::cell_idx_c( (field)->xSize() ); const ::walberla::cell_idx_t ySize__ = ::walberla::cell_idx_c( (field)->ySize() ); const ::walberla::cell_idx_t zSize__ = ::walberla::cell_idx_c( (field)->zSize() ); if( zSize__ >= ySize__ ) { const int izSize = int_c( zSize__ );
#pragma omp parallel for schedule(static)
for( int iz = 0; iz < izSize; ++iz ) { ::walberla::cell_idx_t z = ::walberla::cell_idx_c( iz ); for( ::walberla::cell_idx_t y = ::walberla::cell_idx_t(0); y < ySize__; ++y ) { for( ::walberla::cell_idx_t x = ::walberla::cell_idx_t(0); x < xSize__; ++x ) { { data.push_back(field->get(x,y,z)); } } } } } else { const int iySize = int_c( ySize__ );
#pragma omp parallel for schedule(static)
for( int iy = 0; iy < iySize; ++iy ) { ::walberla::cell_idx_t y = ::walberla::cell_idx_c( iy ); for( ::walberla::cell_idx_t z = ::walberla::cell_idx_t(0); z < zSize__; ++z ) { for( ::walberla::cell_idx_t x = ::walberla::cell_idx_t(0); x < xSize__; ++x ) { { data.push_back(field->get(x,y,z)); } } } } } }
;
}
As you can see, the pragma moves to the outside of the loop, where it does no good. No amount of curly braces was able to fix this for me.