Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 6 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
[build-system]
requires = ["setuptools>=62.0", "setuptools-git-versioning>=2.0", "numpy"]
requires = [
"setuptools>=62.0",
"setuptools-git-versioning>=2.0",
"numpy",
"nanobind",
]
build-backend = "setuptools.build_meta"

[project]
Expand Down
1 change: 1 addition & 0 deletions requirements/conda.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ libobjcryst
pyobjcryst
diffpy.structure
periodictable
nanobind
61 changes: 57 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,23 @@

import numpy
from setuptools import Extension, setup
from setuptools.command.build_ext import build_ext


def get_nanobind_config():
import nanobind

package_dir = Path(nanobind.__file__).parent
return {
"include_dirs": [
nanobind.include_dir(),
str(package_dir / "ext" / "robin_map" / "include"),
],
"source": str(Path(nanobind.source_dir()) / "nb_combined.cpp"),
}


nanobind_macros = [("NB_COMPACT_ASSERTIONS", None)]


def get_boost_libraries():
Expand Down Expand Up @@ -90,11 +107,13 @@ def get_objcryst_libraries():


if os.name == "nt":
compile_args = ["/std:c++14"]
compile_args = ["/std:c++23"]
nanobind_compile_args = ["/std:c++23"]
macros = [("_USE_MATH_DEFINES", None)]
extra_link_args = ["/FORCE:MULTIPLE"]
else:
compile_args = ["-std=c++11"]
compile_args = ["-std=c++23"]
nanobind_compile_args = ["-std=c++23", "-fno-strict-aliasing"]
macros = []
extra_link_args = []

Expand All @@ -112,13 +131,44 @@ def get_objcryst_libraries():
}


class build_ext_with_nanobind(build_ext):
def build_extension(self, ext):
nanobind_source = getattr(ext, "nanobind_source", None)
if not nanobind_source:
super().build_extension(ext)
return

original_extra_objects = list(ext.extra_objects or [])
try:
nanobind_objects = self.compiler.compile(
[nanobind_source],
output_dir=self.build_temp,
macros=(ext.define_macros or []) + nanobind_macros,
include_dirs=ext.include_dirs,
debug=self.debug,
extra_postargs=nanobind_compile_args,
depends=ext.depends,
)
ext.extra_objects = original_extra_objects + nanobind_objects
super().build_extension(ext)
finally:
ext.extra_objects = original_extra_objects


def create_extensions():
"Initialize Extension objects for the setup function."
nanobind_cfg = get_nanobind_config()
ext = Extension(
"diffpy.srreal.srreal_ext",
glob.glob("src/extensions/*.cpp"),
**ext_kws,
**{
**ext_kws,
"include_dirs": (
ext_kws["include_dirs"] + nanobind_cfg["include_dirs"]
),
},
)
ext.nanobind_source = nanobind_cfg["source"]
return [ext]


Expand All @@ -130,4 +180,7 @@ def ext_modules():


if __name__ == "__main__":
setup(ext_modules=ext_modules())
setup(
cmdclass={"build_ext": build_ext_with_nanobind},
ext_modules=ext_modules(),
)
74 changes: 35 additions & 39 deletions src/diffpy/srreal/bondcalculator.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,46 @@
# exported items, these also makes them show in pydoc.
__all__ = ["BondCalculator"]

from diffpy.srreal.srreal_ext import BondCalculator
from diffpy.srreal.srreal_ext import BondCalculator as _BondCalculator
from diffpy.srreal.wraputils import (
propertyFromExtDoubleAttr,
setattrFromKeywordArguments,
)


class BondCalculator(_BondCalculator):
__doc__ = _BondCalculator.__doc__

def __init__(self, **kwargs):
"""Create a new instance of BondCalculator. Keyword arguments can be
used to configure calculator properties, for example:

bdc = BondCalculator(rmin=1.5, rmax=2.5)

Raise ValueError for invalid keyword argument.
"""
super().__init__()
setattrFromKeywordArguments(self, **kwargs)
return

def __call__(self, structure=None, **kwargs):
"""Return sorted bond distances in the specified structure.

Attributes
----------
structure
structure to be evaluated, an instance of diffpy Structure
or pyobjcryst Crystal. Reuse the last structure when None.
kwargs
optional parameter settings for this calculator

Return a sorted numpy array.
"""
setattrFromKeywordArguments(self, **kwargs)
self.eval(structure)
return self.distances


# property wrappers to C++ double attributes

BondCalculator.rmin = propertyFromExtDoubleAttr(
Expand All @@ -39,42 +73,4 @@
)


# method overrides that support keyword arguments


def _init_kwargs(self, **kwargs):
"""Create a new instance of BondCalculator. Keyword arguments can be
used to configure calculator properties, for example:

bdc = BondCalculator(rmin=1.5, rmax=2.5)

Raise ValueError for invalid keyword argument.
"""
BondCalculator.__boostpython__init(self)
setattrFromKeywordArguments(self, **kwargs)
return


def _call_kwargs(self, structure=None, **kwargs):
"""Return sorted bond distances in the specified structure.

Attributes
----------
structure
structure to be evaluated, an instance of diffpy Structure
or pyobjcryst Crystal. Reuse the last structure when None.
kwargs
optional parameter settings for this calculator

Return a sorted numpy array.
"""
setattrFromKeywordArguments(self, **kwargs)
self.eval(structure)
return self.distances


