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)81TargetDataFields::set_lcid( const index lcid ) 82 { 83 lcid_ = lcid; 84 } 85 86 inline index get_lcid()87TargetDataFields::get_lcid() const 88 { 89 return lcid_; 90 } 91 92 inline void set_tid(const thread tid)93TargetDataFields::set_tid( const thread tid ) 94 { 95 tid_ = tid; 96 } 97 98 inline thread get_tid()99TargetDataFields::get_tid() const 100 { 101 return tid_; 102 } 103 104 inline void set_syn_id(const synindex syn_id)105TargetDataFields::set_syn_id( const synindex syn_id ) 106 { 107 syn_id_ = syn_id; 108 } 109 110 inline synindex get_syn_id()111TargetDataFields::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)134SecondaryTargetDataFields::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()141SecondaryTargetDataFields::get_recv_buffer_pos() const 142 { 143 return recv_buffer_pos_; 144 } 145 146 inline void set_syn_id(const synindex syn_id)147SecondaryTargetDataFields::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()154SecondaryTargetDataFields::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()220TargetData::reset_marker() 221 { 222 marker_ = TARGET_DATA_ID_DEFAULT; 223 } 224 225 inline void set_complete_marker()226TargetData::set_complete_marker() 227 { 228 marker_ = TARGET_DATA_ID_COMPLETE; 229 } 230 231 inline void set_end_marker()232TargetData::set_end_marker() 233 { 234 marker_ = TARGET_DATA_ID_END; 235 } 236 237 inline void set_invalid_marker()238TargetData::set_invalid_marker() 239 { 240 marker_ = TARGET_DATA_ID_INVALID; 241 } 242 243 inline bool is_complete_marker()244TargetData::is_complete_marker() const 245 { 246 return marker_ == TARGET_DATA_ID_COMPLETE; 247 } 248 249 inline bool is_end_marker()250TargetData::is_end_marker() const 251 { 252 return marker_ == TARGET_DATA_ID_END; 253 } 254 255 inline bool is_invalid_marker()256TargetData::is_invalid_marker() const 257 { 258 return marker_ == TARGET_DATA_ID_INVALID; 259 } 260 261 inline void set_source_lid(const index source_lid)262TargetData::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)269TargetData::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()276TargetData::get_source_lid() const 277 { 278 return source_lid_; 279 } 280 281 inline thread get_source_tid()282TargetData::get_source_tid() const 283 { 284 return source_tid_; 285 } 286 287 inline void set_is_primary(const bool is_primary)288TargetData::set_is_primary( const bool is_primary ) 289 { 290 is_primary_ = is_primary; 291 } 292 293 inline bool is_primary()294TargetData::is_primary() const 295 { 296 return is_primary_; 297 } 298 } // namespace nest 299 300 #endif // TARGET_DATA_H 301