-
Notifications
You must be signed in to change notification settings - Fork 111
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #391 from ankith26/ankith26-gsoc
[GSoC 2024] Binding PyElastica with Elastica++
- Loading branch information
Showing
479 changed files
with
49,546 additions
and
2,468 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
name: elasticapp (Elastica++ based backend) tests | ||
|
||
# trigger run only on changes to the backend folder. | ||
on: | ||
push: | ||
paths: | ||
- backend/** | ||
pull_request: | ||
paths: | ||
- backend/** | ||
|
||
jobs: | ||
build: | ||
runs-on: ${{ matrix.os }} | ||
strategy: | ||
matrix: | ||
python-version: ["3.10", "3.11"] #, "3.12"] | ||
os: [ubuntu-latest] # , macos-latest] | ||
|
||
steps: | ||
- uses: actions/checkout@v2 | ||
|
||
- name: Set up Python ${{ matrix.python-version }} | ||
uses: actions/[email protected] | ||
with: | ||
python-version: ${{ matrix.python-version }} | ||
|
||
- name: Install PyElastica | ||
run: pip install . -v | ||
|
||
- name: Install elasticapp backend | ||
run: pip install ./backend -v | ||
|
||
- name: Run elasticapp tests | ||
run: | | ||
python -m pip install pytest | ||
pytest backend/tests |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -236,3 +236,6 @@ outcmaes/* | |
|
||
# csv files | ||
*.csv | ||
|
||
# ./backend dependencies | ||
deps |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
--- | ||
# We'll use defaults from the Google style. | ||
# See http://clang.llvm.org/docs/ClangFormat.html for help. | ||
Language: Cpp | ||
BasedOnStyle: Google | ||
AllowShortIfStatementsOnASingleLine: false | ||
AllowShortLoopsOnASingleLine: false | ||
PointerAlignment: Left | ||
DerivePointerAlignment: false | ||
FixNamespaceComments: true | ||
IncludeCategories: | ||
- Regex: "^<.*" | ||
Priority: 1 | ||
- Regex: ".*" | ||
Priority: 2 | ||
NamespaceIndentation: All | ||
SortIncludes: false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# Elasticapp backend for PyElastica | ||
|
||
This file serves as the documentation for the `elasticapp` backend. | ||
|
||
## Installation | ||
|
||
In the root of the PyElastica source tree, run the following command | ||
|
||
``` | ||
pip install ./backend | ||
``` | ||
|
||
> Make sure you install the package from _PyElastica source tree_. | ||
This command will take care of installation of all build-time dependencies, compilation of C++ source files and install the a python package called `elasticapp`. | ||
|
||
## Testing | ||
|
||
Make sure you have `pytest` installed. In the root of the PyElastica source tree, run the following command | ||
|
||
``` | ||
pytest backend/tests | ||
``` | ||
|
||
## Benchmarking | ||
|
||
Standalone scripts for benchmarking purposes are available in `backend/benchmarking` folder. | ||
|
||
### Benchmarking `matmul` | ||
|
||
For benchmarking various `matmul` implementations, run | ||
|
||
``` | ||
python3 backend/benchmarking/matmul.py | ||
``` | ||
|
||
## Contributed By | ||
|
||
- Tejaswin Parthasarathy (Teja) | ||
- [Seung Hyun Kim](https://github.com/skim0119) | ||
- Ankith Pai | ||
- [Yashraj Bhosale](https://github.com/bhosale2) | ||
- Arman Tekinalp | ||
- Songyuan Cui |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
from elasticapp._linalg_numpy import batch_cross | ||
from elasticapp._linalg import batch_cross as batch_cross_final | ||
from elasticapp._PyArrays import Matrix | ||
from elastica._linalg import _batch_cross | ||
import numpy | ||
import time | ||
|
||
# warm up jit for fair comparison | ||
random_1 = numpy.random.random((3, 1)) | ||
random_2 = numpy.random.random((3, 1)) | ||
out1 = _batch_cross(random_1, random_2) | ||
|
||
|
||
def benchmark_batchsize(funcs: list, batches: list[int], num_iterations: int = 1000): | ||
ret: dict = {} | ||
for batch_size in batches: | ||
random_a = numpy.random.random((3, batch_size)) | ||
random_b = numpy.random.random((3, batch_size)) | ||
|
||
ret[batch_size] = {} | ||
for func_name, func, func_wrap in funcs: | ||
random_a_w = func_wrap(random_a) if func_wrap else random_a | ||
random_b_w = func_wrap(random_b) if func_wrap else random_b | ||
|
||
start = time.perf_counter() | ||
for _ in range(num_iterations): | ||
func(random_a_w, random_b_w) | ||
|
||
ret[batch_size][func_name] = (time.perf_counter() - start) / num_iterations | ||
|
||
return ret | ||
|
||
|
||
results = benchmark_batchsize( | ||
[ | ||
("pyelastica", _batch_cross, None), | ||
("elasticapp_blaze_copy", batch_cross, None), | ||
("elasticapp_blaze_final", batch_cross_final, Matrix), | ||
], | ||
[2**i for i in range(14)], | ||
) | ||
for size, data in results.items(): | ||
pyelastica = data["pyelastica"] | ||
elasticapp_blaze_copy = data["elasticapp_blaze_copy"] | ||
elasticapp_blaze_final = data["elasticapp_blaze_final"] | ||
print(f"{size = }") | ||
print(f"{pyelastica = }") | ||
print(f"{elasticapp_blaze_copy = }, ratio: {elasticapp_blaze_copy / pyelastica}") | ||
print(f"{elasticapp_blaze_final = }, ratio: {elasticapp_blaze_final / pyelastica}") | ||
print() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
from elasticapp._rotations import inv_rotate, inv_rotate_scalar | ||
from elasticapp._PyArrays import Tensor | ||
from elastica._rotations import _inv_rotate | ||
import numpy | ||
import time | ||
|
||
# warm up jit for fair comparison | ||
random_1 = numpy.random.random((3, 3, 1)) | ||
out1 = _inv_rotate(random_1) | ||
|
||
|
||
def benchmark_batchsize(funcs: list, batches: list[int], num_iterations: int = 1000): | ||
ret: dict = {} | ||
for batch_size in batches: | ||
random_a = numpy.random.random((3, 3, batch_size)) | ||
|
||
ret[batch_size] = {} | ||
for func_name, func, func_wrap in funcs: | ||
random_a_w = func_wrap(random_a) if func_wrap else random_a | ||
|
||
start = time.perf_counter() | ||
for _ in range(num_iterations): | ||
func(random_a_w) | ||
|
||
ret[batch_size][func_name] = (time.perf_counter() - start) / num_iterations | ||
|
||
return ret | ||
|
||
|
||
results = benchmark_batchsize( | ||
[ | ||
("pyelastica", _inv_rotate, None), | ||
("elasticapp_simd", inv_rotate, Tensor), | ||
("elasticapp_scalar", inv_rotate_scalar, Tensor), | ||
], | ||
[2**i for i in range(14)], | ||
) | ||
for size, data in results.items(): | ||
pyelastica = data["pyelastica"] | ||
elasticapp_simd = data["elasticapp_simd"] | ||
elasticapp_scalar = data["elasticapp_scalar"] | ||
print(f"{size = }") | ||
print(f"{pyelastica = }") | ||
print(f"{elasticapp_simd = }, ratio: {elasticapp_simd / pyelastica}") | ||
print(f"{elasticapp_scalar = }, ratio: {elasticapp_scalar / pyelastica}") | ||
print() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
from elasticapp._linalg_numpy import ( | ||
batch_matmul_naive, | ||
batch_matmul_blaze, | ||
batch_matmul, | ||
) | ||
from elasticapp._linalg import batch_matmul as batch_matmul_final | ||
from elasticapp._PyArrays import Tensor | ||
from elastica._linalg import _batch_matmul | ||
import numpy | ||
import time | ||
|
||
# warm up jit for fair comparison | ||
random_1 = numpy.random.random((3, 3, 1)) | ||
random_2 = numpy.random.random((3, 3, 1)) | ||
out1 = _batch_matmul(random_1, random_2) | ||
|
||
|
||
def benchmark_batchsize(funcs: list, batches: list[int], num_iterations: int = 1000): | ||
ret: dict = {} | ||
for batch_size in batches: | ||
random_a = numpy.random.random((3, 3, batch_size)) | ||
random_b = numpy.random.random((3, 3, batch_size)) | ||
|
||
ret[batch_size] = {} | ||
for func_name, func, func_wrap in funcs: | ||
random_a_w = func_wrap(random_a) if func_wrap else random_a | ||
random_b_w = func_wrap(random_b) if func_wrap else random_b | ||
|
||
start = time.perf_counter() | ||
for _ in range(num_iterations): | ||
func(random_a_w, random_b_w) | ||
|
||
ret[batch_size][func_name] = ( | ||
time.perf_counter() - start | ||
) / num_iterations | ||
|
||
return ret | ||
|
||
|
||
results = benchmark_batchsize( | ||
[ | ||
("pyelastica", _batch_matmul, None), | ||
("elasticapp_naive", batch_matmul_naive, None), | ||
("elasticapp_blaze", batch_matmul_blaze, None), | ||
("elasticapp_blaze_copy", batch_matmul, None), | ||
("elasticapp_blaze_final", batch_matmul_final, Tensor), | ||
], | ||
[2**i for i in range(14)], | ||
) | ||
for size, data in results.items(): | ||
pyelastica = data["pyelastica"] | ||
elasticapp_naive = data["elasticapp_naive"] | ||
elasticapp_blaze = data["elasticapp_blaze"] | ||
elasticapp_blaze_copy = data["elasticapp_blaze_copy"] | ||
elasticapp_blaze_final = data["elasticapp_blaze_final"] | ||
print(f"{size = }") | ||
print(f"{pyelastica = }") | ||
print(f"{elasticapp_naive = }, ratio: {elasticapp_naive / pyelastica}") | ||
print(f"{elasticapp_blaze = }, ratio: {elasticapp_blaze / pyelastica}") | ||
print(f"{elasticapp_blaze_copy = }, ratio: {elasticapp_blaze_copy / pyelastica}") | ||
print(f"{elasticapp_blaze_final = }, ratio: {elasticapp_blaze_final / pyelastica}") | ||
print() |
Oops, something went wrong.