Skip to content

Commit

Permalink
Merge pull request #1 from glotzerlab/port-pair-plugin
Browse files Browse the repository at this point in the history
Port the example pair plugin from HOOMD-blue.
  • Loading branch information
joaander authored Dec 2, 2024
2 parents d97980e + 0817d87 commit ae7438f
Show file tree
Hide file tree
Showing 10 changed files with 333 additions and 27 deletions.
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# HOOMD-blue component template
# HOOMD-blue component template for MD pair potentials

`hoomd-component-template` provides a framework to develop components that extend
[**HOOMD-blue**](https://glotzerlab.engin.umich.edu/hoomd-blue/). It includes template C++ and
Python modules, an example unit test, CMake scripts to build the component, and GitHub Actions
workflows.
`hoomd-md-pair-template` provides a framework to develop components that extend
[**HOOMD-blue**](https://glotzerlab.engin.umich.edu/hoomd-blue/) with MD pairwise
potentials. It includes template C++ and Python modules, an example unit test, CMake
scripts to build the component, and GitHub Actions workflows.

## Building the component

Expand All @@ -12,19 +12,19 @@ To build this component:
1. Build and install **HOOMD-blue** from source.
2. Obtain the component's source.
```
$ git clone https://github.com/glotzerlab/hoomd-component-template
$ git clone https://github.com/glotzerlab/hoomd-md-pair-template
```
3. Configure.
```
$ cmake -B build/hoomd-component-template -S hoomd-component-template
$ cmake -B build/hoomd-md-pair-template -S hoomd-md-pair-template
```
4. Build the component.
```
$ cmake --build build/hoomd-component-template
$ cmake --build build/hoomd-md-pair-template
```
5. Install the component.
```
$ cmake --install build/hoomd-component-template
$ cmake --install build/hoomd-md-pair-template
```
Once installed, the template is available for import via:
Expand All @@ -37,7 +37,7 @@ import hoomd.template
To create a new component:
1. Fork [hoomd-component-template](https://github.com/glotzerlab/hoomd-component-template/).
1. Fork [hoomd-md-pair-template](https://github.com/glotzerlab/hoomd-md-pair-template/).
2. Address all **TODO** comments (including those in `.github/`)
3. Add C++ and Python files to `src/`.
4. Add unit tests in `src/pytest`.
Expand All @@ -57,7 +57,7 @@ new GitHub release with automatically generated release notes.
## Maintaining your component
The HOOMD-blue developers will periodically update
[hoomd-component-template](https://github.com/glotzerlab/hoomd-component-template/), including
[hoomd-md-pair-template](https://github.com/glotzerlab/hoomd-md-pair-template/), including
updates to the GitHub Actions workflow, pre-commit configuration, and CMake scripts. Merge these
changes into your fork to support the latest version of HOOMD-blue.
Expand Down
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ set(_${COMPONENT_NAME}_sources

# TODO: List all GPU C++ source code files in _${COMPONENT_NAME}_cu_sources.
set(_${COMPONENT_NAME}_cu_sources
PotentialPairExampleGPUKernel.cu
)

# TODO: List all Python modules in python_files.
set(python_files
__init__.py
pair.py
version.py
)

Expand Down
172 changes: 172 additions & 0 deletions src/EvaluatorPairExample.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
// Copyright (c) 2009-2024 The Regents of the University of Michigan.
// Part of HOOMD-blue, released under the BSD 3-Clause License.

#ifndef __PAIR_EVALUATOR_EXAMPLE_H__
#define __PAIR_EVALUATOR_EXAMPLE_H__

#ifndef __HIPCC__
#include <string>
#endif

#include "hoomd/HOOMDMath.h"

/*! \file EvaluatorPairExample.h
\brief Defines the pair evaluator class for the example potential
*/

// need to declare these class methods with __device__ qualifiers when building in nvcc
// DEVICE is __host__ __device__ when included in nvcc and blank when included into the host
// compiler
#ifdef __HIPCC__
#define DEVICE __device__
#define HOSTDEVICE __host__ __device__
#else
#define DEVICE
#define HOSTDEVICE
#endif

namespace hoomd
{
namespace md
{

class EvaluatorPairExample
{
public:
//! Define the parameter type used by this pair potential evaluator
struct param_type
{
Scalar k; //!< Spring constant
Scalar sigma; //!< Minima of the spring

DEVICE void load_shared(char*& ptr, unsigned int& available_bytes) { }

HOSTDEVICE void allocate_shared(char*& ptr, unsigned int& available_bytes) const { }

#ifdef ENABLE_HIP
//! Set CUDA memory hints
void set_memory_hint() const
{
// default implementation does nothing
}
#endif

#ifndef __HIPCC__
param_type() : k(0), sigma(0) { }

param_type(pybind11::dict v, bool managed = false)
{
k = v["k"].cast<Scalar>();
sigma = v["sigma"].cast<Scalar>();
}

pybind11::dict asDict()
{
pybind11::dict v;
v["k"] = k;
v["sigma"] = sigma;
return v;
}
#endif
}
#if HOOMD_LONGREAL_SIZE == 32
__attribute__((aligned(8)));
#else
__attribute__((aligned(16)));
#endif

//! Constructs the pair potential evaluator
/*! \param _rsq Squared distance between the particles
\param _rcutsq Squared distance at which the potential goes to 0
\param _params Per type pair parameters of this potential
*/
DEVICE EvaluatorPairExample(Scalar _rsq, Scalar _rcutsq, const param_type& _params)
: rsq(_rsq), rcutsq(_rcutsq), k(_params.k), sigma(_params.sigma)
{
}

//! Example doesn't use charge
DEVICE static bool needsCharge()
{
return false;
}
//! Accept the optional charge value
/*! \param qi Charge of particle i
\param qj Charge of particle j
*/
DEVICE void setCharge(Scalar qi, Scalar qj) { }

//! Evaluate the force and energy
/*! \param force_divr Output parameter to write the computed force divided by r.
\param pair_eng Output parameter to write the computed pair energy
\param energy_shift If true, the potential must be shifted so that
V(r) is continuous at the cutoff
\note There is no need to check if rsq < rcutsq in this method.
Cutoff tests are performed in PotentialPair.
\return True if they are evaluated or false if they are not because
we are beyond the cutoff
*/
DEVICE bool evalForceAndEnergy(Scalar& force_divr, Scalar& pair_eng, bool energy_shift)
{
// compute the force divided by r in force_divr
if (rsq < rcutsq)
{
Scalar r = fast::sqrt(rsq);
Scalar rinv = 1 / r;
Scalar overlap = sigma - r;

force_divr = k * overlap * rinv;

pair_eng = Scalar(0.5) * k * overlap * overlap;

if (energy_shift)
{
Scalar rcut = fast::sqrt(rcutsq);
Scalar cut_overlap = sigma - rcut;
pair_eng -= Scalar(0.5) * k * cut_overlap * cut_overlap;
}
return true;
}
else
return false;
}

//! Example doesn't eval LRC integrals
DEVICE Scalar evalPressureLRCIntegral()
{
return 0;
}

//! Example doesn't eval LRC integrals
DEVICE Scalar evalEnergyLRCIntegral()
{
return 0;
}

#ifndef __HIPCC__
//! Get the name of this potential
/*! \returns The potential name.
*/
static std::string getName()
{
return std::string("example_pair");
}

std::string getShapeSpec() const
{
throw std::runtime_error("Shape definition not supported for this pair potential.");
}
#endif

protected:
Scalar rsq; //!< Stored rsq from the constructor
Scalar rcutsq; //!< Stored rcutsq from the constructor
Scalar k; //!< Stored k from the constructor
Scalar sigma; //!< Stored sigma from the constructor
};

} // end namespace md
} // end namespace hoomd

#endif // __PAIR_EVALUATOR_EXAMPLE_H__
18 changes: 18 additions & 0 deletions src/PotentialPairExampleGPUKernel.cu
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) 2009-2024 The Regents of the University of Michigan.
// Part of HOOMD-blue, released under the BSD 3-Clause License.

#include "EvaluatorPairExample.h"
#include "hoomd/md/PotentialPairGPU.cuh"

namespace hoomd
{
namespace md
{
namespace kernel
{
template __attribute__((visibility("default"))) hipError_t
gpu_compute_pair_forces<EvaluatorPairExample>(const pair_args_t& pair_args,
const EvaluatorPairExample::param_type* d_params);
} // end namespace kernel
} // end namespace md
} // end namespace hoomd
4 changes: 3 additions & 1 deletion src/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,7 @@
"""Template HOOMD-blue component."""
# TODO: Document your component.

# TODO: Import all Python modules in your component.
from . import version
from .pair import ExamplePair

__all__ = ['ExamplePair']
14 changes: 11 additions & 3 deletions src/module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@
// Part of HOOMD-blue, released under the BSD 3-Clause License.

// TODO: Include the header files of classes that will be exported to Python.
#include "EvaluatorPairExample.h"

#include "hoomd/md/PotentialPair.h"
#include <pybind11/pybind11.h>

#ifdef ENABLE_HIP
#include "hoomd/md/PotentialPairGPU.h"
#endif

namespace hoomd
{
namespace md
Expand All @@ -14,11 +20,13 @@ namespace md
// CMakeLists.txt), prefixed with an underscore.
PYBIND11_MODULE(_template, m)
{
// TODO: Call export_Class(m) for each C++ class to be exported to Python.
// TODO: Call export_Class(m) for each C++ class to be exported to Python.

detail::export_PotentialPair<EvaluatorPairExample>(m, "PotentialPairExample");
#ifdef ENABLE_HIP
// TODO: Call export_ClassGPU(m) for each GPU enabled C++ class to be exported
// to Python.
// TODO: Call export_ClassGPU(m) for each GPU enabled C++ class to be exported
// to Python.
detail::export_PotentialPairGPU<EvaluatorPairExample>(m, "PotentialPairExampleGPU");
#endif
}

Expand Down
30 changes: 30 additions & 0 deletions src/pair.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright (c) 2009-2024 The Regents of the University of Michigan.
# Part of HOOMD-blue, released under the BSD 3-Clause License.

"""Example pair potential."""

# Import the C++ module.
from hoomd.data.parameterdicts import TypeParameterDict
from hoomd.data.typeparam import TypeParameter

# Import the hoomd Python package and other necessary components.
from hoomd.md import pair
from hoomd.template import _template


class ExamplePair(pair.Pair):
"""Example pair potential."""

# set static class data
_ext_module = _template
_cpp_class_name = 'PotentialPairExample'
_accepted_modes = ('none', 'shift', 'xplor')

def __init__(self, nlist, default_r_cut=None, default_r_on=0.0, mode='none'):
super().__init__(nlist, default_r_cut, default_r_on, mode)
params = TypeParameter(
'params',
'particle_types',
TypeParameterDict(k=float, sigma=float, len_keys=2),
)
self._add_typeparam(params)
2 changes: 1 addition & 1 deletion src/pytest/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# TODO: List all pytest files in test_files.
set(test_files __init__.py
test_version.py
test_example_pair.py
)

# Copy tests to the install directory.
Expand Down
Loading

0 comments on commit ae7438f

Please sign in to comment.