#include #include #include #include using namespace std; void DebugVector(const vector &xin, MPI_Comm icomm) { int rank, size; MPI_Comm_rank(icomm, &rank); MPI_Comm_size(icomm, &size); int next_process = 0; while (next_process != -1) { // Print the local vector for each process if (rank==next_process){ cout << "x_" << rank << " = "; for (const auto& value : xin) { cout << value << " "; } cout << endl; } MPI_Barrier(icomm); if (rank == 0) { cout << "Enter rank (0-" << size - 1 << ") or -1 to exit: "; cin >> next_process; } MPI_Bcast(&next_process, 1, MPI_INT, 0, icomm); MPI_Barrier(icomm); } } double par_scalar(const vector& x, const vector& y, MPI_Comm icomm) { double local_dot = 0.0; for (size_t i = 0; i < x.size(); ++i) { local_dot += x[i] * y[i]; } double global_dot = 0.0; MPI_Allreduce(&local_dot, &global_dot, 1, MPI_DOUBLE, MPI_SUM, icomm); return global_dot; } tuple find_global_minmax(const vector& xin, MPI_Comm icomm) { int rank, size; MPI_Comm_rank(icomm, &rank); MPI_Comm_size(icomm, &size); // Find local min/max double local_min = *min_element(xin.begin(), xin.end()); double local_max = *max_element(xin.begin(), xin.end()); // Gather local mins/maxs in vector vector local_min_vector(size); vector local_max_vector(size); MPI_Gather(&local_min, 1, MPI_DOUBLE, local_min_vector.data(), 1, MPI_DOUBLE, 0, icomm); MPI_Gather(&local_max, 1, MPI_DOUBLE, local_max_vector.data(), 1, MPI_DOUBLE, 0, icomm); // Find global min/max double global_min(0); double global_max(0); if (rank==0) { global_min = *min_element(local_min_vector.begin(), local_min_vector.end()); global_max = *max_element(local_max_vector.begin(), local_max_vector.end()); } // Broadcast global min/max MPI_Bcast(&global_min, 1, MPI_DOUBLE, 0, icomm); MPI_Bcast(&global_max, 1, MPI_DOUBLE, 0, icomm); return make_tuple(global_min, global_max); } tuple find_global_minmax_Allreduce(const vector& xin, MPI_Comm icomm) { double local_min = *min_element(xin.begin(), xin.end()); double local_max = *max_element(xin.begin(), xin.end()); double global_min(0); double global_max(0); MPI_Allreduce(&local_min, &global_min, 1, MPI_DOUBLE, MPI_MIN, icomm); MPI_Allreduce(&local_max, &global_max, 1, MPI_DOUBLE, MPI_MAX, icomm); return make_tuple(global_min, global_max); } int main(int argc, char *argv[]) { MPI_Comm icomm = MPI_COMM_WORLD; MPI_Init(&argc, &argv); int rank, size; MPI_Comm_rank(icomm, &rank); MPI_Comm_size(icomm, &size); if (rank==0) { cout << "\n There are " << size << " processes running.\n"; } // Create vectors size_t n=20; vector local_vector(n); vector local_vector_inv(n); for (size_t i=0; i recv(n); MPI_Alltoall(local_vector.data(), 5, MPI_DOUBLE, recv.data(), 5, MPI_DOUBLE, icomm); DebugVector(recv, icomm); MPI_Barrier(icomm); if (rank == 0) {printf("\n---- MPI_Alltoall using MPI_IN_PLACE ----\n");} MPI_Alltoall(MPI_IN_PLACE, 0, MPI_DATATYPE_NULL, local_vector.data(), 5, MPI_DOUBLE, icomm); DebugVector(local_vector, icomm); MPI_Finalize(); return 0; }