Skip to content

Commit

Permalink
rename py_recipe to recipe. (#2232)
Browse files Browse the repository at this point in the history
Solve name mismatch Python ./. C++.

Closes #1634
  • Loading branch information
thorstenhater authored Nov 24, 2023
1 parent 29d84bd commit db868d3
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 54 deletions.
9 changes: 4 additions & 5 deletions python/domain_decomposition.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#include <limits>
#include <string>
#include <sstream>

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
Expand Down Expand Up @@ -105,9 +104,9 @@ void register_domain_decomposition(pybind11::module& m) {
// Partition load balancer
// The Python recipe has to be shimmed for passing to the function that takes a C++ recipe.
m.def("partition_load_balance",
[](std::shared_ptr<py_recipe>& recipe, const context_shim& ctx, arb::partition_hint_map hint_map) {
[](std::shared_ptr<recipe>& recipe, const context_shim& ctx, arb::partition_hint_map hint_map) {
try {
return arb::partition_load_balance(py_recipe_shim(recipe), ctx.context, std::move(hint_map));
return arb::partition_load_balance(recipe_shim(recipe), ctx.context, std::move(hint_map));
}
catch (...) {
py_reset_and_throw();
Expand All @@ -120,9 +119,9 @@ void register_domain_decomposition(pybind11::module& m) {
"recipe"_a, "context"_a, "hints"_a=arb::partition_hint_map{});

m.def("partition_by_group",
[](std::shared_ptr<py_recipe>& recipe, const context_shim& ctx, const std::vector<arb::group_description>& groups) {
[](std::shared_ptr<recipe>& recipe, const context_shim& ctx, const std::vector<arb::group_description>& groups) {
try {
return arb::domain_decomposition(py_recipe_shim(recipe), ctx.context, groups);
return arb::domain_decomposition(recipe_shim(recipe), ctx.context, groups);
}
catch (...) {
py_reset_and_throw();
Expand Down
38 changes: 18 additions & 20 deletions python/recipe.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#include <sstream>
#include <string>
#include <vector>

Expand All @@ -15,7 +14,6 @@
#include <arbor/recipe.hpp>

#include "arbor/cable_cell_param.hpp"
#include "conversion.hpp"
#include "error.hpp"
#include "event_generator.hpp"
#include "strprintf.hpp"
Expand Down Expand Up @@ -56,7 +54,7 @@ static arb::util::unique_any convert_cell(pybind11::object o) {

// The py::recipe::cell_decription returns a pybind11::object, that is
// unwrapped and copied into a arb::util::unique_any.
arb::util::unique_any py_recipe_shim::get_cell_description(arb::cell_gid_type gid) const {
arb::util::unique_any recipe_shim::get_cell_description(arb::cell_gid_type gid) const {
return try_catch_pyexception([&](){
pybind11::gil_scoped_acquire guard;
return convert_cell(impl_->cell_description(gid));
Expand All @@ -79,7 +77,7 @@ static std::any convert_gprop(pybind11::object o) {

// The py::recipe::global_properties returns a pybind11::object, that is
// unwrapped and copied into an std::any.
std::any py_recipe_shim::get_global_properties(arb::cell_kind kind) const {
std::any recipe_shim::get_global_properties(arb::cell_kind kind) const {
return try_catch_pyexception([&](){
pybind11::gil_scoped_acquire guard;
return convert_gprop(impl_->global_properties(kind));
Expand Down Expand Up @@ -113,7 +111,7 @@ static std::vector<arb::event_generator> convert_gen(std::vector<pybind11::objec
return gens;
}

std::vector<arb::event_generator> py_recipe_shim::event_generators(arb::cell_gid_type gid) const {
std::vector<arb::event_generator> recipe_shim::event_generators(arb::cell_gid_type gid) const {
return try_catch_pyexception([&](){
pybind11::gil_scoped_acquire guard;
return convert_gen(impl_->event_generators(gid), gid);
Expand Down Expand Up @@ -177,43 +175,43 @@ void register_recipe(pybind11::module& m) {
.def("__repr__", &gj_to_string);

// Recipes
pybind11::class_<py_recipe,
py_recipe_trampoline,
std::shared_ptr<py_recipe>>
pybind11::class_<recipe,
recipe_trampoline,
std::shared_ptr<recipe>>
recipe(m, "recipe", pybind11::dynamic_attr(),
"A description of a model, describing the cells and the network via a cell-centric interface.");
recipe
.def(pybind11::init<>())
.def("num_cells", &py_recipe::num_cells, "The number of cells in the model.")
.def("cell_description", &py_recipe::cell_description, pybind11::return_value_policy::copy,
.def("num_cells", &recipe::num_cells, "The number of cells in the model.")
.def("cell_description", &recipe::cell_description, pybind11::return_value_policy::copy,
"gid"_a,
"High level description of the cell with global identifier gid.")
.def("cell_kind",
&py_recipe::cell_kind,
&recipe::cell_kind,
"gid"_a,
"The kind of cell with global identifier gid.")
.def("event_generators", &py_recipe::event_generators,
.def("event_generators", &recipe::event_generators,
"gid"_a,
"A list of all the event generators that are attached to gid, [] by default.")
.def("connections_on", &py_recipe::connections_on,
.def("connections_on", &recipe::connections_on,
pybind11::call_guard<pybind11::gil_scoped_release>(),
"gid"_a,
"A list of all the incoming connections to gid, [] by default.")
.def("external_connections_on", &py_recipe::external_connections_on,
.def("external_connections_on", &recipe::external_connections_on,
"gid"_a,
"A list of all the incoming connections from _remote_ locations to gid, [] by default.")
.def("gap_junctions_on", &py_recipe::gap_junctions_on,
.def("gap_junctions_on", &recipe::gap_junctions_on,
"gid"_a,
"A list of the gap junctions connected to gid, [] by default.")
.def("probes", &py_recipe::probes,
.def("probes", &recipe::probes,
"gid"_a,
"The probes to allow monitoring.")
.def("global_properties", &py_recipe::global_properties,
.def("global_properties", &recipe::global_properties,
"kind"_a,
"The default properties applied to all cells of type 'kind' in the model.")
// TODO: py_recipe::global_properties
.def("__str__", [](const py_recipe&){return "<arbor.recipe>";})
.def("__repr__", [](const py_recipe&){return "<arbor.recipe>";});
// TODO: recipe::global_properties
.def("__str__", [](const ::pyarb::recipe&){return "<arbor.recipe>";})
.def("__repr__", [](const ::pyarb::recipe&){return "<arbor.recipe>";});

// Probes
pybind11::class_<arb::probe_info> probe(m, "probe");
Expand Down
43 changes: 21 additions & 22 deletions python/recipe.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,22 @@
#include <arbor/recipe.hpp>

#include "error.hpp"
#include "strprintf.hpp"

namespace pyarb {

// pyarb::py_recipe is the recipe interface used by Python.
// pyarb::recipe is the recipe interface used by Python.
// Calls that return generic types return pybind11::object, to avoid
// having to wrap some C++ types used by the C++ interface (specifically
// util::unique_any, std::any, std::unique_ptr, etc.)
// For example, requests for cell description return pybind11::object, instead
// of util::unique_any used by the C++ recipe interface.
// The py_recipe_shim unwraps the python objects, and forwards them
// The recipe_shim unwraps the python objects, and forwards them
// to the C++ back end.

class py_recipe {
class recipe {
public:
py_recipe() = default;
virtual ~py_recipe() {}
recipe() = default;
virtual ~recipe() {}

virtual arb::cell_size_type num_cells() const = 0;
virtual pybind11::object cell_description(arb::cell_gid_type gid) const = 0;
Expand All @@ -53,72 +52,72 @@ class py_recipe {
};
};

class py_recipe_trampoline: public py_recipe {
class recipe_trampoline: public recipe {
public:
arb::cell_size_type num_cells() const override {
PYBIND11_OVERRIDE_PURE(arb::cell_size_type, py_recipe, num_cells);
PYBIND11_OVERRIDE_PURE(arb::cell_size_type, recipe, num_cells);
}

pybind11::object cell_description(arb::cell_gid_type gid) const override {
PYBIND11_OVERRIDE_PURE(pybind11::object, py_recipe, cell_description, gid);
PYBIND11_OVERRIDE_PURE(pybind11::object, recipe, cell_description, gid);
}

arb::cell_kind cell_kind(arb::cell_gid_type gid) const override {
try {
PYBIND11_OVERRIDE_PURE(arb::cell_kind, py_recipe, cell_kind, gid);
PYBIND11_OVERRIDE_PURE(arb::cell_kind, recipe, cell_kind, gid);
}
catch (const pybind11::cast_error& e) {
throw pybind11::type_error{"Couldn't convert return value of recipe.cell_kind(gid) to a cell_kind. Please check your recipe."};
}
}

std::vector<pybind11::object> event_generators(arb::cell_gid_type gid) const override {
PYBIND11_OVERRIDE(std::vector<pybind11::object>, py_recipe, event_generators, gid);
PYBIND11_OVERRIDE(std::vector<pybind11::object>, recipe, event_generators, gid);
}

std::vector<arb::cell_connection> connections_on(arb::cell_gid_type gid) const override {
PYBIND11_OVERRIDE(std::vector<arb::cell_connection>, py_recipe, connections_on, gid);
PYBIND11_OVERRIDE(std::vector<arb::cell_connection>, recipe, connections_on, gid);
}

std::vector<arb::cell_connection> external_connections_on(arb::cell_gid_type gid) const override {
PYBIND11_OVERRIDE(std::vector<arb::cell_connection>, py_recipe, connections_on, gid);
PYBIND11_OVERRIDE(std::vector<arb::cell_connection>, recipe, connections_on, gid);
}

std::vector<arb::gap_junction_connection> gap_junctions_on(arb::cell_gid_type gid) const override {
PYBIND11_OVERRIDE(std::vector<arb::gap_junction_connection>, py_recipe, gap_junctions_on, gid);
PYBIND11_OVERRIDE(std::vector<arb::gap_junction_connection>, recipe, gap_junctions_on, gid);
}

std::vector<arb::probe_info> probes(arb::cell_gid_type gid) const override {
PYBIND11_OVERRIDE(std::vector<arb::probe_info>, py_recipe, probes, gid);
PYBIND11_OVERRIDE(std::vector<arb::probe_info>, recipe, probes, gid);
}

pybind11::object global_properties(arb::cell_kind kind) const override {
PYBIND11_OVERRIDE(pybind11::object, py_recipe, global_properties, kind);
PYBIND11_OVERRIDE(pybind11::object, recipe, global_properties, kind);
}
};

// A recipe shim that holds a pyarb::py_recipe implementation.
// A recipe shim that holds a pyarb::recipe implementation.
// Unwraps/translates python-side output from pyarb::recipe and forwards
// to arb::recipe.
// For example, unwrap cell descriptions stored in PyObject, and rewrap
// in util::unique_any.

class py_recipe_shim: public arb::recipe {
class recipe_shim: public ::arb::recipe {
// pointer to the python recipe implementation
std::shared_ptr<py_recipe> impl_;
std::shared_ptr<::pyarb::recipe> impl_;

public:
using recipe::recipe;
using ::arb::recipe::recipe;

py_recipe_shim(std::shared_ptr<py_recipe> r): impl_(std::move(r)) {}
recipe_shim(std::shared_ptr<::pyarb::recipe> r): impl_(std::move(r)) {}

const char* msg = "Python error already thrown";

arb::cell_size_type num_cells() const override {
return try_catch_pyexception([&](){ return impl_->num_cells(); }, msg);
}

// The pyarb::py_recipe::cell_decription method returns a pybind11::object, that is
// The pyarb::recipe::cell_decription method returns a pybind11::object, that is
// unwrapped and copied into a util::unique_any.
arb::util::unique_any get_cell_description(arb::cell_gid_type gid) const override;

Expand Down
14 changes: 7 additions & 7 deletions python/simulation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,21 +58,21 @@ class simulation_shim {
std::unordered_map<arb::sampler_association_handle, sampler_callback> sampler_map_;

public:
simulation_shim(std::shared_ptr<py_recipe>& rec, const context_shim& ctx, const arb::domain_decomposition& decomp, std::uint64_t seed, pyarb_global_ptr global_ptr):
simulation_shim(std::shared_ptr<recipe>& rec, const context_shim& ctx, const arb::domain_decomposition& decomp, std::uint64_t seed, pyarb_global_ptr global_ptr):
global_ptr_(global_ptr)
{
try {
sim_.reset(new arb::simulation(py_recipe_shim(rec), ctx.context, decomp, seed));
sim_.reset(new arb::simulation(recipe_shim(rec), ctx.context, decomp, seed));
}
catch (...) {
py_reset_and_throw();
throw;
}
}

void update(std::shared_ptr<py_recipe>& rec) {
void update(std::shared_ptr<recipe>& rec) {
try {
sim_->update(py_recipe_shim(rec));
sim_->update(recipe_shim(rec));
}
catch (...) {
py_reset_and_throw();
Expand Down Expand Up @@ -214,16 +214,16 @@ void register_simulation(pybind11::module& m, pyarb_global_ptr global_ptr) {
"The executable form of a model.\n"
"A simulation is constructed from a recipe, and then used to update and monitor model state.");
simulation
// A custom constructor that wraps a python recipe with arb::py_recipe_shim
// A custom constructor that wraps a python recipe with arb::recipe_shim
// before forwarding it to the arb::recipe constructor.
.def(pybind11::init(
[global_ptr](std::shared_ptr<py_recipe>& rec,
[global_ptr](std::shared_ptr<recipe>& rec,
const std::shared_ptr<context_shim>& ctx_,
const std::optional<arb::domain_decomposition>& decomp,
std::uint64_t seed) {
try {
auto ctx = ctx_ ? ctx_ : std::make_shared<context_shim>(make_context_shim());
auto dec = decomp.value_or(arb::partition_load_balance(py_recipe_shim(rec), ctx->context));
auto dec = decomp.value_or(arb::partition_load_balance(recipe_shim(rec), ctx->context));
return new simulation_shim(rec, *ctx, dec, seed, global_ptr);
}
catch (...) {
Expand Down

0 comments on commit db868d3

Please sign in to comment.