Skip to content

Commit 7f7a5c3

Browse files
committed
add platform-specific fallback
1 parent 46bffa8 commit 7f7a5c3

File tree

1 file changed

+30
-1
lines changed

1 file changed

+30
-1
lines changed

include/core/composable/parallel_decorator.hpp

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,17 @@
22

33
#include "integrator_decorator.hpp"
44
#include <vector>
5-
#include <execution>
65
#include <thread>
76
#include <algorithm>
87
#include <ranges>
98
#include <type_traits>
109

10+
// Check for parallel execution support
11+
#if defined(__cpp_lib_execution) && __cpp_lib_execution >= 201902L
12+
#include <execution>
13+
#define PARALLEL_EXECUTION_AVAILABLE
14+
#endif
15+
1116
namespace diffeq::core::composable {
1217

1318
/**
@@ -120,13 +125,20 @@ class ParallelDecorator : public IntegratorDecorator<S> {
120125

121126
// Parallel processing
122127
try {
128+
#ifdef PARALLEL_EXECUTION_AVAILABLE
123129
std::for_each(std::execution::par_unseq,
124130
std::ranges::begin(states), std::ranges::end(states),
125131
[this, dt, end_time](auto& state) {
126132
// Create thread-local copy of integrator
127133
auto local_integrator = this->create_copy();
128134
local_integrator->integrate(state, dt, end_time);
129135
});
136+
#else
137+
// Sequential fallback for platforms without parallel execution support
138+
for (auto& state : states) {
139+
this->wrapped_integrator_->integrate(state, dt, end_time);
140+
}
141+
#endif
130142
} catch (const std::exception& e) {
131143
// Fall back to sequential processing if parallel fails
132144
for (auto& state : states) {
@@ -170,6 +182,7 @@ class ParallelDecorator : public IntegratorDecorator<S> {
170182

171183
// Parallel processing
172184
try {
185+
#ifdef PARALLEL_EXECUTION_AVAILABLE
173186
std::for_each(std::execution::par_unseq,
174187
std::views::iota(0UL, num_simulations).begin(),
175188
std::views::iota(0UL, num_simulations).end(),
@@ -179,6 +192,14 @@ class ParallelDecorator : public IntegratorDecorator<S> {
179192
local_integrator->integrate(state, dt, end_time);
180193
results[i] = processor(state);
181194
});
195+
#else
196+
// Sequential fallback for platforms without parallel execution support
197+
for (size_t i = 0; i < num_simulations; ++i) {
198+
auto state = generator(i);
199+
this->wrapped_integrator_->integrate(state, dt, end_time);
200+
results[i] = processor(state);
201+
}
202+
#endif
182203
} catch (const std::exception& e) {
183204
// Fall back to sequential processing if parallel fails
184205
for (size_t i = 0; i < num_simulations; ++i) {
@@ -222,11 +243,19 @@ class ParallelDecorator : public IntegratorDecorator<S> {
222243
static_cast<size_t>(std::distance(chunk_start, states_end))));
223244

224245
// Create range for this chunk and process in parallel
246+
#ifdef PARALLEL_EXECUTION_AVAILABLE
225247
std::for_each(std::execution::par_unseq, chunk_start, chunk_end,
226248
[this, dt, end_time](auto& state) {
227249
auto local_integrator = this->create_copy();
228250
local_integrator->integrate(state, dt, end_time);
229251
});
252+
#else
253+
// Sequential fallback for platforms without parallel execution support
254+
std::for_each(chunk_start, chunk_end,
255+
[this, dt, end_time](auto& state) {
256+
this->wrapped_integrator_->integrate(state, dt, end_time);
257+
});
258+
#endif
230259

231260
chunk_start = chunk_end;
232261
}

0 commit comments

Comments
 (0)