diff --git a/arbor/arbexcept.cpp b/arbor/arbexcept.cpp index e27f04fad7501d7e5358eca41fc10e2c7303c602..2a384b517110c12fa50a77f9a3a6eb0d91cdcbd6 100644 --- a/arbor/arbexcept.cpp +++ b/arbor/arbexcept.cpp @@ -43,22 +43,12 @@ bad_connection_source_lid::bad_connection_source_lid(cell_gid_type gid, cell_lid gid(gid), src_lid(src_lid), num_sources(num_sources) {} -bad_connection_target_gid::bad_connection_target_gid(cell_gid_type gid, cell_gid_type tgt_gid): - arbor_exception(pprintf("Model building error on cell {}: connection target gid {} has to match cell gid {}].", gid, tgt_gid, gid)), - gid(gid), tgt_gid(tgt_gid) -{} - bad_connection_target_lid::bad_connection_target_lid(cell_gid_type gid, cell_lid_type tgt_lid, cell_size_type num_targets): arbor_exception(pprintf("Model building error on cell {}: connection target index {} is out of range. Cell {} has {} targets", gid, tgt_lid, gid, num_targets) + (num_targets ? pprintf(", in the range [{}:{}].", 0, num_targets-1) : ".")), gid(gid), tgt_lid(tgt_lid), num_targets(num_targets) {} -bad_event_generator_target_gid::bad_event_generator_target_gid(cell_gid_type gid, cell_gid_type tgt_gid): - arbor_exception(pprintf("Model building error on cell {}: event_generator target gid {} has to match cell gid {}].", gid, tgt_gid, gid)), - gid(gid), tgt_gid(tgt_gid) -{} - bad_event_generator_target_lid::bad_event_generator_target_lid(cell_gid_type gid, cell_lid_type tgt_lid, cell_size_type num_targets): arbor_exception(pprintf("Model building error on cell {}: event_generator target index {} is out of range. Cell {} has {} targets", gid, tgt_lid, gid, num_targets) + (num_targets ? pprintf(", in the range [{}:{}].", 0, num_targets-1) : ".")), @@ -81,13 +71,6 @@ gj_unsupported_domain_decomposition::gj_unsupported_domain_decomposition(cell_gi gid_1(gid_1) {} -bad_gj_connection_gid::bad_gj_connection_gid(cell_gid_type gid, cell_gid_type site_0, cell_gid_type site_1): - arbor_exception(pprintf("Model building error on cell {}: recipe::gap_junctions_on(gid={}) -> cell {} <-> cell{}: one of the sites must be on the cell with gid = {})", gid, gid, site_0, site_1, gid)), - gid(gid), - site_0(site_0), - site_1(site_1) -{} - bad_gj_connection_lid::bad_gj_connection_lid(cell_gid_type gid, cell_member_type site): arbor_exception(pprintf("Model building error on cell {}: gap junction index {} on cell {} does not exist)", gid, site.gid, site.index)), gid(gid), diff --git a/arbor/communication/communicator.cpp b/arbor/communication/communicator.cpp index 032f09c43416a3f15d8f170175009fba4f4ccf34..b93638f82836d42484b1933341a5c81ed1e87790 100644 --- a/arbor/communication/communicator.cpp +++ b/arbor/communication/communicator.cpp @@ -87,11 +87,8 @@ communicator::communicator(const recipe& rec, if (c.source.index >= num_sources) { throw arb::bad_connection_source_lid(cell.gid, c.source.index, num_sources); } - if (c.dest.gid != cell.gid) { - throw arb::bad_connection_target_gid(cell.gid, c.dest.gid); - } - if (c.dest.index >= num_targets) { - throw arb::bad_connection_target_lid(cell.gid, c.dest.index, num_targets); + if (c.dest >= num_targets) { + throw arb::bad_connection_target_lid(cell.gid, c.dest, num_targets); } const auto src = dom_dec.gid_domain(c.source.gid); src_domains.push_back(src); diff --git a/arbor/connection.hpp b/arbor/connection.hpp index 4a9fe0fc35bb8341cceaac65fbdc53de73b30629..05be955685a27c19bfd0addb4cdc073ec3c19c96 100644 --- a/arbor/connection.hpp +++ b/arbor/connection.hpp @@ -11,7 +11,7 @@ class connection { public: connection() = default; connection( cell_member_type src, - cell_member_type dest, + cell_lid_type dest, float w, float d, cell_gid_type didx=cell_gid_type(-1)): @@ -26,7 +26,7 @@ public: time_type delay() const { return delay_; } cell_member_type source() const { return source_; } - cell_member_type destination() const { return destination_; } + cell_lid_type destination() const { return destination_; } cell_size_type index_on_domain() const { return index_on_domain_; } spike_event make_event(const spike& s) { @@ -35,7 +35,7 @@ public: private: cell_member_type source_; - cell_member_type destination_; + cell_lid_type destination_; float weight_; float delay_; cell_size_type index_on_domain_; diff --git a/arbor/fvm_lowered_cell_impl.hpp b/arbor/fvm_lowered_cell_impl.hpp index 6086383fcf2483e62d512fc5a27dfabda90aafc9..8bdc287daa9c2e87dff461d0757b43bd4694d598 100644 --- a/arbor/fvm_lowered_cell_impl.hpp +++ b/arbor/fvm_lowered_cell_impl.hpp @@ -644,20 +644,14 @@ std::vector<fvm_gap_junction> fvm_lowered_cell_impl<Backend>::fvm_gap_junctions( for (auto gid: gids) { auto gj_list = rec.gap_junctions_on(gid); for (auto g: gj_list) { - if (gid != g.local.gid && gid != g.peer.gid) { - throw arb::bad_gj_connection_gid(gid, g.local.gid, g.peer.gid); - } - if (g.local.index >= gid_to_cvs[g.local.gid].size()) { - throw arb::bad_gj_connection_lid(gid, g.local); + if (g.local >= gid_to_cvs[gid].size()) { + throw arb::bad_gj_connection_lid(gid, {gid, g.local}); } if (g.peer.index >= gid_to_cvs[g.peer.gid].size()) { throw arb::bad_gj_connection_lid(gid, g.peer); } - auto cv0 = gid_to_cvs[g.local.gid][g.local.index]; + auto cv0 = gid_to_cvs[gid][g.local]; auto cv1 = gid_to_cvs[g.peer.gid][g.peer.index]; - if (gid != g.local.gid) { - std::swap(cv0, cv1); - } v.push_back(fvm_gap_junction(std::make_pair(cv0, cv1), g.ggap * 1e3 / D.cv_area[cv0])); } } @@ -694,18 +688,13 @@ fvm_size_type fvm_lowered_cell_impl<Backend>::fvm_intdom( cell_to_intdom[gid_to_loc[g]] = intdom_id; for (auto gj: rec.gap_junctions_on(g)) { - cell_gid_type peer = - gj.local.gid==g? gj.peer.gid: - gj.peer.gid==g? gj.local.gid: - throw bad_cell_description(cell_kind::cable, g); - - if (!gid_to_loc.count(peer)) { - throw gj_unsupported_domain_decomposition(g, peer); + if (!gid_to_loc.count(gj.peer.gid)) { + throw gj_unsupported_domain_decomposition(g, gj.peer.gid); } - if (!visited.count(peer)) { - visited.insert(peer); - intdomq.push(peer); + if (!visited.count(gj.peer.gid)) { + visited.insert(gj.peer.gid); + intdomq.push(gj.peer.gid); } } } diff --git a/arbor/include/arbor/arbexcept.hpp b/arbor/include/arbor/arbexcept.hpp index 814c628fc98e96e405727cf2ff680f95eb627ff7..2cc0c5ed2d9c872e5bea074ceffa7f2daf82fada 100644 --- a/arbor/include/arbor/arbexcept.hpp +++ b/arbor/include/arbor/arbexcept.hpp @@ -67,11 +67,6 @@ struct bad_connection_source_lid: arbor_exception { cell_size_type num_sources; }; -struct bad_connection_target_gid: arbor_exception { - bad_connection_target_gid(cell_gid_type gid, cell_gid_type tgt_gid); - cell_gid_type gid, tgt_gid; -}; - struct bad_connection_target_lid: arbor_exception { bad_connection_target_lid(cell_gid_type gid, cell_lid_type tgt_lid, cell_size_type num_targets); cell_gid_type gid; @@ -79,11 +74,6 @@ struct bad_connection_target_lid: arbor_exception { cell_size_type num_targets; }; -struct bad_event_generator_target_gid: arbor_exception { - bad_event_generator_target_gid(cell_gid_type gid, cell_gid_type tgt_gid); - cell_gid_type gid, tgt_gid; -}; - struct bad_event_generator_target_lid: arbor_exception { bad_event_generator_target_lid(cell_gid_type gid, cell_lid_type tgt_lid, cell_size_type num_targets); cell_gid_type gid; @@ -106,11 +96,6 @@ struct gj_kind_mismatch: arbor_exception { cell_gid_type gid_0, gid_1; }; -struct bad_gj_connection_gid: arbor_exception { - bad_gj_connection_gid(cell_gid_type gid, cell_gid_type site_0, cell_gid_type site_1); - cell_gid_type gid, site_0, site_1; -}; - struct bad_gj_connection_lid: arbor_exception { bad_gj_connection_lid(cell_gid_type gid, cell_member_type site); cell_gid_type gid; diff --git a/arbor/include/arbor/event_generator.hpp b/arbor/include/arbor/event_generator.hpp index 4e526b58eb7c8f3460b724cb4c114fe148cd3757..95a524522ef695bd736c36d0d341de7e3483d08e 100644 --- a/arbor/include/arbor/event_generator.hpp +++ b/arbor/include/arbor/event_generator.hpp @@ -68,7 +68,7 @@ struct empty_generator { event_seq events(time_type, time_type) { return {nullptr, nullptr}; } - std::vector<cell_member_type> targets() { + std::vector<cell_lid_type> targets() { return {}; }; }; @@ -102,7 +102,7 @@ public: return impl_->events(t0, t1); } - std::vector<cell_member_type> targets() const { + std::vector<cell_lid_type> targets() const { return impl_->targets(); } @@ -110,7 +110,7 @@ private: struct interface { virtual void reset() = 0; virtual event_seq events(time_type, time_type) = 0; - virtual std::vector<cell_member_type> targets() = 0; + virtual std::vector<cell_lid_type> targets() = 0; virtual std::unique_ptr<interface> clone() = 0; virtual ~interface() {} }; @@ -126,7 +126,7 @@ private: return wrapped.events(t0, t1); } - std::vector<cell_member_type> targets() override { + std::vector<cell_lid_type> targets() override { return wrapped.targets(); } @@ -148,7 +148,7 @@ private: // a provided time schedule. struct schedule_generator { - schedule_generator(cell_member_type target, float weight, schedule sched): + schedule_generator(cell_lid_type target, float weight, schedule sched): target_(target), weight_(weight), sched_(std::move(sched)) {} @@ -169,13 +169,13 @@ struct schedule_generator { return {events_.data(), events_.data()+events_.size()}; } - std::vector<cell_member_type> targets() { + std::vector<cell_lid_type> targets() { return {target_}; } private: pse_vector events_; - cell_member_type target_; + cell_lid_type target_; float weight_; schedule sched_; }; @@ -183,7 +183,7 @@ private: // Generate events at integer multiples of dt that lie between tstart and tstop. inline event_generator regular_generator( - cell_member_type target, + cell_lid_type target, float weight, time_type tstart, time_type dt, @@ -194,7 +194,7 @@ inline event_generator regular_generator( template <typename RNG> inline event_generator poisson_generator( - cell_member_type target, + cell_lid_type target, float weight, time_type tstart, time_type rate_kHz, @@ -237,8 +237,8 @@ struct explicit_generator { return {lb, ub}; } - std::vector<cell_member_type> targets() { - std::vector<cell_member_type> tgts; + std::vector<cell_lid_type> targets() { + std::vector<cell_lid_type> tgts; std::transform(events_.begin(), events_.end(), std::back_inserter(tgts), [](auto&& e){ return e.target;}); return tgts; } diff --git a/arbor/include/arbor/recipe.hpp b/arbor/include/arbor/recipe.hpp index 3e8d834f9a2f27d82440ce30f580036b2951fcfe..63fe1a215d446acb1201644fc7cbb468adc53ea3 100644 --- a/arbor/include/arbor/recipe.hpp +++ b/arbor/include/arbor/recipe.hpp @@ -40,26 +40,25 @@ struct probe_info { struct cell_connection { // Connection end-points are represented by pairs // (cell index, source/target index on cell). - using cell_connection_endpoint = cell_member_type; - cell_connection_endpoint source; - cell_connection_endpoint dest; + cell_member_type source; + cell_lid_type dest; float weight; float delay; - cell_connection(cell_connection_endpoint src, cell_connection_endpoint dst, float w, float d): + cell_connection(cell_member_type src, cell_lid_type dst, float w, float d): source(src), dest(dst), weight(w), delay(d) {} }; struct gap_junction_connection { - cell_member_type local; cell_member_type peer; + cell_lid_type local; double ggap; - gap_junction_connection(cell_member_type local, cell_member_type peer, double g): - local(local), peer(peer), ggap(g) {} + gap_junction_connection(cell_member_type peer, cell_lid_type local, double g): + peer(peer), local(local), ggap(g) {} }; class recipe { diff --git a/arbor/include/arbor/simulation.hpp b/arbor/include/arbor/simulation.hpp index c26d022577f47837538686ff68953c79c8b3d74c..1f4afc6926803bb516e54f1af564854096dd74cb 100644 --- a/arbor/include/arbor/simulation.hpp +++ b/arbor/include/arbor/simulation.hpp @@ -59,7 +59,7 @@ public: // Add events directly to targets. // Must be called before calling simulation::run, and must contain events that // are to be delivered at or after the current simulation time. - void inject_events(const pse_vector& events); + void inject_events(const cse_vector& events); ~simulation(); diff --git a/arbor/include/arbor/spike_event.hpp b/arbor/include/arbor/spike_event.hpp index 2b72314c3ca3fce11f8dc61c09391f15fc8962e1..102f3c42403dc1402f5b1cfda2e0a2b399219c30 100644 --- a/arbor/include/arbor/spike_event.hpp +++ b/arbor/include/arbor/spike_event.hpp @@ -11,7 +11,7 @@ namespace arb { // Events delivered to targets on cells with a cell group. struct spike_event { - cell_member_type target; + cell_lid_type target; time_type time; float weight; @@ -26,6 +26,13 @@ struct spike_event { using pse_vector = std::vector<spike_event>; +struct cell_spike_events { + cell_gid_type target; + pse_vector events; +}; + +using cse_vector = std::vector<cell_spike_events>; + std::ostream& operator<<(std::ostream&, const spike_event&); } // namespace arb diff --git a/arbor/mc_cell_group.cpp b/arbor/mc_cell_group.cpp index 395f426e4b918f375caaf42315298f6476cd8962..3a0a27ed0a26ee0ba564a2a23bbe41d573f415d0 100644 --- a/arbor/mc_cell_group.cpp +++ b/arbor/mc_cell_group.cpp @@ -400,7 +400,7 @@ void mc_cell_group::advance(epoch ep, time_type dt, const event_lane_subrange& e for (auto e: lane) { if (e.time>=ep.t1) break; e.time = binners_[lid].bin(e.time, tstart); - auto h = target_handles_[target_handle_divisions_[lid]+e.target.index]; + auto h = target_handles_[target_handle_divisions_[lid]+e.target]; auto ev = deliverable_event(e.time, h, e.weight); staged_events_.push_back(ev); count_staged++; diff --git a/arbor/merge_events.cpp b/arbor/merge_events.cpp index 53dd901ffb5377f088ae645b088d6ef57e3a7060..90241cad646a2d1d55a20ded0501c45c488b6db5 100644 --- a/arbor/merge_events.cpp +++ b/arbor/merge_events.cpp @@ -17,7 +17,7 @@ namespace impl { // A postsynaptic spike event that has delivery time set to // terminal_time, used as a sentinel in `tourney_tree`. -static constexpr spike_event terminal_pse{cell_member_type{0,0}, terminal_time, 0}; +static constexpr spike_event terminal_pse{0, terminal_time, 0}; // The tournament tree data structure is used to merge k sorted lists of events. diff --git a/arbor/partition_load_balance.cpp b/arbor/partition_load_balance.cpp index e8fd413557355138f01db42c29b9d7e51f1b2644..f1f064b7957ec55f788e0f9e98d15ab85f853df7 100644 --- a/arbor/partition_load_balance.cpp +++ b/arbor/partition_load_balance.cpp @@ -92,14 +92,9 @@ domain_decomposition partition_load_balance( // Adjacency list auto conns = rec.gap_junctions_on(element); for (auto c: conns) { - if (element != c.local.gid && element != c.peer.gid) { - throw bad_gj_connection_gid(element, c.local.gid, c.peer.gid); - } - cell_member_type other = c.local.gid == element ? c.peer : c.local; - - if (!visited.count(other.gid)) { - visited.insert(other.gid); - q.push(other.gid); + if (!visited.count(c.peer.gid)) { + visited.insert(c.peer.gid); + q.push(c.peer.gid); } } } diff --git a/arbor/simulation.cpp b/arbor/simulation.cpp index 3ed22957fe32d674e22d6a94f7e462a3673d0706..231c7d9a1cf37f968c09873812d461532c6a64b4 100644 --- a/arbor/simulation.cpp +++ b/arbor/simulation.cpp @@ -110,7 +110,7 @@ public: void set_binning_policy(binning_kind policy, time_type bin_interval); - void inject_events(const pse_vector& events); + void inject_events(const cse_vector& events); spike_export_function global_export_callback_; spike_export_function local_export_callback_; @@ -208,11 +208,8 @@ simulation_state::simulation_state( auto num_targets = rec.num_targets(gid); for (const auto& g: event_gens) { for (const auto& t: g.targets()) { - if (t.gid != gid) { - throw arb::bad_event_generator_target_gid(gid, t.gid); - } - if (t.index >= num_targets) { - throw arb::bad_event_generator_target_lid(gid, t.index, num_targets); + if (t >= num_targets) { + throw arb::bad_event_generator_target_lid(gid, t, num_targets); } } } @@ -468,16 +465,18 @@ void simulation_state::set_binning_policy(binning_kind policy, time_type bin_int [&](cell_group_ptr& group) { group->set_binning_policy(policy, bin_interval); }); } -void simulation_state::inject_events(const pse_vector& events) { +void simulation_state::inject_events(const cse_vector& events) { // Push all events that are to be delivered to local cells into the // pending event list for the event's target cell. - for (auto& e: events) { - if (e.time<epoch_.t1) { - throw bad_event_time(e.time, epoch_.t1); - } - // gid_to_local_ maps gid to index in local cells and of corresponding cell group. - if (auto lidx = util::value_by_key(gid_to_local_, e.target.gid)) { - pending_events_[lidx->cell_index].push_back(e); + for (auto& [gid, pse_vector]: events) { + for (auto& e: pse_vector) { + if (e.time < epoch_.t1) { + throw bad_event_time(e.time, epoch_.t1); + } + // gid_to_local_ maps gid to index in local cells and of corresponding cell group. + if (auto lidx = util::value_by_key(gid_to_local_, gid)) { + pending_events_[lidx->cell_index].push_back(e); + } } } } @@ -537,7 +536,7 @@ void simulation::set_local_spike_callback(spike_export_function export_callback) impl_->local_export_callback_ = std::move(export_callback); } -void simulation::inject_events(const pse_vector& events) { +void simulation::inject_events(const cse_vector& events) { impl_->inject_events(events); } diff --git a/arbor/symmetric_recipe.cpp b/arbor/symmetric_recipe.cpp index 66b846f81e5aca781e336248ec9a95d2fd15e712..ccf9dec5083e79e41a3c0c7ea78db0268d0c0de1 100644 --- a/arbor/symmetric_recipe.cpp +++ b/arbor/symmetric_recipe.cpp @@ -39,7 +39,6 @@ std::vector<cell_connection> symmetric_recipe::connections_on(cell_gid_type i) c for (unsigned j = 0; j < conns.size(); j++) { conns[j].source.gid = (conns[j].source.gid + offset) % n_global; - conns[j].dest.gid = (conns[j].dest.gid + offset) % n_global; } return conns; } diff --git a/doc/concepts/interconnectivity.rst b/doc/concepts/interconnectivity.rst index 11caa96af5a38349dd18287e59e2214ab17a6947..73f9ca9cfac70f72a32d1005e725017fb54de761 100644 --- a/doc/concepts/interconnectivity.rst +++ b/doc/concepts/interconnectivity.rst @@ -53,8 +53,9 @@ A recipe lets you define which sites are connected to which. 1. Create a **gap junction site** on two separate cells as part of their :ref:`cell descriptions <modelcelldesc>` in the :ref:`recipe <modelrecipe>`. - 2. Declare the Gap Junction in the recipe: with two **gap junction sites** identified using :gen:`cell_member` - and a conductance in μS. + 2. Declare the Gap Junction connections in the recipe: between a peer and local **gap junction site** + identified using :gen:`cell_member` and a conductance in μS. Two of these connections are needed, + on each of the peer and local cells. .. Note:: Only cable cells support gap junctions as of now. diff --git a/doc/cpp/interconnectivity.rst b/doc/cpp/interconnectivity.rst index 266708a7503ea3a52da30ba40da2487f2f4af6be..3ac0dc43cee374f2db241c78e5bce6b0789d8667 100644 --- a/doc/cpp/interconnectivity.rst +++ b/doc/cpp/interconnectivity.rst @@ -9,18 +9,17 @@ Interconnectivity post-synaptic destination. The source is typically a threshold detector on a cell or a spike source. The destination is a synapse on the post-synaptic cell. - .. cpp:type:: cell_connection_endpoint = cell_member_type + The :cpp:member:`dest` does not include the gid of a cell, this is because a + :cpp:class:`cell_connection` is bound to the destination cell which means that the gid + is implicitly known. - Connection end-points are represented by pairs - (cell index, source/target index on cell). + .. cpp:member:: cell_member_type source - .. cpp:member:: cell_connection_endpoint source + Source end point, represented by the pair (cell gid, source index on the cell) - Source end point. + .. cpp:member:: cell_lid_type dest - .. cpp:member:: cell_connection_endpoint dest - - Destination end point. + Destination target index on the cell, target cell's gid is implicitly known. .. cpp:member:: float weight @@ -36,16 +35,25 @@ Interconnectivity .. cpp:class:: gap_junction_connection - Describes a gap junction between two gap junction sites. - Gap junction sites are represented by :cpp:type:cell_member_type. + Describes a gap junction between two gap junction sites. The :cpp:member:`local` site does not include + the gid of a cell, this is because a :cpp:class:`gap_junction_connection` is bound to the local + cell which means that the gid is implicitly known. - .. cpp:member:: cell_member_type local + .. note:: - gap junction site: one half of the gap junction connection. + A bidirectional gap-junction between two cells ``c0`` and ``c1`` requires two + :cpp:class:`gap_junction_connection` objects to be constructed: one where ``c0`` is the + :cpp:member:`local` site, and ``c1`` is the :cpp:member:`peer` site; and another where ``c1`` is the + :cpp:member:`local` site, and ``c0`` is the :cpp:member:`peer` site. If :cpp:member:`ggap` is equal + in both connections, a symmetric gap-junction is formed, other wise the gap-junction is asymmetric. .. cpp:member:: cell_member_type peer - gap junction site: other half of the gap junction connection. + Peer gap junction site, represented by the pair (cell gid, gap junction site index on the cell) + + .. cpp:member:: cell_lid_type local + + Local gap junction site index on the cell, the gid of the local site's cell is implicitly known. .. cpp:member:: float ggap diff --git a/doc/cpp/recipe.rst b/doc/cpp/recipe.rst index a71c290f38b11e24897066d0ae6997234d3cc3fc..5660894e4f66f67976cc93924b4aad0040feb75a 100644 --- a/doc/cpp/recipe.rst +++ b/doc/cpp/recipe.rst @@ -74,8 +74,8 @@ Recipe .. cpp:function:: virtual std::vector<cell_connection> connections_on(cell_gid_type gid) const Returns a list of all the **incoming** connections for `gid` . - Each connection ``con`` should have post-synaptic target ``con.dest.gid`` that matches - the argument :cpp:any:`gid`, and a valid synapse id ``con.dest.index`` on `gid`. + Each connection ``con`` should have a valid synapse id ``con.dest`` on the post-synaptic target `gid`, + and a valid source id ``con.source.index`` on the pre-synaptic source ``con.source.gid``. See :cpp:type:`cell_connection`. By default returns an empty list. @@ -83,9 +83,8 @@ Recipe .. cpp:function:: virtual std::vector<gap_junction_connection> gap_junctions_on(cell_gid_type gid) const Returns a list of all the gap junctions connected to `gid`. - Each gap junction ``gj`` should have one of the two gap junction sites ``gj.local.gid`` or - ``gj.peer.gid`` matching the argument :cpp:any:`gid`, and the corresponding synapse id - ``gj.local.index`` or ``gj.peer.index`` should be valid on `gid`. + Each gap junction ``gj`` should have a valid gap junction site id ``gj.local`` on ``gid``, + and a valid gap junction site id ``gj.peer.index`` on ``gj.peer.gid``. See :cpp:type:`gap_junction_connection`. By default returns an empty list. diff --git a/doc/python/cell.rst b/doc/python/cell.rst index ca1d1df158e14c8bbd22686051f1053dbca37d0c..e89d472f3f6749e1cb229f2bb436d5a975fb3093 100644 --- a/doc/python/cell.rst +++ b/doc/python/cell.rst @@ -23,7 +23,7 @@ The types defined below are used as identifiers for cells and members of cell-lo An example is uniquely identifying a synapse in the model. Each synapse has a post-synaptic cell (with :attr:`gid`), and an :attr:`index` into the set of synapses on the post-synaptic cell. - Lexographically ordered by :attr:`gid`, then :attr:`index`. + Lexicographically ordered by :attr:`gid`, then :attr:`index`. .. attribute:: gid diff --git a/doc/python/interconnectivity.rst b/doc/python/interconnectivity.rst index 430496f28d9c7bf5c28e073d783f1bff3840ac8f..944825a2a981abe120a2efefc41bfe0a839180a4 100644 --- a/doc/python/interconnectivity.rst +++ b/doc/python/interconnectivity.rst @@ -10,6 +10,9 @@ Interconnectivity Describes a connection between two cells, defined by source and destination end points (that is pre-synaptic and post-synaptic respectively), a connection weight and a delay time. + The :attr:`dest` does not include the gid of a cell, this is because a :class:`arbor.connection` is bound to the destination cell which means that the gid + is implicitly known. + .. function:: connection(source, destination, weight, delay) Construct a connection between the :attr:`source` and the :attr:`dest` with a :attr:`weight` and :attr:`delay`. @@ -20,7 +23,8 @@ Interconnectivity .. attribute:: dest - The destination end point of the connection (type: :class:`arbor.cell_member`, which can be initialized with a (gid, index) tuple). + The destination end point of the connection (type: :class:`arbor.cell_member.index` representing the index of the destination on the cell). + The gid of the cell is implicitly known. .. attribute:: weight @@ -40,29 +44,43 @@ Interconnectivity import arbor - # construct a connection between cells (0,0) and (1,0) with weight 0.01 and delay of 10 ms. - src = arbor.cell_member(0,0) - dest = arbor.cell_member(1,0) - w = 0.01 - d = 10 - con = arbor.connection(src, dest, w, d) + def connections_on(gid): + # construct a connection from the 0th source index of cell 2 (2,0) + # to the 1st target index of cell gid (gid,1) with weight 0.01 and delay of 10 ms. + src = arbor.cell_member(2,0) + dest = 1 # gid of the destination is is determined by the argument to `connections_on` + w = 0.01 + d = 10 + return [arbor.connection(src, dest, w, d)] .. class:: gap_junction_connection - Describes a gap junction between two gap junction sites. - Gap junction sites are represented by :class:`arbor.cell_member`. + Describes a gap junction between two gap junction sites. Gap junction sites are identified by :class:`arbor.cell_member`. - .. function::gap_junction_connection(local, peer, ggap) + The :attr:`local` site does not include the gid of a cell, this is because a :class:`arbor.gap_junction_connection` is bound to + the destination cell which means that the gid is implicitly known. - Construct a gap junction connection between :attr:`local` and :attr:`peer` with conductance :attr:`ggap`. + .. note:: - .. attribute:: local + A bidirectional gap-junction between two cells ``c0`` and ``c1`` requires two + :class:`gap_junction_connection` objects to be constructed: one where ``c0`` is the + :attr:`local` site, and ``c1`` is the :attr:`peer` site; and another where ``c1`` is the + :attr:`local` site, and ``c0`` is the :attr:`peer` site. If :attr:`ggap` is equal + in both connections, a symmetric gap-junction is formed, other wise the gap-junction is asymmetric. + + .. function::gap_junction_connection(peer, local, ggap) - The gap junction site: one half of the gap junction connection. + Construct a gap junction connection between :attr:`peer` and :attr:`local` with conductance :attr:`ggap`. .. attribute:: peer - The gap junction site: other half of the gap junction connection. + The gap junction site: the remote half of the gap junction connection (type: :class:`arbor.cell_member`, + which can be initialized with a (gid, index) tuple). + + .. attribute:: local + + The gap junction site: the local half of the gap junction connection (type: :class:`arbor.cell_member.index`, representing + the index of the local site on the cell). The gid of the cell is implicitly known. .. attribute:: ggap diff --git a/doc/python/recipe.rst b/doc/python/recipe.rst index 0a945d5f80f677e321cb236f292a0c29bdf0a472..ecdea890931c35597328758123c4c953228bc361 100644 --- a/doc/python/recipe.rst +++ b/doc/python/recipe.rst @@ -33,11 +33,11 @@ Recipe .. function:: cell_kind(gid) - The cell kind of the cell with global identifier :attr:`arbor.cell_member.gid` (return type: :class:`arbor.cell_kind`). + The cell kind of the cell with global identifier ``gid`` (return type: :class:`arbor.cell_kind`). .. function:: cell_description(gid) - A high level description of the cell with global identifier :attr:`arbor.cell_member.gid`, + A high level description of the cell with global identifier ``gid``, for example the morphology, synapses and ion channels required to build a multi-compartment neuron. The type used to describe a cell depends on the kind of the cell. The interface for querying the kind and description of a cell are separate @@ -48,45 +48,43 @@ Recipe .. function:: connections_on(gid) - Returns a list of all the **incoming** connections to :attr:`arbor.cell_member.gid`. - Each connection should have post-synaptic target ``connection.dest.gid`` - that matches the argument :attr:`arbor.cell_member.gid`, - and a valid synapse id ``connection.dest.index`` on :attr:`arbor.cell_member.gid`. + Returns a list of all the **incoming** connections to ``gid``. + Each connection should have a valid synapse id ``connection.dest`` on the post-synaptic target ``gid``, + and a valid source id ``connection.source.index`` on the pre-synaptic source ``connection.source.gid``. See :class:`connection`. By default returns an empty list. .. function:: gap_junctions_on(gid) - Returns a list of all the gap junctions connected to :attr:`arbor.cell_member.gid`. - Each gap junction ``gj`` should have one of the two gap junction sites ``gj.local.gid`` - or ``gj.peer.gid`` matching the argument :attr:`arbor.cell_member.gid`, - and the corresponding synapse id ``gj.local.index`` or ``gj.peer.index`` should be valid on :attr:`arbor.cell_member.gid`. + Returns a list of all the gap junctions connected to ``gid``. + Each gap junction ``gj`` should have a valid gap junction site id ``gj.local`` on ``gid``, + and a valid gap junction site id ``gj.peer.index`` on ``gj.peer.gid``. See :class:`gap_junction_connection`. By default returns an empty list. .. function:: event_generators(gid) - A list of all the :class:`event_generator` s that are attached to :attr:`arbor.cell_member.gid`. + A list of all the :class:`event_generator` s that are attached to ``gid``. By default returns an empty list. .. function:: num_sources(gid) - The number of spike sources on :attr:`arbor.cell_member.gid`. + The number of spike sources on ``gid``. By default returns 0. .. function:: num_targets(gid) - The number of post-synaptic sites on :attr:`arbor.cell_member.gid`, which corresponds to the number of synapses. + The number of post-synaptic sites on ``gid``, which corresponds to the number of synapses. By default returns 0. .. function:: num_gap_junction_sites(gid) - Returns the number of gap junction sites on :attr:`arbor.cell_member.gid`. + Returns the number of gap junction sites on ``gid``. By default returns 0. @@ -132,7 +130,7 @@ Event generator and schedules .. attribute:: target - The target synapse of type :class:`arbor.cell_member`. + The target synapse of type :class:`arbor.cell_member.index`. .. attribute:: weight @@ -222,15 +220,16 @@ An example of an event generator reads as follows: # define a Poisson schedule with start time 1 ms, expected frequency of 5 Hz, # and the target cell's gid as seed - target = arbor.cell_member(0,0) - seed = target.gid - tstart = 1 - freq = 0.005 - sched = arbor.poisson_schedule(tstart, freq, seed) + def event_generators(gid): + target = 0 # index of the synapse on target cell gid + seed = gid + tstart = 1 + freq = 0.005 + sched = arbor.poisson_schedule(tstart, freq, seed) - # construct an event generator with this schedule on target cell and weight 0.1 - w = 0.1 - gen = arbor.event_generator(target, w, sched) + # construct an event generator with this schedule on target cell and weight 0.1 + w = 0.1 + return [arbor.event_generator(target, w, sched)] Example ------- @@ -280,13 +279,13 @@ helpers in cell_parameters and make_cable_cell for building cells are used. src = (gid-1)%self.ncells w = 0.01 d = 10 - return [arbor.connection(arbor.cell_member(src,0), arbor.cell_member(gid,0), w, d)] + return [arbor.connection(arbor.cell_member(src,0), 0, w, d)] # Attach a generator to the first cell in the ring. def event_generators(self, gid): if gid==0: sched = arbor.explicit_schedule([1]) - return [arbor.event_generator(arbor.cell_member(0,0), 0.1, sched)] + return [arbor.event_generator(0, 0.1, sched)] return [] def get_probes(self, id): diff --git a/doc/tutorial/network_ring.rst b/doc/tutorial/network_ring.rst index a7cbe4be120ec3000958715dc2d411717f31cdd7..d0db20cfe192b959ec64eef73dba2fdd8b98b51f 100644 --- a/doc/tutorial/network_ring.rst +++ b/doc/tutorial/network_ring.rst @@ -102,7 +102,9 @@ to :py:class:`arbor.connection` are the **source** and **target** of the connect cell index ``gid`` and the source or target index. (:term:`Remember <connection>` that sources and targets are separately indexed.) -The two endpoints are of type :class:`arbor.cell_member`, and can be initialized with a ``(gid,index)`` tuple. +The source endpoint has type :class:`arbor.cell_member`, and can be initialized with a ``(gid,index)`` tuple. +The gid of the target end-point is implicitly known from the argument of :py:func:`arbor.recipe.connections_on`, +Therefore, we only need to identify the index of the target on the cell using the :class:`arbor.cell_member.index` type. The cells have one synapse (step **3**), so the target endpoint has the 0th index. The cell has one spike generator (step **4**), so its source index is also 0. diff --git a/example/bench/bench.cpp b/example/bench/bench.cpp index ab5912e70ed54a00e08c9ba563de96eff7abf90d..43df04e0e828b30f92ceb4079cb77a09aaf079e3 100644 --- a/example/bench/bench.cpp +++ b/example/bench/bench.cpp @@ -134,7 +134,7 @@ public: arb::cell_gid_type src = dist(rng); if (src>=gid) ++src; // Note: target is {gid, 0}, i.e. the first (and only) target on the cell. - arb::cell_connection con({src, 0}, {gid, 0}, 1.f, params_.network.min_delay); + arb::cell_connection con({src, 0}, 0, 1.f, params_.network.min_delay); cons.push_back(con); } diff --git a/example/brunel/brunel.cpp b/example/brunel/brunel.cpp index 7f208844d08b79dcbe5346a32245727de5483739..8084baaa70d393150daa12d204250806168bfabc 100644 --- a/example/brunel/brunel.cpp +++ b/example/brunel/brunel.cpp @@ -119,12 +119,12 @@ public: std::vector<cell_connection> connections; // Add incoming excitatory connections. for (auto i: sample_subset(gid, 0, ncells_exc_, in_degree_exc_)) { - connections.push_back({{cell_gid_type(i), 0}, {gid, 0}, weight_exc_, delay_}); + connections.push_back({{cell_gid_type(i), 0}, 0, weight_exc_, delay_}); } // Add incoming inhibitory connections. for (auto i: sample_subset(gid, ncells_exc_, ncells_exc_ + ncells_inh_, in_degree_inh_)) { - connections.push_back({{cell_gid_type(i), 0}, {gid, 0}, weight_inh_, delay_}); + connections.push_back({{cell_gid_type(i), 0}, 0, weight_inh_, delay_}); } return connections; } @@ -145,7 +145,7 @@ public: std::mt19937_64 G; G.seed(gid + seed_); time_type t0 = 0; - return {poisson_generator({gid, 0}, weight_ext_, t0, lambda_, G)}; + return {poisson_generator(0, weight_ext_, t0, lambda_, G)}; } cell_size_type num_sources(cell_gid_type) const override { diff --git a/example/dryrun/dryrun.cpp b/example/dryrun/dryrun.cpp index 458938e7c0d7f0784a4febf7dfbd7dacea87d0ed..a743ac753983a5dcff0aa913fd886b5ac2419f73 100644 --- a/example/dryrun/dryrun.cpp +++ b/example/dryrun/dryrun.cpp @@ -108,7 +108,7 @@ public: auto src = source_distribution(src_gen); if (src>=gid) ++src; - return {arb::cell_connection({src, 0}, {gid, 0}, event_weight_, min_delay_)}; + return {arb::cell_connection({src, 0}, 0, event_weight_, min_delay_)}; } // Return an event generator on every 20th gid. This function needs to generate events @@ -117,7 +117,7 @@ public: std::vector<arb::event_generator> event_generators(cell_gid_type gid) const override { std::vector<arb::event_generator> gens; if (gid%20 == 0) { - gens.push_back(arb::explicit_generator(arb::pse_vector{{{gid, 0}, 1.0, event_weight_}})); + gens.push_back(arb::explicit_generator(arb::pse_vector{{0, 1.0, event_weight_}})); } return gens; } diff --git a/example/gap_junctions/gap_junctions.cpp b/example/gap_junctions/gap_junctions.cpp index 323d7667bac3b96d864d63e4ed21375bb1e2f0ec..4c16d2bcb95665d0aec2a41ea528c28753d41a2d 100644 --- a/example/gap_junctions/gap_junctions.cpp +++ b/example/gap_junctions/gap_junctions.cpp @@ -91,7 +91,7 @@ public: if(gid % params_.n_cells_per_cable || (int)gid - 1 < 0) { return{}; } - return {arb::cell_connection({gid - 1, 0}, {gid, 0}, params_.event_weight, params_.event_min_delay)}; + return {arb::cell_connection({gid - 1, 0}, 0, params_.event_weight, params_.event_min_delay)}; } std::vector<arb::probe_info> get_probes(cell_gid_type gid) const override { @@ -121,10 +121,10 @@ public: // Gap junction conductance in μS if (next_cell < cable_end) { - conns.push_back(arb::gap_junction_connection({(cell_gid_type)next_cell, 0}, {gid, 1}, 0.015)); + conns.push_back(arb::gap_junction_connection({(cell_gid_type)next_cell, 0}, 1, 0.015)); } if (prev_cell >= cable_begin) { - conns.push_back(arb::gap_junction_connection({(cell_gid_type)prev_cell, 1}, {gid, 0}, 0.015)); + conns.push_back(arb::gap_junction_connection({(cell_gid_type)prev_cell, 1}, 0, 0.015)); } return conns; diff --git a/example/generators/generators.cpp b/example/generators/generators.cpp index 5b62c95f25e4e763deef3fc91a3fabddeecf2722..a2747ea3850ac5d4623c2f41d09080e0240a1686 100644 --- a/example/generators/generators.cpp +++ b/example/generators/generators.cpp @@ -103,15 +103,15 @@ public: // Add excitatory generator gens.push_back( - poisson_generator(cell_member_type{0,0}, // Target synapse (gid, local_id). - w_e, // Weight of events to deliver - t0, // Events start being delivered from this time - lambda_e, // Expected frequency (kHz) - RNG(29562872))); // Random number generator to use + arb::poisson_generator(0, // Target synapse index on cell `gid` + w_e, // Weight of events to deliver + t0, // Events start being delivered from this time + lambda_e, // Expected frequency (kHz) + RNG(29562872))); // Random number generator to use // Add inhibitory generator gens.emplace_back( - poisson_generator(cell_member_type{0,0}, w_i, t0, lambda_i, RNG(86543891))); + arb::poisson_generator(0, w_i, t0, lambda_i, RNG(86543891))); return gens; } diff --git a/example/lfp/lfp.cpp b/example/lfp/lfp.cpp index 29a557d822b52cfe14e4947fc11aa72e55683ba5..10c463ad2c2410988ed001c54eb62ac3da092acb 100644 --- a/example/lfp/lfp.cpp +++ b/example/lfp/lfp.cpp @@ -187,7 +187,7 @@ int main(int argc, char** argv) { auto context = arb::make_context(); // Weight 0.005 μS, onset at t = 0 ms, mean frequency 0.1 kHz. - auto events = arb::poisson_generator({0, 0}, .005, 0., 0.1, std::minstd_rand{}); + auto events = arb::poisson_generator(0, .005, 0., 0.1, std::minstd_rand{}); lfp_demo_recipe R(events); const double t_stop = 100; // [ms] diff --git a/example/ring/ring.cpp b/example/ring/ring.cpp index a6bfbd1e1ebba37347daf1826b7b635a5b349259..c3091d5a8670a8d08a048a1d742c63e2ed216a21 100644 --- a/example/ring/ring.cpp +++ b/example/ring/ring.cpp @@ -97,7 +97,7 @@ public: // Each cell has one incoming connection, from cell with gid-1. std::vector<arb::cell_connection> connections_on(cell_gid_type gid) const override { cell_gid_type src = gid? gid-1: num_cells_-1; - return {arb::cell_connection({src, 0}, {gid, 0}, event_weight_, min_delay_)}; + return {arb::cell_connection({src, 0}, 0, event_weight_, min_delay_)}; } // Return one event generator on gid 0. This generates a single event that will @@ -105,7 +105,7 @@ public: std::vector<arb::event_generator> event_generators(cell_gid_type gid) const override { std::vector<arb::event_generator> gens; if (!gid) { - gens.push_back(arb::explicit_generator(arb::pse_vector{{{0, 0}, 1.0, event_weight_}})); + gens.push_back(arb::explicit_generator(arb::pse_vector{{0, 1.0, event_weight_}})); } return gens; } diff --git a/example/single/single.cpp b/example/single/single.cpp index b3be1a02aa126e3fe6beb08456d8e055f8bdcd3f..bbe7fcbe43e1e52ee6315ddba76c38e1fb6b068a 100644 --- a/example/single/single.cpp +++ b/example/single/single.cpp @@ -97,8 +97,9 @@ int main(int argc, char** argv) { // Trigger the single synapse (target is gid 0, index 0) at t = 1 ms with // the given weight. - arb::spike_event spike = {{0, 0}, 1., opt.syn_weight}; - sim.inject_events({spike}); + arb::spike_event spike = {0, 1., opt.syn_weight}; + arb::cell_spike_events cell_spikes = {0, {spike}}; + sim.inject_events({cell_spikes}); sim.run(opt.t_end, opt.dt); diff --git a/python/event_generator.cpp b/python/event_generator.cpp index f89df17c1f2c9700a4c4a01d59f1b28ab019ad42..ad7d0bbd27d4772200aa6a866241bfd65e91f0fe 100644 --- a/python/event_generator.cpp +++ b/python/event_generator.cpp @@ -17,7 +17,7 @@ void register_event_generators(pybind11::module& m) { event_generator .def(pybind11::init<>( - [](arb::cell_member_type target, double weight, const schedule_shim_base& sched) { + [](arb::cell_lid_type target, double weight, const schedule_shim_base& sched) { return event_generator_shim(target, weight, sched.schedule()); }), "target"_a, "weight"_a, "sched"_a, "Construct an event generator with arguments:\n" diff --git a/python/event_generator.hpp b/python/event_generator.hpp index d58d8d4d65ad2234005dc1932849edd8dfac9dca..1d0d61c3ac50dea1499ef6f981e959d32b4b1534 100644 --- a/python/event_generator.hpp +++ b/python/event_generator.hpp @@ -6,12 +6,12 @@ namespace pyarb { struct event_generator_shim { - arb::cell_member_type target; + arb::cell_lid_type target; double weight; arb::schedule time_sched; - event_generator_shim(arb::cell_member_type gid, double event_weight, arb::schedule sched): - target(gid), + event_generator_shim(arb::cell_lid_type event_target, double event_weight, arb::schedule sched): + target(event_target), weight(event_weight), time_sched(std::move(sched)) {} diff --git a/python/example/brunel.py b/python/example/brunel.py index d1081fc347778c3a0fb4140585aae49857d24c71..3bd0af9e470e8ae3032686332ce330a941ba5f97 100755 --- a/python/example/brunel.py +++ b/python/example/brunel.py @@ -64,10 +64,10 @@ class brunel_recipe (arbor.recipe): connections=[] # Add incoming excitatory connections. for i in sample_subset(gid, 0, self.ncells_exc_, self.in_degree_exc_): - connections.append(arbor.connection((i,0), (gid,0), self.weight_exc_, self.delay_)) + connections.append(arbor.connection((i,0), 0, self.weight_exc_, self.delay_)) # Add incoming inhibitory connections. for i in sample_subset(gid, self.ncells_exc_, self.ncells_exc_ + self.ncells_inh_, self.in_degree_inh_): - connections.append(arbor.connection((i,0), (gid,0), self.weight_inh_, self.delay_)) + connections.append(arbor.connection((i,0), 0, self.weight_inh_, self.delay_)) return connections def cell_description(self, gid): @@ -83,8 +83,9 @@ class brunel_recipe (arbor.recipe): def event_generators(self, gid): t0 = 0 + idx = 0 sched = arbor.poisson_schedule(t0, self.lambda_, gid + self.seed_) - return [arbor.event_generator(arbor.cell_member(gid,0), self.weight_ext_, sched)] + return [arbor.event_generator(idx, self.weight_ext_, sched)] def num_targets(self, gid): return 1 diff --git a/python/example/network_ring.py b/python/example/network_ring.py index 14671b3b362c0b7c4f179710db4d11234a598b29..236570658edea5b6aa288ccb2fa653ef2f76b6f5 100755 --- a/python/example/network_ring.py +++ b/python/example/network_ring.py @@ -88,7 +88,7 @@ class ring_recipe (arbor.recipe): src = (gid-1)%self.ncells w = 0.01 d = 5 - return [arbor.connection((src,0), (gid,0), w, d)] + return [arbor.connection((src,0), 0, w, d)] def num_targets(self, gid): return 1 @@ -100,7 +100,7 @@ class ring_recipe (arbor.recipe): def event_generators(self, gid): if gid==0: sched = arbor.explicit_schedule([1]) - return [arbor.event_generator((0,0), 0.1, sched)] + return [arbor.event_generator(0, 0.1, sched)] return [] # (10) Place a probe at the root of each cell. diff --git a/python/example/single_cell_stdp.py b/python/example/single_cell_stdp.py index 84fa6550fa2e02acc721717f129a3845fb69a714..2c783520e31034888c499437560114677a391f55 100755 --- a/python/example/single_cell_stdp.py +++ b/python/example/single_cell_stdp.py @@ -59,12 +59,10 @@ class single_recipe(arbor.recipe): stimulus_times = numpy.linspace(50, 500, self.n_pairs) # strong enough stimulus - spike = arbor.event_generator(arbor.cell_member( - 0, 0), 1., arbor.explicit_schedule(stimulus_times)) + spike = arbor.event_generator(0, 1., arbor.explicit_schedule(stimulus_times)) # zero weight -> just modify synaptic weight via stdp - stdp = arbor.event_generator(arbor.cell_member( - 0, 1), 0., arbor.explicit_schedule(stimulus_times - self.dT)) + stdp = arbor.event_generator(1, 0., arbor.explicit_schedule(stimulus_times - self.dT)) return [spike, stdp] diff --git a/python/recipe.cpp b/python/recipe.cpp index 21b9a7ec44b4723c1a4f9936d7ca64007c83c001..9456dd3d407bdc62c5a826fc35d7340c6ee1a68c 100644 --- a/python/recipe.cpp +++ b/python/recipe.cpp @@ -103,7 +103,7 @@ static std::vector<arb::event_generator> convert_gen(std::vector<pybind11::objec auto& p = cast<const pyarb::event_generator_shim&>(g); // convert the event_generator to an arb::event_generator - gens.push_back(arb::schedule_generator({gid, p.target.index}, p.weight, std::move(p.time_sched))); + gens.push_back(arb::schedule_generator(p.target, p.weight, std::move(p.time_sched))); } return gens; @@ -118,13 +118,13 @@ std::vector<arb::event_generator> py_recipe_shim::event_generators(arb::cell_gid } std::string con_to_string(const arb::cell_connection& c) { - return util::pprintf("<arbor.connection: source ({},{}), destination ({},{}), delay {}, weight {}>", - c.source.gid, c.source.index, c.dest.gid, c.dest.index, c.delay, c.weight); + return util::pprintf("<arbor.connection: source ({},{}), destination {}, delay {}, weight {}>", + c.source.gid, c.source.index, c.dest, c.delay, c.weight); } std::string gj_to_string(const arb::gap_junction_connection& gc) { - return util::pprintf("<arbor.gap_junction_connection: local ({},{}), peer ({},{}), ggap {}>", - gc.local.gid, gc.local.index, gc.peer.gid, gc.peer.index, gc.ggap); + return util::pprintf("<arbor.gap_junction_connection: peer ({},{}), local {}, ggap {}>", + gc.peer.gid, gc.peer.index, gc.local, gc.ggap); } void register_recipe(pybind11::module& m) { @@ -135,7 +135,7 @@ void register_recipe(pybind11::module& m) { "Describes a connection between two cells:\n" " Defined by source and destination end points (that is pre-synaptic and post-synaptic respectively), a connection weight and a delay time."); cell_connection - .def(pybind11::init<arb::cell_member_type, arb::cell_member_type, float, float>(), + .def(pybind11::init<arb::cell_member_type, arb::cell_lid_type, float, float>(), "source"_a, "dest"_a, "weight"_a, "delay"_a, "Construct a connection with arguments:\n" " source: The source end point of the connection.\n" @@ -157,7 +157,7 @@ void register_recipe(pybind11::module& m) { pybind11::class_<arb::gap_junction_connection> gap_junction_connection(m, "gap_junction_connection", "Describes a gap junction between two gap junction sites."); gap_junction_connection - .def(pybind11::init<arb::cell_member_type, arb::cell_member_type, double>(), + .def(pybind11::init<arb::cell_member_type, arb::cell_lid_type, double>(), "local"_a, "peer"_a, "ggap"_a, "Construct a gap junction connection with arguments:\n" " local: One half of the gap junction connection.\n" diff --git a/test/unit-distributed/test_communicator.cpp b/test/unit-distributed/test_communicator.cpp index 16c3527de7f5c2be2135c454cdf20f4cdbb75281..5c1f904a8a6b1fe3c221c7622def90401ee1968a 100644 --- a/test/unit-distributed/test_communicator.cpp +++ b/test/unit-distributed/test_communicator.cpp @@ -209,7 +209,7 @@ namespace { // weight is the destination gid // delay is 1 cell_member_type src = {gid==0? size_-1: gid-1, 0}; - cell_member_type dst = {gid, 0}; + cell_lid_type dst = 0; return {cell_connection( src, dst, // end points float(gid), // weight @@ -233,7 +233,7 @@ namespace { spike_event expected_event_ring(cell_gid_type gid, cell_size_type num_cells) { auto sid = source_of(gid, num_cells); return { - {gid, 0u}, // source + 0u, // source sid+1.0f, // time (all conns have delay 1 ms) float(gid)};// weight } @@ -272,7 +272,7 @@ namespace { for (auto sid: util::make_span(0, size_)) { cell_connection con( {sid, 0}, // source - {gid, sid}, // destination + sid, // destination float(gid+sid), // weight 1.0f); // delay cons.push_back(con); @@ -287,7 +287,7 @@ namespace { spike_event expected_event_all2all(cell_gid_type gid, cell_gid_type sid) { return { - {gid, sid}, // target, event from sid goes to synapse with index sid + sid, // target, event from sid goes to synapse with index sid sid+1.0f, // time (all conns have delay 1 ms) float(gid+sid)}; // weight } diff --git a/test/unit-distributed/test_domain_decomposition.cpp b/test/unit-distributed/test_domain_decomposition.cpp index 3b5c336cc7833c5d8822977b21ee00e64624bf26..e905f5645da48db7745b21a3a517721ea40df6cb 100644 --- a/test/unit-distributed/test_domain_decomposition.cpp +++ b/test/unit-distributed/test_domain_decomposition.cpp @@ -85,20 +85,20 @@ namespace { std::vector<gap_junction_connection> gap_junctions_on(cell_gid_type gid) const override { unsigned shift = (gid/size_)*size_; switch (gid % size_) { - case 1 : return { gap_junction_connection({7 + shift, 0}, {gid, 0}, 0.1)}; + case 1 : return { gap_junction_connection({7 + shift, 0}, 0, 0.1)}; case 2 : return { - gap_junction_connection({6 + shift, 0}, {gid, 0}, 0.1), - gap_junction_connection({9 + shift, 0}, {gid, 0}, 0.1) + gap_junction_connection({6 + shift, 0}, 0, 0.1), + gap_junction_connection({9 + shift, 0}, 0, 0.1) }; case 6 : return { - gap_junction_connection({2 + shift, 0}, {gid, 0}, 0.1), - gap_junction_connection({7 + shift, 0}, {gid, 0}, 0.1) + gap_junction_connection({2 + shift, 0}, 0, 0.1), + gap_junction_connection({7 + shift, 0}, 0, 0.1) }; case 7 : return { - gap_junction_connection({6 + shift, 0}, {gid, 0}, 0.1), - gap_junction_connection({1 + shift, 0}, {gid, 0}, 0.1) + gap_junction_connection({6 + shift, 0}, 0, 0.1), + gap_junction_connection({1 + shift, 0}, 0, 0.1) }; - case 9 : return { gap_junction_connection({2 + shift, 0}, {gid, 0}, 0.1)}; + case 9 : return { gap_junction_connection({2 + shift, 0}, 0, 0.1)}; default : return {}; } } @@ -127,10 +127,10 @@ namespace { unsigned group = gid/groups_; unsigned id = gid%size_; if (id == group && group != (groups_ - 1)) { - return {gap_junction_connection({gid + size_, 0}, {gid, 0}, 0.1)}; + return {gap_junction_connection({gid + size_, 0}, 0, 0.1)}; } else if (id == group - 1) { - return {gap_junction_connection({gid - size_, 0}, {gid, 0}, 0.1)}; + return {gap_junction_connection({gid - size_, 0}, 0, 0.1)}; } else { return {}; diff --git a/test/unit/test_domain_decomposition.cpp b/test/unit/test_domain_decomposition.cpp index 8d7e97506722f07a93be786233bd210f24834d31..2db3367993446af5375cfc57a11d5764efca2695 100644 --- a/test/unit/test_domain_decomposition.cpp +++ b/test/unit/test_domain_decomposition.cpp @@ -77,34 +77,40 @@ namespace { } std::vector<gap_junction_connection> gap_junctions_on(cell_gid_type gid) const override { switch (gid) { - case 0 : return {gap_junction_connection({13, 0}, {0, 0}, 0.1)}; + case 0 : return { + gap_junction_connection({13, 0}, 0, 0.1) + }; case 2 : return { - gap_junction_connection({7, 0}, {2, 0}, 0.1), - gap_junction_connection({11, 0}, {2, 0}, 0.1) + gap_junction_connection({7, 0}, 0, 0.1), + gap_junction_connection({11, 0}, 0, 0.1) }; case 3 : return { - gap_junction_connection({4, 0}, {3, 0}, 0.1), - gap_junction_connection({8, 0}, {3, 0}, 0.1) + gap_junction_connection({4, 0}, 0, 0.1), + gap_junction_connection({8, 0}, 0, 0.1) }; case 4 : return { - gap_junction_connection({3, 0}, {4, 0}, 0.1), - gap_junction_connection({8, 0}, {4, 0}, 0.1), - gap_junction_connection({9, 0}, {4, 0}, 0.1) + gap_junction_connection({3, 0}, 0, 0.1), + gap_junction_connection({8, 0}, 0, 0.1), + gap_junction_connection({9, 0}, 0, 0.1) }; case 7 : return { - gap_junction_connection({2, 0}, {7, 0}, 0.1), - gap_junction_connection({11, 0}, {7, 0}, 0.1) + gap_junction_connection({2, 0}, 0, 0.1), + gap_junction_connection({11, 0}, 0, 0.1) };; case 8 : return { - gap_junction_connection({3, 0}, {8, 0}, 0.1), - gap_junction_connection({4, 0}, {8, 0}, 0.1) + gap_junction_connection({3, 0}, 0, 0.1), + gap_junction_connection({4, 0}, 0, 0.1) };; - case 9 : return {gap_junction_connection({4, 0}, {9, 0}, 0.1)}; + case 9 : return { + gap_junction_connection({4, 0}, 0, 0.1) + }; case 11 : return { - gap_junction_connection({2, 0}, {11, 0}, 0.1), - gap_junction_connection({7, 0}, {11, 0}, 0.1) + gap_junction_connection({2, 0}, 0, 0.1), + gap_junction_connection({7, 0}, 0, 0.1) + }; + case 13 : return { + gap_junction_connection({0, 0}, 0, 0.1) }; - case 13 : return {gap_junction_connection({0, 0}, {13, 0}, 0.1)}; default : return {}; } } diff --git a/test/unit/test_event_delivery.cpp b/test/unit/test_event_delivery.cpp index f8fa888e2dd224178a80059be637f4213e92a65b..1d4f9cd95c163e3cebb9b3092481b74aa8aa5556 100644 --- a/test/unit/test_event_delivery.cpp +++ b/test/unit/test_event_delivery.cpp @@ -75,9 +75,9 @@ std::vector<cell_gid_type> run_test_sim(const recipe& R, const group_gids_type& constexpr time_type ev_delta_t = 0.2; - pse_vector cell_events; + cse_vector cell_events; for (unsigned i = 0; i<n; ++i) { - cell_events.push_back({{i, 0u}, i*ev_delta_t, 1.f}); + cell_events.push_back({i, {{0u, i*ev_delta_t, 1.f}}}); } sim.inject_events(cell_events); @@ -112,7 +112,8 @@ struct test_recipe_gj: public test_recipe { std::vector<gap_junction_connection> gap_junctions_on(cell_gid_type i) const override { std::vector<gap_junction_connection> gjs; for (auto p: gj_pairs_) { - if (p.first == i || p.second == i) gjs.push_back({{p.first, 0u}, {p.second, 0u}, 0.}); + if (p.first == i) gjs.push_back({{p.second, 0u}, 0u, 0.}); + if (p.second == i) gjs.push_back({{p.first, 0u}, 0u, 0.}); } return gjs; } diff --git a/test/unit/test_event_generators.cpp b/test/unit/test_event_generators.cpp index 032abda3d88aa9b0795447b1e8e770b74ae9a733..0f17feb47434835ae274689526a789257e7824d4 100644 --- a/test/unit/test_event_generators.cpp +++ b/test/unit/test_event_generators.cpp @@ -18,8 +18,8 @@ namespace{ } TEST(event_generators, assign_and_copy) { - event_generator gen = regular_generator({1, 2}, 5., 0.5, 0.75); - spike_event expected{{1, 2}, 0.75, 5.}; + event_generator gen = regular_generator(2, 5., 0.5, 0.75); + spike_event expected{2, 0.75, 5.}; auto first = [](const event_seq& seq) { if (seq.first==seq.second) throw std::runtime_error("no events"); @@ -54,7 +54,7 @@ TEST(event_generators, regular) { // events regularly spaced 0.5 ms apart. time_type t0 = 2.0; time_type dt = 0.5; - cell_member_type target = {42, 3}; + cell_lid_type target = 3; float weight = 3.14; event_generator gen = regular_generator(target, weight, t0, dt); @@ -81,13 +81,13 @@ TEST(event_generators, regular) { TEST(event_generators, seq) { pse_vector in = { - {{0, 0}, 0.1, 1.0}, - {{0, 0}, 1.0, 2.0}, - {{0, 0}, 1.0, 3.0}, - {{0, 0}, 1.5, 4.0}, - {{0, 0}, 2.3, 5.0}, - {{0, 0}, 3.0, 6.0}, - {{0, 0}, 3.5, 7.0}, + {0, 0.1, 1.0}, + {0, 1.0, 2.0}, + {0, 1.0, 3.0}, + {0, 1.5, 4.0}, + {0, 2.3, 5.0}, + {0, 3.0, 6.0}, + {0, 3.5, 7.0}, }; auto events = [&in] (int b, int e) { @@ -102,10 +102,10 @@ TEST(event_generators, seq) { // Check reported sub-intervals against a smaller set of events. in = { - {{0, 0}, 1.5, 4.0}, - {{0, 0}, 2.3, 5.0}, - {{0, 0}, 3.0, 6.0}, - {{0, 0}, 3.5, 7.0}, + {0, 1.5, 4.0}, + {0, 2.3, 5.0}, + {0, 3.0, 6.0}, + {0, 3.5, 7.0}, }; gen = explicit_generator(in); @@ -143,7 +143,7 @@ TEST(event_generators, poisson) { time_type t0 = 0; time_type t1 = 10; time_type lambda = 10; // expect 10 events per ms - cell_member_type target{4, 2}; + cell_lid_type target = 2; float weight = 42; event_generator gen = poisson_generator(target, weight, t0, lambda, G); diff --git a/test/unit/test_event_queue.cpp b/test/unit/test_event_queue.cpp index 3ce72e0bd7ddbe426619db582413867ebfde578d..b47a3ed32e0f980f21a56fe79701acce5d9b9a40 100644 --- a/test/unit/test_event_queue.cpp +++ b/test/unit/test_event_queue.cpp @@ -14,10 +14,10 @@ TEST(event_queue, push) { ps_event_queue q; - q.push({{1u, 0u}, 2.f, 2.f}); - q.push({{4u, 1u}, 1.f, 2.f}); - q.push({{8u, 2u}, 20.f, 2.f}); - q.push({{2u, 3u}, 8.f, 2.f}); + q.push({0u, 2.f, 2.f}); + q.push({1u, 1.f, 2.f}); + q.push({2u, 20.f, 2.f}); + q.push({3u, 8.f, 2.f}); EXPECT_EQ(4u, q.size()); @@ -33,12 +33,7 @@ TEST(event_queue, push) { TEST(event_queue, pop_if_before) { using ps_event_queue = event_queue<spike_event>; - cell_member_type target[4] = { - {1u, 0u}, - {4u, 1u}, - {8u, 2u}, - {2u, 3u} - }; + cell_lid_type target[4] = {0u, 1u, 2u, 3u}; spike_event events[] = { {target[0], 1.f, 2.f}, diff --git a/test/unit/test_fvm_lowered.cpp b/test/unit/test_fvm_lowered.cpp index 5d11cff324a497ea27a99cfd47a81350eda2e1c1..a35e83931b662fece9be1a10e1573a35459336d7 100644 --- a/test/unit/test_fvm_lowered.cpp +++ b/test/unit/test_fvm_lowered.cpp @@ -107,21 +107,21 @@ public: std::vector<gap_junction_connection> gap_junctions_on(cell_gid_type gid) const override { switch (gid) { case 0 : - return {gap_junction_connection({5, 0}, {0, 0}, 0.1)}; + return {gap_junction_connection({5, 0}, 0, 0.1)}; case 2 : return { - gap_junction_connection({3, 0}, {2, 0}, 0.1), + gap_junction_connection({3, 0}, 0, 0.1), }; case 3 : return { - gap_junction_connection({7, 0}, {3, 0}, 0.1), - gap_junction_connection({3, 0}, {2, 0}, 0.1) + gap_junction_connection({7, 0}, 0, 0.1), + gap_junction_connection({2, 0}, 0, 0.1) }; case 5 : - return {gap_junction_connection({5, 0}, {0, 0}, 0.1)}; + return {gap_junction_connection({0, 0}, 0, 0.1)}; case 7 : return { - gap_junction_connection({3, 0}, {7, 0}, 0.1), + gap_junction_connection({3, 0}, 0, 0.1), }; default : return {}; @@ -173,27 +173,27 @@ public: switch (gid) { case 0 : return { - gap_junction_connection({2, 0}, {0, 0}, 0.1), - gap_junction_connection({3, 0}, {0, 0}, 0.1), - gap_junction_connection({5, 0}, {0, 0}, 0.1) + gap_junction_connection({2, 0}, 0, 0.1), + gap_junction_connection({3, 0}, 0, 0.1), + gap_junction_connection({5, 0}, 0, 0.1) }; case 2 : return { - gap_junction_connection({0, 0}, {2, 0}, 0.1), - gap_junction_connection({3, 0}, {2, 0}, 0.1), - gap_junction_connection({5, 0}, {2, 0}, 0.1) + gap_junction_connection({0, 0}, 0, 0.1), + gap_junction_connection({3, 0}, 0, 0.1), + gap_junction_connection({5, 0}, 0, 0.1) }; case 3 : return { - gap_junction_connection({0, 0}, {3, 0}, 0.1), - gap_junction_connection({2, 0}, {3, 0}, 0.1), - gap_junction_connection({5, 0}, {3, 0}, 0.1) + gap_junction_connection({0, 0}, 0, 0.1), + gap_junction_connection({2, 0}, 0, 0.1), + gap_junction_connection({5, 0}, 0, 0.1) }; case 5 : return { - gap_junction_connection({2, 0}, {5, 0}, 0.1), - gap_junction_connection({3, 0}, {5, 0}, 0.1), - gap_junction_connection({0, 0}, {5, 0}, 0.1) + gap_junction_connection({2, 0}, 0, 0.1), + gap_junction_connection({3, 0}, 0, 0.1), + gap_junction_connection({0, 0}, 0, 0.1) }; default : return {}; @@ -939,7 +939,7 @@ TEST(fvm_lowered, gj_coords_simple) { } std::vector<arb::gap_junction_connection> gap_junctions_on(cell_gid_type gid) const override{ std::vector<gap_junction_connection> conns; - conns.push_back(gap_junction_connection({(gid+1)%2, 0}, {gid, 0}, 0.5)); + conns.push_back(gap_junction_connection({(gid+1)%2, 0}, 0, 0.5)); return conns; } @@ -1007,22 +1007,22 @@ TEST(fvm_lowered, gj_coords_complex) { switch (gid) { case 0: return { - gap_junction_connection({2, 0}, {0, 1}, 0.01), - gap_junction_connection({1, 0}, {0, 0}, 0.03), - gap_junction_connection({1, 1}, {0, 0}, 0.04) + gap_junction_connection({2, 0}, 1, 0.01), + gap_junction_connection({1, 0}, 0, 0.03), + gap_junction_connection({1, 1}, 0, 0.04) }; case 1: return { - gap_junction_connection({0, 0}, {1, 0}, 0.03), - gap_junction_connection({0, 0}, {1, 1}, 0.04), - gap_junction_connection({2, 1}, {1, 2}, 0.02), - gap_junction_connection({2, 2}, {1, 3}, 0.01) + gap_junction_connection({0, 0}, 0, 0.03), + gap_junction_connection({0, 0}, 1, 0.04), + gap_junction_connection({2, 1}, 2, 0.02), + gap_junction_connection({2, 2}, 3, 0.01) }; case 2: return { - gap_junction_connection({0, 1}, {2, 0}, 0.01), - gap_junction_connection({1, 2}, {2, 1}, 0.02), - gap_junction_connection({1, 3}, {2, 2}, 0.01) + gap_junction_connection({0, 1}, 0, 0.01), + gap_junction_connection({1, 2}, 1, 0.02), + gap_junction_connection({1, 3}, 2, 0.01) }; default : return {}; } @@ -1152,8 +1152,8 @@ TEST(fvm_lowered, cell_group_gj) { // connect 5 of the first 10 cells in a ring; connect 5 of the second 10 cells in a ring auto next_cell = gid == 8 ? 0 : (gid == 18 ? 10 : gid + 2); auto prev_cell = gid == 0 ? 8 : (gid == 10 ? 18 : gid - 2); - conns.push_back(gap_junction_connection({next_cell, 0}, {gid, 0}, 0.03)); - conns.push_back(gap_junction_connection({prev_cell, 0}, {gid, 0}, 0.03)); + conns.push_back(gap_junction_connection({next_cell, 0}, 0, 0.03)); + conns.push_back(gap_junction_connection({prev_cell, 0}, 0, 0.03)); } return conns; } diff --git a/test/unit/test_lif_cell_group.cpp b/test/unit/test_lif_cell_group.cpp index 664f7d8876eb930a7337e4c5f430064cbbe00818..272245a140062851e4b3e2e5c7300d183a4df000 100644 --- a/test/unit/test_lif_cell_group.cpp +++ b/test/unit/test_lif_cell_group.cpp @@ -42,7 +42,7 @@ public: std::vector<cell_connection> connections; // gid-1 >= 0 since gid != 0 cell_member_type source{(gid - 1) % n_lif_cells_, 0}; - cell_member_type target{gid, 0}; + cell_lid_type target{0}; cell_connection conn(source, target, weight_, delay_); connections.push_back(conn); @@ -50,7 +50,7 @@ public: // the connection from the last LIF cell as well if (gid == 1) { cell_member_type source{n_lif_cells_, 0}; - cell_member_type target{gid, 0}; + cell_lid_type target{0}; cell_connection conn(source, target, weight_, delay_); connections.push_back(conn); } @@ -101,7 +101,7 @@ public: } std::vector<cell_connection> connections; cell_member_type source{gid - 1, 0}; - cell_member_type target{gid, 0}; + cell_lid_type target{0}; cell_connection conn(source, target, weight_, delay_); connections.push_back(conn); @@ -177,18 +177,18 @@ TEST(lif_cell_group, spikes) { auto decomp = partition_load_balance(recipe, context); simulation sim(recipe, decomp, context); - std::vector<spike_event> events; + cse_vector events; // First event to trigger the spike (first neuron). - events.push_back({{0, 0}, 1, 1000}); + events.push_back({0, {{0, 1, 1000}}}); // This event happens inside the refractory period of the previous // event, thus, should be ignored (first neuron) - events.push_back({{0, 0}, 1.1, 1000}); + events.push_back({0, {{0, 1.1, 1000}}}); // This event happens long after the refractory period of the previous // event, should thus trigger new spike (first neuron). - events.push_back({{0, 0}, 50, 1000}); + events.push_back({0, {{0, 50, 1000}}}); sim.inject_events(events); diff --git a/test/unit/test_merge_events.cpp b/test/unit/test_merge_events.cpp index d1756f4ed9ccce3bf4593e44cd27b688e26aad2b..d61363f4e1d8d9c5c1cd1d1574163cd54f74a7cc 100644 --- a/test/unit/test_merge_events.cpp +++ b/test/unit/test_merge_events.cpp @@ -54,9 +54,9 @@ TEST(merge_events, empty) TEST(merge_events, no_overlap) { pse_vector lc = { - {{0, 0}, 1, 1}, - {{0, 0}, 2, 1}, - {{0, 0}, 3, 3}, + {0, 1, 1}, + {0, 2, 1}, + {0, 3, 3}, }; // Check that the inputs satisfy the precondition that lc is sorted. EXPECT_TRUE(std::is_sorted(lc.begin(), lc.end())); @@ -64,25 +64,25 @@ TEST(merge_events, no_overlap) // These events should be removed from lf by merge_events, and replaced // with events to be delivered after t=10 pse_vector lf = { - {{0, 0}, 1, 1}, - {{0, 0}, 2, 1}, - {{0, 0}, 3, 3}, + {0, 1, 1}, + {0, 2, 1}, + {0, 3, 3}, }; pse_vector events = { - {{0, 0}, 12, 1}, - {{0, 0}, 11, 2}, - {{8, 0}, 10, 4}, - {{0, 0}, 11, 1}, + {0, 12, 1}, + {0, 11, 2}, + {0, 10, 4}, + {0, 11, 1}, }; merge_events(10, terminal_time, lc, events, empty_gens, lf); pse_vector expected = { - {{8, 0}, 10, 4}, - {{0, 0}, 11, 1}, - {{0, 0}, 11, 2}, - {{0, 0}, 12, 1}, + {0, 10, 4}, + {0, 11, 1}, + {0, 11, 2}, + {0, 12, 1}, }; EXPECT_TRUE(std::is_sorted(lf.begin(), lf.end())); @@ -95,11 +95,11 @@ TEST(merge_events, no_overlap) TEST(merge_events, overlap) { pse_vector lc = { - {{0, 0}, 1, 1}, - {{0, 0}, 2, 1}, + {0, 1, 1}, + {0, 2, 1}, // The current epoch ends at t=10, so all events from here down are expected in lf. - {{8, 0}, 10, 2}, - {{0, 0}, 11, 3}, + {0, 10, 2}, + {0, 11, 3}, }; EXPECT_TRUE(std::is_sorted(lc.begin(), lc.end())); @@ -107,23 +107,23 @@ TEST(merge_events, overlap) pse_vector events = { // events are in reverse order: they should be sorted in the output of merge_events. - {{0, 0}, 12, 1}, - {{0, 0}, 11, 2}, - {{0, 0}, 11, 1}, - {{8, 0}, 10, 3}, - {{7, 0}, 10, 8}, + {0, 12, 1}, + {0, 11, 2}, + {0, 11, 1}, + {1, 10, 3}, + {0, 10, 8}, }; merge_events(10, terminal_time, lc, events, empty_gens, lf); pse_vector expected = { - {{7, 0}, 10, 8}, // from events - {{8, 0}, 10, 2}, // from lc - {{8, 0}, 10, 3}, // from events - {{0, 0}, 11, 1}, // from events - {{0, 0}, 11, 2}, // from events - {{0, 0}, 11, 3}, // from lc - {{0, 0}, 12, 1}, // from events + {0, 10, 2}, // from lc + {0, 10, 8}, // from events + {1, 10, 3}, // from events + {0, 11, 1}, // from events + {0, 11, 2}, // from events + {0, 11, 3}, // from lc + {0, 12, 1}, // from events }; EXPECT_TRUE(std::is_sorted(lf.begin(), lf.end())); @@ -137,42 +137,42 @@ TEST(merge_events, X) const time_type t1 = 20; pse_vector lc = { - {{0, 0}, 1, 1}, - {{0, 0}, 5, 1}, + {0, 1, 1}, + {0, 5, 1}, // The current epoch ends at t=10, so all events from here down are expected in lf. - {{8, 0}, 10, 2}, - {{0, 0}, 11, 3}, - {{8, 0}, 20, 2}, - {{0, 0}, 21, 3}, + {0, 10, 2}, + {0, 11, 3}, + {0, 20, 2}, + {0, 21, 3}, }; EXPECT_TRUE(std::is_sorted(lc.begin(), lc.end())); pse_vector lf; pse_vector events = { - {{0, 0}, 12, 1}, - {{1, 0}, 15, 2}, - {{2, 0}, 22, 3}, - {{3, 0}, 26, 4}, + {0, 12, 1}, + {0, 15, 2}, + {0, 22, 3}, + {0, 26, 4}, }; std::vector<event_generator> generators = { - regular_generator(cell_member_type{4,2}, 42.f, t0, 5) + regular_generator(2, 42.f, t0, 5) }; merge_events(t0, t1, lc, events, generators, lf); pse_vector expected = { - {{4, 2}, 10, 42}, // from generator - {{8, 0}, 10, 2}, // from lc - {{0, 0}, 11, 3}, // from lc - {{0, 0}, 12, 1}, // from events - {{1, 0}, 15, 2}, // from events - {{4, 2}, 15, 42}, // from generator - {{8, 0}, 20, 2}, // from lc - {{0, 0}, 21, 3}, // from lc - {{2, 0}, 22, 3}, // from events - {{3, 0}, 26, 4}, // from events + {0, 10, 2}, // from lc + {2, 10, 42}, // from generator + {0, 11, 3}, // from lc + {0, 12, 1}, // from events + {0, 15, 2}, // from events + {2, 15, 42}, // from generator + {0, 20, 2}, // from lc + {0, 21, 3}, // from lc + {0, 22, 3}, // from events + {0, 26, 4}, // from events }; EXPECT_TRUE(std::is_sorted(lf.begin(), lf.end())); @@ -183,19 +183,19 @@ TEST(merge_events, X) TEST(merge_events, tourney_seq) { pse_vector evs1 = { - {{0, 0}, 1, 1}, - {{0, 0}, 2, 2}, - {{0, 0}, 3, 3}, - {{0, 0}, 4, 4}, - {{0, 0}, 5, 5}, + {0, 1, 1}, + {0, 2, 2}, + {0, 3, 3}, + {0, 4, 4}, + {0, 5, 5}, }; pse_vector evs2 = { - {{0, 0}, 1.5, 1}, - {{0, 0}, 2.5, 2}, - {{0, 0}, 3.5, 3}, - {{0, 0}, 4.5, 4}, - {{0, 0}, 5.5, 5}, + {0, 1.5, 1}, + {0, 2.5, 2}, + {0, 3.5, 3}, + {0, 4.5, 4}, + {0, 5.5, 5}, }; event_generator g1 = explicit_generator(evs1); @@ -234,7 +234,7 @@ TEST(merge_events, tourney_poisson) std::vector<event_generator> generators; for (auto i=0u; i<ngen; ++i) { - cell_member_type tgt{0, i}; + cell_lid_type tgt = i; float weight = i; // the first and last generators have the same seed to test that sorting // of events with the same time but different weights works properly. diff --git a/test/unit/test_probe.cpp b/test/unit/test_probe.cpp index f08a4cf0f34f3a6a82f421a1b2fc07e4944f6926..7e705019217bc3105854600730570937231724f5 100644 --- a/test/unit/test_probe.cpp +++ b/test/unit/test_probe.cpp @@ -1249,9 +1249,9 @@ void run_exact_sampling_probe_test(const context& ctx) { std::vector<gap_junction_connection> gap_junctions_on(cell_gid_type gid) const override { switch (gid) { case 1: - return {gap_junction_connection({gid, 0}, {3, 0}, 1.)}; + return {gap_junction_connection({3, 0}, 0, 1.)}; case 3: - return {gap_junction_connection({gid, 0}, {1, 0}, 1.)}; + return {gap_junction_connection({1, 0}, 0, 1.)}; default: return {}; } @@ -1259,7 +1259,7 @@ void run_exact_sampling_probe_test(const context& ctx) { std::vector<event_generator> event_generators(cell_gid_type gid) const override { // Send a single event to cell i at 0.1*i milliseconds. - pse_vector spikes = {spike_event{{gid, 0}, 0.1*gid, 1.f}}; + pse_vector spikes = {spike_event{0, 0.1*gid, 1.f}}; return {explicit_generator(spikes)}; } diff --git a/test/unit/test_recipe.cpp b/test/unit/test_recipe.cpp index 0d2a648985bf268c4dae50e707513224931b26a4..b1b0c04eea577e705b6bb9706d2e22656afa0abb 100644 --- a/test/unit/test_recipe.cpp +++ b/test/unit/test_recipe.cpp @@ -171,36 +171,34 @@ TEST(recipe, gap_junctions) auto cell_1 = custom_cell(0, 0, 3); { - std::vector<arb::gap_junction_connection> gjs_0 = {{{0, 0}, {1, 1}, 0.1}, - {{0, 1}, {1, 2}, 0.1}, - {{0, 2}, {1, 0}, 0.1}}; + std::vector<arb::gap_junction_connection> gjs_0 = {{{1, 1}, 0, 0.1}, + {{1, 2}, 1, 0.1}, + {{1, 0}, 2, 0.1}}; - auto recipe_0 = custom_recipe({cell_0, cell_1}, {0, 0}, {0, 0}, {{}, {}}, {gjs_0, gjs_0}, {{}, {}}); + std::vector<arb::gap_junction_connection> gjs_1 = {{{0, 0}, 1, 0.1}, + {{0, 1}, 2, 0.1}, + {{0, 2}, 0, 0.1}}; + + auto recipe_0 = custom_recipe({cell_0, cell_1}, {0, 0}, {0, 0}, {{}, {}}, {gjs_0, gjs_1}, {{}, {}}); auto decomp_0 = partition_load_balance(recipe_0, context); EXPECT_NO_THROW(simulation(recipe_0, decomp_0, context)); } { - std::vector<arb::gap_junction_connection> gjs_1 = {{{0, 0}, {1, 1}, 0.1}, - {{0, 1}, {1, 2}, 0.1}, - {{0, 2}, {1, 5}, 0.1}}; + std::vector<arb::gap_junction_connection> gjs_0 = {{{1, 1}, 0, 0.1}, + {{1, 2}, 1, 0.1}, + {{1, 5}, 2, 0.1}}; + + std::vector<arb::gap_junction_connection> gjs_1 = {{{0, 0}, 1, 0.1}, + {{0, 1}, 2, 0.1}, + {{0, 2}, 5, 0.1}}; - auto recipe_1 = custom_recipe({cell_0, cell_1}, {0, 0}, {0, 0}, {{}, {}}, {gjs_1, gjs_1}, {{}, {}}); + auto recipe_1 = custom_recipe({cell_0, cell_1}, {0, 0}, {0, 0}, {{}, {}}, {gjs_0, gjs_1}, {{}, {}}); auto decomp_1 = partition_load_balance(recipe_1, context); EXPECT_THROW(simulation(recipe_1, decomp_1, context), arb::bad_gj_connection_lid); } - { - std::vector<arb::gap_junction_connection> gjs_2 = {{{0, 0}, {1, 1}, 0.1}, - {{0, 1}, {1, 2}, 0.1}, - {{0, 2}, {3, 0}, 0.1}}; - - auto recipe_2 = custom_recipe({cell_0, cell_1}, {0, 0}, {0, 0}, {{}, {}}, {gjs_2, gjs_2}, {{}, {}}); - auto context = make_context(resources); - - EXPECT_THROW(partition_load_balance(recipe_2, context), arb::bad_gj_connection_gid); - } } TEST(recipe, connections) @@ -218,13 +216,13 @@ TEST(recipe, connections) auto cell_1 = custom_cell(2, 1, 0); std::vector<arb::cell_connection> conns_0, conns_1; { - conns_0 = {{{1, 0}, {0, 0}, 0.1, 0.1}, - {{1, 1}, {0, 0}, 0.1, 0.1}, - {{1, 0}, {0, 1}, 0.2, 0.4}}; + conns_0 = {{{1, 0}, 0, 0.1, 0.1}, + {{1, 1}, 0, 0.1, 0.1}, + {{1, 0}, 1, 0.2, 0.4}}; - conns_1 = {{{0, 0}, {1, 0}, 0.1, 0.2}, - {{0, 0}, {1, 0}, 0.3, 0.1}, - {{0, 0}, {1, 0}, 0.1, 0.8}}; + conns_1 = {{{0, 0}, 0, 0.1, 0.2}, + {{0, 0}, 0, 0.3, 0.1}, + {{0, 0}, 0, 0.1, 0.8}}; auto recipe_0 = custom_recipe({cell_0, cell_1}, {1, 2}, {2, 1}, {conns_0, conns_1}, {{}, {}}, {{}, {}}); auto decomp_0 = partition_load_balance(recipe_0, context); @@ -232,13 +230,13 @@ TEST(recipe, connections) EXPECT_NO_THROW(simulation(recipe_0, decomp_0, context)); } { - conns_0 = {{{1, 0}, {0, 0}, 0.1, 0.1}, - {{2, 1}, {0, 0}, 0.1, 0.1}, - {{1, 0}, {0, 1}, 0.2, 0.4}}; + conns_0 = {{{1, 0}, 0, 0.1, 0.1}, + {{2, 1}, 0, 0.1, 0.1}, + {{1, 0}, 1, 0.2, 0.4}}; - conns_1 = {{{0, 0}, {1, 0}, 0.1, 0.2}, - {{0, 0}, {1, 0}, 0.3, 0.1}, - {{0, 0}, {1, 0}, 0.1, 0.8}}; + conns_1 = {{{0, 0}, 0, 0.1, 0.2}, + {{0, 0}, 0, 0.3, 0.1}, + {{0, 0}, 0, 0.1, 0.8}}; auto recipe_1 = custom_recipe({cell_0, cell_1}, {1, 2}, {2, 1}, {conns_0, conns_1}, {{}, {}}, {{}, {}}); auto decomp_1 = partition_load_balance(recipe_1, context); @@ -246,13 +244,13 @@ TEST(recipe, connections) EXPECT_THROW(simulation(recipe_1, decomp_1, context), arb::bad_connection_source_gid); } { - conns_0 = {{{1, 0}, {0, 0}, 0.1, 0.1}, - {{1, 1}, {0, 0}, 0.1, 0.1}, - {{1, 3}, {0, 1}, 0.2, 0.4}}; + conns_0 = {{{1, 0}, 0, 0.1, 0.1}, + {{1, 1}, 0, 0.1, 0.1}, + {{1, 3}, 1, 0.2, 0.4}}; - conns_1 = {{{0, 0}, {1, 0}, 0.1, 0.2}, - {{0, 0}, {1, 0}, 0.3, 0.1}, - {{0, 0}, {1, 0}, 0.1, 0.8}}; + conns_1 = {{{0, 0}, 0, 0.1, 0.2}, + {{0, 0}, 0, 0.3, 0.1}, + {{0, 0}, 0, 0.1, 0.8}}; auto recipe_2 = custom_recipe({cell_0, cell_1}, {1, 2}, {2, 1}, {conns_0, conns_1}, {{}, {}}, {{}, {}}); auto decomp_2 = partition_load_balance(recipe_2, context); @@ -260,41 +258,13 @@ TEST(recipe, connections) EXPECT_THROW(simulation(recipe_2, decomp_2, context), arb::bad_connection_source_lid); } { - conns_0 = {{{1, 0}, {0, 0}, 0.1, 0.1}, - {{1, 1}, {0, 0}, 0.1, 0.1}, - {{1, 0}, {0, 1}, 0.2, 0.4}}; - - conns_1 = {{{0, 0}, {1, 0}, 0.1, 0.2}, - {{0, 0}, {7, 0}, 0.3, 0.1}, - {{0, 0}, {1, 0}, 0.1, 0.8}}; - - auto recipe_3 = custom_recipe({cell_0, cell_1}, {1, 2}, {2, 1}, {conns_0, conns_1}, {{}, {}}, {{}, {}}); - auto decomp_3 = partition_load_balance(recipe_3, context); - - EXPECT_THROW(simulation(recipe_3, decomp_3, context), arb::bad_connection_target_gid); - } - { - conns_0 = {{{1, 0}, {0, 0}, 0.1, 0.1}, - {{1, 1}, {0, 0}, 0.1, 0.1}, - {{1, 0}, {0, 1}, 0.2, 0.4}}; + conns_0 = {{{1, 0}, 0, 0.1, 0.1}, + {{1, 1}, 0, 0.1, 0.1}, + {{1, 0}, 1, 0.2, 0.4}}; - conns_1 = {{{0, 0}, {1, 0}, 0.1, 0.2}, - {{0, 0}, {0, 0}, 0.3, 0.1}, - {{0, 0}, {1, 0}, 0.1, 0.8}}; - - auto recipe_5 = custom_recipe({cell_0, cell_1}, {1, 2}, {2, 1}, {conns_0, conns_1}, {{}, {}}, {{}, {}}); - auto decomp_5 = partition_load_balance(recipe_5, context); - - EXPECT_THROW(simulation(recipe_5, decomp_5, context), arb::bad_connection_target_gid); - } - { - conns_0 = {{{1, 0}, {0, 0}, 0.1, 0.1}, - {{1, 1}, {0, 0}, 0.1, 0.1}, - {{1, 0}, {0, 1}, 0.2, 0.4}}; - - conns_1 = {{{0, 0}, {1, 0}, 0.1, 0.2}, - {{0, 0}, {1, 9}, 0.3, 0.1}, - {{0, 0}, {1, 0}, 0.1, 0.8}}; + conns_1 = {{{0, 0}, 0, 0.1, 0.2}, + {{0, 0}, 9, 0.3, 0.1}, + {{0, 0}, 0, 0.1, 0.8}}; auto recipe_4 = custom_recipe({cell_0, cell_1}, {1, 2}, {2, 1}, {conns_0, conns_1}, {{}, {}}, {{}, {}}); auto decomp_4 = partition_load_balance(recipe_4, context); @@ -317,9 +287,9 @@ TEST(recipe, event_generators) { auto cell_1 = custom_cell(2, 1, 0); std::vector<arb::event_generator> gens_0, gens_1; { - gens_0 = {arb::explicit_generator(arb::pse_vector{{{0, 0}, 1.0, 0.1}, {{0, 1}, 2.0, 0.1}})}; + gens_0 = {arb::explicit_generator(arb::pse_vector{{0, 1.0, 0.1}, {1, 2.0, 0.1}})}; - gens_1 = {arb::explicit_generator(arb::pse_vector{{{1, 0}, 1.0, 0.1}})}; + gens_1 = {arb::explicit_generator(arb::pse_vector{{0, 1.0, 0.1}})}; auto recipe_0 = custom_recipe({cell_0, cell_1}, {1, 2}, {2, 1}, {{}, {}}, {{}, {}}, {gens_0, gens_1}); auto decomp_0 = partition_load_balance(recipe_0, context); @@ -327,16 +297,7 @@ TEST(recipe, event_generators) { EXPECT_NO_THROW(simulation(recipe_0, decomp_0, context)); } { - gens_0.clear(); - gens_1 = {arb::explicit_generator(arb::pse_vector{{{0, 0}, 1.0, 0.1}})}; - - auto recipe_0 = custom_recipe({cell_0, cell_1}, {1, 2}, {2, 1}, {{}, {}}, {{}, {}}, {gens_0, gens_1}); - auto decomp_0 = partition_load_balance(recipe_0, context); - - EXPECT_THROW(simulation(recipe_0, decomp_0, context), arb::bad_event_generator_target_gid); - } - { - gens_0 = {arb::explicit_generator(arb::pse_vector{{{0, 0}, 1.0, 0.1}, {{0, 3}, 2.0, 0.1}})}; + gens_0 = {arb::explicit_generator(arb::pse_vector{{0, 1.0, 0.1}, {3, 2.0, 0.1}})}; gens_1.clear(); auto recipe_0 = custom_recipe({cell_0, cell_1}, {1, 2}, {2, 1}, {{}, {}}, {{}, {}}, {gens_0, gens_1}); diff --git a/test/unit/test_simulation.cpp b/test/unit/test_simulation.cpp index dda5be17163645f5815f5d05326836eddaa5c151..88d39b72b49717410a5ab71957188deb9fa92e0d 100644 --- a/test/unit/test_simulation.cpp +++ b/test/unit/test_simulation.cpp @@ -94,7 +94,7 @@ struct lif_chain: public recipe { std::vector<cell_connection> connections_on(cell_gid_type target) const { if (target) { - return {cell_connection({target-1, 0}, {target, 0}, weight_, delay_)}; + return {cell_connection({target-1, 0}, 0, weight_, delay_)}; } else { return {}; @@ -106,7 +106,7 @@ struct lif_chain: public recipe { return {}; } else { - return {schedule_generator({target, 0}, weight_, triggers_)}; + return {schedule_generator(0, weight_, triggers_)}; } }