Skip to content

Commit

Permalink
Merge pull request #72 from Electrostatics/replace_swig
Browse files Browse the repository at this point in the history
WIP: Replace swig
  • Loading branch information
Darren Curtis committed Sep 9, 2020
2 parents e7fbeae + e4d2ce9 commit 9ac865a
Show file tree
Hide file tree
Showing 14 changed files with 376 additions and 3 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Expand Up @@ -62,5 +62,5 @@ jobs:
echo "==================================== BUILD =============================================== "
./.build.sh
env:
# https://codecov.io/gh/Electrostatics/apbs-pdb2pqr
# https://codecov.io/gh/Electrostatics/apbs
CODECOV_TOKEN: "e3a1e24c-5598-4f47-9353-7fa0ac57f98e"
5 changes: 4 additions & 1 deletion .gitmodules
Expand Up @@ -10,4 +10,7 @@
url = https://github.com/Electrostatics/pb_solvers
[submodule "externals/bem"]
path = externals/bem
url = https://github.com/Electrostatics/TABIPB.git
url = https://github.com/Electrostatics/TABIPB.git
[submodule "externals/pybind11"]
path = externals/pybind11
url = https://github.com/pybind/pybind11
2 changes: 1 addition & 1 deletion CMakeLists.txt
Expand Up @@ -58,7 +58,7 @@ OPTION(BUILD_SHARED_LIBS "Build shared libraries." OFF)
message(STATUS "Setting project paths")

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -fpermissive -fPIC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wpedantic -fpermissive -fPIC")
if(WIN32)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /STACK:100000000")
endif()
Expand Down
2 changes: 2 additions & 0 deletions requirements.txt
@@ -1,3 +1,5 @@
python-dev-tools>=2020.9.4
pybind11>=2.5
sphinx>=3.1
sphinx_rtd_theme
sphinx_sitemap
1 change: 1 addition & 0 deletions tools/CMakeLists.txt
Expand Up @@ -5,5 +5,6 @@ add_subdirectory(manip)

if(ENABLE_PYTHON)
add_subdirectory(python)
add_subdirectory(python-pybind)
endif(ENABLE_PYTHON)

28 changes: 28 additions & 0 deletions tools/python-pybind/CMakeLists.txt
@@ -0,0 +1,28 @@

find_package(pybind11 REQUIRED)
add_library(apbs_pybind
MODULE
module.cpp
bind_nosh.cpp
bind_vatom.cpp
bind_valist.cpp
)

set_target_properties(apbs_pybind
PROPERTIES
PREFIX "${PYTHON_MODULE_PREFIX}"
SUFFIX "${PYTHON_MODULE_EXTENSION}"
OUTPUT_NAME "apbs"
)

message(STATUS "LIBS ${APBS_LIBS}")
message(STATUS "INTERNAL_LIBS ${APBS_INTERNAL_LIBS}")
target_link_libraries(
apbs_pybind
PRIVATE
pybind11::module
${APBS_LIBS}
${APBS_INTERNAL_LIBS}
)

install(TARGETS apbs_pybind LIBRARY DESTINATION ${PROJECT_BINARY_DIR}/lib)
22 changes: 22 additions & 0 deletions tools/python-pybind/bind_constants.hpp
@@ -0,0 +1,22 @@
#pragma once

/**
* @file tools/python-pybind/bind_constants.hpp
* @author Asher Mancinelli <asher.mancinelli@pnnl.gov>
* @brief Contains bindings for exported constants.
*
* @note The constants exported here were simply the same ones exported by the
* original SWIG python interface.
*
* @see tools/python/apbslib.c
*/

inline void bind_constants(py::module& m)
{
m.attr("NPT_ENERGY") = py::int_(static_cast<int>(NPT_ENERGY));
m.attr("NPT_FORCE") = py::int_(static_cast<int>(NPT_FORCE));
m.attr("NPT_ELECENERGY") = py::int_(static_cast<int>(NPT_ELECENERGY));
m.attr("NPT_ELECFORCE") = py::int_(static_cast<int>(NPT_ELECFORCE));
m.attr("NPT_APOLENERGY") = py::int_(static_cast<int>(NPT_APOLENERGY));
m.attr("NPT_APOLFORCE") = py::int_(static_cast<int>(NPT_APOLFORCE));
}
67 changes: 67 additions & 0 deletions tools/python-pybind/bind_nosh.cpp
@@ -0,0 +1,67 @@
#include "bind_nosh.hpp"

