Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add distopia! #3914

Merged
merged 50 commits into from
Feb 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
28bf2f9
add starrt of calc_bonds
Nov 4, 2022
280126e
refactor to use distopia inplace API
hmacdope Nov 9, 2022
8a571d4
add in upcast
hmacdope Nov 10, 2022
d6c9220
actually return the distances
hmacdope Nov 10, 2022
dae07fa
distopia to ci
hmacdope Nov 12, 2022
f58b8e1
add initial docs
hmacdope Nov 12, 2022
07016f5
move to using _run backend
hmacdope Nov 20, 2022
908f6fe
add upcast back in
hmacdope Nov 21, 2022
072b743
fix yml CI files
hmacdope Nov 21, 2022
05fe804
change test_pairwise_dist to use allclose rather than equals
hmacdope Nov 21, 2022
1d1300c
change another test to sue assert allclose
hmacdope Nov 21, 2022
a0e1dab
improve docs
hmacdope Nov 24, 2022
3d37504
change distance tests to use distopia backend
hmacdope Nov 24, 2022
22ebd40
split numpy compliance test
hmacdope Nov 24, 2022
8bfc5fc
changelog
hmacdope Nov 25, 2022
5188e15
Merge remote-tracking branch 'upstream/develop' into Add_distopia
hmacdope Nov 25, 2022
43bf661
fix merge issue in changelog
hmacdope Nov 25, 2022
ec76375
add note on varying precision to docs
hmacdope Nov 25, 2022
c9c024e
Merge branch 'develop' into Add_distopia
IAlibay Dec 1, 2022
5889c87
Merge branch 'develop' into Add_distopia
IAlibay Dec 9, 2022
1610cd3
Update testsuite/MDAnalysisTests/lib/test_distances.py
hmacdope Dec 13, 2022
3ff2489
Merge remote-tracking branch 'upstream/develop' into Add_distopia
hmacdope Dec 13, 2022
404e8ba
add warning for triclinic boxes
hmacdope Dec 13, 2022
f237024
darker
hmacdope Dec 13, 2022
9042102
add second importlib try block
hmacdope Dec 13, 2022
56e5091
return callable or ndarray
hmacdope Dec 13, 2022
142cca1
Revert "return callable or ndarray"
hmacdope Dec 13, 2022
773153e
Merge branch 'develop' into Add_distopia
IAlibay Dec 15, 2022
9ee8668
Merge branch 'develop' into Add_distopia
IAlibay Jan 5, 2023
a5bcc63
change docs on default
hmacdope Jan 7, 2023
9ad10b9
start of stub
hmacdope Jan 7, 2023
46f471c
Update package/MDAnalysis/lib/distances.py
hmacdope Jan 7, 2023
9105b0b
add align
hmacdope Jan 7, 2023
1f9e5d5
WIP on stub
hmacdope Jan 7, 2023
e91d4e8
finalise distopia stub
hmacdope Jan 8, 2023
402b90c
change calc_bonds to use distopia stub
hmacdope Jan 8, 2023
f7b79fc
fix type annotation
hmacdope Jan 8, 2023
416afcc
Merge remote-tracking branch 'upstream/develop' into Add_distopia
hmacdope Jan 8, 2023
1ec7445
darker
hmacdope Jan 8, 2023
9e0ea7d
darker distances.py
hmacdope Jan 8, 2023
9ff3ecf
try to make black happier again
hmacdope Jan 8, 2023
e2d606f
fix distances.py again
hmacdope Jan 8, 2023
028f548
finally fix everything
hmacdope Jan 8, 2023
ec04406
fix versionchanged
hmacdope Jan 8, 2023
8f98806
remove try except
hmacdope Jan 8, 2023
e185b7a
Update package/MDAnalysis/lib/distances.py
hmacdope Jan 8, 2023
cba5b5f
Merge remote-tracking branch 'upstream/develop' into Add_distopia
hmacdope Jan 19, 2023
ea8185b
Merge remote-tracking branch 'upstream/develop' into Add_distopia
hmacdope Jan 26, 2023
403b7e6
finalise merge
hmacdope Jan 26, 2023
04bb71b
Merge branch 'develop' into Add_distopia
IAlibay Feb 13, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/actions/setup-deps/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ inputs:
default: 'chemfiles-python>=0.9'
clustalw:
default: 'clustalw=2.1'
distopia:
default: 'distopia>=0.2.0'
h5py:
default: 'h5py>=2.10'
joblib:
Expand Down Expand Up @@ -115,6 +117,7 @@ runs:
CONDA_OPT_DEPS: |
${{ inputs.chemfiles-python }}
${{ inputs.clustalw }}
${{ inputs.distopia }}
${{ inputs.h5py }}
${{ inputs.joblib }}
${{ inputs.netcdf4 }}
Expand Down
2 changes: 2 additions & 0 deletions package/CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ Fixes
(Issue #3336)

Enhancements
* Add distopia distance calculation library bindings as a selectable backend
for `calc_bonds` in `MDA.lib.distances`. (Issue #3783, PR #3914)
* AuxReaders are now pickle-able and copy-able (Issue #1785, PR #3887)
* Add pickling support for Atom, Residue, Segment, ResidueGroup
and SegmentGroup. (PR #3953)
Expand Down
71 changes: 71 additions & 0 deletions package/MDAnalysis/lib/_distopia.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# -*- Mode: python; tab-width: 4; indent-tabs-mode:nil; -*-
# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
#
# MDAnalysis --- https://www.mdanalysis.org
# Copyright (c) 2006-2017 The MDAnalysis Development Team and contributors
# (see the file AUTHORS for the full list of names)
#
# Released under the GNU Public Licence, v2 or any higher version
#
# Please cite your use of MDAnalysis in published work:
#
# R. J. Gowers, M. Linke, J. Barnoud, T. J. E. Reddy, M. N. Melo, S. L. Seyler,
# D. L. Dotson, J. Domanski, S. Buchoux, I. M. Kenney, and O. Beckstein.
# MDAnalysis: A Python package for the rapid analysis of molecular dynamics
# simulations. In S. Benthall and S. Rostrup editors, Proceedings of the 15th
# Python in Science Conference, pages 102-109, Austin, TX, 2016. SciPy.
# doi: 10.25080/majora-629e541a-00e
#
# N. Michaud-Agrawal, E. J. Denning, T. B. Woolf, and O. Beckstein.
# MDAnalysis: A Toolkit for the Analysis of Molecular Dynamics Simulations.
# J. Comput. Chem. 32 (2011), 2319--2327, doi:10.1002/jcc.21787
#

"""Stub module for distopia --- :mod:`MDAnalysis.analysis.distopia`
===================================================================

This module is a stub to provide distopia distance functions to `distances.py`
as a selectable backend.
"""

# check for distopia
try:
import distopia
except ImportError:
HAS_DISTOPIA = False
else:
HAS_DISTOPIA = True

from .c_distances import (
calc_bond_distance_triclinic as _calc_bond_distance_triclinic_serial,
)
import warnings
import numpy as np


def calc_bond_distance_ortho(
coords1, coords2: np.ndarray, box: np.ndarray, results: np.ndarray
) -> None:
distopia.calc_bonds_ortho_float(
coords1, coords2, box[:3], results=results
)
# upcast is currently required, change for 3.0, see #3927


def calc_bond_distance(
coords1: np.ndarray, coords2: np.ndarray, results: np.ndarray
) -> None:
distopia.calc_bonds_no_box_float(
coords1, coords2, results=results
)
# upcast is currently required, change for 3.0, see #3927


def calc_bond_distance_triclinic(
coords1: np.ndarray, coords2: np.ndarray, box: np.ndarray, results: np.ndarray
) -> None:
# redirect to serial backend
warnings.warn(
"distopia does not support triclinic boxes, using serial backend instead."
)
_calc_bond_distance_triclinic_serial(coords1, coords2, box, results)
100 changes: 82 additions & 18 deletions package/MDAnalysis/lib/distances.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,57 @@
with OpenMP
========== ========================= ======================================

Use of the distopia library
---------------------------

MDAnalysis has developed a standalone library, `distopia`_ for accelerating
the distance functions in this module using explicit SIMD vectorisation.
This can provide many-fold speedups in calculating distances. Distopia is
under active development and as such only a selection of functions in this
module are covered. Consult the following table to see if the function
you wish to use is covered by distopia. For more information see the
`distopia documentation`_.

.. Table:: Functions available using the `distopia`_ backend.
:align: center

+-------------------------------------+-----------------------------------+
| Functions | Notes |
+=====================================+===================================+
| MDAnalysis.lib.distances.calc_bonds | Doesn't support triclinic boxes |
+-------------------------------------+-----------------------------------+

If `distopia`_ is installed, the functions in this table will accept the key
'distopia' for the `backend` keyword argument. If the distopia backend is
selected the `distopia` library will be used to calculate the distances. Note
that for functions listed in this table **distopia is not the default backend
if and must be selected.**

.. Note::
Distopia does not currently support triclinic simulation boxes. If you
specify `distopia` as the backend and your simulation box is triclinic,
the function will fall back to the default `serial` backend.

.. Note::
Due to the use of Instruction Set Architecture (`ISA`_) specific SIMD
intrinsics in distopia via `VCL2`_, the precision of your results may
depend on the ISA available on your machine. However, in all tested cases
distopia satisfied the accuracy thresholds used to the functions in this
module. Please document any issues you encounter with distopia's accuracy
in the `relevant distopia issue`_ on the MDAnalysis GitHub repository.

.. _distopia: https://github.com/MDAnalysis/distopia
.. _distopia documentation: https://www.mdanalysis.org/distopia
.. _ISA: https://en.wikipedia.org/wiki/Instruction_set_architecture
.. _VCL2: https://github.com/vectorclass/version2
.. _relevant distopia issue: https://github.com/MDAnalysis/mdanalysis/issues/3915

.. versionadded:: 0.13.0
.. versionchanged:: 2.3.0
Distance functions can now accept an
:class:`~MDAnalysis.core.groups.AtomGroup` or an :class:`np.ndarray`
.. versionchanged:: 2.5.0
Interface to the `distopia`_ package added.

Functions
---------
Expand Down Expand Up @@ -83,6 +130,7 @@
from ._augment import augment_coordinates, undo_augment
from .nsgrid import FastNS
from .c_distances import _minimize_vectors_ortho, _minimize_vectors_triclinic
from ._distopia import HAS_DISTOPIA


# hack to select backend with backend=<backend> kwarg. Note that
Expand All @@ -97,8 +145,11 @@
package="MDAnalysis.lib")
except ImportError:
pass
del importlib

if HAS_DISTOPIA:
_distances["distopia"] = importlib.import_module("._distopia",
package="MDAnalysis.lib")
del importlib

def _run(funcname: str, args: Optional[tuple] = None,
kwargs: Optional[dict] = None, backend: str = "serial") -> Callable:
Expand Down Expand Up @@ -1408,15 +1459,15 @@ def calc_bonds(coords1: Union[npt.NDArray, 'AtomGroup'],
Preallocated result array of dtype ``numpy.float64`` and shape ``(n,)``
(for ``n`` coordinate pairs). Avoids recreating the array in repeated
function calls.
backend : {'serial', 'OpenMP'}, optional
Keyword selecting the type of acceleration.
backend : {'serial', 'OpenMP', 'distopia'}, optional
Keyword selecting the type of acceleration. Defaults to 'serial'.

Returns
-------
bondlengths : numpy.ndarray (``dtype=numpy.float64``, ``shape=(n,)``) or numpy.float64
Array containing the bond lengths between each pair of coordinates. If
two single coordinates were supplied, their distance is returned as a
single number instead of an array.
bondlengths : numpy.ndarray (``dtype=numpy.float64``, ``shape=(n,)``) or
numpy.float64 Array containing the bond lengths between each pair of
coordinates. If two single coordinates were supplied, their distance is
returned as a single number instead of an array.


.. versionadded:: 0.8
Expand All @@ -1428,26 +1479,39 @@ def calc_bonds(coords1: Union[npt.NDArray, 'AtomGroup'],
.. versionchanged:: 2.3.0
Can now accept an :class:`~MDAnalysis.core.groups.AtomGroup` as an
argument in any position and checks inputs using type hinting.
.. versionchanged:: 2.5.0
Can now optionally use the fast distance functions from distopia
"""
numatom = coords1.shape[0]
bondlengths = _check_result_array(result, (numatom,))

if numatom > 0:
if box is not None:
boxtype, box = check_box(box)
if boxtype == 'ortho':
_run("calc_bond_distance_ortho",
args=(coords1, coords2, box, bondlengths),
backend=backend)
if boxtype == "ortho":
if backend == 'distopia':
bondlengths = bondlengths.astype(np.float32)
_run(
"calc_bond_distance_ortho",
args=(coords1, coords2, box, bondlengths),
backend=backend,
)
else:
_run("calc_bond_distance_triclinic",
args=(coords1, coords2, box, bondlengths),
backend=backend)
_run(
"calc_bond_distance_triclinic",
args=(coords1, coords2, box, bondlengths),
backend=backend,
)
else:
_run("calc_bond_distance",
args=(coords1, coords2, bondlengths),
backend=backend)

if backend == 'distopia':
bondlengths = bondlengths.astype(np.float32)
_run(
"calc_bond_distance",
args=(coords1, coords2, bondlengths),
backend=backend,
)
if backend == 'distopia':
bondlengths = bondlengths.astype(np.float64)
return bondlengths


Expand Down
4 changes: 2 additions & 2 deletions testsuite/MDAnalysisTests/analysis/test_distances.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ def test_pairwise_dist(self, ag, ag2, expected):
'''Ensure that pairwise distances between atoms are
correctly calculated.'''
actual = MDAnalysis.analysis.distances.dist(ag, ag2)[2]
assert_equal(actual, expected)
assert_allclose(actual, expected)

def test_pairwise_dist_box(self, ag, ag2, expected_box, box):
'''Ensure that pairwise distances between atoms are
Expand All @@ -161,7 +161,7 @@ def test_pairwise_dist_offset_effect(self, ag, ag2, expected):
pairwise distance matrix.'''
actual = MDAnalysis.analysis.distances.dist(
ag, ag2, offset=229)[2]
assert_equal(actual, expected)
assert_allclose(actual, expected)

def test_offset_calculation(self, ag, ag2):
'''Test that offsets fed to dist() are correctly calculated.'''
Expand Down
Loading