diff options
author | Jan Huwald <jh@sotun.de> | 2012-05-07 20:01:51 (GMT) |
---|---|---|
committer | Jan Huwald <jh@sotun.de> | 2012-05-07 20:01:51 (GMT) |
commit | 420d2ef464d4a741028e132e662d5626806a41f5 (patch) | |
tree | 1aca6eb512e4ed0fb5f3c10c528cb998b6ffd695 /core/pointers.hpp |
Diffstat (limited to 'core/pointers.hpp')
-rw-r--r-- | core/pointers.hpp | 213 |
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 |