// ================================================================== // Author: Jean-Michel Richer // Email: jean-michel.richer@univ-angers.fr // Date: Aug 2020 // Last modified: September 2026 // Purpose: Demonstrate basic minimum functionaly on an array // The master create a big array and sends part of it to the // slaves // ================================================================== #include // for sleep #include #include #include #include #include #include using namespace std; #include "./ezmpi.hpp" using namespace ez::mpi; #include int initialization_method = 1; /** * run master and slaves */ void run(int argc, char* argv[]) { Process process(argc, argv); process.verbose(false); // the big vector for the master int big_vec_size = 100; vector big_vec; // reserve space for the local vector on eaxh process int local_vec_size = big_vec_size / process.nbr_processes(); vector local_vec(local_vec_size); if (process.is_master()) { big_vec.resize(big_vec_size); process << "- master local vector size=" << local_vec_size << endl; // obtain a random seed from the hardware random_device rd; // standard Mersenne Twister engine seeded with rd() mt19937 gen(rd()); uniform_int_distribution<> distrib(0, big_vec_size * 2); if (initialization_method == 1) { iota(big_vec.begin(), big_vec.end(), 1); reverse(big_vec.begin(), big_vec.end()); } else { // generate random values for the big vector generate(big_vec.begin(), big_vec.end(), [&]() { return distrib(gen); }); } process << "- big vector=" << big_vec << endl; } // distribution from the big vector to the local vectors as slices // for example if big_vec_size=100 et the number of processes is 4 // each process will get 25 elements process.scatter(big_vec, big_vec_size, local_vec); process << "- local vector=" << local_vec << endl; // each process (included the master) finds the minimum value in its // local vector int local_minimum = *std::min_element(local_vec.begin(), local_vec.end()); // each process reports the local minimum found in its local vector process << "- local minimum=" << local_minimum << endl; // perform reduction of a minimum // note: this code must be excuted by all processes int global_minimum = -1; process.reduce(local_minimum, global_minimum, MPI::MIN); if (process.is_master()) { process << "- global minimum=" << global_minimum << endl; } process.logs(cout); } // ============================================================== // version C++ // ============================================================== int main(int argc, char** argv) { int opt; while ((opt = getopt(argc, argv, "i:")) != -1) { switch (opt) { case 'i': initialization_method = std::stoi(optarg); break; default: cerr << "use -i 1 or -i 2 to initialize the big vector" << endl; } } if ((initialization_method < 1) or (initialization_method > 2)) { initialization_method = 1; } // call a function that contains the code for the master and // the slaves in order to avoid problems of initialization and // finalization of processes run(argc, argv); exit(EXIT_SUCCESS); }