Skip to content

Commit

Permalink
Add legacy checkpoint test
Browse files Browse the repository at this point in the history
  • Loading branch information
jorgensd committed Feb 7, 2024
1 parent 259d75b commit 68c461e
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 11 deletions.
27 changes: 27 additions & 0 deletions .github/workflows/create_legacy_checkpoint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Generate adios4dolfinx legacy data

on:
workflow_call:

env:
data_dir: "legacy_checkpoint"


jobs:
create-data:
runs-on: "ubuntu-22.04"
container: ghcr.io/fenics/dolfinx/dolfinx:v0.7.3
env:
adios4dolfinx_version: "0.7.1"
steps:
- uses: actions/checkout@v4

- name: Install legacy version of adios4dolfinx
- run: python3 -m pip install adios4dolfinx==${adios4dolfinx_version}
- name: Create datasets
run: python3 ./tests/create_legacy_checkpoint.py --output-dir=$data_dir

- uses: actions/upload-artifact@v4
with:
name: ${{ env.data_dir }}
path: ./${{ env.data_dir }}
11 changes: 10 additions & 1 deletion .github/workflows/test_package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ jobs:
create-datasets:
uses: ./.github/workflows/create_legacy_data.yml

create-legacy-datasets:
uses: ./.github/workflows/create_legacy_checkpoint.yml

check-formatting:
uses: ./.github/workflows/check_formatting.yml

Expand All @@ -43,7 +46,13 @@ jobs:
with:
name: legacy
path: ./legacy


- name: Download legacy data
uses: actions/download-artifact@v4
with:
name: legacy_checkpoint
path: ./legacy_checkpoint

- name: Install package
run: python3 -m pip install .[test]

Expand Down
3 changes: 2 additions & 1 deletion src/adios4dolfinx/checkpointing.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,8 @@ def read_function(u: dolfinx.fem.Function, filename: Path, engine: str = "BP4",
else:
array_path = f"{name}_values"
time_name = f"{name}_time"
input_array, starting_pos = read_array(adios, filename, array_path, engine, comm, time, time_name)
input_array, starting_pos = read_array(adios, filename, array_path, engine, comm, time, time_name,
legacy=legacy)
recv_array = send_dofs_and_recv_values(
input_dofmap.array, dof_owner, comm, input_array, starting_pos
)
Expand Down
68 changes: 68 additions & 0 deletions tests/create_legacy_checkpoint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Copyright (C) 2024 Jørgen Schartum Dokken
#
# This file is part of adios4dolfinx
#
# SPDX-License-Identifier: MIT


"""
Functions to create checkpoints with adios4dolfinx v0.7.x
"""

import argparse
import pathlib

import numpy as np
from mpi4py import MPI
import adios4dolfinx
import dolfinx
from importlib.metadata import version

a4d_version = version("adios4dolfinx")
assert a4d_version < "0.8.0", f"Creating a legacy checkpoint requires adios4dolfinx < 0.8.0, you have {a4d_version}."


def f(x):
values = np.zeros((2, x.shape[1]), dtype=np.float64)
values[0] = x[0]
values[1] = -x[1]
return values


def write_checkpoint(filename, mesh, el, f):
V = dolfinx.fem.FunctionSpace(mesh, el)
uh = dolfinx.fem.Function(V, dtype=np.float64)
uh.interpolate(f)

adios4dolfinx.write_mesh(V.mesh, filename)
adios4dolfinx.write_function(uh, filename)


def verify_checkpoint(filename, el, f):
mesh = adios4dolfinx.read_mesh(MPI.COMM_WORLD, filename, "BP4", dolfinx.mesh.GhostMode.shared_facet)
V = dolfinx.fem.FunctionSpace(mesh, el)
uh = dolfinx.fem.Function(V, dtype=np.float64)
adios4dolfinx.read_function(uh, filename)

u_ex = dolfinx.fem.Function(V, dtype=np.float64)
u_ex.interpolate(f)

np.testing.assert_allclose(u_ex.x.array, uh.x.array, atol=1e-15)


if __name__ == "__main__":
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter
)
parser.add_argument("--output-dir", type=str, default="legacy_checkpoint", dest="dir")

inputs = parser.parse_args()
path = pathlib.Path(inputs.dir)
path.mkdir(exist_ok=True, parents=True)
filename = path / "adios4dolfinx_checkpoint.bp"

