Cypress  1.0
C++ Spiking Neural Network Simulation Framework
network.hpp
Go to the documentation of this file.
1 /*
2  * Cypress -- C++ Spiking Neural Network Simulation Framework
3  * Copyright (C) 2016 Andreas Stöckel
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
34 #pragma once
35 
36 #ifndef CYPRESS_CORE_NETWORK_HPP
37 #define CYPRESS_CORE_NETWORK_HPP
38 
42 
43 namespace cypress {
44 
45 /*
46  * Forward declarations
47  */
48 class Network;
49 template <typename T>
50 class Population;
51 template <typename T>
53 template <typename T>
54 class Neuron;
55 
61 template <typename T>
62 class Population
63  : public IterableMixin<Population<T>, Neuron<T>, Accessor>,
64  public ViewableMixin<Population<T>, PopulationView<T>, Accessor>,
65  public DataMixin<Population<T>, Accessor, typename T::Parameters,
66  typename T::Signals>,
67  public PopulationMixin<Population<T>, Accessor>,
68  public ConnectableMixin<Population<T>, Accessor> {
69 private:
70  using PopulationMixin_ = PopulationMixin<Population<T>, Accessor>;
71  using DataMixin_ = DataMixin<Population<T>, Accessor,
72  typename T::Parameters, typename T::Signals>;
74  using ViewableMixin_ =
76 
77  PopulationBase m_population;
78 
79 public:
81  using IterableMixin_::operator();
82  using ViewableMixin_::operator();
83 
88  explicit Population(const PopulationBase &population)
89  : m_population(population)
90  {
91  }
92 
106  Population(Network &network, size_t size,
107  const typename T::Parameters &params = typename T::Parameters(),
108  const typename T::Signals &signals = typename T::Signals(),
109  const char *name = "");
110 
124  Population(Network &network, size_t size,
125  const typename T::Parameters &params, const char *name)
126  : Population(network, size, params, typename T::Signals(), name)
127  {
128  }
129 
134  operator PopulationBase() const { return m_population; }
135  operator const PopulationBase &() const { return m_population; }
136  operator PopulationBase &() { return m_population; }
137 
143  const NeuronType &type() const { return T::inst(); }
144 
151  Network network() const;
152 
158  PopulationIndex pid() const { return m_population.pid(); }
159 };
160 
166 template <typename T>
167 class PopulationView
168  : public IterableMixin<PopulationView<T>, Neuron<T>, Accessor>,
169  public ViewableMixin<PopulationView<T>, PopulationView<T>, Accessor>,
170  public DataMixin<PopulationView<T>, Accessor, typename T::Parameters,
171  typename T::Signals>,
172  public ConnectableMixin<PopulationView<T>, Accessor> {
173 private:
174  using IterableMixin_ =
176  using ViewableMixin_ =
178 
179  PopulationViewBase m_view;
180 
181 public:
182  using IterableMixin_::operator();
183  using ViewableMixin_::operator();
184 
199  NeuronIndex nid0, NeuronIndex nid1)
200  : m_view(network, pid, nid0, nid1)
201  {
202  if ((network.populations()[pid].size() < size_t(nid1)) ||
203  (nid1 < nid0)) {
204  throw CypressException(
205  "2nd Neuron index " + std::to_string(nid1) +
206  "is either bigger than Population size or start neuron id");
207  }
208  }
209 
214  operator PopulationViewBase() const { return m_view; }
215  operator const PopulationViewBase &() const { return m_view; }
216  operator PopulationViewBase &() { return m_view; }
217 
223  const NeuronType &type() const { return T::inst(); }
224 
231  Network network() const;
232 
238  PopulationIndex pid() const { return m_view.pid(); }
239 
243  NeuronIndex nid_begin() const { return m_view.nid_begin(); }
244 
249  NeuronIndex nid_end() const { return m_view.nid_end(); }
250 };
251 
256 template <typename T>
257 class Neuron : public NeuronMixin<Neuron<T>>,
258  public IterableMixin<Neuron<T>, Neuron<T>, Accessor>,
259  public ViewableMixin<Neuron<T>, PopulationViewBase, Accessor>,
260  public DataMixin<Neuron<T>, Accessor, typename T::Parameters,
261  typename T::Signals>,
262  public ConnectableMixin<Neuron<T>, Accessor> {
263 private:
264  using DataMixin_ = DataMixin<Neuron<T>, Accessor, typename T::Parameters,
265  typename T::Signals>;
267  using ViewableMixin_ =
269 
270  NeuronBase m_neuron;
271 
272 public:
273  using IterableMixin_::operator();
274  using ViewableMixin_::operator();
275 
283  explicit Neuron(const NeuronBase &neuron) : m_neuron(neuron) {}
284 
293  template <typename Parent>
294  Neuron(const Parent &parent, NeuronIndex nid)
295  : m_neuron(parent, nid)
296  {
297  }
298 
303  operator NeuronBase() const { return m_neuron; }
304  operator const NeuronBase &() const { return m_neuron; }
305  operator NeuronBase &() { return m_neuron; }
306 
310  const NeuronType &type() const { return T::inst(); }
311 
315  Network network() const;
316 
324  {
325  return Population<T>(m_neuron.network(), pid());
326  }
327 
331  PopulationIndex pid() const { return m_neuron.pid(); }
332 
338  NeuronIndex nid() const { return m_neuron.nid(); }
339 };
340 
341 namespace internal {
342 template <typename PopulationType>
343 auto resolve_population(Network &, PopulationType p);
344 }
345 
349 class Network : public NetworkBase {
350 private:
351  template <typename T>
352  friend class Population;
353 
354  template <typename T>
355  size_t create_population_index(size_t size,
356  const typename T::Parameters &params,
357  const typename T::Signals &signals,
358  const std::string &name = std::string())
359  {
360  return NetworkBase::create_population_index(size, T::inst(), params,
361  signals, name);
362  }
363 
364 public:
367 
368  Network() = default;
369  Network(const Network &) = default;
370  Network(Network &&) noexcept = default;
371  Network &operator=(const Network &) = default;
372  Network &operator=(Network &&) = default;
373  ~Network() = default;
374 
379 
384  {
385  *this = Network(o);
386  return *this;
387  }
388 
398  template <typename T>
399  std::vector<Population<T>> populations(
400  const std::string &name = std::string())
401  {
402  std::vector<Population<T>> res;
403  for (const PopulationBase &p : populations(name, T::inst())) {
404  res.emplace_back(PopulationBase(*this, p.pid()));
405  }
406  return res;
407  }
408 
419  PopulationBase population(const std::string &name = std::string())
420  {
421  auto pops = populations(name);
422  if (pops.empty()) {
424  std::string("Population with name \"") + name +
425  "\" does not exist");
426  }
427  return pops.back();
428  }
429 
439  template <typename T>
440  Population<T> population(const std::string &name = std::string())
441  {
442  auto pops = populations<T>(name);
443  if (pops.empty()) {
445  std::string("Population of type \"") + T::inst().name +
446  "\" with name \"" + name + "\" does not exist");
447  }
448  return pops.back();
449  }
450 
451  template <typename T>
453  const typename T::Parameters &params,
454  const typename T::Signals &signals,
455  const char *name = "")
456  {
457  return Population<T>(*this, size, params, signals, name);
458  }
459 
460  template <typename T>
462  size_t size,
463  const typename T::Parameters &params = typename T::Parameters(),
464  const char *name = "")
465  {
466  return Population<T>(*this, size, params, name);
467  }
468 
469  /*
470  * One-line builder-like interface
471  */
472 
473  template <typename T>
475  const char *name, size_t size, const typename T::Parameters &params,
476  const typename T::Signals &signals = typename T::Signals())
477  {
478  create_population<T>(size, params, signals, name);
479  return *this;
480  }
481 
482  template <typename Source, typename Target>
483  Network &add_connection(const Source &source, const Target &target,
484  std::unique_ptr<Connector> connector, const char *name = "")
485  {
486  internal::resolve_population(*this, source)
487  .connect_to(internal::resolve_population(*this, target),
488  std::move(connector), name);
489  return *this;
490  }
491 
504  Network &run(const Backend &backend, Real duration = 0.0)
505  {
506  NetworkBase::run(backend, duration);
507  return *this;
508  }
509 
531  Network &run(const std::string &backend_id, Real duration = 0.0,
532  int argc = 0, const char *argv[] = nullptr)
533  {
534  NetworkBase::run(backend_id, duration, argc, argv);
535  return *this;
536  }
537 };
538 
539 /*
540  * Out-of-class function definitions.
541  */
542 
543 template <typename T>
545  const typename T::Parameters &params,
546  const typename T::Signals &signals,
547  const char *name)
548  : Population(PopulationBase(network, network.create_population_index<T>(
549  size, params, signals, name)))
550 {
551 }
552 
553 template <typename T>
555 {
556  return Network(m_population.network());
557 }
558 
559 template <typename T>
561 {
562  return Network(m_view.network());
563 }
564 
565 template <typename T>
567 {
568  return Network(m_neuron.network());
569 }
570 
571 namespace internal {
572 template <typename PopulationType>
573 inline auto resolve_population(Network &, PopulationType p)
574 {
575  return p;
576 }
577 
578 template <>
579 inline auto resolve_population(Network &net, const char *str)
580 {
581  return net.population(str);
582 }
583 
584 template <>
585 inline auto resolve_population(Network &net, const std::string &str)
586 {
587  return net.population(str);
588 }
589 }
590 }
591 
592 #endif /* CYPRESS_CORE_NETWORK_HPP */
593 
Definition: neurons_base.hpp:54
PopulationIndex pid() const
Definition: network.hpp:331
NeuronIndex nid() const
Definition: network.hpp:338
Network & operator=(const NetworkBase &o)
Definition: network.hpp:383
Population< T > population() const
Definition: network.hpp:323
Network network() const
Definition: network.hpp:560
PopulationBase population(PopulationIndex pid)
Definition: network_base.hpp:67
Definition: network_base_objects.hpp:103
Definition: network_base_objects.hpp:241
const NeuronType & type() const
Definition: network.hpp:310
int32_t NeuronIndex
Definition: types.hpp:74
Definition: network_base.hpp:64
Definition: backend.hpp:50
Population(const PopulationBase &population)
Definition: network.hpp:88
NeuronIndex nid_end() const
Definition: network_base_objects.hpp:162
Network network() const
Definition: network.hpp:554
Definition: network.hpp:54
Definition: network_base.hpp:70
Neuron(const Parent &parent, NeuronIndex nid)
Definition: network.hpp:294
Definition: exceptions.hpp:65
const T::Signals signals() const
Definition: network_mixins.hpp:253
Definition: network.hpp:50
double Real
Definition: types.hpp:56
auto resolve_population(Network &net, const std::string &str)
Definition: network.hpp:585
Definition: network_mixins.hpp:103
Population(Network &network, size_t size, const typename T::Parameters &params, const char *name)
Definition: network.hpp:124
PopulationIndex pid() const
Definition: network_base_objects.hpp:151
PopulationIndex pid() const
Definition: network_base_objects.hpp:96
PopulationView(const NetworkBase &network, PopulationIndex pid, NeuronIndex nid0, NeuronIndex nid1)
Definition: network.hpp:198
NeuronIndex nid() const
Definition: network_base_objects.hpp:230
Population< T > create_population(size_t size, const typename T::Parameters &params=typename T::Parameters(), const char *name="")
Definition: network.hpp:461
Network & run(const std::string &backend_id, Real duration=0.0, int argc=0, const char *argv[]=nullptr)
Definition: network.hpp:531
Definition: network_base_objects.hpp:169
NetworkBase network() const
Definition: network_base_objects.hpp:89
PopulationIndex create_population_index(size_t size, const NeuronType &type, const NeuronParameters &params, const NeuronSignals &signals, const std::string &name)
size_t size() const
Definition: network_mixins.hpp:81
Definition: network_base.hpp:116
NeuronIndex nid_begin() const
Definition: network_base_objects.hpp:156
Definition: network_base_objects.hpp:53
Network & add_connection(const Source &source, const Target &target, std::unique_ptr< Connector > connector, const char *name="")
Definition: network.hpp:483
Population< T > create_population(size_t size, const typename T::Parameters &params, const typename T::Signals &signals, const char *name="")
Definition: network.hpp:452
const std::vector< PopulationBase > populations(const std::string &name=std::string(), const NeuronType &type=NullNeuron::inst()) const
PopulationIndex pid() const
Definition: network.hpp:158
std::vector< Population< T > > populations(const std::string &name=std::string())
Definition: network.hpp:399
Definition: network.hpp:349
Network & add_population(const char *name, size_t size, const typename T::Parameters &params, const typename T::Signals &signals=typename T::Signals())
Definition: network.hpp:474
Population< T > population(const std::string &name=std::string())
Definition: network.hpp:440
NeuronIndex nid_end() const
Definition: network.hpp:249
NetworkBase network() const
Definition: network_base_objects.hpp:207
Network & run(const Backend &backend, Real duration=0.0)
Definition: network.hpp:504
Definition: brainscales_lib.hpp:39
const std::string & name() const
Definition: network_mixins.hpp:66
const NeuronType & type() const
Definition: network.hpp:143
void run(const Backend &backend, Real duration=0.0)
PopulationIndex pid() const
Definition: network_base_objects.hpp:223
Definition: network_mixins.hpp:363
Neuron(const NeuronBase &neuron)
Definition: network.hpp:283
PopulationBase population(const std::string &name=std::string())
Definition: network.hpp:419
NeuronIndex nid_begin() const
Definition: network.hpp:243
Definition: network_mixins.hpp:268
Network network() const
Definition: network.hpp:566
int32_t PopulationIndex
Definition: types.hpp:75
Definition: exceptions.hpp:38
PopulationIndex pid() const
Definition: network.hpp:238
const NeuronType & type() const
Definition: network.hpp:223
Definition: network.hpp:52
auto resolve_population(Network &, PopulationType p)
Definition: network.hpp:573