Skip to content

Commit 83a5ba6

Browse files
committed
Fix bug in elastic.cu and continue effort to fix MacOS and Windows builds
1 parent 3dd6264 commit 83a5ba6

5 files changed

Lines changed: 195 additions & 16 deletions

File tree

pyproject.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,16 @@ repair-wheel-command = "auditwheel repair -w {dest_dir} {wheel} --exclude libcud
5151
before-test = "pip install torch --index-url https://download.pytorch.org/whl/cpu"
5252

5353
[tool.cibuildwheel.windows]
54+
# Activate VS environment so torch.compile can find the compiler.
55+
before-test = 'call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"'
5456
test-command = "pytest tests/test_scalar.py"
5557

5658
[tool.cibuildwheel.macos]
59+
# Install libomp for linking during build and for runtime in the test env.
60+
before-build = "brew install libomp"
5761
before-test = "brew install libomp"
58-
environment = { OMP_PREFIX = "{brew_prefix}/opt/libomp" }
62+
# Set flags to find and enable OpenMP during the build.
63+
environment = { CFLAGS="-Xclang -fopenmp -I$(brew --prefix libomp)/include", LDFLAGS="-L$(brew --prefix libomp)/lib" }
5964
test-command = "pytest tests/test_scalar.py"
6065

6166
[tool.scikit-build.sdist]

