Sheet 7 (7_3)
This commit is contained in:
parent
4c107a5c28
commit
b26d44a2fe
5 changed files with 349 additions and 0 deletions
23
Sheet_7/bsp_7_3/Makefile
Normal file
23
Sheet_7/bsp_7_3/Makefile
Normal file
|
|
@ -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
|
||||
64
Sheet_7/bsp_7_3/main.cpp
Normal file
64
Sheet_7/bsp_7_3/main.cpp
Normal file
|
|
@ -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 <iostream> // MPI
|
||||
#include <mpi.h>
|
||||
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<double> x(10,3);
|
||||
if(myrank==0) {cout << endl << "E5" << endl;}
|
||||
vecdebug(x, icomm);
|
||||
|
||||
// E6
|
||||
vector<double> y(10,1.0/3);
|
||||
double res = par_scalar(x,y,icomm);
|
||||
if(myrank==0)
|
||||
{
|
||||
cout << endl << endl << "E6" << endl;
|
||||
cout << "<x,y> = " << res << endl << endl;
|
||||
}
|
||||
|
||||
// E7
|
||||
vector<double> 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<double> c(n);
|
||||
for(size_t i=0; i<n; ++i)
|
||||
{
|
||||
c[i] = myrank*100 +(i%5)*10+i;
|
||||
}
|
||||
vector<double> 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;
|
||||
}
|
||||
|
||||
|
||||
90
Sheet_7/bsp_7_3/results_7_3.txt
Normal file
90
Sheet_7/bsp_7_3/results_7_3.txt
Normal file
|
|
@ -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
|
||||
<x,y> = 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)
|
||||
141
Sheet_7/bsp_7_3/vec_func.cpp
Normal file
141
Sheet_7/bsp_7_3/vec_func.cpp
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
#include "vec_func.h"
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <mpi.h> // MPI
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
// see http://www.open-mpi.org/doc/current
|
||||
// for details on MPI functions
|
||||
|
||||
void vecdebug(vector<double> 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<size; ++i)
|
||||
{
|
||||
MPI_Barrier(icomm);
|
||||
if(myrank == 0) // only one process for input
|
||||
{
|
||||
cout << "\nChoose next process for printing vector (0-3): ";
|
||||
cout.flush();
|
||||
cin >> 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<n; ++k)
|
||||
{
|
||||
cout << "x_" << k << " = " << x[k] << " (" << myrank << ")\t";
|
||||
cout.flush();
|
||||
// in brackets we have the actual process
|
||||
}
|
||||
cout << endl;
|
||||
cout.flush();
|
||||
}
|
||||
|
||||
MPI_Barrier(icomm);
|
||||
}
|
||||
// to avoid some output chaos with cout you could also do it with MPI_Send and MPI_Recv
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
double par_scalar(vector<double> const & x, vector<double> 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.size(); ++k)
|
||||
{
|
||||
sum_local += x[k]*y[k];
|
||||
}
|
||||
|
||||
auto ierr = MPI_Allreduce(&sum_local, &sum_global, 1, MPI_DOUBLE, MPI_SUM, icomm); // reduce local sums to global sum
|
||||
assert(ierr == 0);
|
||||
|
||||
return sum_global;
|
||||
}
|
||||
|
||||
|
||||
void min_max_exch(vector<double> &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;
|
||||
}
|
||||
31
Sheet_7/bsp_7_3/vec_func.h
Normal file
31
Sheet_7/bsp_7_3/vec_func.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
// general header for all functions in directory
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <mpi.h>
|
||||
#include <vector>
|
||||
|
||||
/** 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<double> 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<double> const & x, std::vector<double> 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<double> &x, double &min_val, double &max_val, const MPI_Comm &icomm);
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue