Skip to content

Commit 24c4818

Browse files
authored
Merge pull request #8 from slimgroup/compat
new judi version
2 parents f498b9c + 1bd864a commit 24c4818

File tree

6 files changed

+162
-37
lines changed

6 files changed

+162
-37
lines changed

.github/workflows/runtests.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- main
10+
11+
jobs:
12+
test:
13+
name: Julia ${{ matrix.version }} - ${{ matrix.os }}
14+
runs-on: ${{ matrix.os }}
15+
env:
16+
DEVITO_ARCH: gcc-9
17+
DEVITO_LANGUAGE: "openmp"
18+
DEVITO_LOGGING: "ERROR"
19+
OMP_NUM_THREADS: 1
20+
21+
strategy:
22+
fail-fast: false
23+
24+
matrix:
25+
version: ['1.6', '1.7', '1.8', '1']
26+
os: [ubuntu-latest]
27+
28+
steps:
29+
- name: Checkout ImageGather.jl
30+
uses: actions/checkout@v3
31+
32+
- name: Setup julia
33+
uses: julia-actions/setup-julia@v1
34+
with:
35+
version: ${{ matrix.version }}
36+
37+
- name: Build ImageGather.jl
38+
uses: julia-actions/julia-buildpkg@latest
39+
40+
- name: Run tests
41+
id: test
42+
uses: julia-actions/julia-runtest@latest

Project.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
name = "ImageGather"
22
uuid = "355d8124-6b2e-49b5-aab5-cdbc0a5fccbe"
33
authors = ["mloubout <[email protected]>"]
4-
version = "0.2.4"
4+
version = "0.2.5"
55

66
[deps]
77
JUDI = "f3b833dc-6b2e-5b9c-b940-873ed6319979"
8+
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
89

910
[compat]
10-
JUDI = "3.1.3"
11+
JUDI = "3.3.1"
1112
julia = "1"
1213

1314
[extras]

src/implementation.py

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,52 +16,50 @@
1616
def double_rtm(model, wavelet, src_coords, res, res_o, rec_coords, space_order=8):
1717
"""
1818
"""
19-
_, u, _ = forward(model, src_coords, None, wavelet, space_order=space_order,
20-
save=True)
21-
22-
# Illumination
23-
illum = Function(name="I", grid=model.grid, space_order=0)
24-
Operator(Inc(illum, u**2))()
19+
_, u, illum, _ = forward(model, src_coords, None, wavelet, space_order=space_order,
20+
illum=True, save=True)
2521

2622
# RTMs
27-
rtm, _ = gradient(model, res, rec_coords, u, space_order=space_order)
28-
rtmo, _ = gradient(model, res_o, rec_coords, u, space_order=space_order)
23+
rtm = gradient(model, res, rec_coords, u, space_order=space_order)[0]
24+
rtmo = gradient(model, res_o, rec_coords, u, space_order=space_order)[0]
2925
return rtm.data, rtmo.data, illum.data
3026

3127

32-
def cig_grad(model, src_coords, wavelet, rec_coords, res, offsets, isic=False, space_order=8, omni=False):
28+
def cig_grad(model, src_coords, wavelet, rec_coords, res, offsets, ic="as", space_order=8, omni=False, illum=False):
3329
"""
3430
"""
3531
u = forward(model, src_coords, None, wavelet, space_order=space_order, save=True)[1]
36-
# Setting adjoint wavefieldgradient
32+
# Setting adjoint wavefield
3733
v = wavefield(model, space_order, fw=False)
3834

3935
# Set up PDE expression and rearrange
4036
pde = wave_kernel(model, v, fw=False)
4137

4238
# Setup source and receiver
4339
go_expr = geom_expr(model, v, src_coords=rec_coords,
44-
wavelet=res, fw=False)
40+
wavelet=res, fw=False)
4541
# Setup gradient wrt m with all offsets
4642
ohs = make_offsets(offsets, model, omni)
47-
x = u.indices[1]
4843

