Skip to content

Commit 88289d2

Browse files
committed
update ignore.
1 parent 80cc76e commit 88289d2

File tree

6 files changed

+68
-33
lines changed

6 files changed

+68
-33
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
virtual_env/
2+
3+
14
# Byte-compiled / optimized / DLL files
25
__pycache__/
36
*.py[cod]

README.md

+34-5
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
# Symmetric padding for Pytorch
1+
# Exercise three extending Pytorch
22

3-
Welcome to the `sympad_pytorch` repository!
3+
In this exercise you will use setuptools to compile a pytorch extension with PyTorch's `cpp_extension`
4+
module.
45

5-
## Description
66

7-
This repository implements a `symmetric` padding extension for PyTorch. Symmetric padding, for example, is the default in `pywt` (https://pywavelets.readthedocs.io). Providing this functionality as a C++ module in PyTorch will allow us to speed up Wavelet computations in PyTorch.
7+
The task is to implement `symmetric` padding extension for PyTorch. Symmetric padding, for example, is the default in `pywt` (https://pywavelets.readthedocs.io). PyTorch lacks this functionality. In this exercise, we will provide it.
88

9-
## Testing and Verification
9+
### Testing and Verification
1010

1111
Follow these steps:
1212

@@ -15,3 +15,32 @@ Follow these steps:
1515
3. Run the tests with `nox -s test`.
1616

1717

18+
### Implementing your module in c++.
19+
20+
Symmetric padding extends a signal by mirroring samples. This mode is also known as half-sample symmetric [[pywt-docs](https://pywavelets.readthedocs.io/en/latest/ref/signal-extension-modes.html) ].
21+
The idea is to repeat samples in reverse order at the boundary.
22+
23+
```
24+
... x2 x1 | x1 x2 ... xn | xn xn-1 ...
25+
```
26+
27+
Implement this boundary extension mode in the `src/sympad.cpp` file's `_pad_symmetric_1d`-function by resolving the `TODO`'s in the code.
28+
29+
30+
### Using your Pytorch module
31+
32+
1. create a virtual environment `python -m venv virtual_env` or a conda environment.
33+
2. activate the environment `source virtual_env/bin/activate`
34+
3. Install your module
35+
- pip install torch numpy build
36+
- python -m build --no-isolation
37+
- pip install dist/sympad-0.0.1-cp312-cp312-linux_x86_64.whl
38+
39+
4. Run your module start the python interpreter with `python`.
40+
5. `import torch, sympad` and `import numpy as np`.
41+
6. Pad a tensor using your own method.
42+
- Run `array = np.arange(9).reshape(3,3)`
43+
- `print(array)`
44+
- Run `sympad.pad_symmetric(torch.from_numpy(array), [(1,1), (1,1)])`
45+
46+

noxfile.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def test_pad(session):
1717
session.install("torch")
1818
session.install("build")
1919
session.run("python", "-m", "build", "--no-isolation")
20-
session.install("dist/sympad-0.0.1.tar.gz")
20+
session.install("dist/sympad-0.0.1-cp312-cp312-linux_x86_64.whl")
2121
session.run("pytest")
2222

2323

@@ -54,5 +54,4 @@ def mypy(session):
5454
"""Check type hints."""
5555
session.install("torch")
5656
session.install("mypy")
57-
5857
session.run("mypy", "--ignore-missing-imports", "test")

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from setuptools import Extension, setup
1+
from setuptools import setup
22
from torch.utils import cpp_extension
33

44
setup(

src/sympad.cpp

+19-20
Original file line numberDiff line numberDiff line change
@@ -23,30 +23,32 @@ torch::Tensor _pad_symmetric_1d(torch::Tensor signal, pair<int, int> pad_tuple,
2323
// pad recursively until we have enough values.
2424
if (padl > dimlen || padr > dimlen)
2525
{
26+
// make_pair allows you to call _pad_symmetric_1d.
27+
// https://en.cppreference.com/w/cpp/utility/pair/make_pair .
28+
2629
if (padl > dimlen)
2730
{
28-
signal = _pad_symmetric_1d(signal, make_pair(dimlen, 0), dim);
29-
padl = padl - dimlen;
31+
// TODO: pad as many values as possible and adjust padl.
32+
3033
}
3134
else
3235
{
33-
signal = _pad_symmetric_1d(signal, make_pair(0, dimlen), dim);
34-
padr = padr - dimlen;
36+
// TODO: pad as many values as possible and adjust padr.
3537
}
36-
return _pad_symmetric_1d(signal, make_pair(padl, padr), dim);
38+
//TODO: Return i.e. with a call of _pad_symmetric_1d instead of signal.
39+
return signal;
3740
}
3841
else
3942
{
4043
vector<torch::Tensor> cat_list = {signal};
41-
if (padl > 0)
42-
{
43-
cat_list.insert(cat_list.begin(), signal.slice(dim, 0, padl).flip(dim));
44-
}
45-
if (padr > 0)
46-
{
47-
cat_list.push_back(signal.slice(dim, dimlen-padr, dimlen).flip(dim));
48-
}
49-
return torch::cat(cat_list, dim);
44+
// use i.e. the vectors insert and push_pack methods to implement symmetric padding.
45+
// torch tensors provide the slice( dimension, start, stop) function as well as
46+
// the flip(dimesnion) functions, which will help you.
47+
48+
// TODO: implement me.
49+
50+
// return a tensor by calling torch::cat instead of signal
51+
return signal;
5052
}
5153
}
5254

@@ -69,15 +71,12 @@ torch::Tensor pad_symmetric(torch::Tensor signal, vector<pair<int, int>> pad_lis
6971
}
7072

7173
int dims = signal.dim() - 1;
72-
reverse(pad_lists.begin(), pad_lists.end());
73-
for (int pos = 0; pos < pad_dims; pos++)
74-
{
75-
int current_axis = dims - pos;
76-
signal = _pad_symmetric_1d(signal, pad_lists[pos], current_axis);
77-
}
74+
//take a look at https://cplusplus.com/reference/algorithm/reverse/ .
75+
// loop through the dimension vector and pad the specified dimension using _pad_symmetric_1d.
7876
return signal;
7977
}
8078

79+
// This code defines the python bindings for your function.
8180
PYBIND11_MODULE(sympad, m) {
8281
m.def("pad_symmetric", &pad_symmetric, "A function that pads a tensor symmetrically");
8382
m.def("_pad_symmetric_1d", &_pad_symmetric_1d, "A function that pads a tensor symmetrically in 1D.");

test/test_sympad.py

+10-5
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
@pytest.mark.parametrize("size", [[5], [6], [9], [3]])
1010
@pytest.mark.parametrize(
1111
"pad_list",
12-
[(1, 4), (2, 2), (3, 3), (4, 1), (5, 0), (0, 5), (0, 0), (1, 1), (3, 1), (1, 3)],
12+
[(1, 4), (2, 2), (3, 3), (4, 1), (5, 0),
13+
(0, 5), (0, 0), (1, 1), (3, 1), (1, 3)],
1314
)
1415
def test_pad_symmetric_1d(size: list[int], pad_list: tuple[int, int]) -> None:
1516
"""Test high-dimensional symetric padding."""
@@ -19,9 +20,11 @@ def test_pad_symmetric_1d(size: list[int], pad_list: tuple[int, int]) -> None:
1920
assert np.allclose(my_pad.numpy(), np_pad)
2021

2122

22-
@pytest.mark.parametrize("size", [[6, 5], [5, 6], [5, 5], [9, 9], [3, 3], [4, 4]])
23+
@pytest.mark.parametrize("size", [[6, 5], [5, 6], [5, 5],
24+
[9, 9], [3, 3], [4, 4]])
2325
@pytest.mark.parametrize("pad_list", [[(1, 4), (4, 1)], [(2, 2), (3, 3)]])
24-
def test_pad_symmetric_2d(size: list[int], pad_list: list[tuple[int, int]]) -> None:
26+
def test_pad_symmetric_2d(size: list[int],
27+
pad_list: list[tuple[int, int]]) -> None:
2528
"""Test high-dimensional symetric padding."""
2629
array = np.random.randint(0, 9, size=size)
2730
my_pad = pad_symmetric(torch.from_numpy(array), pad_list)
@@ -33,7 +36,8 @@ def test_pad_symmetric_2d(size: list[int], pad_list: list[tuple[int, int]]) -> N
3336
@pytest.mark.parametrize(
3437
"pad_list", [[(0, 0), (1, 4), (4, 1)], [(1, 1), (2, 2), (3, 3)]]
3538
)
36-
def test_pad_symmetric_3d(size: list[int], pad_list: list[tuple[int, int]]) -> None:
39+
def test_pad_symmetric_3d(size: list[int],
40+
pad_list: list[tuple[int, int]]) -> None:
3741
"""Test high-dimensional symetric padding."""
3842
array = np.random.randint(0, 9, size=size)
3943
my_pad = pad_symmetric(torch.from_numpy(array), pad_list)
@@ -59,7 +63,8 @@ def test_pad_symmetric_small() -> None:
5963
((7, 7), (7, 7)),
6064
],
6165
)
62-
@pytest.mark.parametrize("size", [(3, 3), (4, 4), (2, 2), (1, 1), (2, 1), (2, 1)])
66+
@pytest.mark.parametrize("size", [(3, 3), (4, 4), (2, 2),
67+
(1, 1), (2, 1), (2, 1)])
6368
def test_pad_symmetric_wrap(pad_list, size: tuple[int, int]) -> None:
6469
"""Test high-dimensional symetric padding."""
6570
array = np.random.randint(0, 9, size=size)

0 commit comments

Comments
 (0)