From 93b1aa79649b1b2eeec0dd8f32d6a6a42ef8ae3c Mon Sep 17 00:00:00 2001 From: Philip Loche Date: Tue, 5 Dec 2023 18:01:33 +0100 Subject: [PATCH] Add metatensor as extra deps when installing --- docs/src/references/metatensor/index.rst | 7 +++++ examples/README.rst | 7 +++++ pyproject.toml | 4 ++- src/meshlode/__init__.py | 7 ++++- src/meshlode/metatensor/meshpotential.py | 10 +++++- tests/metatensor/test_madelung.py | 9 +++--- .../test_metatensor_meshpotential.py | 16 +++++----- tox.ini | 31 +++++++++++++++---- 8 files changed, 71 insertions(+), 20 deletions(-) diff --git a/docs/src/references/metatensor/index.rst b/docs/src/references/metatensor/index.rst index 9735d635..ee6d7f83 100644 --- a/docs/src/references/metatensor/index.rst +++ b/docs/src/references/metatensor/index.rst @@ -4,6 +4,13 @@ Metatensor Bindings ################### MeshLODE calculators returning representations as :py:class:`metatensor.TensorMap`. +For using these bindings you need to install the ``metatensor.torch`` optional +dependencies. + +.. code-block:: bash + + pip install .[metatensor] + For a plain :py:class:`torch.Tensor` refer to :ref:`calculators`. .. toctree:: diff --git a/examples/README.rst b/examples/README.rst index 6d03712e..37a7675b 100644 --- a/examples/README.rst +++ b/examples/README.rst @@ -6,3 +6,10 @@ Examples This section list introductory examples and recipes to the various classes and functions of ``MeshLODE``. For details on the API specification of the functions take a look at the :ref:`userdoc-reference` section. + +For running the all examples install with the ``examples`` and ``metatensor`` optional +dependencies. + +.. code-block:: bash + + pip install .[examples,metatensor] diff --git a/pyproject.toml b/pyproject.toml index 5b4c38f2..3afd1855 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,7 +35,6 @@ keywords = [ ] dependencies = [ "torch >= 1.11", - "metatensor[torch]", ] dynamic = ["version"] @@ -44,6 +43,9 @@ examples = [ "ase", "matplotlib", ] +metatensor = [ + "metatensor[torch]", +] [project.urls] homepage = "http://meshlode.readthedocs.io" diff --git a/src/meshlode/__init__.py b/src/meshlode/__init__.py index 3e245b6c..527135a4 100644 --- a/src/meshlode/__init__.py +++ b/src/meshlode/__init__.py @@ -1,6 +1,11 @@ from .calculators.meshpotential import MeshPotential from .lib.system import System -from . import metatensor # noqa + +try: + from . import metatensor # noqa +except ImportError: + pass + __all__ = ["MeshPotential", "System"] __version__ = "0.0.0-dev" diff --git a/src/meshlode/metatensor/meshpotential.py b/src/meshlode/metatensor/meshpotential.py index 05973db0..7323d51a 100644 --- a/src/meshlode/metatensor/meshpotential.py +++ b/src/meshlode/metatensor/meshpotential.py @@ -1,7 +1,15 @@ from typing import Dict, List, Union import torch -from metatensor.torch import Labels, TensorBlock, TensorMap + + +try: + from metatensor.torch import Labels, TensorBlock, TensorMap +except ImportError: + raise ImportError( + "metatensor.torch is required for meshlode.metatensor but is not installed. " + "Try installing it with:\npip install metatensor[torch]" + ) from meshlode.lib.system import System diff --git a/tests/metatensor/test_madelung.py b/tests/metatensor/test_madelung.py index 38eab555..a8faf17f 100644 --- a/tests/metatensor/test_madelung.py +++ b/tests/metatensor/test_madelung.py @@ -6,7 +6,8 @@ from torch.testing import assert_close from meshlode import System -from meshlode.metatensor import MeshPotential + +meshlode_metatensor = pytest.importorskip("meshlode.metatensor") class TestMadelung: @@ -119,7 +120,7 @@ def test_madelung_low_order( madelung = dic["madelung"] / scaling_factor mesh_spacing = smearing / 2 * scaling_factor smearing_eff = smearing * scaling_factor - MP = MeshPotential( + MP = meshlode_metatensor.MeshPotential( smearing_eff, mesh_spacing, interpolation_order, subtract_self=True ) potentials_mesh = MP._compute_single_frame(cell, positions, charges) @@ -153,7 +154,7 @@ def test_madelung_high_order( madelung = dic["madelung"] / scaling_factor mesh_spacing = smearing / 10 * scaling_factor smearing_eff = smearing * scaling_factor - MP = MeshPotential( + MP = meshlode_metatensor.MeshPotential( smearing_eff, mesh_spacing, interpolation_order, subtract_self=True ) potentials_mesh = MP._compute_single_frame(cell, positions, charges) @@ -187,7 +188,7 @@ def test_madelung_low_order_metatensor( smearing_eff = smearing * scaling_factor n_atoms = len(positions) frame = System(species=atomic_numbers, positions=positions, cell=cell) - MP = MeshPotential( + MP = meshlode_metatensor.MeshPotential( atomic_smearing=smearing_eff, mesh_spacing=mesh_spacing, interpolation_order=interpolation_order, diff --git a/tests/metatensor/test_metatensor_meshpotential.py b/tests/metatensor/test_metatensor_meshpotential.py index c780cdfe..13d8d802 100644 --- a/tests/metatensor/test_metatensor_meshpotential.py +++ b/tests/metatensor/test_metatensor_meshpotential.py @@ -2,11 +2,12 @@ import pytest import torch -from metatensor.torch import Labels from packaging import version from meshlode import System -from meshlode.metatensor import MeshPotential + +metatensor_torch = pytest.importorskip("metatensor.torch") +meshlode_metatensor = pytest.importorskip("meshlode.metatensor") # Define toy system consisting of a single structure for testing @@ -18,9 +19,10 @@ def toy_system_single_frame() -> System: ) -# Initialize the calculators. For now, only the MeshPotential is implemented. -def descriptor() -> MeshPotential: - return MeshPotential( +# Initialize the calculators. For now, only the meshlode_metatensor.MeshPotential is +# implemented. +def descriptor() -> meshlode_metatensor.MeshPotential: + return meshlode_metatensor.MeshPotential( atomic_smearing=1.0, ) @@ -90,7 +92,7 @@ class TestMultiFrameToySystem: for atomic_smearing in [0.01, 0.3, 3.7]: for mesh_spacing in [15.3, 0.19]: for interpolation_order in [1, 2, 3, 4, 5]: - MP = MeshPotential( + MP = meshlode_metatensor.MeshPotential( atomic_smearing=atomic_smearing, mesh_spacing=mesh_spacing, interpolation_order=interpolation_order, @@ -115,7 +117,7 @@ def test_tensormap_labels(self, features): ] ) label_names = ["species_center", "species_neighbor"] - labels_ref = Labels(names=label_names, values=label_values) + labels_ref = metatensor_torch.Labels(names=label_names, values=label_values) assert labels_ref == features.keys diff --git a/tox.ini b/tox.ini index e564dea1..b4d28c93 100644 --- a/tox.ini +++ b/tox.ini @@ -14,8 +14,7 @@ lint_folders = passenv = * [testenv:build] -# builds the package and checks integrity - +description = Asserts package build integrity. usedevelop = true deps = build @@ -31,12 +30,13 @@ commands = check-manifest {toxinidir} [testenv:tests] +description = Run ALL test suite with pytest and {basepython}. usedevelop = true -changedir = tests deps = coverage[toml] pytest pytest-cov +extras = metatensor commands = # Run unit tests @@ -49,7 +49,24 @@ commands = commands_post = coverage xml +[testenv:tests-min] +description = Run the minimal core tests with pytest and {basepython}. +usedevelop = true +deps = + coverage[toml] + pytest + pytest-cov + +commands = + # Run unit tests + pytest --cov --import-mode=append {posargs} + +# after executing the pytest assembles the coverage reports +commands_post = + coverage xml + [testenv:lint] +description = Run linters and type checks skip_install = true deps = black @@ -69,8 +86,7 @@ commands = {[tox]lint_folders} "{toxinidir}/README.rst" [testenv:format] -# Abuse tox to do actual formatting. Users can call `tox -e format` to run -# formatting on all files +description = Abuse tox to do actual formatting on all files. skip_install = true deps = black @@ -82,11 +98,14 @@ commands = isort {[tox]lint_folders} [testenv:docs] +description = Building the package documentation. usedevelop = true deps = -r docs/requirements.txt # The documentation runs "examples" to produce outputs via sphinx-gallery. -extras = examples +extras = + examples + metatensor commands = sphinx-build {posargs:-E} -W -b html docs/src docs/build/html