4#include <fhsim/simobject/ISimObjectCreator.h>
27inline int ReadNumThreads(ISimObjectCreator* creator)
30 creator->GetIntParam(
"NumThreads", &numThreads, numThreads);
32 const std::string message =
"NumThreads = " + std::to_string(numThreads) +
" is negative; expected 0 (OpenMP's default), 1 (serial) or more.";
33 creator->ReportParameterError(
"NumThreads", message);
34 throw std::invalid_argument(message);
38 numThreads = omp_get_max_threads();
42 return std::max(numThreads, 1);
46inline int ChunkBegin(
const int count,
const int chunk,
const int chunks)
48 return count * chunk / chunks;
60template <
class UpdateNodes,
class AddForces>
61void SumForcesInChunks(
const int chunks,
const int numNodes, std::vector<double>& buffers,
double*
const nodeForce, UpdateNodes updateNodes, AddForces addForces)
63 const size_t bufferSize = 3 *
static_cast<size_t>(numNodes);
65# pragma omp parallel num_threads(chunks)
69 const int first = omp_get_thread_num();
70 const int stride = omp_get_num_threads();
75 for (
int chunk = first; chunk < chunks; chunk += stride)
76 updateNodes(ChunkBegin(numNodes, chunk, chunks), ChunkBegin(numNodes, chunk + 1, chunks));
80 for (
int chunk = first; chunk < chunks; chunk += stride) {
81 double*
const forces = buffers.data() + chunk * bufferSize;
82 std::fill(forces, forces + bufferSize, 0.0);
83 addForces(chunk, chunks, forces);
86 for (
int chunk = 0; chunk < chunks; chunk++) {
87 const double*
const forces = buffers.data() + chunk * bufferSize;
88 for (
size_t i = 0; i < bufferSize; i++)
89 nodeForce[i] += forces[i];