BondCalculator.__boostpython__init = BondCalculator.__init__
BondCalculator.__init__ = _init_kwargs
BondCalculator.__call__ = _call_kwargs

# End of file
78 changes: 37 additions & 41 deletions src/diffpy/srreal/bvscalculator.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,48 @@
# exported items
__all__ = ["BVSCalculator"]

from diffpy.srreal.srreal_ext import BVSCalculator
from diffpy.srreal.srreal_ext import BVSCalculator as _BVSCalculator
from diffpy.srreal.wraputils import (
propertyFromExtDoubleAttr,
setattrFromKeywordArguments,
)


class BVSCalculator(_BVSCalculator):
__doc__ = _BVSCalculator.__doc__

def __init__(self, **kwargs):
"""Create a new instance of BVSCalculator.
Keyword arguments can be used to configure the calculator properties,
for example:
bvscalc = BVSCalculator(valenceprecision=0.001)
Raise ValueError for invalid keyword argument.
"""
super().__init__()
setattrFromKeywordArguments(self, **kwargs)
return

def __call__(self, structure=None, **kwargs):
"""Return bond valence sums at each atom site in the structure.
Attributes
----------
structure
structure to be evaluated, an instance of diffpy Structure
or pyobjcryst Crystal. Reuse the last structure when None.
kwargs
optional parameter settings for this calculator
Return an array of calculated valence sums.
See valences for the expected values.
"""
setattrFromKeywordArguments(self, **kwargs)
rv = self.eval(structure)
return rv


# Property wrappers to C++ double attributes

BVSCalculator.valenceprecision = propertyFromExtDoubleAttr(
Expand Down Expand Up @@ -55,44 +91,4 @@
)


# method overrides that support keyword arguments


def _init_kwargs(self, **kwargs):
"""Create a new instance of BVSCalculator.
Keyword arguments can be used to configure the calculator properties,
for example:
bvscalc = BVSCalculator(valenceprecision=0.001)
Raise ValueError for invalid keyword argument.
"""
BVSCalculator.__boostpython__init(self)
setattrFromKeywordArguments(self, **kwargs)
return


def _call_kwargs(self, structure=None, **kwargs):
"""Return bond valence sums at each atom site in the structure.
Attributes
----------
structure
structure to be evaluated, an instance of diffpy Structure
or pyobjcryst Crystal. Reuse the last structure when None.
kwargs
optional parameter settings for this calculator
Return an array of calculated valence sums.
See valences for the expected values.
"""
setattrFromKeywordArguments(self, **kwargs)
rv = self.eval(structure)
return rv


BVSCalculator.__boostpython__init = BVSCalculator.__init__
BVSCalculator.__init__ = _init_kwargs
BVSCalculator.__call__ = _call_kwargs

# End of file
74 changes: 35 additions & 39 deletions src/diffpy/srreal/overlapcalculator.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,46 @@
# exported items, these also makes them show in pydoc.
__all__ = ["OverlapCalculator"]

from diffpy.srreal.srreal_ext import OverlapCalculator
from diffpy.srreal.srreal_ext import OverlapCalculator as _OverlapCalculator
from diffpy.srreal.wraputils import (
propertyFromExtDoubleAttr,
setattrFromKeywordArguments,
)


class OverlapCalculator(_OverlapCalculator):
__doc__ = _OverlapCalculator.__doc__

def __init__(self, **kwargs):
"""Create a new instance of OverlapCalculator. Keyword arguments can
be used to configure calculator properties, for example:

olc = OverlapCalculator(rmax=2.5)

Raise ValueError for invalid keyword argument.
"""
super().__init__()
setattrFromKeywordArguments(self, **kwargs)
return

def __call__(self, structure=None, **kwargs):
"""Return siteSquareOverlaps per each site of the structure.

Attributes
----------
structure
structure to be evaluated, an instance of diffpy Structure
or pyobjcryst Crystal. Reuse the last structure when None.
kwargs
optional parameter settings for this calculator

Return a numpy array.
"""
setattrFromKeywordArguments(self, **kwargs)
self.eval(structure)
return self.sitesquareoverlaps


# property wrappers to C++ double attributes

OverlapCalculator.rmin = propertyFromExtDoubleAttr(
Expand All @@ -47,42 +81,4 @@
""",
)

# method overrides that support keyword arguments


def _init_kwargs(self, **kwargs):
"""Create a new instance of OverlapCalculator. Keyword arguments can
be used to configure calculator properties, for example:

olc = OverlapCalculator(rmax=2.5)

Raise ValueError for invalid keyword argument.
"""
OverlapCalculator.__boostpython__init(self)
setattrFromKeywordArguments(self, **kwargs)
return


def _call_kwargs(self, structure=None, **kwargs):
"""Return siteSquareOverlaps per each site of the structure.

Attributes
----------
structure
structure to be evaluated, an instance of diffpy Structure
or pyobjcryst Crystal. Reuse the last structure when None.
kwargs
optional parameter settings for this calculator

Return a numpy array.
"""
setattrFromKeywordArguments(self, **kwargs)
self.eval(structure)
return self.sitesquareoverlaps


OverlapCalculator.__boostpython__init = OverlapCalculator.__init__
OverlapCalculator.__init__ = _init_kwargs
OverlapCalculator.__call__ = _call_kwargs

# End of file
Loading
Loading