mesh = dolfinx.mesh.create_unit_square(MPI.COMM_WORLD, 10, 10)
el = ("N1curl", 3)
write_checkpoint(filename, mesh, el, f)
MPI.COMM_WORLD.Barrier()
verify_checkpoint(filename, el, f)
4 changes: 1 addition & 3 deletions tests/create_legacy_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
"""

import argparse
import os
import pathlib

import dolfin
Expand Down Expand Up @@ -135,8 +134,7 @@ def verify_xdmf(

inputs = parser.parse_args()
path = pathlib.Path(inputs.dir)
if not os.path.exists(path):
os.mkdir(path)
path.mkdir(exist_ok=True, parents=True)
h5_filename = path / f"{inputs.name}.h5"
xdmf_filename = path / f"{inputs.name}_checkpoint.xdmf"

Expand Down
46 changes: 40 additions & 6 deletions tests/test_legacy_readers.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,19 @@

import dolfinx
import numpy as np
import pytest
import ufl
from dolfinx.fem.petsc import LinearProblem

from adios4dolfinx import (read_function_from_legacy_h5,
read_mesh_from_legacy_h5)
from adios4dolfinx import (read_function, read_function_from_legacy_h5,
read_mesh, read_mesh_from_legacy_h5)


def test_legacy_mesh():
comm = MPI.COMM_WORLD
path = (pathlib.Path("legacy") / "mesh.h5").absolute()
if not path.exists():
pytest.skip(f"{path} does not exist")
mesh = read_mesh_from_legacy_h5(comm=comm, filename=path, group="/mesh")
assert mesh.topology.dim == 3
volume = mesh.comm.allreduce(
Expand All @@ -42,6 +45,8 @@ def test_legacy_mesh():
def test_read_legacy_mesh_from_checkpoint():
comm = MPI.COMM_WORLD
filename = (pathlib.Path("legacy") / "mesh_checkpoint.h5").absolute()
if not filename.exists():
pytest.skip(f"{filename} does not exist")
mesh = read_mesh_from_legacy_h5(comm=comm, filename=filename, group="/Mesh/mesh")
assert mesh.topology.dim == 3
volume = mesh.comm.allreduce(
Expand All @@ -63,6 +68,8 @@ def test_read_legacy_mesh_from_checkpoint():
def test_legacy_function():
comm = MPI.COMM_WORLD
path = (pathlib.Path("legacy") / "mesh.h5").absolute()
if not path.exists():
pytest.skip(f"{path} does not exist")
mesh = read_mesh_from_legacy_h5(comm, path, "/mesh")
V = dolfinx.fem.functionspace(mesh, ("DG", 2))
u = ufl.TrialFunction(V)
Expand All @@ -80,7 +87,7 @@ def test_legacy_function():

u_in = dolfinx.fem.Function(V)
read_function_from_legacy_h5(mesh.comm, path, u_in, group="v")
assert np.allclose(uh.x.array, u_in.x.array)
np.testing.assert_allclose(uh.x.array, u_in.x.array, atol=1e-14)

W = dolfinx.fem.functionspace(mesh, ("DG", 2, (mesh.geometry.dim, )))
wh = dolfinx.fem.Function(W)
Expand All @@ -89,12 +96,14 @@ def test_legacy_function():

read_function_from_legacy_h5(mesh.comm, path, w_in, group="w")

assert np.allclose(wh.x.array, w_in.x.array)
np.testing.assert_allclose(wh.x.array, w_in.x.array, atol=1e-14)


def test_read_legacy_function_from_checkpoint():
comm = MPI.COMM_WORLD
path = (pathlib.Path("legacy") / "mesh_checkpoint.h5").absolute()
if not path.exists():
pytest.skip(f"{path} does not exist")
mesh = read_mesh_from_legacy_h5(comm, path, "/Mesh/mesh")

V = dolfinx.fem.functionspace(mesh, ("DG", 2))
Expand Down Expand Up @@ -126,8 +135,33 @@ def test_read_legacy_function_from_checkpoint():
w_in = dolfinx.fem.Function(W)

read_function_from_legacy_h5(mesh.comm, path, w_in, group="w", step=0)
assert np.allclose(wh.x.array, w_in.x.array)
np.testing.assert_allclose(wh.x.array, w_in.x.array, atol=1e-14)

wh.interpolate(lambda x: np.vstack((x[0], 0*x[0], x[1])))
read_function_from_legacy_h5(mesh.comm, path, w_in, group="w", step=1)
assert np.allclose(wh.x.array, w_in.x.array)
np.testing.assert_allclose(wh.x.array, w_in.x.array, atol=1e-14)


def test_adios4dolfinx_legacy():
comm = MPI.COMM_WORLD
path = (pathlib.Path("legacy_checkpoint") / "adios4dolfinx_checkpoint.bp").absolute()
if not path.exists():
pytest.skip(f"{path} does not exist")

el = ("N1curl", 3)
mesh = read_mesh(comm, path, "BP4", dolfinx.mesh.GhostMode.shared_facet)

def f(x):
values = np.zeros((2, x.shape[1]), dtype=np.float64)
values[0] = x[0]
values[1] = -x[1]
return values

V = dolfinx.fem.functionspace(mesh, el)
u = dolfinx.fem.Function(V)
read_function(u, path, engine="BP4", legacy=True)

u_ex = dolfinx.fem.Function(V)
u_ex.interpolate(f)

np.testing.assert_allclose(u.x.array, u_ex.x.array, atol=1e-14)

0 comments on commit 68c461e

Please sign in to comment.