Skip to content
Snippets Groups Projects
Commit a0640a11 authored by Ben Cumming's avatar Ben Cumming Committed by Sam Yates
Browse files

Remove generic event interface on cell_group

`cell_group` had a template method `cell_group::enqueue_events()`, which was parameterized on the type of container used to pass the set of events to enqueue. This PR removes the template, and makes `time_type` a globally defined type in `common_types.hpp`.

The `time_type` that permeated the code is taken from `spike`, which is itself a specialized type alias of `basic_spike`. This is not an intuitive location to define the `time_type`, and hides the fact that as implemented it was effectively a global typedef.

  * Define the default time type in `common_types.hpp`: `using time_type = float`.
  * Use this global `time_type` in the definition of `spike` and `postsynaptic_spike_event`.
  * Replace generic `cell_group::enqueue_events` method with concrete `cell_group::enque_events(const std::vector<post_synaptic_event>&)`.
parent 2e57545c
No related branches found
No related tags found
No related merge requests found
......@@ -35,7 +35,7 @@ using lowered_cell = fvm::fvm_multicell<gpu::backend>;
using lowered_cell = fvm::fvm_multicell<multicore::backend>;
#endif
using model_type = model<lowered_cell>;
using sample_trace_type = sample_trace<model_type::time_type, double>;
using sample_trace_type = sample_trace<time_type, double>;
using file_export_type = io::exporter_spike_file<global_policy>;
void banner();
std::unique_ptr<recipe> make_recipe(const io::cl_options&, const probe_distribution&);
......@@ -122,7 +122,7 @@ int main(int argc, char** argv) {
// Attach samplers to all probes
std::vector<std::unique_ptr<sample_trace_type>> traces;
const model_type::time_type sample_dt = 0.1;
const time_type sample_dt = 0.1;
for (auto probe: m.probes()) {
if (options.trace_max_gid && probe.id.gid>*options.trace_max_gid) {
continue;
......
......@@ -28,7 +28,6 @@ public:
using size_type = typename lowered_cell_type::value_type;
using source_id_type = cell_member_type;
using time_type = spike::time_type;
using sampler_function = std::function<util::optional<time_type>(time_type, double)>;
cell_group() = default;
......@@ -86,7 +85,7 @@ public:
lowered_.setup_integration(tfinal, dt);
std::vector<sample_event<time_type>> requeue_sample_events;
std::vector<sample_event> requeue_sample_events;
while (!lowered_.integration_complete()) {
// Take any pending samples.
// TODO: Placeholder: this will be replaced by a backend polling implementation.
......@@ -145,8 +144,7 @@ public:
PL();
}
template <typename R>
void enqueue_events(const R& events) {
void enqueue_events(const std::vector<postsynaptic_spike_event>& events) {
for (auto& e: events) {
events_.push(e);
}
......@@ -167,7 +165,7 @@ public:
void add_sampler(cell_member_type probe_id, sampler_function s, time_type start_time = 0) {
auto handle = get_probe_handle(probe_id);
using size_type = sample_event<time_type>::size_type;
using size_type = sample_event::size_type;
auto sampler_index = size_type(samplers_.size());
samplers_.push_back({handle, probe_id.gid, s});
sampler_start_times_.push_back(start_time);
......@@ -192,10 +190,10 @@ private:
event_binner binner_;
// Pending events to be delivered.
event_queue<postsynaptic_spike_event<time_type>> events_;
event_queue<postsynaptic_spike_event> events_;
// Pending samples to be taken.
event_queue<sample_event<time_type>> sample_events_;
event_queue<sample_event> sample_events_;
std::vector<time_type> sampler_start_times_;
// Handles for accessing lowered cell.
......@@ -263,7 +261,7 @@ private:
void reset_samplers() {
// clear all pending sample events and reset to start at time 0
sample_events_.clear();
using size_type = sample_event<time_type>::size_type;
using size_type = sample_event::size_type;
for(size_type i=0; i<samplers_.size(); ++i) {
sample_events_.push({i, sampler_start_times_[i]});
}
......
......@@ -49,6 +49,10 @@ struct cell_member_type {
DEFINE_LEXICOGRAPHIC_ORDERING(cell_member_type,(a.gid,a.index),(b.gid,b.index))
// For storing time values [ms]
using time_type = float;
} // namespace mc
} // namespace nest
......
......@@ -7,6 +7,7 @@
#include <functional>
#include <algorithms.hpp>
#include <common_types.hpp>
#include <connection.hpp>
#include <communication/gathered_vector.hpp>
#include <event_queue.hpp>
......@@ -34,11 +35,10 @@ template <typename CommunicationPolicy>
class communicator {
public:
using communication_policy_type = CommunicationPolicy;
using time_type = spike::time_type;
/// per-cell group lists of events to be delivered
using event_queue =
std::vector<postsynaptic_spike_event<time_type>>;
std::vector<postsynaptic_spike_event>;
using gid_partition_type =
util::partition_range<std::vector<cell_gid_type>::const_iterator>;
......
......@@ -11,8 +11,6 @@ namespace mc {
class connection {
public:
using time_type = spike::time_type;
connection() = default;
connection(cell_member_type src, cell_member_type dest, float w, time_type d) :
source_(src),
......@@ -27,7 +25,7 @@ public:
cell_member_type source() const { return source_; }
cell_member_type destination() const { return destination_; }
postsynaptic_spike_event<time_type> make_event(const spike& s) {
postsynaptic_spike_event make_event(const spike& s) {
return {destination_, s.time + delay_, weight_};
}
......
......@@ -16,8 +16,7 @@ void event_binner::reset() {
last_event_times_.clear();
}
event_binner::time_type
event_binner::bin(cell_gid_type id, time_type t, time_type t_min) {
time_type event_binner::bin(cell_gid_type id, time_type t, time_type t_min) {
time_type t_binned = t;
switch (policy_) {
......@@ -43,7 +42,7 @@ event_binner::bin(cell_gid_type id, time_type t, time_type t_min) {
return std::max(t_binned, t_min);
}
util::optional<event_binner::time_type>
util::optional<time_type>
event_binner::last_event_time(cell_gid_type id) {
auto it = last_event_times_.find(id);
return it==last_event_times_.end()? util::nothing: util::just(it->second);
......
......@@ -18,8 +18,6 @@ enum class binning_kind {
class event_binner {
public:
using time_type = spike::time_type;
event_binner(): policy_(binning_kind::none), bin_interval_(0) {}
event_binner(binning_kind policy, time_type bin_interval):
......
......@@ -20,18 +20,13 @@ namespace mc {
* Time values must be well ordered with respect to `operator>`.
*/
template <typename Time>
struct postsynaptic_spike_event {
using time_type = Time;
cell_member_type target;
time_type time;
float weight;
};
template <typename Time>
struct sample_event {
using time_type = Time;
using size_type = std::uint32_t;
size_type sampler_index;
......@@ -58,7 +53,7 @@ template <typename Event>
class event_queue {
public :
using value_type = Event;
using time_type = impl::event_time_type<Event>;
using event_time_type = impl::event_time_type<Event>;
event_queue() {}
......@@ -79,7 +74,7 @@ public :
}
// Return time t of head of queue if `t_until` > `t`.
util::optional<time_type> time_if_before(const time_type& t_until) {
util::optional<event_time_type> time_if_before(const event_time_type& t_until) {
if (queue_.empty()) {
return util::nothing;
}
......@@ -105,7 +100,7 @@ public :
}
// Pop and return top event `ev` of queue if `t_until` > `event_time(ev)`.
util::optional<value_type> pop_if_before(const time_type& t_until) {
util::optional<value_type> pop_if_before(const event_time_type& t_until) {
using ::nest::mc::event_time;
return pop_if(
[&t_until](const value_type& ev) { return t_until > event_time(ev); }
......@@ -113,7 +108,7 @@ public :
}
// Pop and return top event `ev` of queue unless `event_time(ev)` > `t_until`
util::optional<value_type> pop_if_not_after(const time_type& t_until) {
util::optional<value_type> pop_if_not_after(const event_time_type& t_until) {
using ::nest::mc::event_time;
return pop_if(
[&t_until](const value_type& ev) { return !(event_time(ev) > t_until); }
......@@ -143,8 +138,8 @@ private:
} // namespace nest
} // namespace mc
template <typename T>
inline std::ostream& operator<<(std::ostream& o, const nest::mc::postsynaptic_spike_event<T>& e)
inline std::ostream& operator<<(
std::ostream& o, const nest::mc::postsynaptic_spike_event& e)
{
return o << "event[" << e.target << "," << e.time << "," << e.weight << "]";
}
......@@ -28,7 +28,6 @@ class model {
public:
// FIXME: this is an intermediate step to remove the template parameter from model
using cell_group_type = cell_group<Cell>; // FIXME
using time_type = typename spike::time_type;
using communicator_type = communication::communicator<communication::global_policy>;
using spike_export_function = std::function<void(const std::vector<spike>&)>;
......
......@@ -8,10 +8,9 @@
namespace nest {
namespace mc {
template <typename I, typename Time>
template <typename I>
struct basic_spike {
using id_type = I;
using time_type = Time;
id_type source = id_type{};
time_type time = -1;
......@@ -24,21 +23,21 @@ struct basic_spike {
};
/// Standard specialization:
using spike = basic_spike<cell_member_type, float>;
using spike = basic_spike<cell_member_type>;
} // namespace mc
} // namespace nest
// Custom stream operator for printing nest::mc::spike<> values.
template <typename I, typename T>
std::ostream& operator<<(std::ostream& o, nest::mc::basic_spike<I, T> s) {
template <typename I>
std::ostream& operator<<(std::ostream& o, nest::mc::basic_spike<I> s) {
return o << "spike[t " << s.time << ", src " << s.source << "]";
}
/// Less than comparison operator for nest::mc::spike<> values:
/// spikes are ordered by spike time, for use in sorting and queueing.
template <typename I, typename T>
bool operator<(nest::mc::basic_spike<I, T> lhs, nest::mc::basic_spike<I, T> rhs) {
template <typename I>
bool operator<(nest::mc::basic_spike<I> lhs, nest::mc::basic_spike<I> rhs) {
return lhs.time < rhs.time;
}
......
......@@ -8,7 +8,7 @@
using namespace nest::mc;
TEST(event_queue, push) {
using ps_event_queue = event_queue<postsynaptic_spike_event<float>>;
using ps_event_queue = event_queue<postsynaptic_spike_event>;
ps_event_queue q;
......@@ -29,7 +29,7 @@ TEST(event_queue, push) {
}
TEST(event_queue, pop_if_before) {
using ps_event_queue = event_queue<postsynaptic_spike_event<float>>;
using ps_event_queue = event_queue<postsynaptic_spike_event>;
cell_member_type target[4] = {
{1u, 0u},
......@@ -38,7 +38,7 @@ TEST(event_queue, pop_if_before) {
{2u, 3u}
};
postsynaptic_spike_event<float> events[] = {
postsynaptic_spike_event events[] = {
{target[0], 1.f, 2.f},
{target[1], 2.f, 2.f},
{target[2], 3.f, 2.f},
......
......@@ -39,7 +39,7 @@ void run_synapse_test(
add_common_voltage_probes(c);
// injected spike events
postsynaptic_spike_event<float> synthetic_events[] = {
std::vector<postsynaptic_spike_event> synthetic_events = {
{{0u, 0u}, 10.0, 0.04},
{{0u, 0u}, 20.0, 0.04},
{{0u, 0u}, 40.0, 0.04}
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment