WUT_Computer_Science/Programming/PORR/code/threads_indep.py

94 lines
3.0 KiB
Python
Raw Normal View History

2025-01-01 18:50:11 +01:00
import gc
import time
2025-01-13 18:21:02 +01:00
import numpy as np
2025-01-13 17:05:20 +01:00
from numba import njit, prange
2025-01-01 18:50:11 +01:00
from time_measurement import time_measurement_longest, longest_threads_time_accumulator, tests_time
import linear_algebra_utils as linAlg
2025-01-13 17:32:54 +01:00
2025-01-13 17:05:20 +01:00
@njit(parallel=True)
def numba_matrix_vector_multiply(A, input_x, Ax):
2025-01-13 17:32:54 +01:00
for i in prange(len(A)):
2025-01-13 18:21:02 +01:00
acc = 0.0
for j in range(len(input_x)):
acc += A[i][j] * input_x[j]
Ax[i] = acc
2025-01-13 17:05:20 +01:00
@njit(parallel=True)
def numba_vector_vector_subtraction(b, Ax, residual):
for i in prange(len(b)):
residual[i] = b[i] - Ax[i]
2025-01-13 18:21:02 +01:00
@njit(nopython=True)
2025-01-13 17:05:20 +01:00
def numba_scalar_vector_multiply(omega, vector, result):
2025-01-13 18:21:02 +01:00
omega_real = omega.real
for i in range(len(vector)):
result[i] = omega_real * vector[i]
2025-01-13 17:05:20 +01:00
@njit(parallel=True)
def numba_vector_vector_addition(input_x, vector, output_x):
for i in prange(len(input_x)):
output_x[i] = input_x[i] + vector[i]
2025-01-13 18:21:02 +01:00
2025-01-13 17:05:20 +01:00
# Funkcje z dekoratorem
2025-01-01 18:50:11 +01:00
@time_measurement_longest(longest_threads_time_accumulator)
2025-01-13 17:05:20 +01:00
def matrix_vector_multiply(A, input_x, Ax):
numba_matrix_vector_multiply(A, input_x, Ax)
2025-01-01 18:50:11 +01:00
@time_measurement_longest(longest_threads_time_accumulator)
2025-01-13 17:05:20 +01:00
def vector_vector_subtraction(b, Ax, residual):
numba_vector_vector_subtraction(b, Ax, residual)
2025-01-01 18:50:11 +01:00
@time_measurement_longest(longest_threads_time_accumulator)
2025-01-13 17:05:20 +01:00
def scalar_vector_multiply(omega, vector, result):
numba_scalar_vector_multiply(omega, vector, result)
2025-01-01 18:50:11 +01:00
@time_measurement_longest(longest_threads_time_accumulator)
2025-01-13 17:05:20 +01:00
def vector_vector_addition(input_x, vector, output_x):
numba_vector_vector_addition(input_x, vector, output_x)
2025-01-01 18:50:11 +01:00
2025-01-13 17:05:20 +01:00
# Metoda Richardson z obsługą wątków
2025-01-01 18:50:11 +01:00
def RichardsonMethodThreads(A, b, lambda_min, lambda_max, max_iterations, x0=None, tol=1e-5):
longest_threads_time_accumulator.hard_reset()
gc.disable()
start_time = time.perf_counter()
2025-01-13 17:32:54 +01:00
x0 = x0 if x0 is not None else [0.0] * len(b)
x = x0[:]
2025-01-13 17:05:20 +01:00
2025-01-01 18:50:11 +01:00
omega = 2 / (lambda_min + lambda_max)
2025-01-13 17:05:20 +01:00
n = len(b)
for iteration in range(max_iterations):
2025-01-13 17:32:54 +01:00
Ax = [0.0] * n
2025-01-13 17:05:20 +01:00
matrix_vector_multiply(A, x, Ax)
longest_threads_time_accumulator.save_lap_and_reset()
2025-01-13 17:32:54 +01:00
residual = [0.0] * n
2025-01-13 17:05:20 +01:00
vector_vector_subtraction(b, Ax, residual)
longest_threads_time_accumulator.save_lap_and_reset()
2025-01-13 17:32:54 +01:00
change_vector = [0.0] * n
2025-01-13 17:05:20 +01:00
scalar_vector_multiply(omega, residual, change_vector)
longest_threads_time_accumulator.save_lap_and_reset()
2025-01-13 17:32:54 +01:00
_x = [0.0] * n
2025-01-13 17:05:20 +01:00
vector_vector_addition(x, change_vector, _x)
longest_threads_time_accumulator.save_lap_and_reset()
2025-01-13 17:32:54 +01:00
x = _x[:]
2025-01-13 17:05:20 +01:00
if linAlg.SequentialLinearAlgebraUtils.vector_norm(residual) < tol:
break
2025-01-01 18:50:11 +01:00
end_time = time.perf_counter()
gc.enable()
total_time = end_time - start_time
sequential_time = total_time - longest_threads_time_accumulator.total_time
2025-01-13 17:05:20 +01:00
2025-01-01 18:50:11 +01:00
print(f"Total: {total_time:.3e}s, Seq: {sequential_time:.3e}s, Parallel (threads): {longest_threads_time_accumulator.total_time:.3e}s, Tests time: {tests_time.total_time:.3e}s")
2025-01-13 17:05:20 +01:00
return x, 0