diff --git a/arbor/fvm_lowered_cell_impl.hpp b/arbor/fvm_lowered_cell_impl.hpp index 2e5574fc271aedbbdb4e708c5566791fa2d851d3..3badb637e571c9a2d11f6193b07f2283c2887224 100644 --- a/arbor/fvm_lowered_cell_impl.hpp +++ b/arbor/fvm_lowered_cell_impl.hpp @@ -443,9 +443,13 @@ void fvm_lowered_cell_impl<B>::initialize( // (builtin stimulus, for example, has no targets) if (!config.target.empty()) { - for (auto j: make_span(multiplicity_part[i])) { - target_handles[config.target[j]] = target_handle(mech_id, i, cv_to_intdom[cv]); - } + if(!config.multiplicity.empty()) { + for (auto j: make_span(multiplicity_part[i])) { + target_handles[config.target[j]] = target_handle(mech_id, i, cv_to_intdom[cv]); + } + } else { + target_handles[config.target[i]] = target_handle(mech_id, i, cv_to_intdom[cv]); + }; } } } diff --git a/test/simple_recipes.hpp b/test/simple_recipes.hpp index 6dded63c62e2b721f48bad2547294cb28af764b1..b92ae176642c9f3df4f3d47336b954aae22f2a5d 100644 --- a/test/simple_recipes.hpp +++ b/test/simple_recipes.hpp @@ -92,15 +92,17 @@ protected: class cable1d_recipe: public simple_recipe_base { public: template <typename Seq> - explicit cable1d_recipe(const Seq& cells) { + explicit cable1d_recipe(const Seq& cells, bool coalesce = true) { for (const auto& c: cells) { cells_.emplace_back(c); } + cell_gprop_.coalesce_synapses = coalesce; } - explicit cable1d_recipe(const cable_cell& c) { + explicit cable1d_recipe(const cable_cell& c, bool coalesce = true) { cells_.reserve(1); cells_.emplace_back(c); + cell_gprop_.coalesce_synapses = coalesce; } cell_size_type num_cells() const override { return cells_.size(); } diff --git a/test/unit/test_fvm_layout.cpp b/test/unit/test_fvm_layout.cpp index a4a1541fb9e0be6a8d9ac88e408e72fb021bf539..9731ff5603bb485ceac10b1ee82a14c2aba630cc 100644 --- a/test/unit/test_fvm_layout.cpp +++ b/test/unit/test_fvm_layout.cpp @@ -352,6 +352,7 @@ TEST(fvm_layout, coalescing_synapses) { { cable_cell cell = make_cell_ball_and_stick(); + bool coalesce_synapses = true; // Add synapses of two varieties. cell.add_synapse({1, 0.3}, "expsyn"); @@ -360,7 +361,7 @@ TEST(fvm_layout, coalescing_synapses) { cell.add_synapse({1, 0.9}, "expsyn"); fvm_discretization D = fvm_discretize({cell}); - fvm_mechanism_data M = fvm_build_mechanism_data(global_default_catalogue(), {cell}, D); + fvm_mechanism_data M = fvm_build_mechanism_data(global_default_catalogue(), {cell}, D, coalesce_synapses); auto &expsyn_config = M.mechanisms.at("expsyn"); EXPECT_EQ(ivec({1, 2, 3, 4}), expsyn_config.cv); @@ -368,6 +369,7 @@ TEST(fvm_layout, coalescing_synapses) { } { cable_cell cell = make_cell_ball_and_stick(); + bool coalesce_synapses = true; // Add synapses of two varieties. cell.add_synapse({1, 0.3}, "expsyn"); @@ -376,7 +378,7 @@ TEST(fvm_layout, coalescing_synapses) { cell.add_synapse({1, 0.9}, "exp2syn"); fvm_discretization D = fvm_discretize({cell}); - fvm_mechanism_data M = fvm_build_mechanism_data(global_default_catalogue(), {cell}, D); + fvm_mechanism_data M = fvm_build_mechanism_data(global_default_catalogue(), {cell}, D, coalesce_synapses); auto &expsyn_config = M.mechanisms.at("expsyn"); EXPECT_EQ(ivec({1, 3}), expsyn_config.cv); @@ -386,6 +388,44 @@ TEST(fvm_layout, coalescing_synapses) { EXPECT_EQ(ivec({2, 4}), exp2syn_config.cv); EXPECT_EQ(ivec({1, 1}), exp2syn_config.multiplicity); } + { + cable_cell cell = make_cell_ball_and_stick(); + bool coalesce_synapses = false; + + // Add synapses of two varieties. + cell.add_synapse({1, 0.3}, "expsyn"); + cell.add_synapse({1, 0.5}, "expsyn"); + cell.add_synapse({1, 0.7}, "expsyn"); + cell.add_synapse({1, 0.9}, "expsyn"); + + fvm_discretization D = fvm_discretize({cell}); + fvm_mechanism_data M = fvm_build_mechanism_data(global_default_catalogue(), {cell}, D, coalesce_synapses); + + auto &expsyn_config = M.mechanisms.at("expsyn"); + EXPECT_EQ(ivec({1, 2, 3, 4}), expsyn_config.cv); + EXPECT_TRUE(expsyn_config.multiplicity.empty()); + } + { + cable_cell cell = make_cell_ball_and_stick(); + bool coalesce_synapses = false; + + // Add synapses of two varieties. + cell.add_synapse({1, 0.3}, "expsyn"); + cell.add_synapse({1, 0.5}, "exp2syn"); + cell.add_synapse({1, 0.7}, "expsyn"); + cell.add_synapse({1, 0.9}, "exp2syn"); + + fvm_discretization D = fvm_discretize({cell}); + fvm_mechanism_data M = fvm_build_mechanism_data(global_default_catalogue(), {cell}, D, coalesce_synapses); + + auto &expsyn_config = M.mechanisms.at("expsyn"); + EXPECT_EQ(ivec({1, 3}), expsyn_config.cv); + EXPECT_TRUE(expsyn_config.multiplicity.empty()); + + auto &exp2syn_config = M.mechanisms.at("exp2syn"); + EXPECT_EQ(ivec({2, 4}), exp2syn_config.cv); + EXPECT_TRUE(exp2syn_config.multiplicity.empty()); + } { cable_cell cell = make_cell_ball_and_stick(); diff --git a/test/unit/test_fvm_lowered.cpp b/test/unit/test_fvm_lowered.cpp index 59fa34d1df9b66e0934dcc4378ccb2d82249c5f8..34adc17e0b2c4f75bd3f288bf13adc4dfa25d658 100644 --- a/test/unit/test_fvm_lowered.cpp +++ b/test/unit/test_fvm_lowered.cpp @@ -263,34 +263,42 @@ TEST(fvm_lowered, target_handles) { std::vector<fvm_index_type> cell_to_intdom; probe_association_map<probe_handle> probe_map; - fvm_cell fvcell(context); - fvcell.initialize({0, 1}, cable1d_recipe(cells), cell_to_intdom, targets, probe_map); + auto test_target_handles = [&](fvm_cell& cell) { + mechanism *expsyn = find_mechanism(cell, "expsyn"); + ASSERT_TRUE(expsyn); + mechanism *exp2syn = find_mechanism(cell, "exp2syn"); + ASSERT_TRUE(exp2syn); + + unsigned expsyn_id = expsyn->mechanism_id(); + unsigned exp2syn_id = exp2syn->mechanism_id(); - mechanism* expsyn = find_mechanism(fvcell, "expsyn"); - ASSERT_TRUE(expsyn); - mechanism* exp2syn = find_mechanism(fvcell, "exp2syn"); - ASSERT_TRUE(exp2syn); + EXPECT_EQ(4u, targets.size()); - unsigned expsyn_id = expsyn->mechanism_id(); - unsigned exp2syn_id = exp2syn->mechanism_id(); + EXPECT_EQ(expsyn_id, targets[0].mech_id); + EXPECT_EQ(1u, targets[0].mech_index); + EXPECT_EQ(0u, targets[0].intdom_index); - EXPECT_EQ(4u, targets.size()); + EXPECT_EQ(expsyn_id, targets[1].mech_id); + EXPECT_EQ(0u, targets[1].mech_index); + EXPECT_EQ(0u, targets[1].intdom_index); - EXPECT_EQ(expsyn_id, targets[0].mech_id); - EXPECT_EQ(1u, targets[0].mech_index); - EXPECT_EQ(0u, targets[0].intdom_index); + EXPECT_EQ(exp2syn_id, targets[2].mech_id); + EXPECT_EQ(0u, targets[2].mech_index); + EXPECT_EQ(1u, targets[2].intdom_index); + + EXPECT_EQ(expsyn_id, targets[3].mech_id); + EXPECT_EQ(2u, targets[3].mech_index); + EXPECT_EQ(1u, targets[3].intdom_index); + }; - EXPECT_EQ(expsyn_id, targets[1].mech_id); - EXPECT_EQ(0u, targets[1].mech_index); - EXPECT_EQ(0u, targets[1].intdom_index); + fvm_cell fvcell0(context); + fvcell0.initialize({0, 1}, cable1d_recipe(cells, true), cell_to_intdom, targets, probe_map); + test_target_handles(fvcell0); - EXPECT_EQ(exp2syn_id, targets[2].mech_id); - EXPECT_EQ(0u, targets[2].mech_index); - EXPECT_EQ(1u, targets[2].intdom_index); + fvm_cell fvcell1(context); + fvcell1.initialize({0, 1}, cable1d_recipe(cells, false), cell_to_intdom, targets, probe_map); + test_target_handles(fvcell1); - EXPECT_EQ(expsyn_id, targets[3].mech_id); - EXPECT_EQ(2u, targets[3].mech_index); - EXPECT_EQ(1u, targets[3].intdom_index); } TEST(fvm_lowered, stimulus) {