Skip to content

Commit f94d550

Browse files
authored
Merge pull request #660 from mrava87/test-cupy2
ci: modified test suite to run on cupy
2 parents 44bae08 + 4f3bb29 commit f94d550

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+2640
-987
lines changed

Makefile

100755100644
Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
PIP := $(shell command -v pip3 2> /dev/null || command which pip 2> /dev/null)
22
PYTHON := $(shell command -v python3 2> /dev/null || command which python 2> /dev/null)
33

4-
.PHONY: install dev-install install_conda dev-install_conda tests doc docupdate servedoc lint typeannot coverage
4+
.PHONY: install dev-install dev-install_gpu install_conda dev-install_conda dev-install_conda_arm tests doc docupdate servedoc lint typeannot coverage
55

66
pipcheck:
77
ifndef PIP
@@ -24,6 +24,11 @@ dev-install:
2424
$(PIP) install -r requirements-dev.txt &&\
2525
$(PIP) install -r requirements-torch.txt && $(PIP) install -e .
2626

27+
dev-install_gpu:
28+
make pipcheck
29+
$(PIP) install -r requirements-dev-gpu.txt &&\
30+
$(PIP) install -e .
31+
2732
install_conda:
2833
conda env create -f environment.yml && conda activate pylops && pip install .
2934

@@ -33,6 +38,9 @@ dev-install_conda:
3338
dev-install_conda_arm:
3439
conda env create -f environment-dev-arm.yml && conda activate pylops && pip install -e .
3540

41+
dev-install_conda_gpu:
42+
conda env create -f environment-dev-gpu.yml && conda activate pylops_gpu && pip install -e .
43+
3644
tests:
3745
make pythoncheck
3846
pytest

environment-dev-arm.yml

100755100644
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ channels:
55
- numba
66
- pytorch
77
dependencies:
8-
- python>=3.6.4
8+
- python>=3.9.0
99
- pip
1010
- numpy>=1.21.0
1111
- scipy>=1.11.0

environment-dev-gpu.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: pylops_gpu
2+
channels:
3+
- conda-forge
4+
- defaults
5+
- numba
6+
dependencies:
7+
- python>=3.11.0
8+
- pip
9+
- numpy>=1.21.0
10+
- scipy>=1.11.0
11+
- cupy
12+
- sympy
13+
- matplotlib
14+
- ipython
15+
- pytest
16+
- Sphinx
17+
- numpydoc
18+
- numba
19+
- icc_rt
20+
- pre-commit
21+
- autopep8
22+
- isort
23+
- black
24+
- pip:
25+
- torch
26+
- pytest-runner
27+
- setuptools_scm
28+
- pydata-sphinx-theme
29+
- sphinx-gallery
30+
- nbsphinx
31+
- sphinxemoji
32+
- image
33+
- flake8
34+
- mypy

environment-dev.yml

100755100644
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ channels:
55
- numba
66
- pytorch
77
dependencies:
8-
- python>=3.6.4
8+
- python>=3.9.0
99
- pip
1010
- numpy>=1.21.0
1111
- scipy>=1.11.0

environment.yml

100755100644
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@ name: pylops
22
channels:
33
- defaults
44
dependencies:
5-
- python>=3.6.4
5+
- python>=3.9.0
66
- numpy>=1.21.0
77
- scipy>=1.14.0

pytests/test_avo.py

100755100644
Lines changed: 66 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
1-
import numpy as np
1+
import os
2+
3+
if int(os.environ.get("TEST_CUPY_PYLOPS", 0)):
4+
import cupy as np
5+
from cupy.testing import assert_array_almost_equal
6+
7+
backend = "cupy"
8+
else:
9+
import numpy as np
10+
from numpy.testing import assert_array_almost_equal
11+
12+
backend = "numpy"
13+
import numpy as npp
214
import pytest
3-
from numpy.testing import assert_array_almost_equal
415
from scipy.signal import filtfilt
5-
from scipy.sparse.linalg import lsqr
616

717
from pylops.avo.avo import (
818
akirichards,
@@ -13,7 +23,9 @@
1323
zoeppritz_scattering,
1424
)
1525
from pylops.avo.prestack import AVOLinearModelling
26+
from pylops.optimization.basic import lsqr
1627
from pylops.utils import dottest
28+
from pylops.utils.backend import to_numpy
1729

1830
np.random.seed(0)
1931

