3
\$\begingroup\$

I am learning MPI (via boost::mpi) and wrote this program that takes the euclidean norm of a 1-D vector (represented as an array here.) I want to make sure that I am using boost::mpi properly, in terms of both functions used and the way the code is parallelized.

The sample below is the program with just the norm functionality; it takes no input from the user and always uses the same seed for consistency reasons. Another limitation is that the vector size must be evenly divisible into the MPI world size.

I appreciate any comments and am thankful for your time.

#include <boost/mpi.hpp>
#include <chrono>
#include <cmath>
#include <iostream>
#include <numeric>
#include <random>
#include <utility>
#include <vector>
int main() {
 boost::mpi::environment env;
 boost::mpi::communicator world;
 //unsigned long TWIST_SEED = std::chrono::system_clock::now().time_since_epoch().count();
 unsigned long TWIST_SEED = 2;
 unsigned long VECT_SIZE = 10;
 double *main_vector = new double[VECT_SIZE];
 if (world.rank() == 0) {
 std::mt19937 generator(TWIST_SEED);
 std::uniform_real_distribution<double> dis(-222222.22, 222222.22);
 for (int i = 0; i < VECT_SIZE; i++) {
 main_vector[i] = dis(generator);
 }
 }
 int n_bar = VECT_SIZE / world.size();
 if (world.rank() == 0) {
 if (VECT_SIZE <= 10) {
 std::cout << "Your vector is small enough to output. It is: \n{";
 for (int i = 0; i < VECT_SIZE; i++) {
 if (i == VECT_SIZE - 1) {
 std::cout << main_vector[i];
 } else {
 std::cout << main_vector[i] << ", ";
 }
 }
 std::cout << "}" << std::endl;
 }
 }
 double *local_vector = new double[n_bar];
 boost::mpi::scatter(world, main_vector, local_vector, n_bar, 0);
 std::vector<double> dot;
 double local_dot = 0.0;
 for (int i = 0; i < n_bar; i++) {
 local_dot += local_vector[i] * local_vector[i];
 }
 boost::mpi::gather(world, local_dot, dot, 0);
 if (world.rank() == 0) {
 std::cout << "The norm is " << sqrt(std::accumulate(dot.begin(), dot.end(), 0.0)) << std::endl;
 }
 delete[] main_vector;
 return 0;
}
asked Feb 11, 2019 at 22:06
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

You've misspelt std::sqrt.

Calculation of 2D and 3D Euclidean norm is more accurate and efficient via std::hypot() - would it be reasonable to use that as a basis for the N-dimensional form?

As always, prefer standard containers such as std::vector over raw pointers created with new[].

answered Feb 12, 2019 at 9:36
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.