16 #include "utils/HDFDatabase.h"
17 #include "utils/mpi_utils.h"
38 d_distributed(distributed),
41 CAROM_VERIFY(
dim > 0);
44 MPI_Initialized(&mpi_init);
46 MPI_Comm_size(MPI_COMM_WORLD, &d_num_procs);
47 MPI_Comm_rank(MPI_COMM_WORLD, &d_rank);
62 d_distributed(distributed),
63 d_owns_data(copy_data)
65 CAROM_VERIFY(vec != 0);
66 CAROM_VERIFY(
dim > 0);
69 memcpy(d_vec, vec, d_alloc_size*
sizeof(
double));
77 MPI_Initialized(&mpi_init);
79 MPI_Comm_size(MPI_COMM_WORLD, &d_num_procs);
80 MPI_Comm_rank(MPI_COMM_WORLD, &d_rank);
92 d_distributed(other.d_distributed),
97 MPI_Initialized(&mpi_init);
99 MPI_Comm_size(MPI_COMM_WORLD, &d_num_procs);
100 MPI_Comm_rank(MPI_COMM_WORLD, &d_rank);
106 memcpy(d_vec, other.d_vec, d_alloc_size*
sizeof(
double));
111 if (d_owns_data && d_vec) {
120 d_distributed = rhs.d_distributed;
121 d_num_procs = rhs.d_num_procs;
123 memcpy(d_vec, rhs.d_vec, d_dim*
sizeof(
double));
131 CAROM_ASSERT(d_dim == rhs.d_dim);
132 for(
int i=0; i<d_dim; ++i) d_vec[i] += rhs.d_vec[i];
140 CAROM_ASSERT(d_dim == rhs.d_dim);
141 for(
int i=0; i<d_dim; ++i) d_vec[i] -= rhs.d_vec[i];
148 for(
int i=0; i<d_dim; ++i) d_vec[i] = a;
155 for(
int i=0; i<d_dim; ++i) d_vec[i] *= a;
162 transformer(d_dim, d_vec);
168 std::function<
void(
const int size,
double* vector)> transformer)
const {
170 result.d_distributed = d_distributed;
171 transformer(d_dim, result.d_vec);
176 std::function<
void(
const int size,
double* origVector,
double* resultVector)>
179 transformer(d_dim, origVector->d_vec, d_vec);
186 std::function<
void(
const int size,
double* origVector,
double* resultVector)>
190 result.d_distributed = d_distributed;
191 transformer(d_dim, origVector->d_vec, result.d_vec);
197 const Vector& other)
const
199 CAROM_ASSERT(
dim() == other.
dim());
202 double local_ip = 0.0;
203 for (
int i = 0; i < d_dim; ++i) {
204 local_ip += d_vec[i]*other.d_vec[i];
206 if (d_num_procs > 1 && d_distributed) {
207 MPI_Allreduce(&local_ip, &ip, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
232 double Norm =
norm();
233 for (
int i = 0; i < d_dim; ++i) {
246 CAROM_ASSERT(
dim() == other.
dim());
252 for (
int i = 0; i < d_dim; ++i) {
253 result.d_vec[i] = d_vec[i] + other.d_vec[i];
265 CAROM_ASSERT(
dim() == other.
dim());
271 for (
int i = 0; i < d_dim; ++i) {
272 result.d_vec[i] = d_vec[i] + factor*other.d_vec[i];
282 CAROM_ASSERT(
dim() == other.
dim());
285 for (
int i = 0; i < d_dim; ++i) {
286 d_vec[i] += factor*other.d_vec[i];
297 CAROM_ASSERT(
dim() == other.
dim());
303 for (
int i = 0; i < d_dim; ++i) {
304 result.d_vec[i] = d_vec[i] - other.d_vec[i];
319 for (
int i = 0; i < d_dim; ++i) {
320 result.d_vec[i] = factor*d_vec[i];
327 CAROM_ASSERT(!base_file_name.empty());
330 MPI_Initialized(&mpi_init);
333 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
340 sprintf(tmp,
".%06d", rank);
341 std::string full_file_name = base_file_name + tmp;
343 database.
create(full_file_name);
345 sprintf(tmp,
"distributed");
349 sprintf(tmp,
"data");
358 const bool success = MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
359 CAROM_ASSERT(success);
361 std::string filename_str = prefix + std::to_string(my_rank);
362 const char * filename = filename_str.c_str();
363 FILE * pFile = fopen(filename,
"w");
364 for (
int k = 0; k < d_dim; ++k) {
365 fprintf(pFile,
" %25.20e\n", d_vec[k]);
373 CAROM_ASSERT(!base_file_name.empty());
376 MPI_Initialized(&mpi_init);
379 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
386 sprintf(tmp,
".%06d", rank);
387 std::string full_file_name = base_file_name + tmp;
389 database.
open(full_file_name,
"r");
391 sprintf(tmp,
"distributed");
399 sprintf(tmp,
"data");
403 MPI_Comm_size(MPI_COMM_WORLD, &d_num_procs);
414 CAROM_ASSERT(!base_file_name.empty());
417 MPI_Initialized(&mpi_init);
420 sprintf(tmp,
".%06d", rank);
421 std::string full_file_name = base_file_name + tmp;
423 database.
open(full_file_name,
"r");
425 sprintf(tmp,
"distributed");
433 sprintf(tmp,
"data");
437 MPI_Comm_size(MPI_COMM_WORLD, &d_num_procs);
447 const int n = nmax > 0 ? nmax : d_dim;
450 for (
int i=1; i<n; ++i)
463 CAROM_VERIFY(d_owns_data);
464 CAROM_VERIFY(local_dim >= 0);
466 std::vector<int> row_offsets;
469 CAROM_VERIFY(global_dim == d_dim);
470 int local_offset = row_offsets[d_rank];
471 const int new_size = local_dim;
473 double *d_new_vec =
new double [new_size];
475 memcpy(d_new_vec, &d_vec[local_offset], 8 * new_size);
479 d_alloc_size = new_size;
482 d_distributed =
true;
489 CAROM_VERIFY(d_owns_data);
491 std::vector<int> row_offsets;
494 const int new_size = global_dim;
496 int *data_offsets =
new int[row_offsets.size() - 1];
497 int *data_cnts =
new int[row_offsets.size() - 1];
498 for (
int k = 0; k < row_offsets.size() - 1; k++)
500 data_offsets[k] = row_offsets[k];
501 data_cnts[k] = (row_offsets[k+1] - row_offsets[k]);
504 double *d_new_vec =
new double [new_size] {0.0};
505 CAROM_VERIFY(MPI_Allgatherv(d_vec, d_dim, MPI_DOUBLE,
506 d_new_vec, data_cnts, data_offsets, MPI_DOUBLE,
507 MPI_COMM_WORLD) == MPI_SUCCESS);
510 delete [] data_offsets;
513 d_alloc_size = new_size;
516 d_distributed =
false;
528 Vector centroid(*points[0]);
529 for (
int i = 1; i < points.size(); i++) {
530 centroid += *points[i];
532 centroid.
mult(1.0 / points.size(), centroid);
534 double min_dist_to_centroid;
535 for (
int i = 0; i < points.size(); i++) {
537 centroid.
minus(*points[i], diff);
538 double dist_to_centroid = diff.
norm();
539 if (i == 0 || dist_to_centroid < min_dist_to_centroid)
541 min_dist_to_centroid = dist_to_centroid;
551 std::vector<double> dist_to_points(points.size(), 0);
552 for (
int i = 0; i < points.size(); i++) {
553 for (
int j = i + 1; j < points.size(); j++) {
555 points[i]->
minus(*points[j], diff);
556 double dist = diff.
norm();
557 dist_to_points[i] += dist;
558 dist_to_points[j] += dist;
562 double closest_dist_to_points = INT_MAX;
563 for (
int i = 0; i < dist_to_points.size(); i++) {
564 if (dist_to_points[i] < closest_dist_to_points)
566 closest_dist_to_points = dist_to_points[i];
578 std::vector<const Vector*> temp_points;
579 for (
int i = 0; i < points.size(); i++)
581 temp_points.push_back(&points[i]);
587 const Vector & test_point)
589 int closest_point = 0;
590 double closest_dist_to_test_point = INT_MAX;
591 for (
int i = 0; i < points.size(); i++) {
593 test_point.
minus(*points[i], diff);
594 double dist = diff.
norm();
595 if (dist < closest_dist_to_test_point)
597 closest_dist_to_test_point = dist;
602 return closest_point;
606 const Vector & test_point)
608 std::vector<const Vector*> temp_points;
609 for (
int i = 0; i < points.size(); i++)
611 temp_points.push_back(&points[i]);
void getInteger(const std::string &key, int &data)
Reads an integer associated with the supplied key from the currently open database file.
void putInteger(const std::string &key, int data)
Writes an integer associated with the supplied key to currently open database file.
virtual void getDoubleArray(const std::string &key, double *data, int nelements, const bool distributed=false) override
Reads an array of doubles associated with the supplied key from the currently open HDF5 database file...
virtual bool create(const std::string &file_name, const MPI_Comm comm=MPI_COMM_NULL) override
Creates a new HDF5 database file with the supplied name.
virtual bool open(const std::string &file_name, const std::string &type, const MPI_Comm comm=MPI_COMM_NULL) override
Opens an existing HDF5 database file with the supplied name.
virtual void putDoubleArray(const std::string &key, const double *const data, int nelements, const bool distributed=false) override
Writes an array of doubles associated with the supplied key to the currently open HDF5 database file.
virtual bool close() override
Closes the currently open HDF5 database file.
void setSize(int dim)
Sets the length of the vector and reallocates storage if needed. All values are initialized to zero.
void read(const std::string &base_file_name)
read Vector from (a) HDF file(s).
Vector & operator-=(const Vector &rhs)
Subtraction operator.
bool distributed() const
Returns true if the Vector is distributed.
void print(const char *prefix) const
print Vector into (a) ascii file(s).
void distribute(const int local_dim)
Distribute this vector among MPI processes, based on the specified local dimension....
double norm() const
Form the norm of this.
double normalize()
Normalizes the Vector and returns its norm.
std::unique_ptr< Vector > minus(const Vector &other) const
Subtracts other and this and returns the result.
void write(const std::string &base_file_name)
write Vector into (a) HDF file(s).
std::unique_ptr< Vector > plus(const Vector &other) const
Adds other and this and returns the result.
std::unique_ptr< Vector > plusAx(double factor, const Vector &other) const
Adds factor*other and this and returns the result.
Vector & operator=(const Vector &rhs)
Assignment operator.
double inner_product(const Vector &other) const
Inner product, reference form.
void plusEqAx(double factor, const Vector &other)
Adds factor*other to this.
std::unique_ptr< Vector > mult(double factor) const
Multiplies this by the supplied constant and returns the result.
double norm2() const
Form the squared norm of this.
Vector & transform(std::function< void(const int size, double *vector)> transformer)
Transform the vector using a supplied function.
Vector & operator+=(const Vector &rhs)
Addition operator.
double localMin(int nmax=0)
Compute the local minimum of this.
void local_read(const std::string &base_file_name, int rank)
read read a single rank of a distributed Vector from (a) HDF file(s).
int dim() const
Returns the dimension of the Vector on this processor.
Vector & operator*=(const double &a)
Scaling operator.
void gather()
Gather all the distributed elements among MPI processes. This becomes not distributed after this func...
int getCenterPoint(const std::vector< const Vector * > &points, bool use_centroid)
Get center point of a group of points.
int get_global_offsets(const int local_dim, std::vector< int > &offsets, const MPI_Comm &comm)
Save integer offsets for each MPI rank under MPI communicator comm, where each rank as the size of lo...
int getClosestPoint(const std::vector< const Vector * > &points, const Vector &test_point)
Get closest point to a test point among a group of points.