Skip to content

Commit ec81d32

Browse files
committed
Fixed typo
2 parents 5815fed + dd5c268 commit ec81d32

16 files changed

+484
-165
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,3 +196,6 @@ skbuild/*
196196

197197
# helper files
198198
*TMP.py
199+
200+
# files from profiling
201+
*.lprof

README.md

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,53 @@
1-
Names: Lorenzo Tomada, Gaspare Li Causi
1+
Names: Gaspare Li Causi, Lorenzo Tomada
22

3-
email: ltomada@sissa.it, glicausi@sissa.it
3+
email: glicausi@sissa.it, ltomada@sissa.it
44

5+
# TODO
6+
Running example in run.sh
7+
8+
# Introduction
59
This repository contains the final project for the course in Development Tools in Scientific Computing.
610

11+
The goal of this project is to implement an efficient eigenvalue solver.
12+
This is done following an efficient strategy specialized for symmetric matrices, which is described in detail in the notebook `Documentation.ipynb` in the `docs` folder.
13+
14+
# General details
15+
The implementation of the solver is done using `mpi4py`. Moreover, the package relies on a `C++` backend that is automatically compiled when running `python -m pip install .`.
16+
A more detailed discussion on dependencies and on how to install the package is provided at the end of the `README.md` file.
17+
## Repo structure
18+
We implemented various GitHub workflows, which include unit testing, documentation generation and code formatting.
19+
20+
1. Unit tests are performed using `pytest`. They are run automatically after each push. There are three test files in the `test` folder, namely `test_eigensolvers.py` (using to test the implementation of the Lanczos method and the QR algorithm), `test_zero_finder.py` (used to ensure correctness of helper functions for the divide et impera algorithm), and `test_utils.py` (to test that some helper functions work as expected).
21+
2. All the code is commented in detail in terms of docstrings and comments corresponding to the most salient lines of code. The documentation is generated automatially using `sphinx` at each push and deployed to `GitHub` pages.
22+
3. After each push, the code is automatically formatted using the `black` formatter.
23+
24+
## Where to find important files
25+
All the important files are in the `src/pyclassify folder`. In the root directory, the only interesting files are the `CMakeLists.txt` and the `setup.py`. Notice that the `setup.py` was added to the `pyproject.toml` file as it made it easier to automatically compile the library during installation and to deal with external dependencies, e.g. `Eigen`.
26+
27+
In the `src/pyclassify` folder, the file `utils.py` contains some helper functions, e.g. the ones need to check that a matrix is of the correct shape.
28+
The `cxx_utils.cpp` file contains the implementation in `C++` of some functions that are needed in the divide and conquer algorithm (e.g. the implementations of deflation, QR method and secular solvers).
29+
In addition, the `parallel_tridiag_eigen.py` contains the actual implementation of the divide and conquer method, while `eigenvalues.py` contains the implementation of the Lanczos algorithm.
30+
The `zero_finder.py` just consists of a first implementation of some of the functions in `cxx_utils.cpp` and has not been removed since it is used in tests to ensure that the `C++` implementation is correct.
31+
32+
## What did we implement?
33+
In order to solve an eigenvalue problem, we considered multiple strategies.
34+
1. The most trivial one was to implement the power method in order to be able to compute (at least) the biggest eigenvalue. We then used `numba` to try and optimize it, but in this case just-in-time compilation was not extremely beneficial.The implementation of the power method is contained in `eigenvalues.py`.
35+
2. Lanczos + QR: this is an approach (tailored to the case of symmetric matrices) to compute *all* the eigenvalues and eigenvectors. Notice that, also in the case of the QR method,`numba` was not very beneficial in terms of speed-up, resulting in a pretty slow methodology. For this reason, we implemented the QR method in `C++` and used `pybind11` to expose it to `Python`. All the code written in `C++` can be found in `cxx_utils.cpp`.
36+
3. `CuPy` implementation of all of the above: we implemented all the above methodologies using `CuPy` to see whether using GPU could speed up computations. Since this was not the case, we commented all the lines of code involving `CuPy`, so that installation of the package is no longer required and we can use our code also on machines that do not have GPU.
37+
4. The core of the project is the implementation (as well as a generalization of the simplified case in which $\rho=\$ considered in our reference) of the _divide et implera_ method for the computation of eigenvalues of a symmetric matrix. Some helpers were originally written in `Python` and then translated to `C++` for efficiency reasons: their original implementation is in `zero_finder.py` and is still present in the project for testing purposes. The translated version can be found in `cxx_utils.cpp`. Instead, the implementation of the actual method to compute the eigenvalues starting from a tridiagonal matrix is contained in `parallel_tridiag_eigen.py` and makes use of `mpi4py`.
38+
39+
# Results
40+
The results of the profiling (runtime vs matrix size, memory consumption, scalability, and so on) are discussed in detail in `Documentation.ipynb`.
41+
All the scripts in the `scripts` folder are either used for profiling or to provide running examples.
742

8-
TO DO:
9-
1) Profile runtime and memory usage, saving the results and plotting
10-
2) Runtime vs matrix size comparison (follow in detail the instructions on the course repo)
11-
3) Accuracy vs efficiency
12-
4) Add missing tests
43+
# How to run
44+
We provide an example of running code in the `script` folder.
45+
In the `shell` folder, we provide a `submit.sbatch` file to run using `SLURM`, as well as a `submit.sh` to run the same experiment locally.
46+
In particular, these two files perform memory profiling.
1347

1448
# To install using Ulysses:
1549
```bash
16-
source shell/submit.sh
50+
source shell/load_modules.sh
1751
```
1852
The previous line will load CMake and gcc. Both are needed to compile the project.
1953
In addition, it will enable the istallation of `mpi4py`.

experiments/config.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
dim: 200
2+
density: 0.2
3+
n_processes: 2
4+
plot: true

experiments/config_accuracy.yaml

Lines changed: 0 additions & 2 deletions
This file was deleted.

experiments/config_profiling.yaml

Lines changed: 0 additions & 2 deletions
This file was deleted.

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ authors = [
1818
dynamic = ["dependencies"]
1919

2020
[tool.scikit-build]
21-
# Optional: specify the build directory
2221
build-dir = "build"
2322

23+
2424
[tool.setuptools.packages.find]
2525
where = ["src"]
2626
exclude = ["scripts", "tests", "shell", "experiments"]
@@ -30,3 +30,4 @@ dependencies = { file = ["requirements.txt"] }
3030

3131
[project.optional-dependencies]
3232
test = ["pytest"]
33+

scripts/mpi_running.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
# from pyclassify.parallel_tridiag_eigen import parallel_eigen
2-
from pyclassify import parallel_tridiag_eigen
32
from time import time
43
import numpy as np
54
from mpi4py import MPI
@@ -10,7 +9,7 @@ def parallel_eig(d, off_d, nprocs):
109

1110
print("inside parallel_eig")
1211
comm = MPI.COMM_SELF.Spawn(
13-
sys.executable, args=["parallel_tridiag_eigen.py"], maxprocs=nprocs
12+
sys.executable, args=["./parallel_tridiag_eigen.py"], maxprocs=nprocs
1413
)
1514
print("sending")
1615
comm.send(d, dest=0, tag=11)
@@ -27,7 +26,7 @@ def parallel_eig(d, off_d, nprocs):
2726
return eigvals, eigvecs, delta_t
2827

2928

30-
n = 1000
29+
n = 100
3130
nprocs = 4
3231
# np.random.seed(42)
3332
d = np.random.rand(n) * 2

scripts/plot_scalability.py

Lines changed: 0 additions & 44 deletions
This file was deleted.

0 commit comments

Comments
 (0)