@@ -24,16 +36,20 @@
2436
# Create medium parameters for multiple contrasts
2537
nt0 = 201
2638
dt0 = 0.004
27-
t0 = np.arange(nt0) * dt0
28-
vp = 1200 + np.arange(nt0) + filtfilt(np.ones(5) / 5.0, 1, np.random.normal(0, 80, nt0))
29-
vs = 600 + vp / 2 + filtfilt(np.ones(5) / 5.0, 1, np.random.normal(0, 20, nt0))
30-
rho = 1000 + vp + filtfilt(np.ones(5) / 5.0, 1, np.random.normal(0, 30, nt0))
31-
m = (np.stack((np.log(vp), np.log(vs), np.log(rho)), axis=1)).ravel()
39+
t0 = npp.arange(nt0) * dt0
40+
vp = (
41+
1200
42+
+ npp.arange(nt0)
43+
+ filtfilt(npp.ones(5) / 5.0, 1, npp.random.normal(0, 80, nt0))
44+
)
45+
vs = 600 + vp / 2 + filtfilt(npp.ones(5) / 5.0, 1, npp.random.normal(0, 20, nt0))
46+
rho = 1000 + vp + filtfilt(npp.ones(5) / 5.0, 1, npp.random.normal(0, 30, nt0))
47+
m = npp.stack((npp.log(vp), npp.log(vs), npp.log(rho)), axis=1).ravel()
3248

3349
# Angles
3450
ntheta = 21
3551
thetamin, thetamax = 0, 40
36-
theta = np.linspace(thetamin, thetamax, ntheta)
52+
theta = npp.linspace(thetamin, thetamax, ntheta)
3753

