-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvec_to_mat.py
More file actions
86 lines (64 loc) · 2.44 KB
/
vec_to_mat.py
File metadata and controls
86 lines (64 loc) · 2.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
"""Experimenting with PETSc mat-vec multiplication"""
import time
import numpy as np
from colorama import Fore
from firedrake import COMM_WORLD
from firedrake.petsc import PETSc
from mpi4py import MPI
from utilities import (
Print,
convert_petsc_vector_to_matrix_seq,
create_petsc_vector,
gather_local_to_global_matrix,
get_local_subvector,
)
nproc = COMM_WORLD.size
rank = COMM_WORLD.rank
# --------------------------------------------
# EXP: Multiplication of the transpose of mpi PETSc matrix with a sequential PETSc vector
# c = A.T * b
# [k x 1] = [m x k].T * [m x 1]
# --------------------------------------------
def convert_petsc_vector_to_matrix(vector: PETSc.Vec) -> PETSc.Mat:
"""Convert a PETSc vector to a PETSc matrix of one column
with the same number of rows as the size of the vector
Args:
vector (PETSc.Vec): PETSc vector
Returns:
PETSc.Mat: PETSc matrix (partitioned)
"""
vector_local = get_local_subvector(vector)
matrix_local = convert_petsc_vector_to_matrix_seq(vector_local)
return gather_local_to_global_matrix(matrix_local, partition_like=vector)
def test_matrix_vector_equivalence(vector: PETSc.Vec, matrix: PETSc.Mat):
"""Test if the PETSc matrix and PETSc vector contain the same values within the ownership range of each process."""
local_range = vector.getOwnershipRange()
local_values_vector = vector.getArray()
# Get the corresponding column values from the matrix
local_values_matrix = np.array(
[matrix.getValue(row, 0) for row in range(*local_range)]
)
# Check if both arrays are equivalent
assert np.allclose(
local_values_vector, local_values_matrix
), f"Values in vector and matrix do not match on process {rank}."
if __name__ == "__main__":
m, k = 500000, 50
np.random.seed(0)
b_np = np.random.randint(low=0, high=6, size=m)
# Setup
b = create_petsc_vector(b_np)
# print_vector_partitioning(b, "vector b")
matvec_start = time.time()
# Convert the vector to a matrix
b_matrix = convert_petsc_vector_to_matrix(b)
# Run the test
test_matrix_vector_equivalence(b, b_matrix)
print(f"Test completed successfully on process {rank}.")
matvec_end = time.time()
matvec_local = matvec_end - matvec_start
matvec = COMM_WORLD.allreduce(matvec_local, op=MPI.SUM)
Print(
f"Total time taken for mat-vec operations:: {matvec:.2f} seconds",
Fore.RED,
)