Solved exc1

This commit is contained in:
WickedJack99
2025-06-21 11:09:31 +02:00
parent ce6ae9d60d
commit b84e81b9d8
16 changed files with 257 additions and 68 deletions

14
.vscode/settings.json vendored
View File

@@ -68,6 +68,18 @@
"set": "cpp",
"unordered_map": "cpp",
"xhash": "cpp",
"xtree": "cpp"
"xtree": "cpp",
"codecvt": "cpp",
"condition_variable": "cpp",
"cstdarg": "cpp",
"cwctype": "cpp",
"deque": "cpp",
"map": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"string_view": "cpp",
"numbers": "cpp",
"semaphore": "cpp",
"cinttypes": "cpp"
}
}

View File

@@ -0,0 +1,69 @@
import os
import re
import matplotlib.pyplot as plt
def parse_result_files(fixed_N, directory="."):
pattern = re.compile(r"runtime_p_(\d+)_N_({})\.txt".format(fixed_N))
results = []
for filename in os.listdir(directory):
match = pattern.match(filename)
if match:
p = int(match.group(1))
with open(os.path.join(directory, filename), "r") as f:
line = f.readline().strip()
time_str, N_str = line.split(",")
time = float(time_str)
results.append((p, time))
results.sort(key=lambda x: x[0]) # sort by number of processes
return results
def plot_results(results, N, output_file="sieve_scaling_plot.png"):
ps = [p for p, _ in results]
times = [t for _, t in results]
performance = [N / t for t in times]
speedup = [times[0] / t for t in times]
efficiency = [s / p for s, p in zip(speedup, ps)]
plt.figure(figsize=(12, 8))
# Performance plot
plt.subplot(3, 1, 1)
plt.plot(ps, performance, marker='o')
plt.title(f"Performance (N = {N})")
plt.xlabel("Processes")
plt.ylabel("Performance (N / time)")
# Speedup plot
plt.subplot(3, 1, 2)
plt.plot(ps, speedup, marker='o')
plt.title("Speedup")
plt.xlabel("Processes")
plt.ylabel("Speedup (T1 / Tp)")
# Efficiency plot
plt.subplot(3, 1, 3)
plt.plot(ps, efficiency, marker='o')
plt.title("Efficiency")
plt.xlabel("Processes")
plt.ylabel("Efficiency (Speedup / p)")
plt.tight_layout()
plt.savefig(output_file)
print(f"Plot saved to: {output_file}")
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("N", type=int, help="Fixed N to plot results for")
parser.add_argument("--dir", type=str, default=".", help="Directory with result files")
parser.add_argument("--out", type=str, default="sieve_scaling_plot.png", help="Output image file")
args = parser.parse_args()
data = parse_result_files(args.N, args.dir)
if not data:
print(f"No matching files found for N = {args.N}")
else:
plot_results(data, args.N, args.out)

View File

@@ -0,0 +1 @@
2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,

View File

@@ -0,0 +1 @@
2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997,

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
0.232095,1000000

View File

@@ -0,0 +1 @@
0.121674,1000000

View File

@@ -0,0 +1 @@
0.0957458,1000000

View File

@@ -0,0 +1 @@
0.0001227,100

View File

@@ -0,0 +1 @@
0.0001636,1000

View File

@@ -0,0 +1 @@
0.07924,1000000

View File

@@ -0,0 +1 @@
42.6024,100000000

164
lab12/exc1/sieve_e.cpp Normal file
View File