4944
# Subsurface offsets.
50-
hs = (h.shape[0] for h in ohs.values())
51-
hd = (h.indices[0] for h in ohs.values())
45+
hs = tuple(h.shape[0] for h in ohs.values())
46+
hd = tuple(h.indices[0] for h in ohs.values())
5247
gradm = Function(name="gradm", grid=model.grid, shape=(*hs, *u.shape[1:]),
53-
dimensions=(*hd, *model.grid.dimensions), space_order=0)
48+
dimensions=(*hd, *model.grid.dimensions))
49+
5450
uh, vh = shifted_wf(u, v, ohs)
55-
g_expr = grad_expr(gradm, uh, vh, model, ic=isic)
51+
g_expr = grad_expr(gradm, uh, vh, model, ic=ic)
5652

5753
# Create operator and run
58-
subs = model.spacing_map
59-
op = Operator(pde + go_expr + g_expr,subs=subs, name="cig_sso", opt=opt_op(model))
54+
subs = model.grid.spacing_map
55+
op = Operator(pde + go_expr + g_expr, subs=subs, name="cig_sso", opt=opt_op(model))
56+
6057
try:
6158
op.cfunction
6259
except:
63-
op = Operator(pde + go_expr + g_expr,subs=subs, name="cig_sso", opt='advanced')
60+
op = Operator(pde + go_expr + g_expr, subs=subs, name="cig_sso", opt='advanced')
6461
op.cfunction
62+
6563
# Get bounds from offsets
6664
dim_kw = make_kw(ohs, DimensionTuple(*u.shape[1:], getters=model.grid.dimensions))
6765
op(dt=model.critical_dt, **dim_kw)
@@ -70,7 +68,7 @@ def cig_grad(model, src_coords, wavelet, rec_coords, res, offsets, isic=False, s
7068
return gradm.data
7169

7270

73-
def cig_lin(model, src_coords, wavelet, rec_coords, dm_ext, offsets, isic=False, space_order=8, omni=False):
71+
def cig_lin(model, src_coords, wavelet, rec_coords, dm_ext, offsets, ic="as", space_order=8, omni=False):
7472
"""
7573
"""
7674
nt = wavelet.shape[0]
@@ -83,7 +81,7 @@ def cig_lin(model, src_coords, wavelet, rec_coords, dm_ext, offsets, isic=False,
8381

8482
# Set up PDE expression and rearrange
8583
pde = wave_kernel(model, u)
86-
qlin = ext_src(model, u, dm_ext, oh, isic=isic)
84+
qlin = ext_src(model, u, dm_ext, oh, ic=ic)
8785
fact = 1 / (model.damp/dt + (model.m * model.irho)/dt**2)
8886
pdel = wave_kernel(model, ul) + [Inc(ul.forward, fact * qlin)]
8987

@@ -92,7 +90,7 @@ def cig_lin(model, src_coords, wavelet, rec_coords, dm_ext, offsets, isic=False,
9290
go_exprl = geom_expr(model, ul, rec_coords=rec_coords, nt=nt)
9391
_, rcvl = src_rec(model, ul, rec_coords=rec_coords, nt=nt)
9492
# Create operator and run
95-
subs = model.spacing_map
93+
subs = model.grid.spacing_map
9694
op = Operator(pde + go_expr + pdel + go_exprl,
9795
subs=subs, name="extborn", opt=opt_op(model))
9896
op.cfunction
@@ -104,7 +102,7 @@ def cig_lin(model, src_coords, wavelet, rec_coords, dm_ext, offsets, isic=False,
104102
return rcvl.data
105103

106104

107-
def ext_src(model, u, dm_ext, oh, isic=False):
105+
def ext_src(model, u, dm_ext, oh, ic="as"):
108106
# Extended perturbation
109107
hs = (h.shape[0] for h in oh.values())
110108
hd = (h.indices[0] for h in oh.values())
@@ -137,6 +135,8 @@ def shifted_wf(u, v, ohs):
137135
uh = u
138136
vh = v
139137
for k, v in ohs.items():
138+
if v.shape[0] == 1:
139+
continue
140140
uh = uh._subs(k, k-v)
141141
vh = vh._subs(k, k+v)
142142
return uh, vh
@@ -152,6 +152,6 @@ def _shift(u, oh):
152152
def make_kw(ohs, shape):
153153
kw = dict()
154154
for d, v in ohs.items():
155-
kw['%s_m' % d.name] = -np.min(v.data)
156-
kw['%s_M' % d.name] = shape[d] - np.max(v.data)
155+
kw['%s_m' % d.name] = -np.min(v.data.view(np.ndarray))
156+
kw['%s_M' % d.name] = shape[d] - np.max(v.data.view(np.ndarray))
157157
return kw

src/subsurface_gather.jl

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ end
3434
function make_input(J::judiExtendedJacobian{D, :born, FT}, dm) where {D<:Number, FT}
3535
srcGeom, srcData = JUDI.make_src(J.q, J.F.qInjection)
3636
return srcGeom, srcData, J.F.rInterpolation.data[1], nothing, dm
37-
end
37+
end
38+
3839
*(J::judiExtendedJacobian{T, :born, O}, dm::Array{T, 3}) where {T, O} = J*vec(dm)
3940
*(J::judiExtendedJacobian{T, :born, O}, dm::Array{T, 4}) where {T, O} = J*vec(dm)
4041

@@ -59,15 +60,15 @@ function propagate(J::judiExtendedJacobian{T, :born, O}, q::AbstractArray{T}) wh
5960
dtComp = convert(Float32, modelPy."critical_dt")
6061

6162
# Extrapolate input data to computational grid
62-
qIn = time_resample(srcData, srcGeometry, dtComp)[1]
63+
qIn = time_resample(srcData, srcGeometry, dtComp)
6364

6465
# Set up coordinates
6566
src_coords = setup_grid(srcGeometry, J.model.n) # shifts source coordinates by origin
6667
rec_coords = setup_grid(recGeometry, J.model.n) # shifts rec coordinates by origin
6768

6869
# Devito interface
6970
dD = JUDI.wrapcall_data(impl."cig_lin", modelPy, src_coords, qIn, rec_coords,
70-
dmd, J.offsets, isic=J.options.IC, space_order=J.options.space_order, omni=J.omni)
71+
dmd, J.offsets, ic=J.options.IC, space_order=J.options.space_order, omni=J.omni)
7172
dD = time_resample(dD, dtComp, recGeometry)
7273
# Output shot record as judiVector
7374
return judiVector{Float32, Matrix{Float32}}(1, recGeometry, [dD])
@@ -84,16 +85,18 @@ function propagate(J::judiExtendedJacobian{T, :adjoint_born, O}, q::AbstractArra
8485
dtComp = convert(Float32, modelPy."critical_dt")
8586

8687
# Extrapolate input data to computational grid
87-
qIn = time_resample(srcData, srcGeometry, dtComp)[1]
88-
dObserved = time_resample(recData, recGeometry, dtComp)[1]
88+
qIn = time_resample(srcData, srcGeometry, dtComp)
89+
dObserved = time_resample(recData, recGeometry, dtComp)
8990

9091
# Set up coordinates
9192
src_coords = setup_grid(srcGeometry, J.model.n) # shifts source coordinates by origin
9293
rec_coords = setup_grid(recGeometry, J.model.n) # shifts rec coordinates by origin
9394

9495
# Devito
95-
g = pycall(impl."cig_grad", PyArray, modelPy, src_coords, qIn, rec_coords, dObserved,
96-
J.offsets, isic=J.options.IC, space_order=J.options.space_order, omni=J.omni)
96+
g = JUDI.pylock() do
97+
pycall(impl."cig_grad", PyArray, modelPy, src_coords, qIn, rec_coords, dObserved, J.offsets,
98+
illum=false, ic=J.options.IC, space_order=J.options.space_order, omni=J.omni)
99+
end
97100
g = remove_padding_cig(g, modelPy.padsizes; true_adjoint=J.options.sum_padding)
98101
return g
99102
end

src/surface_gather.jl

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,11 @@ function double_rtm_cig(model_full, q::judiVector, data::judiVector, offs, optio
7474
mute!(res, off_r .- scale; dt=dtComp/1f3, t0=.25)
7575
res_o = res .* off_r'
7676
# Double rtm
77-
rtm, rtmo, illum = pycall(impl."double_rtm", Tuple{PyArray, PyArray, PyArray},
78-
modelPy, qIn, src_coords, res, res_o, rec_coords, space_order=options.space_order)
77+
78+
rtm, rtmo, illum = JUDI.pylock() do
79+
pycall(impl."double_rtm", Tuple{PyArray, PyArray, PyArray},
80+
modelPy, qIn, src_coords, res, res_o, rec_coords, space_order=options.space_order)
81+
end
7982
rtm = remove_padding(rtm, modelPy.padsizes)
8083
rtmo = remove_padding(rtmo, modelPy.padsizes)
8184
illum = remove_padding(illum, modelPy.padsizes)

test/runtests.jl

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,79 @@
11
using ImageGather, Test
22

3-
@test true
3+
using JUDI, LinearAlgebra
4+
5+
# Set up model structure
6+
n = (301, 151) # (x,y,z) or (x,z)
7+
d = (10., 10.)
8+
o = (0., 0.)
9+
10+
# Velocity [km/s]
11+
v = 1.5f0 .* ones(Float32,n)
12+
v[:, 76:end] .= 2.5f0
13+
v0 = 1.5f0 .* ones(Float32,n)
14+
# Slowness squared [s^2/km^2]
15+
m = (1f0 ./ v).^2
16+
m0 = (1f0 ./ v0).^2
17+
18+
# Setup info and model structure
19+
nsrc = 1 # number of sources
20+
model = Model(n, d, o, m; nb=40)
21+
model0 = Model(n, d, o, m0; nb=40)
22+
23+
dm = model.m - model0.m
24+
25+
# Set up receiver geometry
26+
nxrec = 151
27+
xrec = range(0f0, stop=(n[1] -1)*d[1], length=nxrec)
28+
yrec = 0f0
29+
zrec = range(20f0, stop=20f0, length=nxrec)
30+
31+
# receiver sampling and recording time
32+
timeD = 2000f0 # receiver recording time [ms]
33+
dtD = 4f0 # receiver sampling interval [ms]
34+
35+
# Set up receiver structure
36+
recGeometry = Geometry(xrec, yrec, zrec; dt=dtD, t=timeD, nsrc=nsrc)
37+
# Set up source geometry (cell array with source locations for each shot)
38+
xsrc = 1500f0
39+
ysrc = 0f0
40+
zsrc = 20f0
41+
42+
# Set up source structure
43+
srcGeometry = Geometry(xsrc, ysrc, zsrc; dt=dtD, t=timeD)
44+
# setup wavelet
45+
f0 = 0.015f0 # kHz
46+
wavelet = ricker_wavelet(timeD, dtD, f0)
47+
q = diff(judiVector(srcGeometry, wavelet))
48+
49+
###################################################################################################
50+
opt = Options()
51+
# Setup operators
52+
F = judiModeling(model, srcGeometry, recGeometry; options=opt)
53+
J0 = judiJacobian(F(model0), q)
54+
# Nonlinear modeling
55+
dD = J0*dm
56+
rtm = J0'*dD
57+
58+
# Common surface offset image gather
59+
offsets = -40f0:model.d[1]:40f0
60+
nh = length(offsets)
61+
62+
J = judiExtendedJacobian(F(model0), q, offsets)
63+
64+
ssodm = J'*dD
65+
@test size(ssodm, 1) == nh
66+
67+
ssor = zeros(Float32, size(ssodm)...)
68+
for h=1:size(ssor, 1)
69+
ssor[h, :, :] .= dm.data
70+
end
71+
72+
dDe = J*ssor
73+
# @show norm(dDe - dD), norm(ssor[:] - dm[:])
74+
a, b = dot(dD, dDe), dot(ssodm[:], ssor[:])
75+
76+
@test (a-b)/(a+b) 0 atol=sqrt(eps(1f0)) rtol=0
77+
78+
# Make sure zero offset is the rtm, remove the sumpadding
79+
@test norm(rtm.data - ssodm[div(nh, 2)+1, :, :])/norm(rtm) 0f0 atol=1f-5 rtol=0

0 commit comments

Comments
 (0)