3854
# Parameters
3955
par1 = {"vsvp": 0.5, "linearization": "akirich"} # constant vsvp
@@ -47,16 +63,16 @@ def test_zoeppritz():
4763
`<https://www.crewes.org/ResearchLinks/ExplorerPrograms/ZE/index.html>`_
4864
as benchmark
4965
"""
50-
r_zoep = zoeppritz_scattering(vp1, vs1, rho1, vp0, vs0, rho0, theta[0])
66+
r_zoep = zoeppritz_scattering(vp1, vs1, rho1, vp0, vs0, rho0, np.asarray(theta)[:1])
5167
rpp_zoep = zoeppritz_element(
52-
vp1, vs1, rho1, vp0, vs0, rho0, theta[0], element="PdPu"
68+
vp1, vs1, rho1, vp0, vs0, rho0, np.asarray(theta)[:1], element="PdPu"
5369
)
54-
rpp_zoep1 = zoeppritz_pp(vp1, vs1, rho1, vp0, vs0, rho0, theta[0])
70+
rpp_zoep1 = zoeppritz_pp(vp1, vs1, rho1, vp0, vs0, rho0, np.asarray(theta)[:1])
5571

5672
assert r_zoep.shape == (4, 4, 1)
57-
assert r_zoep[0, 0] == pytest.approx(0.04658, rel=1e-3)
58-
assert rpp_zoep == pytest.approx(0.04658, rel=1e-3)
59-
assert rpp_zoep1 == pytest.approx(0.04658, rel=1e-3)
73+
assert to_numpy(r_zoep[0, 0, 0]) == pytest.approx(0.04658, rel=1e-3)
74+
assert to_numpy(rpp_zoep) == pytest.approx(0.04658, rel=1e-3)
75+
assert to_numpy(rpp_zoep1) == pytest.approx(0.04658, rel=1e-3)
6076

6177

6278
def test_zoeppritz_and_approx_zeroangle():
@@ -66,22 +82,24 @@ def test_zoeppritz_and_approx_zeroangle():
6682
ai1, si1, _ = vp1 * rho1, vs1 * rho1, vp1 / vs1
6783

6884
# Zoeppritz
69-
rpp_zoep = zoeppritz_pp(vp1, vs1, rho1, vp0, vs0, rho0, theta[0])
70-
rpp_zoep_approx = approx_zoeppritz_pp(vp1, vs1, rho1, vp0, vs0, rho0, theta[0])
85+
rpp_zoep = zoeppritz_pp(vp1, vs1, rho1, vp0, vs0, rho0, np.asarray(theta)[:1])
86+
rpp_zoep_approx = approx_zoeppritz_pp(
87+
vp1, vs1, rho1, vp0, vs0, rho0, np.asarray(theta)[:1]
88+
)
7189

7290
# Aki Richards
73-
rvp = np.log(vp0) - np.log(vp1)
74-
rvs = np.log(vs0) - np.log(vs1)
75-
rrho = np.log(rho0) - np.log(rho1)
91+
rvp = np.asarray(np.log(vp0) - np.log(vp1))
92+
rvs = np.asarray(np.log(vs0) - np.log(vs1))
93+
rrho = np.asarray(np.log(rho0) - np.log(rho1))
7694

77-
G1, G2, G3 = akirichards(theta[0], vs1 / vp1)
95+
G1, G2, G3 = akirichards(np.asarray(theta)[:1], vs1 / vp1)
7896
rpp_aki = G1 * rvp + G2 * rvs + G3 * rrho
7997

8098
# Fatti
81-
rai = np.log(ai0) - np.log(ai1)
82-
rsi = np.log(si0) - np.log(si1)
99+
rai = np.asarray(np.log(ai0) - np.log(ai1))
100+
rsi = np.asarray(np.log(si0) - np.log(si1))
83101

84-
G1, G2, G3 = fatti(theta[0], vs1 / vp1)
102+
G1, G2, G3 = fatti(np.asarray(theta)[:1], vs1 / vp1)
85103
rpp_fatti = G1 * rai + G2 * rsi + G3 * rrho
86104

87105
assert_array_almost_equal(rpp_zoep, rpp_zoep_approx, decimal=3)
@@ -97,22 +115,24 @@ def test_zoeppritz_and_approx_multipleangles():
97115
ai1, si1 = vp1 * rho1, vs1 * rho1
98116

99117
# Zoeppritz
100-
rpp_zoep = zoeppritz_pp(vp1, vs1, rho1, vp0, vs0, rho0, theta)
101-
rpp_zoep_approx = approx_zoeppritz_pp(vp1, vs1, rho1, vp0, vs0, rho0, theta)
118+
rpp_zoep = zoeppritz_pp(vp1, vs1, rho1, vp0, vs0, rho0, np.asarray(theta))
119+
rpp_zoep_approx = approx_zoeppritz_pp(
120+
vp1, vs1, rho1, vp0, vs0, rho0, np.asarray(theta)
121+
)
102122

103123
# Aki Richards
104-
rvp = np.log(vp0) - np.log(vp1)
105-
rvs = np.log(vs0) - np.log(vs1)
106-
rrho = np.log(rho0) - np.log(rho1)
124+
rvp = np.asarray(np.log(vp0) - np.log(vp1))
125+
rvs = np.asarray(np.log(vs0) - np.log(vs1))
126+
rrho = np.asarray(np.log(rho0) - np.log(rho1))
107127

108-
G1, G2, G3 = akirichards(theta, vs1 / vp1)
128+
G1, G2, G3 = akirichards(np.asarray(theta), vs1 / vp1)
109129
rpp_aki = G1 * rvp + G2 * rvs + G3 * rrho
110130

111131
# Fatti
112-
rai = np.log(ai0) - np.log(ai1)
113-
rsi = np.log(si0) - np.log(si1)
132+
rai = np.asarray(np.log(ai0) - np.log(ai1))
133+
rsi = np.asarray(np.log(si0) - np.log(si1))
114134

115-
G1, G2, G3 = fatti(theta, vs1 / vp1)
135+
G1, G2, G3 = fatti(np.asarray(theta), vs1 / vp1)
116136
rpp_fatti = G1 * rai + G2 * rsi + G3 * rrho
117137

118138
assert_array_almost_equal(rpp_zoep, rpp_zoep_approx, decimal=3)
@@ -124,11 +144,21 @@ def test_zoeppritz_and_approx_multipleangles():
124144
def test_AVOLinearModelling(par):
125145
"""Dot-test and inversion for AVOLinearModelling"""
126146
AVOop = AVOLinearModelling(
127-
theta, vsvp=par["vsvp"], nt0=nt0, linearization=par["linearization"]
147+
np.asarray(theta),
148+
vsvp=par["vsvp"] if isinstance(par["vsvp"], float) else np.asarray(par["vsvp"]),
149+
nt0=nt0,
150+
linearization=par["linearization"],
128151
)
129-
assert dottest(AVOop, ntheta * nt0, 3 * nt0)
152+
assert dottest(AVOop, ntheta * nt0, 3 * nt0, backend=backend)
130153

131154
minv = lsqr(
132-
AVOop, AVOop * m, damp=1e-20, iter_lim=1000, atol=1e-8, btol=1e-8, show=0
155+
AVOop,
156+
AVOop * np.asarray(m),
157+
x0=np.zeros_like(m),
158+
damp=1e-20,
159+
niter=1000,
160+
atol=1e-8,
161+
btol=1e-8,
162+
show=0,
133163
)[0]
134164
assert_array_almost_equal(m, minv, decimal=3)

0 commit comments

Comments
 (0)