Merge branch 'kais_try'

This commit is contained in:
kai
2025-06-01 16:05:39 +02:00
21 changed files with 340 additions and 183 deletions

28
lab10/jacobi/comp.py Normal file
View File

@@ -0,0 +1,28 @@
import csv
import math
def compare_csv(file1, file2):
with open(file1, newline='') as f1, open(file2, newline='') as f2:
reader1 = list(csv.reader(f1))
reader2 = list(csv.reader(f2))
if len(reader1) != len(reader2):
print(f"Unterschiedliche Zeilenzahl: {len(reader1)} vs {len(reader2)}")
return
for row_idx, (row1, row2) in enumerate(zip(reader1, reader2), start=1):
if len(row1) != len(row2):
print(f"Zeile {row_idx}: unterschiedliche Spaltenanzahl")
continue
for col_idx, (cell1, cell2) in enumerate(zip(row1, row2), start=1):
try:
if not math.isclose(float(cell1), float(cell2), abs_tol=1e-7):
print(f"Unterschied in Zeile {row_idx}, Spalte {col_idx}: {cell1}{cell2} diff: {abs(float(cell1) - float(cell2))}")
except ValueError:
# print(f"{cell1}: {cell2}")
pass
if __name__ == "__main__":
compare_csv("result_parallel.asc", "result_serial.asc")

32
lab10/jacobi/creator.py Normal file
View File

@@ -0,0 +1,32 @@
import math
import subprocess
core_counts = [1, 2, 4, 6, 8, 12, 16, 18, 24, 32, 36, 48]
cores_per_node = 12
max_nodes = 4
for y in core_counts:
x = math.ceil(y / cores_per_node)
if x > max_nodes:
print(f"Skipping {y} cores: requires more than {max_nodes} nodes.")
continue
filename = f"slurm_{y}.sh"
script = f"""#!/bin/bash
#SBATCH --job-name=mpi_g5_{y}
#SBATCH --output=jacobi_{y}.txt
#SBATCH --nodes={x}
#SBATCH --ntasks={y}
srun --mpi=pmix ./jacobi
"""
with open(filename, "w") as f:
f.write(script)
# Submit the job
result = subprocess.run(["sbatch", filename], capture_output=True, text=True)
if result.returncode == 0:
print(f"Submitted {filename}: {result.stdout.strip()}")
else:
print(f"Failed to submit {filename}: {result.stderr.strip()}")

6
lab10/jacobi/do_all.sh Executable file
View File

