diff --git a/arbor/arbexcept.cpp b/arbor/arbexcept.cpp index 46025c6c776373ce92bf70d8b241e0cfb016da1c..2bc11e9274d82eb57a14c440928ed8b194a90f2c 100644 --- a/arbor/arbexcept.cpp +++ b/arbor/arbexcept.cpp @@ -10,6 +10,11 @@ namespace arb { using arb::util::pprintf; +bad_cell_probe::bad_cell_probe(cell_kind kind, cell_gid_type gid): + arbor_exception(pprintf("recipe::get_grobe() is not supported for cell with gid {} of kind {})", gid, kind)), + gid(gid), + kind(kind) +{} bad_cell_description::bad_cell_description(cell_kind kind, cell_gid_type gid): arbor_exception(pprintf("recipe::get_cell_kind(gid={}) -> {} does not match the cell type provided by recipe::get_cell_description(gid={})", gid, kind, gid)), gid(gid), diff --git a/arbor/benchmark_cell_group.cpp b/arbor/benchmark_cell_group.cpp index c6a6e2582f9422ea2a76b2b3aa9892bf9cd36ce2..4d4f1630053c4bab6e1d0c708e069f188d09fe9a 100644 --- a/arbor/benchmark_cell_group.cpp +++ b/arbor/benchmark_cell_group.cpp @@ -1,6 +1,7 @@ #include <chrono> #include <exception> +#include <arbor/arbexcept.hpp> #include <arbor/benchmark_cell.hpp> #include <arbor/recipe.hpp> #include <arbor/schedule.hpp> @@ -17,6 +18,12 @@ benchmark_cell_group::benchmark_cell_group(const std::vector<cell_gid_type>& gid const recipe& rec): gids_(gids) { + for (auto gid: gids_) { + if (!rec.get_probes(gid).empty()) { + throw bad_cell_probe(cell_kind::benchmark, gid); + } + } + cells_.reserve(gids_.size()); for (auto gid: gids_) { cells_.push_back(util::any_cast<benchmark_cell>(rec.get_cell_description(gid))); diff --git a/arbor/include/arbor/arbexcept.hpp b/arbor/include/arbor/arbexcept.hpp index e1dcf8b1c4338a38b92705a447e69bdcccad10e7..f9e1a7eb7befc50a5961a95df633190be066113a 100644 --- a/arbor/include/arbor/arbexcept.hpp +++ b/arbor/include/arbor/arbexcept.hpp @@ -29,6 +29,12 @@ struct arbor_exception: std::runtime_error { // Recipe errors: +struct bad_cell_probe: arbor_exception { + bad_cell_probe(cell_kind kind, cell_gid_type gid); + cell_gid_type gid; + cell_kind kind; +}; + struct bad_cell_description: arbor_exception { bad_cell_description(cell_kind kind, cell_gid_type gid); cell_gid_type gid; diff --git a/arbor/lif_cell_group.cpp b/arbor/lif_cell_group.cpp index c87c6692a07006eb7289cb99bc28c124a47f054c..1ec02ba98de55500c8770317577f0deecff162a4 100644 --- a/arbor/lif_cell_group.cpp +++ b/arbor/lif_cell_group.cpp @@ -1,3 +1,5 @@ +#include <arbor/arbexcept.hpp> + #include <lif_cell_group.hpp> #include "profile/profiler_macro.hpp" @@ -9,6 +11,11 @@ using namespace arb; lif_cell_group::lif_cell_group(const std::vector<cell_gid_type>& gids, const recipe& rec): gids_(gids) { + for (auto gid: gids_) { + if (!rec.get_probes(gid).empty()) { + throw bad_cell_probe(cell_kind::lif, gid); + } + } // Default to no binning of events set_binning_policy(binning_kind::none, 0); diff --git a/arbor/spike_source_cell_group.cpp b/arbor/spike_source_cell_group.cpp index 7abba54e961ed85e6509f7bf4529a6118b3d2a40..025d94e9a28677ed847ebba74bd14afc7c68977e 100644 --- a/arbor/spike_source_cell_group.cpp +++ b/arbor/spike_source_cell_group.cpp @@ -15,6 +15,12 @@ namespace arb { spike_source_cell_group::spike_source_cell_group(const std::vector<cell_gid_type>& gids, const recipe& rec): gids_(gids) { + for (auto gid: gids_) { + if (!rec.get_probes(gid).empty()) { + throw bad_cell_probe(cell_kind::spike_source, gid); + } + } + time_sequences_.reserve(gids_.size()); for (auto gid: gids_) { try { diff --git a/test/unit/test_lif_cell_group.cpp b/test/unit/test_lif_cell_group.cpp index 1041705f4542bd4f0faf813ef853dd3665ea35ef..664f7d8876eb930a7337e4c5f430064cbbe00818 100644 --- a/test/unit/test_lif_cell_group.cpp +++ b/test/unit/test_lif_cell_group.cpp @@ -1,5 +1,7 @@ #include "../gtest.h" +#include <arbor/arbexcept.hpp> +#include <arbor/cable_cell.hpp> #include <arbor/domain_decomposition.hpp> #include <arbor/lif_cell.hpp> #include <arbor/load_balance.hpp> @@ -122,6 +124,40 @@ private: float weight_, delay_; }; +// LIF cell with probe +class probe_recipe: public arb::recipe { +public: + probe_recipe() {} + + cell_size_type num_cells() const override { + return 1; + } + cell_kind get_cell_kind(cell_gid_type gid) const override { + return cell_kind::lif; + } + std::vector<cell_connection> connections_on(cell_gid_type gid) const override { + return {}; + } + util::unique_any get_cell_description(cell_gid_type gid) const override { + return lif_cell(); + } + cell_size_type num_sources(cell_gid_type) const override { + return 1; + } + cell_size_type num_targets(cell_gid_type) const override { + return 1; + } + std::vector<probe_info> get_probes(cell_gid_type gid) const override{ + return {arb::cable_probe_membrane_voltage{mlocation{0, 0}}}; + } +}; +TEST(lif_cell_group, throw) { + probe_recipe rec; + auto context = make_context(); + auto decomp = partition_load_balance(rec, context); + EXPECT_THROW(simulation(rec, decomp, context), bad_cell_probe); +} + TEST(lif_cell_group, recipe) { ring_recipe rr(100, 1, 0.1);