int parseInputFromString(NOsh *nosh, std::string str)
{
int ret, bufsize;
Vio *sock;

startVio();

VASSERT( bufsize <= VMAX_BUFSIZE );
sock = Vio_ctor("BUFF","ASC",VNULL,"0","r");

Vio_bufTake(sock, const_cast<char*>(str.c_str()), str.size());

ret = NOsh_parseInput(nosh, sock);
sock->VIObuffer = VNULL;
Vio_dtor(&sock);
return ret;
}

void bind_nosh(py::module& m)
{
m.def("getPotentials", &getPotentials<double>);

py::class_<NOsh_calc>(m, "NOsh_calc")
.def("__init__",
[] (NOsh_calc* self, NOsh_CalcType calcType)
{
self = NOsh_calc_ctor(calcType);
})
.def("NOsh_calc_mgparm_set",
[] (NOsh_calc* nosh, MGparm& mgparm)
{
nosh->mgparm = &mgparm;
})
.def("__del__",
[] (NOsh_calc* self)
{
NOsh_calc_dtor(&self);
});

py::class_<NOsh>(m, "NOsh")
.def(py::init<>())
.def("parseInputFromString",
[] (NOsh* self, std::string str) -> int
{
int ret, bufsize;
Vio *sock;

startVio();

VASSERT( bufsize <= VMAX_BUFSIZE );
sock = Vio_ctor("BUFF","ASC",VNULL,"0","r");

Vio_bufTake(sock, const_cast<char*>(str.c_str()), str.size());

ret = NOsh_parseInput(self, sock);
sock->VIObuffer = VNULL;
Vio_dtor(&sock);
return ret;
})
.def("__del__",
[] (NOsh* self)
{
NOsh_dtor(&self);
});
}
77 changes: 77 additions & 0 deletions tools/python-pybind/bind_nosh.hpp
@@ -0,0 +1,77 @@
#pragma once

#include <string>
#include <vector>

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
namespace py = pybind11;

#ifdef __GNUC__
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
extern "C"
{
#include "apbscfg.h"
#include "routines.h"
#include "generic/nosh.h"
#include "generic/valist.h"
#include "generic/vatom.h"
}

/**
* @file tools/python-pybind/bind_nosh.hpp
* @author Asher Mancinelli <asher.mancinelli@pnnl.gov>
* @brief Contains bindings for nosh-related functions.
*
* @note keep all implementations in the impl unless templated.
* @note contains bindings for nosh and all classes encapsulated by this struct
* within the source.
*
* @see src/generic/nosh.h:195
*/

/**
* @todo request help documenting
*/
template<typename T>
std::vector<T> getPotentials(NOsh *nosh, PBEparm *pbeparm, Vpmg *pmg, Valist *alist)
{
Vgrid *grid;
Vatom *atom;
int i, rc, nx, ny, nz;
double hx, hy, hzed, xcent, ycent, zcent, xmin, ymin, zmin;
double value;
double *position;
std::vector<T> values;

nx = pmg->pmgp->nx;
ny = pmg->pmgp->ny;
nz = pmg->pmgp->nz;
hx = pmg->pmgp->hx;
hy = pmg->pmgp->hy;
hzed = pmg->pmgp->hzed;
xcent = pmg->pmgp->xcent;
ycent = pmg->pmgp->ycent;
zcent = pmg->pmgp->zcent;
xmin = xcent - 0.5*(nx-1)*hx;
ymin = ycent - 0.5*(ny-1)*hy;
zmin = zcent - 0.5*(nz-1)*hzed;

Vpmg_fillArray(pmg, pmg->rwork, VDT_POT, 0.0, pbeparm->pbetype, pbeparm);
grid = Vgrid_ctor(nx, ny, nz, hx, hy, hzed, xmin, ymin, zmin,
pmg->rwork);
for (i=0;i<Valist_getNumberAtoms(alist);i++){
atom = Valist_getAtom(alist, i);
position = Vatom_getPosition(atom);
Vgrid_value(grid, position, &value);
values[i] = value;
}
Vgrid_dtor(&grid);
return values;
}

