8 #include "eckit/config/LocalConfiguration.h"
10 #include "ioda/distribution/Accumulator.h"
11 #include "ioda/distribution/Distribution.h"
12 #include "ioda/distribution/DistributionUtils.h"
13 #include "ioda/distribution/InefficientDistribution.h"
14 #include "ioda/distribution/ReplicaOfNonoverlappingDistribution.h"
15 #include "ioda/distribution/ReplicaOfGeneralDistribution.h"
17 #include "oops/util/DateTime.h"
18 #include "oops/util/missingValues.h"
26 std::size_t numVariables,
const std::vector<T> &v) {
27 const T missingValue = util::missingValue(missingValue);
28 const std::size_t numLocations = v.size() / numVariables;
31 std::unique_ptr<Accumulator<std::size_t>> accumulator = dist.
createAccumulator<std::size_t>();
32 for (
size_t loc = 0, element = 0; loc < numLocations; ++loc) {
34 for (
size_t var = 0; var < numVariables; ++var, ++element)
35 if (v[element] != missingValue)
37 accumulator->addTerm(loc, term);
40 return accumulator->computeResult();
45 std::size_t numVariables,
46 const std::vector<T> &v1,
47 const std::vector<T> &v2) {
48 ASSERT(v1.size() == v2.size());
49 const T missingValue = util::missingValue(missingValue);
50 const std::size_t numLocations = v1.size() / numVariables;
53 std::unique_ptr<Accumulator<double>> accumulator = dist.
createAccumulator<
double>();
54 for (
size_t loc = 0, element = 0; loc < numLocations; ++loc) {
56 for (
size_t var = 0; var < numVariables; ++var, ++element)
57 if (v1[element] != missingValue && v2[element] != missingValue)
58 term += v1[element] * v2[element];
59 accumulator->addTerm(loc, term);
62 return accumulator->computeResult();
69 std::size_t numVariables,
70 const std::vector<double> &v1,
71 const std::vector<double> &v2) {
76 std::size_t numVariables,
77 const std::vector<float> &v1,
78 const std::vector<float> &v2) {
83 std::size_t numVariables,
84 const std::vector<int> &v1,
85 const std::vector<int> &v2) {
91 std::size_t numVariables,
92 const std::vector<double> &v) {
97 std::size_t numVariables,
98 const std::vector<float> &v) {
103 std::size_t numVariables,
104 const std::vector<int> &v) {
109 std::size_t numVariables,
110 const std::vector<std::string> &v) {
115 std::size_t numVariables,
116 const std::vector<util::DateTime> &v) {
122 const eckit::mpi::Comm & comm,
123 std::shared_ptr<const Distribution> master,
124 const std::vector<std::size_t> &masterRecordNums) {
125 if (master->isNonoverlapping())
126 return std::make_shared<ReplicaOfNonoverlappingDistribution>(comm, std::move(master));
127 else if (master->isIdentity())
128 return std::make_shared<InefficientDistribution>(comm, eckit::LocalConfiguration());
130 return std::make_shared<ReplicaOfGeneralDistribution>(comm, std::move(master),
class for distributing obs across multiple process elements
std::unique_ptr< Accumulator< T > > createAccumulator() const
Create an object that can be used to calculate the sum of a location-dependent quantity over location...
double dotProductImpl(const Distribution &dist, std::size_t numVariables, const std::vector< T > &v1, const std::vector< T > &v2)
std::size_t globalNumNonMissingObsImpl(const Distribution &dist, std::size_t numVariables, const std::vector< T > &v)
double dotProduct(const Distribution &dist, std::size_t numVariables, const std::vector< double > &v1, const std::vector< double > &v2)
std::size_t globalNumNonMissingObs(const Distribution &dist, std::size_t numVariables, const std::vector< double > &v)
std::shared_ptr< Distribution > createReplicaDistribution(const eckit::mpi::Comm &comm, std::shared_ptr< const Distribution > master, const std::vector< std::size_t > &masterRecordNums)
Create a suitable replica distribution for the distribution master.