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

WIP: Replace swig #72

Merged
merged 8 commits into from Sep 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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);