@@ -0,0 +1,6 @@
#!/bin/bash
git pull
make
python3 creator.py
sleep 0.5
squeue

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@@ -41,7 +41,7 @@ Matrix getCompleteInitialCondition(int n) {
return getInitialCondition(n, 0, 1);
}
Matrix run(Jacobi& jacobi, const Matrix& init, double eps, int maxNumIter) {
Matrix run(Jacobi &jacobi, const Matrix &init, double eps, int maxNumIter) {
auto [m, dist, nIter] = jacobi.run(init, eps, maxNumIter);
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
@@ -52,9 +52,7 @@ Matrix run(Jacobi& jacobi, const Matrix& init, double eps, int maxNumIter) {
return m;
}
double benchmark(Jacobi& jacobi,
const Matrix& init,
double eps,
double benchmark(Jacobi &jacobi, const Matrix &init, double eps,
int maxNumIter) {
auto start = std::chrono::system_clock::now();
jacobi.run(init, eps, maxNumIter);
@@ -142,7 +140,7 @@ void runParallel(int n, double eps, int maxNumIter) {
}
}
int main(int argc, char* argv[]) {
int main(int argc, char *argv[]) {
MPI_Init(&argc, &argv);
int rank, numProc;
@@ -158,26 +156,24 @@ int main(int argc, char* argv[]) {
// Result is saved to file.
// Use this to graphically verify the correctness of the parallel
// implementation.
//runSerial(n, eps, maxNumIter);
runSerial(n, eps, maxNumIter);
runParallel(n, eps, maxNumIter);
// Run the benchmark
//double serialTime = 0;
double serialTime = 0;
double parallelTime = 0;
//serialTime = serialBenchmark(n, eps, maxNumIter);
serialTime = serialBenchmark(n, eps, maxNumIter);
parallelTime = parallelBenchmark(n, eps, maxNumIter);
if (rank == 0) {
//std::cout << "Serial time: " << serialTime << "ms" << std::endl;
std::cout << "Serial time: ms" << std::endl;
std::cout << "Serial time: " << serialTime << "ms" << std::endl;
std::cout << "Parallel time: " << parallelTime << "ms" << std::endl;
//std::cout << "Speedup: " << serialTime / parallelTime << std::endl;
std::cout << "Speedup: " << serialTime / parallelTime << std::endl;
std::ofstream fout("benchmark.txt", std::ios::app);
fout << numProc << "\t" << parallelTime << "\n";
}
MPI_Finalize();
}
}

View File

@@ -1,38 +1,27 @@
#include "jacobi.h"
#include "jacobi_main.h"
#include <iostream>
#include <iterator>
#include <vector>
std::vector<double> getFilledBuffer(const Matrix &matrix, int row)
{
std::vector<double> getFilledBuffer(const Matrix &matrix, int row) {
int numCols = matrix.cols();
std::vector<double> rowBuffer(numCols);
// Extract the row (matrix is column-major)
for (int j = 0; j < numCols; ++j)
{
for (int j = 0; j < numCols; ++j) {
rowBuffer[j] = matrix(row, j);
}
return rowBuffer;
}
/**
* Takes a matrix and an index indexRowLocal which defines which row of the local matrix has to be sent.
*
* Sends data of that row via MPI_Send to process with rank receiverRank.
*
* indexRowGlobal identifies row in the view of the whole matrix, used from receiving process
* to identify if lower or upper halo by comparing against rowHaloUpperIndex and rowHaloLowerIndex.
*/
void sendLocalRow(MPI_Request &request, std::vector<double> &row, const Matrix &matrix, const int indexRowLocal, const int receiverRank, const int indexRowGlobal)
{
row = getFilledBuffer(matrix, indexRowLocal);
MPI_Isend(row.data(), row.size(), MPI_DOUBLE, receiverRank, indexRowGlobal, MPI_COMM_WORLD, &request);
}
Jacobi::Result JacobiMPI::run(const Matrix &init, double epsilon, int maxNumIter)
{
Jacobi::Result JacobiMPI::run(const Matrix &init, double epsilon,
int maxNumIter) {
int rank, numProc;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &numProc);
// std::cout << "rank: " << rank << std::endl;
// std::cout << "numProc: " << numProc << std::endl;
std::vector<Matrix> phi(2, init);
@@ -42,6 +31,8 @@ Jacobi::Result JacobiMPI::run(const Matrix &init, double epsilon, int maxNumIter
const int neighborUpper = rank - 1;
const int neighborLower = rank + 1;
// std::cout << neighborUpper << ":" << neighborLower << std::endl;
const int indexRowGlobalStart = (rank * numRows);
const int indexRowGlobalEnd = (rank * numRows) + (numRows - 1);
@@ -56,28 +47,27 @@ Jacobi::Result JacobiMPI::run(const Matrix &init, double epsilon, int maxNumIter
int t0 = 0; // array index of current timestep
int t1 = 1; // array index of next timestep
while (dist > epsilon && nIter < maxNumIter)
{
while (dist > epsilon && nIter < maxNumIter) {
dist = 0;
if (rank == 0)
{
std::vector<double> row;
MPI_Request request;
sendLocalRow(request, row, phi[t0], numRows - 1, neighborLower, indexRowGlobalEnd);
MPI_Wait(&request, MPI_STATUS_IGNORE);
if (rank == 0) {
MPI_Request send_lower;
std::vector<double> send_vec_low = phi[t0].get_row(numRows - 1);
MPI_Isend(send_vec_low.data(), numCols, MPI_DOUBLE, neighborLower,
indexRowGlobalEnd, MPI_COMM_WORLD, &send_lower);
MPI_Request requestLower;
MPI_Irecv(haloLower.data(), haloLower.size(), MPI_DOUBLE,
neighborLower, rowHaloLowerIndex, MPI_COMM_WORLD, &requestLower);
MPI_Irecv(haloLower.data(), numCols, MPI_DOUBLE, neighborLower,
rowHaloLowerIndex, MPI_COMM_WORLD, &requestLower);
MPI_Wait(&send_lower, MPI_STATUS_IGNORE);
MPI_Wait(&requestLower, MPI_STATUS_IGNORE);
for (int i = 1; i < numRows; ++i)
{
for (int j = 1; j < numCols - 1; ++j)
{
for (int i = 1; i < numRows; ++i) {
for (int j = 1; j < numCols - 1; ++j) {
double valueBottom;
(i == numRows - 1) ? valueBottom = haloLower[j] : valueBottom = phi[t0](i + 1, j);
(i == numRows - 1) ? valueBottom = haloLower[j]
: valueBottom = phi[t0](i + 1, j);
phi[t1](i, j) = .25 * (valueBottom + phi[t0](i - 1, j) +
phi[t0](i, j + 1) + phi[t0](i, j - 1));
const double diff = phi[t1](i, j) - phi[t0](i, j);
@@ -86,23 +76,21 @@ Jacobi::Result JacobiMPI::run(const Matrix &init, double epsilon, int maxNumIter
}
}
else if (rank == (numProc - 1))
{
std::vector<double> row;
else if (rank == (numProc - 1)) {
MPI_Request send_upper;
std::vector<double> send_vec_up = phi[t0].get_row(0);
MPI_Isend(send_vec_up.data(), numCols, MPI_DOUBLE, neighborUpper,
indexRowGlobalStart, MPI_COMM_WORLD, &send_upper);
MPI_Request request;
sendLocalRow(request, row, phi[t0], 0, neighborUpper, indexRowGlobalStart);
MPI_Wait(&request, MPI_STATUS_IGNORE);
MPI_Request request_upper;
MPI_Irecv(haloUpper.data(), numCols, MPI_DOUBLE, neighborUpper,
rowHaloUpperIndex, MPI_COMM_WORLD, &request_upper);
MPI_Request requestUpper;
MPI_Irecv(haloUpper.data(), haloUpper.size(), MPI_DOUBLE,
neighborUpper, rowHaloUpperIndex, MPI_COMM_WORLD, &requestUpper);
MPI_Wait(&requestUpper, MPI_STATUS_IGNORE);
MPI_Wait(&send_upper, MPI_STATUS_IGNORE);
MPI_Wait(&request_upper, MPI_STATUS_IGNORE);
for (int i = 0; i < numRows - 1; ++i)
{
for (int j = 1; j < numCols - 1; ++j)
{
for (int i = 0; i < numRows - 1; ++i) {
for (int j = 1; j < numCols - 1; ++j) {
double valueTop;
(i == 0) ? valueTop = haloUpper[j] : valueTop = phi[t0](i - 1, j);
phi[t1](i, j) = .25 * (phi[t0](i + 1, j) + valueTop +
@@ -113,51 +101,45 @@ Jacobi::Result JacobiMPI::run(const Matrix &init, double epsilon, int maxNumIter
}
}
else
{
std::vector<double> rowUpper;
std::vector<double> rowLower;
else {
MPI_Request send_upper;
MPI_Request send_lower;
MPI_Request requestSendUpper;
MPI_Request requestSendLower;
sendLocalRow(requestSendUpper, rowUpper, phi[t0], 0, neighborUpper, indexRowGlobalStart);
sendLocalRow(requestSendLower, rowLower, phi[t0], numRows - 1, neighborLower, indexRowGlobalEnd);
std::vector<double> send_vec_up = phi[t0].get_row(0);
MPI_Isend(send_vec_up.data(), numCols, MPI_DOUBLE, neighborUpper,
indexRowGlobalStart, MPI_COMM_WORLD, &send_upper);
MPI_Request sendRequests[2] = {requestSendUpper, requestSendLower};
MPI_Waitall(2, sendRequests, MPI_STATUSES_IGNORE);
std::vector<double> send_vec_low = phi[t0].get_row(numRows - 1);
MPI_Isend(send_vec_low.data(), numCols, MPI_DOUBLE, neighborLower,
indexRowGlobalEnd, MPI_COMM_WORLD, &send_lower);
MPI_Request requestUpper;
MPI_Irecv(haloUpper.data(), haloUpper.size(), MPI_DOUBLE,
neighborUpper, rowHaloUpperIndex, MPI_COMM_WORLD, &requestUpper);
MPI_Request requestLower;
MPI_Irecv(haloLower.data(), haloLower.size(), MPI_DOUBLE,
neighborLower, rowHaloLowerIndex, MPI_COMM_WORLD, &requestLower);
MPI_Request request_upper;
MPI_Request request_lower;
MPI_Irecv(haloUpper.data(), numCols, MPI_DOUBLE, neighborUpper,
rowHaloUpperIndex, MPI_COMM_WORLD, &request_upper);
MPI_Irecv(haloLower.data(), numCols, MPI_DOUBLE, neighborLower,
rowHaloLowerIndex, MPI_COMM_WORLD, &request_lower);
MPI_Request requests[2] = {requestUpper, requestLower};
MPI_Waitall(2, requests, MPI_STATUSES_IGNORE);
MPI_Wait(&send_upper, MPI_STATUS_IGNORE);
MPI_Wait(&send_lower, MPI_STATUS_IGNORE);
MPI_Wait(&request_upper, MPI_STATUS_IGNORE);
MPI_Wait(&request_lower, MPI_STATUS_IGNORE);
for (int i = 0; i < numRows; ++i)
{
for (int j = 1; j < numCols - 1; ++j)
{
if (i == 0)
{
for (int i = 0; i < numRows; ++i) {
for (int j = 1; j < numCols - 1; ++j) {
if (i == 0) {
double valueTop = haloUpper[j];
phi[t1](i, j) = .25 * (phi[t0](i + 1, j) + valueTop +
phi[t0](i, j + 1) + phi[t0](i, j - 1));
const double diff = phi[t1](i, j) - phi[t0](i, j);
dist = std::max(dist, std::abs(diff));
}
else if (i == numRows - 1)
{
} else if (i == numRows - 1) {
double valueBottom = haloLower[j];
phi[t1](i, j) = .25 * (valueBottom + phi[t0](i - 1, j) +
phi[t0](i, j + 1) + phi[t0](i, j - 1));
const double diff = phi[t1](i, j) - phi[t0](i, j);
dist = std::max(dist, std::abs(diff));
}
else
{
} else {
phi[t1](i, j) = .25 * (phi[t0](i + 1, j) + phi[t0](i - 1, j) +
phi[t0](i, j + 1) + phi[t0](i, j - 1));
const double diff = phi[t1](i, j) - phi[t0](i, j);
@@ -167,16 +149,17 @@ Jacobi::Result JacobiMPI::run(const Matrix &init, double epsilon, int maxNumIter
}
}
// if (nIter % 1000 == 0) {
// std::cout << "Iteration " << nIter << ", dist=" << dist << "\n";
// }
double globalDist;
double globalDist = 0;
MPI_Allreduce(&dist, &globalDist, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
dist = globalDist;
nIter++;
std::swap(t0, t1);
// if (nIter == 100) {
// std::cout << phi[t1] << std::endl;
// }
}
// std::cout << phi[t1] << std::endl;
return Jacobi::Result{phi[t0], dist, nIter};
}

View File

@@ -16,14 +16,13 @@
* limitations under the License.
*/
#ifndef MATRIX_H
#define MATRIX_H
#include <vector>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <vector>
/**
* Matrix class
@@ -40,7 +39,7 @@
*
*/
class Matrix {
public:
public:
/**
* Create a matrix of size m x n and initialize all entries to zero.
* @param rows number of rows
@@ -79,19 +78,19 @@ class Matrix {
*/
static Matrix uninit(std::pair<int, int> dim);
Matrix(const Matrix& other);
Matrix(Matrix&& other);
Matrix(const Matrix &other);
Matrix(Matrix &&other);
~Matrix();
Matrix& operator=(const Matrix& other);
Matrix& operator=(Matrix&& other);
Matrix &operator=(const Matrix &other);
Matrix &operator=(Matrix &&other);
// Access element a_ij of the matrix
double& operator()(int i, int j);
const double& operator()(int i, int j) const;
double &operator()(int i, int j);
const double &operator()(int i, int j) const;
// Obtain a pointer to the underlying data
double* data();
const double* data() const;
double *data();
const double *data() const;
// Getter functions for the dimensions
std::pair<int, int> dim() const;
@@ -100,44 +99,55 @@ class Matrix {
int numEntries() const;
// Comparison operators
bool operator==(const Matrix& b);
bool operator!=(const Matrix& b);
bool operator==(const Matrix &b);
bool operator!=(const Matrix &b);
// addition
Matrix& operator+=(const Matrix& b);
Matrix &operator+=(const Matrix &b);
// subtraction
Matrix& operator-=(const Matrix& b);
Matrix &operator-=(const Matrix &b);
// scalar multiplication
Matrix& operator*=(double x);
Matrix &operator*=(double x);
// scalar division
Matrix& operator/=(double x);
Matrix &operator/=(double x);
private:
std::vector<double> get_row(int i) {
std::vector<double> row(0);
int start = this->cols() * i;
int end = this->cols() * i + cols();
for (int j = start; j < end; j++) {
row.push_back(this->data()[j]);
}
return row;
}
private:
// Constructor is private to prevent creating an uninitialized matrix
// accidentally. Use Matrix::zeros() or Matrix::uninit() instead
Matrix(int m, int n);
int numRows_; // number of rows
int numCols_; // number of columns
double* data_; // the matrix' entries
int numRows_; // number of rows
int numCols_; // number of columns
double *data_; // the matrix' entries
};
/**
* Vector class
*
*
* This class implements a vector of size n. The vector is stored in a
* Matrix of size n x 1.
*
*
* Constructors are provided to create a vector of zeros or an uninitialized
* vector. The uninitialized vector is not initialized, i.e. the entries are
* not set to zero. This is useful for performance reasons, e.g. to control
* the placement of vector entries in locality-domain memory.
*/
class Vector {
public:
public:
static Vector zeros(int n) {
Vector vec;
vec.data_ = Matrix::zeros(n, 1);
@@ -150,19 +160,19 @@ class Vector {
return vec;
}
bool operator==(const Vector& b) { return data_ == b.data_; }
bool operator!=(const Vector& b) { return !operator==(b); }
double& operator()(int i) { return data_(i, 0); }
const double& operator()(int i) const { return data_(i, 0); }
double* data() { return data_.data(); }
const double* data() const { return data_.data(); }
bool operator==(const Vector &b) { return data_ == b.data_; }
bool operator!=(const Vector &b) { return !operator==(b); }
double &operator()(int i) { return data_(i, 0); }
const double &operator()(int i) const { return data_(i, 0); }
double *data() { return data_.data(); }
const double *data() const { return data_.data(); }
Vector operator+=(const Vector& b) {
Vector operator+=(const Vector &b) {
data_ += b.data_;
return *this;
}
Vector operator-=(const Vector& b) {
Vector operator-=(const Vector &b) {
data_ -= b.data_;
return *this;
}
@@ -177,7 +187,7 @@ class Vector {
int size() const { return data_.rows(); }
private:
private:
Matrix data_ = Matrix::zeros(0, 0);
};
@@ -193,27 +203,21 @@ inline Matrix Matrix::zeros(int m, int n) {
return mat;
}
inline Matrix Matrix::zeros(int n) {
return zeros(n, n);
}
inline Matrix Matrix::zeros(int n) { return zeros(n, n); }
inline Matrix Matrix::zeros(std::pair<int, int> dim) {
return zeros(dim.first, dim.second);
}
inline Matrix Matrix::uninit(int m, int n) {
return Matrix(m, n);
}
inline Matrix Matrix::uninit(int m, int n) { return Matrix(m, n); }
inline Matrix Matrix::uninit(int n) {
return uninit(n, n);
}
inline Matrix Matrix::uninit(int n) { return uninit(n, n); }
inline Matrix Matrix::uninit(std::pair<int, int> dim) {
return uninit(dim.first, dim.second);
}
inline Matrix::Matrix(const Matrix& other) {
inline Matrix::Matrix(const Matrix &other) {
numRows_ = other.numRows_;
numCols_ = other.numCols_;
if (numRows_ == 0 || numCols_ == 0) {
@@ -228,7 +232,7 @@ inline Matrix::Matrix(const Matrix& other) {
}
}
inline Matrix::Matrix(Matrix&& other) {
inline Matrix::Matrix(Matrix &&other) {
numRows_ = other.numRows_;
numCols_ = other.numCols_;
data_ = other.data_;
@@ -244,7 +248,7 @@ inline Matrix::~Matrix() {
}
}
inline Matrix& Matrix::operator=(const Matrix& other) {
inline Matrix &Matrix::operator=(const Matrix &other) {
if (this != &other) {
if (data_ != nullptr) {
delete[] data_;
@@ -261,7 +265,7 @@ inline Matrix& Matrix::operator=(const Matrix& other) {
return *this;
}
inline Matrix& Matrix::operator=(Matrix&& other) {
inline Matrix &Matrix::operator=(Matrix &&other) {
if (this != &other) {
if (data_ != nullptr) {
delete[] data_;
@@ -276,39 +280,29 @@ inline Matrix& Matrix::operator=(Matrix&& other) {
return *this;
}
inline double& Matrix::operator()(int i, int j) {
inline double &Matrix::operator()(int i, int j) {
return data_[i * numCols_ + j];
}
inline const double& Matrix::operator()(int i, int j) const {
inline const double &Matrix::operator()(int i, int j) const {
return data_[i * numCols_ + j];
}
inline double* Matrix::data() {
return data_;
}
inline double *Matrix::data() { return data_; }
inline const double* Matrix::data() const {
return data_;
}
inline const double *Matrix::data() const { return data_; }
inline std::pair<int, int> Matrix::dim() const {
return std::pair<int, int>(numRows_, numCols_);
}
inline int Matrix::rows() const {
return numRows_;
}
inline int Matrix::rows() const { return numRows_; }
inline int Matrix::cols() const {
return numCols_;
}
inline int Matrix::cols() const { return numCols_; }
inline int Matrix::numEntries() const {
return numRows_ * numCols_;
}
inline int Matrix::numEntries() const { return numRows_ * numCols_; }
inline bool Matrix::operator==(const Matrix& b) {
inline bool Matrix::operator==(const Matrix &b) {
const double eps = 1e-12;
if (numRows_ != b.numRows_ || numCols_ != b.numCols_) {
return false;
@@ -323,11 +317,9 @@ inline bool Matrix::operator==(const Matrix& b) {
return true;
}
inline bool Matrix::operator!=(const Matrix& b) {
return !operator==(b);
}
inline bool Matrix::operator!=(const Matrix &b) { return !operator==(b); }
inline Matrix& Matrix::operator+=(const Matrix& b) {
inline Matrix &Matrix::operator+=(const Matrix &b) {
for (int i = 0; i < numRows_; ++i) {
for (int j = 0; j < numCols_; ++j) {
operator()(i, j) += b(i, j);
@@ -336,7 +328,7 @@ inline Matrix& Matrix::operator+=(const Matrix& b) {
return *this;
}
inline Matrix& Matrix::operator-=(const Matrix& b) {
inline Matrix &Matrix::operator-=(const Matrix &b) {
for (int i = 0; i < numRows_; ++i) {
for (int j = 0; j < numCols_; ++j) {
operator()(i, j) -= b(i, j);
@@ -345,7 +337,7 @@ inline Matrix& Matrix::operator-=(const Matrix& b) {
return *this;
}
inline Matrix& Matrix::operator*=(double x) {
inline Matrix &Matrix::operator*=(double x) {
for (int i = 0; i < numRows_; ++i) {
for (int j = 0; j < numCols_; ++j) {
operator()(i, j) *= x;
@@ -354,7 +346,7 @@ inline Matrix& Matrix::operator*=(double x) {
return *this;
}
inline Matrix& Matrix::operator/=(double x) {
inline Matrix &Matrix::operator/=(double x) {
for (int i = 0; i < numRows_; ++i) {
for (int j = 0; j < numCols_; ++j) {
operator()(i, j) /= x;
@@ -370,7 +362,7 @@ inline Matrix::Matrix(int m, int n) : numRows_(m), numCols_(n) {
}
}
inline std::ostream& operator<<(std::ostream& os, const Matrix& a) {
inline std::ostream &operator<<(std::ostream &os, const Matrix &a) {
const int width = 10;
const int precision = 4;
@@ -389,8 +381,7 @@ inline std::ostream& operator<<(std::ostream& os, const Matrix& a) {
return os;
}
inline bool equalWithinRange(const Matrix& a,
const Matrix& b,
inline bool equalWithinRange(const Matrix &a, const Matrix &b,
double eps = 1e-12) {
if (a.rows() != b.rows() || a.cols() != b.cols())
return false;
@@ -408,4 +399,4 @@ inline bool equalWithinRange(const Matrix& a,
return true;
}
#endif // MATRIX_H
#endif // MATRIX_H

View File

@@ -1,16 +1,16 @@
#include "matrix_io.h"
#include "matrix.h"
#include <exception>
#include <fstream>
#include <mpi.h>
#include <exception>
#include "matrix.h"
#include "matrix_io.h"
MatrixIO::MatrixIO() {
MPI_Comm_rank(MPI_COMM_WORLD, &rank_);
MPI_Comm_size(MPI_COMM_WORLD, &numProc_);
}
void MatrixIO::saveDistributed(const Matrix& distributedMatrix,
const std::string& filename) {
void MatrixIO::saveDistributed(const Matrix &distributedMatrix,
const std::string &filename) {
Matrix mat = gatherMatrixOnRoot(distributedMatrix);
if (rank_ == 0) {
@@ -18,7 +18,7 @@ void MatrixIO::saveDistributed(const Matrix& distributedMatrix,
}
}
void MatrixIO::saveSerial(const Matrix& m, const std::string& filename) {
void MatrixIO::saveSerial(const Matrix &m, const std::string &filename) {
std::ofstream fout(filename);
const int numRows = m.rows();
const int numCols = m.cols();
@@ -31,7 +31,7 @@ void MatrixIO::saveSerial(const Matrix& m, const std::string& filename) {
}
}
Matrix MatrixIO::loadDistributed(const std::string& filename) {
Matrix MatrixIO::loadDistributed(const std::string &filename) {
Matrix matrixOnRoot = Matrix::zeros(0, 0);
if (rank_ == 0) {
matrixOnRoot = loadSerial(filename);
@@ -41,7 +41,7 @@ Matrix MatrixIO::loadDistributed(const std::string& filename) {
return distributedMatrix;
}
Matrix MatrixIO::loadSerial(const std::string& filename) {
Matrix MatrixIO::loadSerial(const std::string &filename) {
std::ifstream fin(filename);
// Check first character (has to be #)
@@ -66,7 +66,7 @@ Matrix MatrixIO::loadSerial(const std::string& filename) {
return mat;
}
Matrix MatrixIO::gatherMatrixOnRoot(const Matrix& distributedMatrix) {
Matrix MatrixIO::gatherMatrixOnRoot(const Matrix &distributedMatrix) {
const int numRowsLocal = distributedMatrix.rows();
const int numCols = distributedMatrix.cols();
const int numRowsTotal = numRowsLocal * numProc_;
@@ -84,7 +84,7 @@ Matrix MatrixIO::gatherMatrixOnRoot(const Matrix& distributedMatrix) {
return matrixOnRoot;
}
Matrix MatrixIO::scatterMatrixFromRoot(const Matrix& matrixOnRoot) {
Matrix MatrixIO::scatterMatrixFromRoot(const Matrix &matrixOnRoot) {
int numRowsTotal = matrixOnRoot.rows();
int numCols = matrixOnRoot.cols();

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

55
lab10/jacobi/plot_res.py Normal file
View File

@@ -0,0 +1,55 @@
import matplotlib.pyplot as plt
# Pfad zum Verzeichnis mit den Dateien
data_dir = "resluts/" # ggf. anpassen
threads = [1, 2, 4, 6, 8, 12, 16, 18, 24, 32, 36, 48]
times = [
175246,
89030.8,
45182.7,
30198.1,
22710.1,
15256.1,
13512.1,
13073.2,
10036.8,
9845.38,
8423.65,
7676.71,
]
speedups = [
1,
1.96838,
3.90997,
5.8091,
7.73292,
11.4934,
13.0374,
13.4461,
17.4421,
17.9058,
20.8097,
22.8728,
]
efficiency = [speedup / thread for speedup, thread in zip(speedups, threads)]
# plt.figure(figsize=(10, 5))
plt.plot(threads, efficiency, marker="o", label="Speedup")
plt.title("Efficiency")
plt.xlabel("Threads")
plt.ylabel("Efficiency")
plt.grid(True)
# plt.legend()
# plt.tight_layout()
plt.savefig("efficiency_plot.png")
plt.clf()
# --- Plot 2: Performance ---
plt.plot(threads, times, marker="o")
plt.title("Performance")
plt.xlabel("Threads")
plt.ylabel("Performance (ms)")
plt.grid(True)
plt.savefig("performance_plot.png")

View File

@@ -0,0 +1,6 @@
Starting serial benchmark
Serial benchmark finished, time=175344ms
Parallel benchmark finished, time=15256.1ms
Serial time: 175344ms
Parallel time: 15256.1ms
Speedup: 11.4934

View File

@@ -0,0 +1,6 @@
Starting serial benchmark
Serial benchmark finished, time=176163ms
Parallel benchmark finished, time=13512.1ms
Serial time: 176163ms
Parallel time: 13512.1ms
Speedup: 13.0374

View File

@@ -0,0 +1,6 @@
Starting serial benchmark
Serial benchmark finished, time=175784ms
Parallel benchmark finished, time=13073.2ms
Serial time: 175784ms
Parallel time: 13073.2ms
Speedup: 13.4461

View File

@@ -0,0 +1,6 @@
Starting serial benchmark
Serial benchmark finished, time=175246ms
Parallel benchmark finished, time=89030.8ms
Serial time: 175246ms
Parallel time: 89030.8ms
Speedup: 1.96838

View File

@@ -0,0 +1,6 @@
Starting serial benchmark
Serial benchmark finished, time=175063ms
Parallel benchmark finished, time=10036.8ms
Serial time: 175063ms
Parallel time: 10036.8ms
Speedup: 17.4421

View File

@@ -0,0 +1,6 @@
Starting serial benchmark
Serial benchmark finished, time=176290ms
Parallel benchmark finished, time=9845.38ms
Serial time: 176290ms
Parallel time: 9845.38ms
Speedup: 17.9058

View File

@@ -0,0 +1,6 @@
Starting serial benchmark
Serial benchmark finished, time=175294ms
Parallel benchmark finished, time=8423.65ms
Serial time: 175294ms
Parallel time: 8423.65ms
Speedup: 20.8097

View File

@@ -0,0 +1,6 @@
Starting serial benchmark
Serial benchmark finished, time=176663ms
Parallel benchmark finished, time=45182.7ms
Serial time: 176663ms
Parallel time: 45182.7ms
Speedup: 3.90997

View File

@@ -0,0 +1,6 @@
Starting serial benchmark
Serial benchmark finished, time=175588ms
Parallel benchmark finished, time=7676.71ms
Serial time: 175588ms
Parallel time: 7676.71ms
Speedup: 22.8728

View File

@@ -0,0 +1,6 @@
Starting serial benchmark
Serial benchmark finished, time=175424ms
Parallel benchmark finished, time=30198.1ms
Serial time: 175424ms
Parallel time: 30198.1ms
Speedup: 5.8091

View File

@@ -0,0 +1,6 @@
Starting serial benchmark
Serial benchmark finished, time=175615ms
Parallel benchmark finished, time=22710.1ms
Serial time: 175615ms
Parallel time: 22710.1ms
Speedup: 7.73292