src/deepwave/elastic.cu

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -531,10 +531,10 @@ __global__ void backward_kernel_v(
531531
if (mu_requires_grad) {
532532
grad_mu_yx[i] += sigmaxy[i] * dvydxdvxdy_store[i] * (DW_DTYPE)step_ratio;
533533
}
534-
if (pml_y == 0 || pml_y == 2) {
534+
if (pml_y) {
535535
m_vxy[i] = mu_yx_shot[j] * dt * ayh[y] * sigmaxy[i] + ayh[y] * m_vxy[i];
536536
}
537-
if (pml_x == 0 || pml_x == 2) {
537+
if (pml_x) {
538538
m_vyx[i] = mu_yx_shot[j] * dt * axh[x] * sigmaxy[i] + axh[x] * m_vyx[i];
539539
}
540540
sigmaxy[i] += ((pml_y ? -DIFFYH1(SIGMAXY_Y_PML) : -DIFFYH1(SIGMAXY_Y)) +

tests/test_callbacks.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,3 +410,63 @@ def do_nothing(state: deepwave.common.CallbackState) -> None:
410410
)
411411
for i in range(len(out1)):
412412
assert torch.allclose(out1[i], out2[i])
413+
414+
415+
def test_scalar_backward_callback_only_call_count() -> None:
416+
"""Check that the backward callback is called the correct number of times
417+
when no forward callback is provided.
418+
"""
419+
v = torch.ones(10, 10) * 1500
420+
v.requires_grad_()
421+
dx = 5.0
422+
dt = 0.004
423+
nt = 20
424+
source_amplitudes = torch.zeros(1, 1, nt)
425+
source_amplitudes[0, 0, 5] = 1
426+
source_locations = torch.zeros(1, 1, 2, dtype=torch.long)
427+
source_locations[0, 0, 0] = 5
428+
source_locations[0, 0, 1] = 5
429+
receiver_locations = torch.zeros(1, 1, 2, dtype=torch.long)
430+
receiver_locations[0, 0, 0] = 5
431+
receiver_locations[0, 0, 1] = 5
432+
433+
class Counter:
434+
"""A simple counter class for callbacks."""
435+
436+
def __init__(self) -> None:
437+
self.count = 0
438+
439+
def __call__(self, state: deepwave.common.CallbackState) -> None:
440+
"""Increments the counter."""
441+
self.count += 1
442+
443+
# Test with a frequency that divides nt evenly
444+
backward_counter = Counter()
445+
out = deepwave.scalar(
446+
v,
447+
dx,
448+
dt,
449+
source_amplitudes=source_amplitudes,
450+
source_locations=source_locations,
451+
receiver_locations=receiver_locations,
452+
backward_callback=backward_counter,
453+
callback_frequency=2,
454+
)
455+
out[-1].sum().backward()
456+
assert backward_counter.count == nt / 2
457+
458+
# Test with a frequency that does not divide nt evenly
459+
v.grad.zero_()
460+
backward_counter = Counter()
461+
out = deepwave.scalar(
462+
v,
463+
dx,
464+
dt,
465+
source_amplitudes=source_amplitudes,
466+
source_locations=source_locations,
467+
receiver_locations=receiver_locations,
468+
backward_callback=backward_counter,
469+
callback_frequency=3,
470+
)
471+
out[-1].sum().backward()
472+
assert backward_counter.count == (nt + 2) // 3

tests/test_callbacks_born.py

Lines changed: 57 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -309,30 +309,74 @@ def do_nothing(state: deepwave.common.CallbackState) -> None:
309309
for i in range(len(out1)):
310310
assert torch.allclose(out1[i], out2[i])
311311
assert torch.allclose(grad1_v, grad2_v)
312-
assert torch.allclose(grad1_scatter, grad2_scatter)
313-
v.grad.zero_()
314-
scatter.grad.zero_()
312+
313+
314+
def test_scalar_born_backward_callback_only_call_count() -> None:
315+
"""Check that the backward callback is called the correct number of times
316+
when no forward callback is provided.
317+
"""
318+
v = torch.ones(10, 10) * 1500
319+
scatter = torch.ones(10, 10)
320+
v.requires_grad_()
321+
scatter.requires_grad_()
322+
dx = 5.0
323+
dt = 0.004
324+
nt = 20
325+
source_amplitudes = torch.zeros(1, 1, nt)
326+
source_amplitudes[0, 0, 5] = 1
327+
source_locations = torch.zeros(1, 1, 2, dtype=torch.long)
328+
source_locations[0, 0, 0] = 5
329+
source_locations[0, 0, 1] = 5
330+
receiver_locations = torch.zeros(1, 1, 2, dtype=torch.long)
331+
receiver_locations[0, 0, 0] = 5
332+
receiver_locations[0, 0, 1] = 5
333+
334+
class Counter:
335+
"""A simple counter class for callbacks."""
336+
337+
def __init__(self) -> None:
338+
self.count = 0
339+
340+
def __call__(self, state: deepwave.common.CallbackState) -> None:
341+
"""Increments the counter."""
342+
self.count += 1
343+
344+
# Test with a frequency that divides nt evenly
345+
backward_counter = Counter()
346+
out = deepwave.scalar_born(
347+
v,
348+
scatter,
349+
dx,
350+
dt,
351+
source_amplitudes=source_amplitudes,
352+
source_locations=source_locations,
353+
receiver_locations=receiver_locations,
354+
backward_callback=backward_counter,
355+
callback_frequency=2,
356+
)
357+
out[-1].sum().backward()
358+
grad1_scatter = scatter.grad.detach()
359+
assert backward_counter.count == nt / 2
315360

316361
# Test with a frequency that does not divide nt evenly
317-
out3 = deepwave.scalar_born(
362+
v.grad.zero_()
363+
scatter.grad.zero_()
364+
backward_counter = Counter()
365+
out = deepwave.scalar_born(
318366
v,
319367
scatter,
320368
dx,
321369
dt,
322370
source_amplitudes=source_amplitudes,
323371
source_locations=source_locations,
324372
receiver_locations=receiver_locations,
325-
forward_callback=do_nothing,
326-
backward_callback=do_nothing,
373+
backward_callback=backward_counter,
327374
callback_frequency=3,
328375
)
329-
out3[-1].sum().backward()
330-
grad3_v = v.grad.clone()
331-
grad3_scatter = scatter.grad.clone()
332-
for i in range(len(out1)):
333-
assert torch.allclose(out1[i], out3[i])
334-
assert torch.allclose(grad1_v, grad3_v)
335-
assert torch.allclose(grad1_scatter, grad3_scatter)
376+
out[-1].sum().backward()
377+
grad2_scatter = scatter.grad.detach()
378+
assert backward_counter.count == (nt + 2) // 3
379+
assert torch.allclose(grad1_scatter, grad2_scatter)
336380

337381

338382
def test_scalar_born_multishot_equivalence() -> None:

tests/test_callbacks_elastic.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,3 +370,73 @@ def do_nothing(state: deepwave.common.CallbackState) -> None:
370370
assert torch.allclose(grad1_lamb, grad3_lamb)
371371
assert torch.allclose(grad1_mu, grad3_mu)
372372
assert torch.allclose(grad1_buoyancy, grad3_buoyancy)
373+
374+
375+
def test_elastic_backward_callback_only_call_count() -> None:
376+
"""Check that the backward callback is called the correct number of times
377+
when no forward callback is provided.
378+
"""
379+
lamb = torch.ones(10, 10) * 2200
380+
mu = torch.ones(10, 10) * 1000
381+
buoyancy = torch.ones(10, 10) * 1 / 2200
382+
lamb.requires_grad_()
383+
mu.requires_grad_()
384+
buoyancy.requires_grad_()
385+
dx = 5.0
386+
dt = 0.004
387+
nt = 20
388+
source_amplitudes_y = torch.zeros(1, 1, nt)
389+
source_amplitudes_y[0, 0, 5] = 1
390+
source_locations_y = torch.zeros(1, 1, 2, dtype=torch.long)
391+
source_locations_y[0, 0, 0] = 5
392+
source_locations_y[0, 0, 1] = 5
393+
receiver_locations_y = torch.zeros(1, 1, 2, dtype=torch.long)
394+
receiver_locations_y[0, 0, 0] = 5
395+
receiver_locations_y[0, 0, 1] = 5
396+
397+
class Counter:
398+
"""A simple counter class for callbacks."""
399+
400+
def __init__(self) -> None:
401+
self.count = 0
402+
403+
def __call__(self, state: deepwave.common.CallbackState) -> None:
404+
"""Increments the counter."""
405+
self.count += 1
406+
407+
# Test with a frequency that divides nt evenly
408+
backward_counter = Counter()
409+
out = deepwave.elastic(
410+
lamb,
411+
mu,
412+
buoyancy,
413+
dx,
414+
dt,
415+
source_amplitudes_y=source_amplitudes_y,
416+
source_locations_y=source_locations_y,
417+
receiver_locations_y=receiver_locations_y,
418+
backward_callback=backward_counter,
419+
callback_frequency=2,
420+
)
421+
out[-1].sum().backward()
422+
assert backward_counter.count == nt / 2
423+
424+
# Test with a frequency that does not divide nt evenly
425+
lamb.grad.zero_()
426+
mu.grad.zero_()
427+
buoyancy.grad.zero_()
428+
backward_counter = Counter()
429+
out = deepwave.elastic(
430+
lamb,
431+
mu,
432+
buoyancy,
433+
dx,
434+
dt,
435+
source_amplitudes_y=source_amplitudes_y,
436+
source_locations_y=source_locations_y,
437+
receiver_locations_y=receiver_locations_y,
438+
backward_callback=backward_counter,
439+
callback_frequency=3,
440+
)
441+
out[-1].sum().backward()
442+
assert backward_counter.count == (nt + 2) // 3

0 commit comments

Comments
 (0)