Skip to content

Commit

Permalink
Update auto-testing framework in CI
Browse files Browse the repository at this point in the history
  • Loading branch information
mortele committed Dec 22, 2021
1 parent 6f60516 commit f785bf3
Show file tree
Hide file tree
Showing 14 changed files with 340 additions and 328 deletions.
6 changes: 3 additions & 3 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ omit =
setup.py
conf.py
test/*
benchmarks/*
examples/*
docs/*
utils/*
hymd/__init__.py
hymd/__main__.py
hymd/main.py
hymd/gaussian_core.py
35 changes: 18 additions & 17 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,26 @@ jobs:
${{ runner.os }}-
- name: Install dependencies
run: |
sudo apt-get install libhdf5-openmpi-dev libfftw3-3 libfftw3-dev
python -m pip install --upgrade pip
pip install wheel
pip install pytest pytest-cov pytest-mpi coverage
pip install --upgrade numpy mpi4py cython
pip install -r requirements.txt
- name: Compile fortran modules
sudo apt-get update
sudo apt-get install -y python3-mpi4py python3-numpy
sudo apt-get install -y libhdf5-openmpi-dev libfftw3-3 libfftw3-dev
- name: Install python dependencies
run: |
cd hymd/
make clean
make
cd ..
python3 -m pip install --upgrade pip
python3 -m pip install --upgrade wheel numpy mpi4py cython
python3 -m pip install -r requirements.txt
- name: Install package
run: |
python3 -m pip install .
- name: Test with pytest
run: |
pytest -v --cov=./ --cov-report=
#### NPROCS=6
#### chmod +x pytest-mpi
#### ./pytest-mpi --nprocs ${NPROCS} --order-output --verbose
#### mpirun -n ${NPROCS} utils/mute_all_ranks_except.sh 0 pytest -v --only-mpi --cov=./ --cov-append --cov-report=
- name: Coverage report
python3 -m pip install pytest pytest-cov pytest-mpi coverage
pytest --cov=./
chmod +x pytest-mpi
./pytest-mpi -c -ca -n 2 -ns -oo
- name: Coverage report and upload
run: |
coverage report
coverage xml
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v2
21 changes: 16 additions & 5 deletions hymd/force.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,18 @@ def prepare_bonds_old(molecules, names, bonds, indices, config):
and name_mid_2 == a.atom_3
and name_j == a.atom_4
)
if match_forward:
if (
match_forward
and [
bond_graph.nodes()[p[3]]["local_index"],
bond_graph.nodes()[p[2]]["local_index"],
bond_graph.nodes()[p[1]]["local_index"],
bond_graph.nodes()[i]["local_index"],
a.coeffs,
a.dih_type,
]
not in bonds_4
):
bonds_4.append(
[
bond_graph.nodes()[i]["local_index"],
Expand Down Expand Up @@ -297,7 +308,7 @@ def compute_dihedral_forces__plain(f_dihedrals, r, bonds_4, box_size):
f_dihedrals.fill(0.0)
energy = 0.0

for a, b, c, d, coeff, phase in bonds_4:
for a, b, c, d, coeffs, phase in bonds_4:
f = r[a, :] - r[b, :]
g = r[b, :] - r[c, :]
h = r[d, :] - r[c, :]
Expand All @@ -323,9 +334,9 @@ def compute_dihedral_forces__plain(f_dihedrals, r, bonds_4, box_size):

df = 0

for m in range(len(coeff)):
energy += coeff[m] * (1 + np.cos(m * phi - phase[m]))
df += m * coeff[m] * np.sin(m * phi - phase[m])
for m in range(len(coeffs[0])):
energy += coeffs[0][m] * (1 + np.cos(m * phi - coeffs[1][m]))
df += m * coeffs[0][m] * np.sin(m * phi - coeffs[1][m])

force_on_a = df * gn * v / vv
force_on_d = df * gn * w / ww
Expand Down
2 changes: 1 addition & 1 deletion hymd/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "1.0.0"
__version__ = "1.0.1"
12 changes: 12 additions & 0 deletions pytest-mpi
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ while [[ "$#" -gt 0 ]]; do
-s|--capture=no) CAPTURE=1 ;;
-x|--exitfirst) EXITFIRST=1 ;;
-ns|--no-summary) SUMMARY=1 ;;
-c|--coverage) COVERAGE=1 ;;
-ca|--cov-append) COVERAGE_APPEND=1 ;;
-oo|--order-output) ORDEROUTPUT=1 ;;
-h|--help) HELP=1 ;;
*) echo "Unknown parameter passed: $1"; exit 1 ;;
Expand All @@ -38,6 +40,8 @@ then
echo " -s --capture=no Pass --capture=no to pytest."
echo " -x --exitfirst Pass --exitfirst to pytest."
echo " -ns --no-summary Pass --no-summary to pytest."
echo " -c --coverage Pass --cov=./ to pytest."
echo " -ca --cov-append Pass --cov-append to pytest."
echo " -oo --order-output Dump output from ranks in order."
echo " -u --unmute Unmute (show output from) only a specfic MPI rank."
else
Expand All @@ -60,6 +64,14 @@ else
PYTEST_ARGS="${PYTEST_ARGS} --exitfirst"
fi

if [ "${COVERAGE}" -eq 1 ]; then
PYTEST_ARGS="${PYTEST_ARGS} --cov=./"
fi

if [ "${COVERAGE_APPEND}" -eq 1 ]; then
PYTEST_ARGS="${PYTEST_ARGS} --cov-append"
fi

if [ "${ORDEROUTPUT}" -eq 1 ]; then
mpirun -n ${NPROCS} --output-filename outtest pytest ${PYTEST_ARGS} --only-mpi >/dev/null
for ((RANK=0; RANK<${NPROCS}; RANK++)); do
Expand Down
1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ h5py
mpi4py
mpsort
networkx
numba
numpy
pfft-python
pmesh
Expand Down
115 changes: 82 additions & 33 deletions test/conftest.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,10 @@
from mpi4py import MPI
import sys
import os
import sympy
import numpy as np
import h5py
import pytest
import collections

# fmt: off
# TODO: Remove this when we have a working pip installable main package and
# can test against installed package by
#
# pip3 install -e . && python3 -m pytest
curr_path = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.join(curr_path, os.pardir, 'hymd'))


@pytest.fixture
def three_atoms():
Expand Down Expand Up @@ -144,29 +135,29 @@ def alanine_octapeptide():
dtype=np.float64)
bonds = np.array(
[
[ 1, 2, -1], # BB(0)
[ 0, -1, -1], # SC(1)
[ 0, 3, 4], # BB(2)
[ 2, -1, -1], # SC(3)
[ 2, 5, 6], # BB(4)
[ 4, -1, -1], # SC(5)
[ 4, 7, 8], # BB(6)
[ 6, -1, -1], # SC(7)
[ 6, 9, 10], # BB(8)
[ 8, -1, -1], # SC(9)
[ 8, 11, 12], # BB(10)
[10, -1, -1], # SC(11)
[10, 13, 14], # BB(12)
[12, -1, -1], # SC(13)
[12, 15, -1], # BB(14)
[14, -1, -1], # SC(15)
[1, 2, -1], # BB(0)
[0, -1, -1], # SC(1)
[0, 3, 4], # BB(2)
[2, -1, -1], # SC(3)
[2, 5, 6], # BB(4)
[4, -1, -1], # SC(5)
[4, 7, 8], # BB(6)
[6, -1, -1], # SC(7)
[6, 9, 10], # BB(8)
[8, -1, -1], # SC(9)
[8, 11, 12], # BB(10)
[10, -1, -1], # SC(11)
[10, 13, 14], # BB(12)
[12, -1, -1], # SC(13)
[12, 15, -1], # BB(14)
[14, -1, -1], # SC(15)
],
dtype=int)
names = np.array(
[
b"BB", b"SC", b"BB", b"SC", b"BB", b"SC", b"BB", b"SC",
b"BB", b"SC", b"BB", b"SC", b"BB", b"SC", b"BB", b"SC",
],
],
dtype="S5"
)
CONF = {}
Expand All @@ -177,7 +168,8 @@ def alanine_octapeptide():
"Angle", ["atom_1", "atom_2", "atom_3", "equilibrium", "strength"]
)
Dihedral = collections.namedtuple(
"Dihedral", ["atom_1", "atom_2", "atom_3", "atom_4", "coeff", "phase"]
"Dihedral",
["atom_1", "atom_2", "atom_3", "atom_4", "coeffs", "dih_type"]
)
# Values for bonds and angles taken from MARTINI 3 parameters.
# Not used to test dihedral forces.
Expand All @@ -188,20 +180,25 @@ def alanine_octapeptide():
CONF["bond_3"] = (
Angle("BB", "BB", "BB", 127, 20),
Angle("BB", "BB", "SC", 100, 25),
#Angle("SC", "BB", "BB", 100, 25), # In martini they have only the first angle of this type
)
# Symbolic arrays of 1s and 0s for analytical check
CONF["bond_4"] = (
Dihedral(
"BB", "BB", "BB", "BB",
[1 for _ in range(5)],
[0 for _ in range(5)],
"BB", "BB", "BB", "BB",
np.array([
[1, 1, 1, 1, 1],
[0, 0, 0, 0, 0]
]),
0,
),
)
for k, v in {"Np": 8, "types": 2, "mass": 72.0, "L": [5.0, 5.0, 5.0]}.items():
for k, v in {
"Np": 8, "types": 2, "mass": 72.0, "L": [5.0, 5.0, 5.0]
}.items():
CONF[k] = v
return indices, bonds, names, molecules, r, CONF


@pytest.fixture()
def h5py_molecules_file(mpi_file_name):
n_particles = 1000
Expand Down Expand Up @@ -557,3 +554,55 @@ def molecules_with_solvent():
dtype=int)
return (np.arange(0, r.shape[0]), r, molecules, velocities, bonds, names,
types)


@pytest.fixture
def filter(sigma):
k = sympy.var('k:%d' % (3))

def H1(k):
return sympy.functions.elementary.exponential.exp(
-0.5 * sigma**2 * (k0**2 + k1**2 + k2**2) # noqa: F821
)
H1 = sympy.lambdify([k], H1(k))

def H(k, v):
return v * H1(k)

return sigma, H


@pytest.fixture
def v_ext(types, kappa, rho0, sigma):
n_types = len(types)
phi = sympy.var('phi:%d' % (n_types))

def w(phi):
return 0.5 / (kappa * rho0) * (sum(phi) - rho0)**2

v_external = [
sympy.lambdify([phi], sympy.diff(w(phi), "phi%d" % (i)))
for i in range(n_types)
]

w = sympy.lambdify([phi], w(phi))
return types, n_types, kappa, rho0, sigma, w, v_external
"""
k = sympy.var("k:%d" % (3))
def H1(k):
return sympy.functions.elementary.exponential.exp(
-0.5 * sigma**2 * (k0**2 + k1**2 + k2**2) # noqa: F821
)
kdHdk = [
k0 * sympy.diff(H1(k), "k0"), # noqa: F821
k1 * sympy.diff(H1(k), "k1"), # noqa: F821
k2 * sympy.diff(H1(k), "k2") # noqa: F821
]
kdHdk = [sympy.lambdify([k], kdHdk[i]) for i in range(3)]
H1 = sympy.lambdify([k], H1(k))
def H(k, v):
return v * H1(k)
"""
2 changes: 1 addition & 1 deletion test/test_distribute_input.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import numpy as np
import h5py
from file_io import distribute_input
from hymd.file_io import distribute_input


def _distribute_nranks(size, in_path, n_particles):
Expand Down
6 changes: 3 additions & 3 deletions test/test_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
import pmesh
import logging
import numpy as np
from input_parser import Config
from file_io import distribute_input
from field import domain_decomposition
from hymd.input_parser import Config
from hymd.file_io import distribute_input
from hymd.field import domain_decomposition


@pytest.mark.mpi()
Expand Down
Loading

0 comments on commit f785bf3

Please sign in to comment.