@@ -0,0 +1,164 @@
#include <vector>
#include <iostream>
#include <mpi.h>
#include <limits>
#include <fstream>
std::vector<int> get_start_condition(int N, int count_proc, int rank)
{
int total_elements = N - 1;
int base_chunk = total_elements / count_proc;
int remainder = total_elements % count_proc;
int start_offset = rank * base_chunk + std::min(rank, remainder);
int chunk_size = base_chunk + (rank < remainder ? 1 : 0);
int start = 2 + start_offset;
int end = start + chunk_size;
std::vector<int> start_set;
for (int i = start; i < end; ++i)
{
if (i == 2 || i % 2 == 1)
start_set.emplace_back(i);
}
return start_set;
}
// mark element as not prim by setting to 0
// point out next k while sieving
int sieve(std::vector<int> &set, int k)
{
bool next_k_set = false;
int next_k = k;
for (int &elem : set)
{
if ((elem > k) && (elem != 0))
{
if (!next_k_set)
{
next_k = elem;
next_k_set = true;
}
if (elem % k == 0)
{
elem = 0;
}
}
}
return next_k;
}
void print_vec(std::vector<int> vec)
{
for (int elem : vec)
{
std::cout << elem << ", ";
}
std::cout << std::endl;
}
void save_result_to_file(std::vector<int> vec, int N)
{
std::ofstream outfile("primes_" + std::to_string(N) + ".txt");
for (int val : vec)
{
outfile << val << ",";
}
outfile << std::endl;
outfile.close();
}
void save_runtime_to_file(double runtime, int N, int numProc)
{
std::ofstream outfile("runtime_p_" + std::to_string(numProc) + "_N_" + std::to_string(N) + ".txt");
outfile << runtime << "," << N;
outfile << std::endl;
outfile.close();
}
int main(int argc, char *argv[])
{
MPI_Init(&argc, &argv);
double start_time = MPI_Wtime();
int N = atoi(argv[1]);
int numProc, rank;
MPI_Comm_size(MPI_COMM_WORLD, &numProc);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
std::vector<int> list_to_sieve = get_start_condition(N, numProc, rank);
int k = 2;
int global_min_k = 0;
int local_max_N = list_to_sieve[list_to_sieve.size() - 1];
while (true)
{
int offered_k = (k < local_max_N) ? sieve(list_to_sieve, k) : std::numeric_limits<int>::max();
MPI_Allreduce(&offered_k, &global_min_k, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD);
if (global_min_k * global_min_k >= N)
break;
k = global_min_k;
}
std::vector<int> recvcounts(numProc);
std::vector<int> displs(numProc);
int local_size = list_to_sieve.size();
std::vector<int> final_results(numProc * local_size);
// 1. Share local sizes from all ranks to rank 0
MPI_Gather(&local_size, 1, MPI_INT,
recvcounts.data(), 1, MPI_INT,
0, MPI_COMM_WORLD);
// 2. Calculate displacements on rank 0
if (rank == 0)
{
displs[0] = 0;
for (int i = 1; i < numProc; ++i)
{
displs[i] = displs[i - 1] + recvcounts[i - 1];
}
// Resize final_results based on total size
int total = displs[numProc - 1] + recvcounts[numProc - 1];
final_results.resize(total);
}
if (rank == 0)
{
std::copy(list_to_sieve.begin(), list_to_sieve.end(), final_results.begin());
MPI_Gatherv(MPI_IN_PLACE, local_size, MPI_INT,
final_results.data(), recvcounts.data(), displs.data(), MPI_INT,
0, MPI_COMM_WORLD);
}
else
{
MPI_Gatherv(list_to_sieve.data(), local_size, MPI_INT,
nullptr, nullptr, nullptr, MPI_INT,
0, MPI_COMM_WORLD);
}
double end_time = MPI_Wtime();
double elapsed = end_time - start_time;
if (rank == 0)
{
std::vector<int> non_zero_results;
for (int val : final_results)
{
if (val != 0)
non_zero_results.push_back(val);
}
save_result_to_file(non_zero_results, N);
save_runtime_to_file(elapsed, N, numProc);
}
MPI_Finalize();
return 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

View File

@@ -1,67 +0,0 @@
#include <vector>
#include <iostream>
#include <mpi.h>
std::vector<int> get_start_condition(int N, int count_proc, int rank)
{
int total_elements = N - 1; // because range starts at 2
int base_chunk = total_elements / count_proc;
int remainder = total_elements % count_proc;
int start_offset = rank * base_chunk + std::min(rank, remainder);
int chunk_size = base_chunk + (rank < remainder ? 1 : 0);
int start = 2 + start_offset;
int end = start + chunk_size; // exclusive
std::vector<int> start_set;
for (int i = start; i < end; ++i)
{
start_set.emplace_back(i);
}
return start_set;
}
// mark element as not prim by setting to 0
// 2,3,4
// 0,1,2
// even numbers are at even indices
// index is (number - 2) or (number - start)
void sieve(std::vector<int> &set, int k)
{
for (int &elem : set)
{
if ((elem != k) && (elem != 0) && (elem % k == 0))
{
elem = 0;
}
}
}
void print_vec(std::vector<int> vec)
{
for (int elem : vec)
{
std::cout << elem << ", ";
}
std::cout << std::endl;
}
int main(int argc, char *argv[])
{
// MPI_Init(&argc, &argv);
int procs = atoi(argv[1]);
int N = atoi(argv[2]);
std::cout << "Procs: " << procs << " N: " << N << std::endl;
for (int proc = 0; proc < procs; proc++)
{
std::vector<int> elems = get_start_condition(N, procs, proc);
print_vec(elems);
}
// MPI_Finalize();
}