/**
* @brief Perform binding to module
*/
void bind_nosh(py::module& m);
66 changes: 66 additions & 0 deletions tools/python-pybind/bind_valist.cpp
@@ -0,0 +1,66 @@
#include "bind_valist.hpp"

void Valist_load(Valist *self,
int size,
std::vector<double> x,
std::vector<double> y,
std::vector<double> z,
std::vector<double> chg,
std::vector<double> rad)
{

int i, j;
double pos[3];

Vatom *atom;

VASSERT(self != VNULL);

self->atoms = static_cast<Vatom*>(Vmem_malloc(self->vmem, size, sizeof(Vatom)));
self->number = size;
for (i = 0; i < size; i++) {
pos[0] = x[i];
pos[1] = y[i];
pos[2] = z[i];
Vatom_setCharge(&(self->atoms[i]), chg[i]);
Vatom_setRadius(&(self->atoms[i]), rad[i]);
Vatom_setPosition(&(self->atoms[i]), pos);
Vatom_setAtomID(&(self->atoms[i]), i);
}

self->center[0] = 0.0;
self->center[1] = 0.0;
self->center[2] = 0.0;
self->maxrad = 0.0;
self->charge = 0.0;

/* Reset stat variables */
atom = &(self->atoms[0]);
for (i = 0; i < 3; i++) {
self->maxcrd[i] = self->mincrd[i] = atom->position[i];
}
self->maxrad = atom->radius;

for (i = 0; i < self->number; i++) {
atom = &(self->atoms[i]);
for (j = 0; j < 3; j++) {
if (atom->position[j] < self->mincrd[j])
self->mincrd[j] = atom->position[j];
if (atom->position[j] > self->maxcrd[j])
self->maxcrd[j] = atom->position[j];
}
if (atom->radius > self->maxrad) self->maxrad = atom->radius;
self->charge = self->charge + atom->charge;
}

self->center[0] = 0.5 * (self->maxcrd[0] + self->mincrd[0]);
self->center[1] = 0.5 * (self->maxcrd[1] + self->mincrd[1]);
self->center[2] = 0.5 * (self->maxcrd[2] + self->mincrd[2]);
}

void bind_valist(py::module &m)
{
py::class_<Valist>(m, "Valist")
.def(py::init<>())
.def("load", &Valist_load);
}
43 changes: 43 additions & 0 deletions tools/python-pybind/bind_valist.hpp
@@ -0,0 +1,43 @@
#pragma once

#include <vector>

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
namespace py = pybind11;

#ifdef __GNUC__
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
extern "C"
{
#include "generic/valist.h"
}

/**
* @file tools/python-pybind/bind_valist.hpp
* @author Asher Mancinelli <asher.mancinelli@pnnl.gov>
* @brief Contains bindings for Valist-related functions.
*
* @note keep all implementations in the impl unless templated.
* @note contains bindings for nosh and all classes encapsulated by this struct
* within the source.
*
* @see src/generic/valist.h:195
*/

/**
* @todo request documentation for this
*/
void Valist_load(Valist *self,
int size,
std::vector<double> x,
std::vector<double> y,
std::vector<double> z,
std::vector<double> chg,
std::vector<double> rad);

/**
* @brief Perform binding to module
*/
void bind_valist(py::module& m);
5 changes: 5 additions & 0 deletions tools/python-pybind/bind_vatom.cpp
@@ -0,0 +1,5 @@
#include "bind_vatom.hpp"

void bind_vatom(py::module& m)
{
}
26 changes: 26 additions & 0 deletions tools/python-pybind/bind_vatom.hpp
@@ -0,0 +1,26 @@
#pragma once

#include <pybind11/pybind11.h>
namespace py = pybind11;

extern "C"
{
#include "generic/valist.h"
}

/**
* @file tools/python-pybind/bind_valist.hpp
* @author Asher Mancinelli <asher.mancinelli@pnnl.gov>
* @brief Contains bindings for Valist-related functions.
*
* @note keep all implementations in the impl unless templated.
* @note contains bindings for nosh and all classes encapsulated by this struct
* within the source.
*
* @see src/generic/valist.h:195
*/

/**
* @brief Perform binding of _Vatom_ to module
*/
void bind_vatom(py::module& m);

0 comments on commit 9ac865a

Please sign in to comment.