summaryrefslogtreecommitdiff
path: root/core/pointers.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/pointers.hpp')
-rw-r--r--core/pointers.hpp213
1 files changed, 213 insertions, 0 deletions
diff --git a/core/pointers.hpp b/core/pointers.hpp
new file mode 100644
index 0000000..cae5f4b
--- /dev/null
+++ b/core/pointers.hpp
@@ -0,0 +1,213 @@
+#ifndef wOYVH4QhyaNIiefhP4sh9Osro2k
+#define wOYVH4QhyaNIiefhP4sh9Osro2k
+
+#include <assert.h>
+
+#include <iostream>
+
+#include <boost/integer.hpp>
+#include <boost/static_assert.hpp>
+
+#include "simlimits.hpp"
+#include "template_helpers.hpp"
+
+// HINT: the template Ptr<> is defined in quant_types; it is an empty,
+// forbidden basecase anyway
+#include "quant_types.hpp"
+
+namespace PtrImpl {
+
+using boost::is_same;
+
+template<typename Quant, typename IterPtr>
+struct Iter {
+ Iter(IterPtr ptr) : ptr(ptr) {}
+ Ptr<Quant> operator* () const { return Ptr<Quant>(ptr); }
+#define REL(op) bool operator op (Iter i) { return ptr op i.ptr; }
+ REL(!=)
+ REL(==)
+#undef REL
+ Iter& operator++ () { ptr++; return *this; }
+ Iter& operator-- () { ptr--; return *this; }
+ IterPtr ptr;
+};
+
+template<typename Quant, typename IterPtr>
+struct Range {
+ typedef Iter<Quant, IterPtr> iter_t;
+ // init range with raw begin/end ptr or the first and last element
+ // to visit (DIFFERENT SEMANTICS!)
+ Range(IterPtr p1, IterPtr p2) : p1(p1), p2(p2) {}
+ Range(Ptr<Quant> p1, Ptr<Quant> p2) : p1(p1.raw), p2(p2.raw + 1) {}
+ iter_t begin() const { return iter_t(p1); }
+ iter_t end() const { return iter_t(p2); }
+ IterPtr p1, p2;
+};
+
+// we discriminate between storage and iter pointer to allow a zero
+// bit storage pointer while maintaining a conforming iteration
+// strategy
+template<typename Quant, uint64_t instanceCount,
+ typename StoragePtr = typename boost::uint_value_t<instanceCount - 1>::least,
+ typename IterPtr = typename boost::uint_value_t<instanceCount >::least>
+struct Common {
+ typedef StoragePtr ptr_t;
+ typedef Range<Quant, IterPtr> range_t;
+
+ Common() = delete;
+ //Common(const StoragePtr raw) : raw(raw) {}
+ explicit Common(const IterPtr ptr) : raw(ptr) {}
+ const StoragePtr operator() () const { return raw; }
+ Ptr<Quant>& operator++ () { raw++; return FORCE_CONV(Ptr<Quant>, *this); }
+#define REL(op) bool operator op (Common const &i) const { return raw op i.raw; }
+ REL(!=)
+ REL(==)
+ REL(<) REL(<=)
+ REL(>) REL(>=)
+#undef REL
+
+ static range_t all() {
+ BOOST_STATIC_ASSERT((is_same<typename Quant::class_t,
+ ContinuousPropertyClass>::value));
+ return range_t(0, instanceCount);
+ }
+
+ // return instanceCount; different semantic for continuous and
+ // discrete quants, so we use two identical function
+ static constexpr IterPtr numInstances() {
+ BOOST_STATIC_ASSERT((is_same<typename Quant::class_t,
+ ContinuousPropertyClass>::value));
+ return instanceCount;
+ }
+
+ static constexpr IterPtr maxInstances() {
+ BOOST_STATIC_ASSERT((is_same<typename Quant::class_t,
+ DiscretePropertyClass>::value));
+ return instanceCount;
+ }
+
+ StoragePtr raw;
+};
+
+// we define the Common<>-instances later used to maintain
+// one-source-of-truth albeit circular dependencies
+typedef Common<Synapse, maxNeurons * maxSynapsesPerNeuron> CommonSynapse;
+typedef Common<Neuron, maxNeurons> CommonNeuron;
+
+} // NS
+
+////////////////////////////////////////////////////////////////////////////////
+// CONTINOUS PROPERTIES
+////////////////////////////////////////////////////////////////////////////////
+
+#define PTR_DEFAULT_CTOR \
+ explicit Ptr(const ptr_t raw) : Common(raw) {}
+
+template<>
+struct Ptr<Global> : PtrImpl::Common<Global, 1> {
+ Ptr() : Common(0) {}
+ explicit Ptr(const uint64_t raw) : Common(0) { assert(raw == 0); }
+// #define REL(op) bool operator op (Ptr &i) { return raw op i.raw; }
+// REL(!=)
+// REL(==)
+// REL(<) REL(<=)
+// REL(>) REL(>=)
+// #undef REL
+
+
+ inline PtrImpl::CommonNeuron::range_t childs() const;
+};
+
+template<>
+struct Ptr<Neuron> : PtrImpl::CommonNeuron {
+ PTR_DEFAULT_CTOR
+
+
+ inline PtrImpl::CommonSynapse::range_t childs() const;
+};
+
+template<>
+struct Ptr<Synapse> : PtrImpl::CommonSynapse {
+ typedef boost::uint_value_t<maxSynapsesPerNeuron>::least offset_t;
+
+ PTR_DEFAULT_CTOR
+ Ptr(const Ptr<Neuron> neuron, const offset_t synapse)
+ : Common(neuron() * maxSynapsesPerNeuron + synapse) {}
+
+ const Ptr<Neuron> extractNeuron() const {
+ return Ptr<Neuron>(raw / maxSynapsesPerNeuron);
+ }
+ const offset_t extractSynapseOffset() const {
+ return (raw % maxSynapsesPerNeuron);
+ }
+};
+
+// we have to declare childs()-functions after childs' Ptr<>
+
+inline PtrImpl::CommonNeuron::range_t Ptr<Global>::childs() const {
+ return PtrImpl::CommonNeuron::range_t{
+ Ptr<Neuron>{0},
+ Ptr<Neuron>{maxNeurons - 1}};
+}
+
+inline PtrImpl::CommonSynapse::range_t Ptr<Neuron>::childs() const {
+ return PtrImpl::CommonSynapse::range_t{
+ Ptr<Synapse>{*this, 0},
+ Ptr<Synapse>{*this, maxSynapsesPerNeuron - 1}};
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// DISCRETE PROPERTIES
+////////////////////////////////////////////////////////////////////////////////
+
+template<>
+struct Ptr<GlobalMsg> : PtrImpl::Common<GlobalMsg, maxGlobalMsg> {
+ PTR_DEFAULT_CTOR
+};
+
+template<>
+struct Ptr<Spike> : PtrImpl::Common<Spike, maxSpikes> {
+ PTR_DEFAULT_CTOR
+};
+
+template<>
+struct Ptr<RandomSpike> : PtrImpl::Common<RandomSpike, maxRandomSpikes> {
+ PTR_DEFAULT_CTOR
+};
+
+template<>
+struct Ptr<SpikeArrival> : PtrImpl::Common<SpikeArrival,
+ maxSpikes * maxSynapsesPerNeuron> {
+ typedef boost::uint_value_t<maxSynapsesPerNeuron>::least offset_t;
+
+ PTR_DEFAULT_CTOR
+ // HINT: offset refers to the topology table of the neuron
+ // corresponding to the given spike, _not_ to the synpase offset of
+ // the receiving neuron
+ Ptr(const Ptr<Spike> spike, const offset_t offset)
+ : Common(spike() * maxSynapsesPerNeuron + offset) {}
+ const Ptr<Spike> extractSpike() const {
+ return Ptr<Spike>(raw / maxSynapsesPerNeuron);
+ }
+};
+
+// Stream I/O
+
+namespace std {
+#define GEN(T) \
+ ostream& operator<< (ostream &os, Ptr<T> val) { return os << (uint64_t) val(); }
+
+GEN(Global)
+GEN(Neuron)
+GEN(Synapse)
+GEN(GlobalMsg)
+GEN(Spike)
+GEN(RandomSpike)
+GEN(SpikeArrival)
+
+#undef GEN
+}
+
+
+
+#endif // wOYVH4QhyaNIiefhP4sh9Osro2k
contact: Jan Huwald // Impressum