From b26d44a2fec0e36aa73f6ae0c522dabf31b78530 Mon Sep 17 00:00:00 2001 From: "g.mandl" Date: Wed, 7 Jan 2026 01:00:22 +0100 Subject: [PATCH] Sheet 7 (7_3) --- Sheet_7/bsp_7_3/Makefile | 23 ++++++ Sheet_7/bsp_7_3/main.cpp | 64 +++++++++++++++ Sheet_7/bsp_7_3/results_7_3.txt | 90 ++++++++++++++++++++ Sheet_7/bsp_7_3/vec_func.cpp | 141 ++++++++++++++++++++++++++++++++ Sheet_7/bsp_7_3/vec_func.h | 31 +++++++ 5 files changed, 349 insertions(+) create mode 100644 Sheet_7/bsp_7_3/Makefile create mode 100644 Sheet_7/bsp_7_3/main.cpp create mode 100644 Sheet_7/bsp_7_3/results_7_3.txt create mode 100644 Sheet_7/bsp_7_3/vec_func.cpp create mode 100644 Sheet_7/bsp_7_3/vec_func.h diff --git a/Sheet_7/bsp_7_3/Makefile b/Sheet_7/bsp_7_3/Makefile new file mode 100644 index 0000000..bce6301 --- /dev/null +++ b/Sheet_7/bsp_7_3/Makefile @@ -0,0 +1,23 @@ +# +# Compile with +# make 2>&1 | grep -v openmpi +# to avoid warnings caused by OpenMPI + +# use GNU-Compiler tools +COMPILER=GCC_ +# alternatively from the shell +# export COMPILER=GCC_ +# or, alternatively from the shell +# make COMPILER=GCC_ + +MAIN = main +SOURCES = ${MAIN}.cpp vec_func.cpp +OBJECTS = $(SOURCES:.cpp=.o) + +PROGRAM = ${MAIN}.${COMPILER} + +# uncomment the next to lines for debugging and detailed performance analysis +CXXFLAGS += -g +LINKFLAGS += + +include ../${COMPILER}default.mk diff --git a/Sheet_7/bsp_7_3/main.cpp b/Sheet_7/bsp_7_3/main.cpp new file mode 100644 index 0000000..e84dbb7 --- /dev/null +++ b/Sheet_7/bsp_7_3/main.cpp @@ -0,0 +1,64 @@ +// MPI code in C++. +// See [Gropp/Lusk/Skjellum, "Using MPI", p.33/41 etc.] +// and /opt/mpich/include/mpi2c++/comm.h for details + +#include "vec_func.h" +#include // MPI +#include +using namespace std; + +int main(int argc, char *argv[]) +{ + MPI_Comm icomm = MPI_COMM_WORLD; + MPI_Init(&argc, &argv); + + int myrank; + MPI_Comm_rank(icomm, &myrank); + + // E5 + vector x(10,3); + if(myrank==0) {cout << endl << "E5" << endl;} + vecdebug(x, icomm); + + // E6 + vector y(10,1.0/3); + double res = par_scalar(x,y,icomm); + if(myrank==0) + { + cout << endl << endl << "E6" << endl; + cout << " = " << res << endl << endl; + } + + // E7 + vector a{myrank*10, myrank*10-1, myrank*10-2}; + if(myrank==0) {cout << "E7\n" << "original vector" << endl;} + vecdebug(a, icomm); + double min_val, max_val; + min_max_exch(a, min_val, max_val, icomm); + if(myrank==0) {cout << "min = " << min_val << "\tmax = " << max_val << endl << endl << "vector after changing min-max" << endl;} + vecdebug(a, icomm); + + // E8 + int n = 20; + vector c(n); + for(size_t i=0; i recv(n); + MPI_Alltoall(c.data(), 5, MPI_DOUBLE, recv.data(), 5, MPI_DOUBLE, icomm); + if(myrank==0) {cout << endl << "Ex 8\n" << "Alltoall" << endl;} + vecdebug(recv, icomm); + + MPI_Alltoall(MPI_IN_PLACE, 0, MPI_DATATYPE_NULL, c.data(), 5, MPI_DOUBLE, icomm); + if(myrank==0) {cout << endl << "Ex 8\n" << "Alltoall - IN_PLACE" << endl;} + vecdebug(c, icomm); + + + + MPI_Finalize(); + + return 0; +} + + diff --git a/Sheet_7/bsp_7_3/results_7_3.txt b/Sheet_7/bsp_7_3/results_7_3.txt new file mode 100644 index 0000000..666e9ac --- /dev/null +++ b/Sheet_7/bsp_7_3/results_7_3.txt @@ -0,0 +1,90 @@ +/usr/bin/mpirun --oversubscribe -display-map -mca btl ^openib -np 4 ./main.GCC_ + Data for JOB [39743,1] offset 0 Total slots allocated 4 + + ======================== JOB MAP ======================== + + Data for node: LAPTOP-LTDL04HH Num slots: 4 Max slots: 0 Num procs: 4 + Process OMPI jobid: [39743,1] App: 0 Process rank: 0 Bound: UNBOUND + Process OMPI jobid: [39743,1] App: 0 Process rank: 1 Bound: UNBOUND + Process OMPI jobid: [39743,1] App: 0 Process rank: 2 Bound: UNBOUND + Process OMPI jobid: [39743,1] App: 0 Process rank: 3 Bound: UNBOUND + + ============================================================= + +E5 + +Choose next process for printing vector (0-3): 0 +x_0 = 3 (0) x_1 = 3 (0) x_2 = 3 (0) x_3 = 3 (0) x_4 = 3 (0) x_5 = 3 (0) x_6 = 3 (0) x_7 = 3 (0) x_8 = 3 (0) x_9 = 3 (0) + +Choose next process for printing vector (0-3): 1 +x_0 = 3 (1) x_1 = 3 (1) x_2 = 3 (1) x_3 = 3 (1) x_4 = 3 (1) x_5 = 3 (1) x_6 = 3 (1) x_7 = 3 (1) x_8 = 3 (1) x_9 = 3 (1) + +Choose next process for printing vector (0-3): 2 +x_0 = 3 (2) x_1 = 3 (2) x_2 = 3 (2) x_3 = 3 (2) x_4 = 3 (2) x_5 = 3 (2) x_6 = 3 (2) x_7 = 3 (2) x_8 = 3 (2) x_9 = 3 (2) + +Choose next process for printing vector (0-3): 3 +x_0 = 3 (3) x_1 = 3 (3) x_2 = 3 (3) x_3 = 3 (3) x_4 = 3 (3) x_5 = 3 (3) x_6 = 3 (3) x_7 = 3 (3) x_8 = 3 (3) x_9 = 3 (3) + + +E6 + = 40 + +E7 +original vector + +Choose next process for printing vector (0-3): 0 +x_0 = 0 (0) x_1 = -1 (0) x_2 = -2 (0) + +Choose next process for printing vector (0-3): 1 +x_0 = 10 (1) x_1 = 9 (1) x_2 = 8 (1) + +Choose next process for printing vector (0-3): 2 +x_0 = 20 (2) x_1 = 19 (2) x_2 = 18 (2) + +Choose next process for printing vector (0-3): 3 +x_0 = 30 (3) x_1 = 29 (3) x_2 = 28 (3) +min = -2 max = 30 + +vector after changing min-max + +Choose next process for printing vector (0-3): 0 +x_0 = 0 (0) x_1 = -1 (0) x_2 = 30 (0) + +Choose next process for printing vector (0-3): 1 +x_0 = 10 (1) x_1 = 9 (1) x_2 = 8 (1) + +Choose next process for printing vector (0-3): 2 +x_0 = 20 (2) x_1 = 19 (2) x_2 = 18 (2) + +Choose next process for printing vector (0-3): 3 +x_0 = -2 (3) x_1 = 29 (3) x_2 = 28 (3) + +Ex 8 +Alltoall + +Choose next process for printing vector (0-3): 0 +x_0 = 0 (0) x_1 = 11 (0) x_2 = 22 (0) x_3 = 33 (0) x_4 = 44 (0) x_5 = 100 (0) x_6 = 111 (0) x_7 = 122 (0) x_8 = 133 (0) x_9 = 144 (0) x_10 = 200 (0) x_11 = 211 (0) x_12 = 222 (0) x_13 = 233 (0) x_14 = 244 (0) x_15 = 300 (0) x_16 = 311 (0) x_17 = 322 (0) x_18 = 333 (0) x_19 = 344 (0) + +Choose next process for printing vector (0-3): 1 +x_0 = 5 (1) x_1 = 16 (1) x_2 = 27 (1) x_3 = 38 (1) x_4 = 49 (1) x_5 = 105 (1) x_6 = 116 (1) x_7 = 127 (1) x_8 = 138 (1) x_9 = 149 (1) x_10 = 205 (1) x_11 = 216 (1) x_12 = 227 (1) x_13 = 238 (1) x_14 = 249 (1) x_15 = 305 (1) x_16 = 316 (1) x_17 = 327 (1) x_18 = 338 (1) x_19 = 349 (1) + +Choose next process for printing vector (0-3): 2 +x_0 = 10 (2) x_1 = 21 (2) x_2 = 32 (2) x_3 = 43 (2) x_4 = 54 (2) x_5 = 110 (2) x_6 = 121 (2) x_7 = 132 (2) x_8 = 143 (2) x_9 = 154 (2) x_10 = 210 (2) x_11 = 221 (2) x_12 = 232 (2) x_13 = 243 (2) x_14 = 254 (2) x_15 = 310 (2) x_16 = 321 (2) x_17 = 332 (2) x_18 = 343 (2) x_19 = 354 (2) + +Choose next process for printing vector (0-3): 3 +x_0 = 15 (3) x_1 = 26 (3) x_2 = 37 (3) x_3 = 48 (3) x_4 = 59 (3) x_5 = 115 (3) x_6 = 126 (3) x_7 = 137 (3) x_8 = 148 (3) x_9 = 159 (3) x_10 = 215 (3) x_11 = 226 (3) x_12 = 237 (3) x_13 = 248 (3) x_14 = 259 (3) x_15 = 315 (3) x_16 = 326 (3) x_17 = 337 (3) x_18 = 348 (3) x_19 = 359 (3) + +Ex 8 +Alltoall - IN_PLACE + +Choose next process for printing vector (0-3): 0 +x_0 = 0 (0) x_1 = 11 (0) x_2 = 22 (0) x_3 = 33 (0) x_4 = 44 (0) x_5 = 100 (0) x_6 = 111 (0) x_7 = 122 (0) x_8 = 133 (0) x_9 = 144 (0) x_10 = 200 (0) x_11 = 211 (0) x_12 = 222 (0) x_13 = 233 (0) x_14 = 244 (0) x_15 = 300 (0) x_16 = 311 (0) x_17 = 322 (0) x_18 = 333 (0) x_19 = 344 (0) + +Choose next process for printing vector (0-3): 1 +x_0 = 5 (1) x_1 = 16 (1) x_2 = 27 (1) x_3 = 38 (1) x_4 = 49 (1) x_5 = 105 (1) x_6 = 116 (1) x_7 = 127 (1) x_8 = 138 (1) x_9 = 149 (1) x_10 = 205 (1) x_11 = 216 (1) x_12 = 227 (1) x_13 = 238 (1) x_14 = 249 (1) x_15 = 305 (1) x_16 = 316 (1) x_17 = 327 (1) x_18 = 338 (1) x_19 = 349 (1) + +Choose next process for printing vector (0-3): 2 +x_0 = 10 (2) x_1 = 21 (2) x_2 = 32 (2) x_3 = 43 (2) x_4 = 54 (2) x_5 = 110 (2) x_6 = 121 (2) x_7 = 132 (2) x_8 = 143 (2) x_9 = 154 (2) x_10 = 210 (2) x_11 = 221 (2) x_12 = 232 (2) x_13 = 243 (2) x_14 = 254 (2) x_15 = 310 (2) x_16 = 321 (2) x_17 = 332 (2) x_18 = 343 (2) x_19 = 354 (2) + +Choose next process for printing vector (0-3): 3 +x_0 = 15 (3) x_1 = 26 (3) x_2 = 37 (3) x_3 = 48 (3) x_4 = 59 (3) x_5 = 115 (3) x_6 = 126 (3) x_7 = 137 (3) x_8 = 148 (3) x_9 = 159 (3) x_10 = 215 (3) x_11 = 226 (3) x_12 = 237 (3) x_13 = 248 (3) x_14 = 259 (3) x_15 = 315 (3) x_16 = 326 (3) x_17 = 337 (3) x_18 = 348 (3) x_19 = 359 (3) \ No newline at end of file diff --git a/Sheet_7/bsp_7_3/vec_func.cpp b/Sheet_7/bsp_7_3/vec_func.cpp new file mode 100644 index 0000000..5893aee --- /dev/null +++ b/Sheet_7/bsp_7_3/vec_func.cpp @@ -0,0 +1,141 @@ +#include "vec_func.h" +#include +#include +#include +#include // MPI +#include +using namespace std; + +// see http://www.open-mpi.org/doc/current +// for details on MPI functions + +void vecdebug(vector const & x, const MPI_Comm &icomm) +{ + int myrank, size; + MPI_Comm_rank(icomm, &myrank); + MPI_Comm_size(icomm, &size); + int ierr; + + int n = x.size(); + + int take_process; + for(int i=0; i> take_process; // no check for wrong input + } + + ierr = MPI_Bcast(&take_process, 1, MPI_INT, 0, icomm); // broadcast value of "take_process" to all processes -> all know what's going on + // information comes from process 0 + assert(ierr == 0); + + MPI_Barrier(icomm); + + if(take_process == myrank) + { + for(int k=0; k const & x, vector const & y, const MPI_Comm &icomm) +{ + assert(x.size()==y.size()); + + double sum_local = 0; + double sum_global = 0; + + for(size_t k=0; k &x, double &min_val, double &max_val, const MPI_Comm &icomm) +{ + int myrank; + MPI_Comm_rank(icomm, &myrank); + int local_n = x.size(); + int global_offset = myrank * local_n; // for interchanging + + struct {double value; int index;} local_min, local_max, global_min, global_max; // global index + + local_min.value = x[0]; + local_max.value = x[0]; + local_min.index = global_offset; + local_max.index = global_offset; + + // finding local min/max with the corresponding global index + for (int i = 1; i < local_n; ++i) + { + if (x[i] < local_min.value) + { + local_min.value = x[i]; + local_min.index = global_offset + i; + } + if (x[i] > local_max.value) + { + local_max.value = x[i]; + local_max.index = global_offset + i; + } + } + + // reduction to the global one including the global index (need it later for interchanging) + MPI_Allreduce(&local_min, &global_min, 1, MPI_DOUBLE_INT, MPI_MINLOC, icomm); + MPI_Allreduce(&local_max, &global_max, 1, MPI_DOUBLE_INT, MPI_MAXLOC, icomm); + min_val = global_min.value; + max_val = global_max.value; + + // calculating the process and the local index for interchanging the min and max value + int rank_min = global_min.index / local_n; + int rank_max = global_max.index / local_n; + int local_min_idx = global_min.index % local_n; + int local_max_idx = global_max.index % local_n; + + // interchanging + if (rank_min != rank_max) + { + double recv_value; + if (myrank == rank_min) + { + MPI_Sendrecv(&x[local_min_idx], 1, MPI_DOUBLE, rank_max, 0, &recv_value, 1, MPI_DOUBLE, rank_max, 0, icomm, MPI_STATUS_IGNORE); // from last it gets received, first send it to + x[local_min_idx] = recv_value; + } + + if (myrank == rank_max) + { + MPI_Sendrecv(&x[local_max_idx], 1, MPI_DOUBLE, rank_min, 0, &recv_value, 1, MPI_DOUBLE, rank_min, 0, icomm, MPI_STATUS_IGNORE); + x[local_max_idx] = recv_value; + } + + } + else // min and max value are on same process + { + swap(x[local_min_idx], x[local_max_idx]); + } + + return; +} diff --git a/Sheet_7/bsp_7_3/vec_func.h b/Sheet_7/bsp_7_3/vec_func.h new file mode 100644 index 0000000..c025789 --- /dev/null +++ b/Sheet_7/bsp_7_3/vec_func.h @@ -0,0 +1,31 @@ +// general header for all functions in directory + +#pragma once + +#include +#include + +/** Debug and print the vector with MPI, you can choose the process which should present its values + @param[in] x vector to print + @param[in] icomm the MPI process group that is used. +*/ +void vecdebug(std::vector const & x, const MPI_Comm &icomm); + +/** Calculate the scalar product of two vectors (MPI) + @param[in] x vector + @param[in] y vector + @param[in] icomm the MPI process group that is used. + @return sum euclidean scalar product +*/ +double par_scalar(std::vector const & x, std::vector const & y, const MPI_Comm &icomm); + + +/** Determine min and max value of the vector and exchanging those two values + @param[in,out] x vector + @param[in,out] min_val + @param[in,out] max_val + @param[in] icomm the MPI process group that is used. +*/ +void min_max_exch(std::vector &x, double &min_val, double &max_val, const MPI_Comm &icomm); + +