1 /*
2  *  target_data.h
3  *
4  *  This file is part of NEST.
5  *
6  *  Copyright (C) 2004 The NEST Initiative
7  *
8  *  NEST is free software: you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation, either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  NEST is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with NEST.  If not, see <http://www.gnu.org/licenses/>.
20  *
21  */
22 
23 #ifndef TARGET_DATA_H
24 #define TARGET_DATA_H
25 
26 // C++ includes:
27 #include <limits>
28 
29 // Includes from nestkernel:
30 #include "nest_types.h"
31 #include "static_assert.h"
32 #include "target.h"
33 
34 namespace nest
35 {
36 class TargetDataFields
37 {
38 private:
39   unsigned int lcid_ : NUM_BITS_LCID;
40   unsigned int tid_ : NUM_BITS_TID;
41   unsigned int syn_id_ : NUM_BITS_SYN_ID;
42 
43 public:
44   // Members must be set explicitly -- no defaults
45 
46   /**
47    * Sets the local connection ID.
48    */
49   void set_lcid( const index lcid );
50 
51   /**
52    * Returns the local connection ID.
53    */
54   index get_lcid() const;
55 
56   /**
57    * Sets the target ID.
58    */
59   void set_tid( const thread tid );
60 
61   /**
62    * Returns the target ID.
63    */
64   thread get_tid() const;
65 
66   /**
67    * Sets the synapse-type ID.
68    */
69   void set_syn_id( const synindex syn_id );
70 
71   /**
72    * Returns the synapse-type ID.
73    */
74   synindex get_syn_id() const;
75 };
76 
77 //! check legal size
78 using success_target_data_fields_size = StaticAssert< sizeof( TargetDataFields ) == 8 >::success;
79 
80 inline void
set_lcid(const index lcid)81 TargetDataFields::set_lcid( const index lcid )
82 {
83   lcid_ = lcid;
84 }
85 
86 inline index
get_lcid()87 TargetDataFields::get_lcid() const
88 {
89   return lcid_;
90 }
91 
92 inline void
set_tid(const thread tid)93 TargetDataFields::set_tid( const thread tid )
94 {
95   tid_ = tid;
96 }
97 
98 inline thread
get_tid()99 TargetDataFields::get_tid() const
100 {
101   return tid_;
102 }
103 
104 inline void
set_syn_id(const synindex syn_id)105 TargetDataFields::set_syn_id( const synindex syn_id )
106 {
107   syn_id_ = syn_id;
108 }
109 
110 inline synindex
get_syn_id()111 TargetDataFields::get_syn_id() const
112 {
113   return syn_id_;
114 }
115 
116 class SecondaryTargetDataFields
117 {
118 private:
119   unsigned int recv_buffer_pos_;
120   unsigned char syn_id_;
121 
122 public:
123   // Members must be set explicitly -- no defaults
124   void set_recv_buffer_pos( const size_t pos );
125   size_t get_recv_buffer_pos() const;
126   void set_syn_id( const synindex syn_id );
127   synindex get_syn_id() const;
128 };
129 
130 //! check legal size
131 using success_secondary_target_data_fields_size = StaticAssert< sizeof( SecondaryTargetDataFields ) == 8 >::success;
132 
133 inline void
set_recv_buffer_pos(const size_t pos)134 SecondaryTargetDataFields::set_recv_buffer_pos( const size_t pos )
135 {
136   assert( pos < std::numeric_limits< unsigned int >::max() );
137   recv_buffer_pos_ = pos;
138 }
139 
140 inline size_t
get_recv_buffer_pos()141 SecondaryTargetDataFields::get_recv_buffer_pos() const
142 {
143   return recv_buffer_pos_;
144 }
145 
146 inline void
set_syn_id(const synindex syn_id)147 SecondaryTargetDataFields::set_syn_id( const synindex syn_id )
148 {
149   assert( syn_id < std::numeric_limits< unsigned char >::max() );
150   syn_id_ = syn_id;
151 }
152 
153 inline synindex
get_syn_id()154 SecondaryTargetDataFields::get_syn_id() const
155 {
156   return syn_id_;
157 }
158 
159 enum enum_status_target_data_id
160 {
161   TARGET_DATA_ID_DEFAULT,
162   TARGET_DATA_ID_COMPLETE,
163   TARGET_DATA_ID_END,
164   TARGET_DATA_ID_INVALID
165 };
166 
167 /**
168  * Used to communicate part of the connection infrastructure from
169  * post- to presynaptic side. These are the elements of the MPI
170  * buffers.
171  * SeeAlso: SpikeData
172  */
173 class TargetData
174 {
175   // Members must be set explicitly -- no defaults
176   // Done this way to create large vector without preconstruction
177   // and to handle variant fields
178 
179 private:
180   static constexpr uint8_t NUM_BITS_LID = 19U;
181   static constexpr uint8_t NUM_BITS_MARKER = 2U;
182   static constexpr uint8_t NUM_BITS_IS_PRIMARY = 1U;
183 
184   static constexpr int MAX_LID = generate_max_value( NUM_BITS_LID );
185 
186   unsigned int source_lid_ : NUM_BITS_LID; //!< local id of presynaptic neuron
187   //! thread index of presynaptic neuron
188   unsigned int source_tid_ : NUM_BITS_TID;
189   unsigned int marker_ : NUM_BITS_MARKER;
190   //! TargetData has TargetDataFields else SecondaryTargetDataFields
191   bool is_primary_ : NUM_BITS_IS_PRIMARY;
192 
193 public:
194   //! variant fields
195   union
196   {
197     TargetDataFields target_data;
198     SecondaryTargetDataFields secondary_data;
199   };
200 
201   void reset_marker();
202   void set_complete_marker();
203   void set_end_marker();
204   void set_invalid_marker();
205   bool is_complete_marker() const;
206   bool is_end_marker() const;
207   bool is_invalid_marker() const;
208   void set_source_lid( const index source_lid );
209   void set_source_tid( const thread source_tid );
210   index get_source_lid() const;
211   thread get_source_tid() const;
212   void set_is_primary( const bool is_primary );
213   bool is_primary() const;
214 };
215 
216 //! check legal size
217 using success_target_data_size = StaticAssert< sizeof( TargetData ) == 12 >::success;
218 
219 inline void
reset_marker()220 TargetData::reset_marker()
221 {
222   marker_ = TARGET_DATA_ID_DEFAULT;
223 }
224 
225 inline void
set_complete_marker()226 TargetData::set_complete_marker()
227 {
228   marker_ = TARGET_DATA_ID_COMPLETE;
229 }
230 
231 inline void
set_end_marker()232 TargetData::set_end_marker()
233 {
234   marker_ = TARGET_DATA_ID_END;
235 }
236 
237 inline void
set_invalid_marker()238 TargetData::set_invalid_marker()
239 {
240   marker_ = TARGET_DATA_ID_INVALID;
241 }
242 
243 inline bool
is_complete_marker()244 TargetData::is_complete_marker() const
245 {
246   return marker_ == TARGET_DATA_ID_COMPLETE;
247 }
248 
249 inline bool
is_end_marker()250 TargetData::is_end_marker() const
251 {
252   return marker_ == TARGET_DATA_ID_END;
253 }
254 
255 inline bool
is_invalid_marker()256 TargetData::is_invalid_marker() const
257 {
258   return marker_ == TARGET_DATA_ID_INVALID;
259 }
260 
261 inline void
set_source_lid(const index source_lid)262 TargetData::set_source_lid( const index source_lid )
263 {
264   assert( source_lid < MAX_LID );
265   source_lid_ = source_lid;
266 }
267 
268 inline void
set_source_tid(const thread source_tid)269 TargetData::set_source_tid( const thread source_tid )
270 {
271   assert( source_tid < MAX_TID );
272   source_tid_ = source_tid;
273 }
274 
275 inline index
get_source_lid()276 TargetData::get_source_lid() const
277 {
278   return source_lid_;
279 }
280 
281 inline thread
get_source_tid()282 TargetData::get_source_tid() const
283 {
284   return source_tid_;
285 }
286 
287 inline void
set_is_primary(const bool is_primary)288 TargetData::set_is_primary( const bool is_primary )
289 {
290   is_primary_ = is_primary;
291 }
292 
293 inline bool
is_primary()294 TargetData::is_primary() const
295 {
296   return is_primary_;
297 }
298 } // namespace nest
299 
300 #endif // TARGET_DATA_H
301