22using std::ranges::views::iota;
35 #define translateIntoCPPExecutionPolicyForParallelLoop( placement ) \
36 placement==peano4::utils::LoopPlacement::Serial ? std::execution::seq : std::execution::par
38 #define translateIntoCPPExecutionPolicyForSimtLoop( placement ) \
53#define parallelForWithSchedulerInstructions(counter, max, loopParallelism) \
55 auto counter##Range = iota(0, max); \
56 std::for_each( std::execution::par_unseq, counter##Range, [&]( const int counter ) {
63#define endParallelFor \
68#define parallelDforWithSchedulerInstructions2d(counter, max, loopParallelism) \
70 tarch::la::Vector<2, int> counter##Max(max); \
71 auto counter##Range0 = iota(0, counter##Max(0)); \
72 auto counter##Range1 = iota(0, counter##Max(1)); \
73 std::for_each( std::execution::par, cartesian_product( counter##Range0, counter##Range1 ), [&]( auto counter##Native ) { \
74 tarch::la::Vector<2, int> counter = { counter##Native[0], counter##Native[1] };
77#define parallelDforWithSchedulerInstructions3d(counter, max, loopParallelism) \
79 tarch::la::Vector<3, int> counter##Max(max); \
80 auto counter##Range0 = iota(0, counter##Max(0)); \
81 auto counter##Range1 = iota(0, counter##Max(1)); \
82 auto counter##Range2 = iota(0, counter##Max(2)); \
83 std::for_each( std::execution::par, cartesian_product( counter##Range0, counter##Range1, counter##Range2 ), [&]( auto counter##Native ) { \
84 tarch::la::Vector<3, int> counter = { counter##Native[0], counter##Native[1], counter##Native[2] };
87#define parallelDforWithSchedulerInstructions4d(counter, max, loopParallelism) \
89 tarch::la::Vector<4, int> counter##Max(max); \
90 auto counter##Range0 = iota(0, counter##Max(0)); \
91 auto counter##Range1 = iota(0, counter##Max(1)); \
92 auto counter##Range2 = iota(0, counter##Max(2)); \
93 auto counter##Range3 = iota(0, counter##Max(3)); \
94 std::for_each( std::execution::par, cartesian_product( counter##Range0, counter##Range1, counter##Range2, counter##Range3 ), [&]( auto counter##Native ) { \
95 tarch::la::Vector<4, int> counter = { counter##Native[0], counter##Native[1], counter##Native[2], counter##Native[3] };
98#define parallelDforWithSchedulerInstructions5d(counter, max, loopParallelism) \
100 tarch::la::Vector<5, int> counter##Max(max); \
101 auto counter##Range0 = iota(0, counter##Max(0)); \
102 auto counter##Range1 = iota(0, counter##Max(1)); \
103 auto counter##Range2 = iota(0, counter##Max(2)); \
104 auto counter##Range3 = iota(0, counter##Max(3)); \
105 auto counter##Range4 = iota(0, counter##Max(4)); \
106 std::for_each( std::execution::par, cartesian_product( counter##Range0, counter##Range1, counter##Range2, counter##Range3, counter##Range4 ), [&]( auto counter##Native ) { \
107 tarch::la::Vector<5, int> counter = { counter##Native[0], counter##Native[1], counter##Native[2], counter##Native[3], counter##Native[4] };
115#define endParallelDfor \
120#define simtForWithSchedulerInstructions(counter, max, loopParallelism) \
122 std::for_each( std::execution::par_unseq, iota(0, max), [&]( const int counter ) {
134#define simtDforWithSchedulerInstructions2d(counter, max, loopParallelism) \
136 tarch::la::Vector<2, int> counter##Max(max); \
137 auto counter##Range0 = iota(0, counter##Max(0)); \
138 auto counter##Range1 = iota(0, counter##Max(1)); \
139 std::for_each( std::execution::par_unseq, cartesian_product( counter##Range0, counter##Range1 ), [&]( auto counter##Native ) { \
140 tarch::la::Vector<2, int> counter = { counter##Native[0], counter##Native[1] };
143#define simtDforWithSchedulerInstructions3d(counter, max, loopParallelism) \
145 tarch::la::Vector<3, int> counter##Max(max); \
146 auto counter##Range0 = iota(0, counter##Max(0)); \
147 auto counter##Range1 = iota(0, counter##Max(1)); \
148 auto counter##Range2 = iota(0, counter##Max(2)); \
149 std::for_each( std::execution::par_unseq, cartesian_product( counter##Range0, counter##Range1, counter##Range2 ), [&]( auto counter##Native ) { \
150 tarch::la::Vector<3, int> counter = { counter##Native[0], counter##Native[1], counter##Native[2] };
153#define simtDforWithSchedulerInstructions4d(counter, max, loopParallelism) \
155 tarch::la::Vector<4, int> counter##Max(max); \
156 auto counter##Range0 = iota(0, counter##Max(0)); \
157 auto counter##Range1 = iota(0, counter##Max(1)); \
158 auto counter##Range2 = iota(0, counter##Max(2)); \
159 auto counter##Range3 = iota(0, counter##Max(3)); \
160 std::for_each( std::execution::par_unseq, cartesian_product( counter##Range0, counter##Range1, counter##Range2, counter##Range3 ), [&]( auto counter##Native ) { \
161 tarch::la::Vector<4, int> counter = { counter##Native[0], counter##Native[1], counter##Native[2], counter##Native[3] };
164#define simtDforWithSchedulerInstructions5d(counter, max, loopParallelism) \
166 tarch::la::Vector<5, int> counter##Max(max); \
167 auto counter##Range0 = iota(0, counter##Max(0)); \
168 auto counter##Range1 = iota(0, counter##Max(1)); \
169 auto counter##Range2 = iota(0, counter##Max(2)); \
170 auto counter##Range3 = iota(0, counter##Max(3)); \
171 auto counter##Range4 = iota(0, counter##Max(4)); \
172 std::for_each( std::execution::par_unseq, cartesian_product( counter##Range0, counter##Range1, counter##Range2, counter##Range3, counter##Range4 ), [&]( auto counter##Native ) { \
173 tarch::la::Vector<5, int> counter = { counter##Native[0], counter##Native[1], counter##Native[2], counter##Native[3], counter##Native[4] };
constexpr tl::views::detail::cartesian_product_fn cartesian_product