Program Listing for File SimRunner.cu
↰ Return to documentation for file (src/flamegpu/simulation/detail/SimRunner.cu
)
#include "flamegpu/simulation/detail/SimRunner.h"
#include "flamegpu/simulation/RunPlanVector.h"
namespace flamegpu {
namespace detail {
SimRunner::SimRunner(const std::shared_ptr<const ModelData> _model,
std::atomic<unsigned int> &_err_ct,
std::atomic<unsigned int> &_next_run,
const RunPlanVector &_plans,
std::shared_ptr<const StepLoggingConfig> _step_log_config,
std::shared_ptr<const LoggingConfig> _exit_log_config,
int _device_id,
unsigned int _runner_id,
flamegpu::Verbosity _verbosity,
bool _fail_fast,
std::map<unsigned int, RunLog> &_run_logs,
std::queue<unsigned int> &_log_export_queue,
std::mutex &_log_export_queue_mutex,
std::condition_variable &_log_export_queue_cdn,
std::vector<ErrorDetail> &_err_detail,
const unsigned int _total_runners,
bool _isSWIG)
: AbstractSimRunner(
_model,
_err_ct,
_next_run,
_plans,
_step_log_config,
_exit_log_config,
_device_id,
_runner_id,
_verbosity,
_run_logs,
_log_export_queue,
_log_export_queue_mutex,
_log_export_queue_cdn,
_err_detail,
_total_runners,
_isSWIG)
, fail_fast(_fail_fast) { }
void SimRunner::main() {
unsigned int run_id = 0;
// While there are still plans to process
while ((run_id = next_run++) < plans.size()) {
try {
runSimulation(run_id);
// Print progress to console
if (verbosity >= Verbosity::Default) {
const int progress = static_cast<int>(next_run.load()) - static_cast<int>(total_runners) + 1;
fprintf(stdout, "\rCUDAEnsemble progress: %d/%u", progress < 1 ? 1 : progress, static_cast<unsigned int>(plans.size()));
fflush(stdout);
}
} catch(std::exception &e) {
++err_ct;
if (this->fail_fast) {
// Kill the other workers early
next_run += static_cast<unsigned int>(plans.size());
{
// log_export_mutex is treated as our protection for race conditions on err_detail
std::lock_guard<std::mutex> lck(log_export_queue_mutex);
log_export_queue.push(UINT_MAX);
// Build the error detail (fixed len char array for string)
err_detail.push_back(ErrorDetail{run_id, static_cast<unsigned int>(device_id), runner_id, });
strncpy(err_detail.back().exception_string, e.what(), sizeof(ErrorDetail::exception_string)-1);
err_detail.back().exception_string[sizeof(ErrorDetail::exception_string) - 1] = '\0';
}
return;
} else {
// Progress flush
if (verbosity >= Verbosity::Default) {
fprintf(stdout, "\n");
fflush(stdout);
}
if (verbosity > Verbosity::Quiet)
fprintf(stderr, "Warning: Run %u failed on device %d, thread %u with exception: \n%s\n", run_id, device_id, runner_id, e.what());
}
}
}
}
} // namespace detail
} // namespace flamegpu