GeNN  4.9.0
GPU enhanced Neuronal Networks (GeNN)
sharedLibraryModel.h
Go to the documentation of this file.
1 #pragma once
2 
3 // Standard C++ includes
4 #include <algorithm>
5 #include <array>
6 #include <iostream>
7 #include <string>
8 #include <vector>
9 #include <utility>
10 #include <unordered_map>
11 #include <bitset>
12 
13 // Platform includes
14 #ifdef _WIN32
15 #include <windows.h>
16 #else
17 extern "C"
18 {
19 #include <dlfcn.h>
20 }
21 #endif
22 
23 // GeNN userproject includes
24 #include "spikeRecorder.h"
25 
26 //----------------------------------------------------------------------------
27 // SharedLibraryModel
28 //----------------------------------------------------------------------------
29 // Interface for spike recorders
30 template<typename scalar = float>
32 {
33 public:
35  : m_Library(nullptr), m_AllocateMem(nullptr), m_AllocateRecordingBuffers(nullptr),
36  m_FreeMem(nullptr), m_Initialize(nullptr), m_InitializeSparse(nullptr),
37  m_StepTime(nullptr), m_PullRecordingBuffersFromDevice(nullptr),
38  m_NCCLGenerateUniqueID(nullptr), m_NCCLGetUniqueID(nullptr),
39  m_NCCLInitCommunicator(nullptr), m_NCCLUniqueIDBytes(nullptr)
40  {
41  }
42 
43  SharedLibraryModel(const std::string &pathToModel, const std::string &modelName,
44  bool includeModelNameInDLL = false)
45  {
46  if(!open(pathToModel, modelName, includeModelNameInDLL)) {
47  throw std::runtime_error("Unable to open library");
48  }
49  }
50 
52  {
53  // Close model library
54  close();
55  }
56 
57  //----------------------------------------------------------------------------
58  // Public API
59  //----------------------------------------------------------------------------
60  bool open(const std::string &pathToModel, const std::string &modelName,
61  bool includeModelNameInDLL = false)
62  {
63 #ifdef _WIN32
64  const std::string runnerName = includeModelNameInDLL ? ("runner_" + modelName) : "runner";
65 #ifdef _DEBUG
66  const std::string libraryName = pathToModel + "\\" + runnerName + "_Debug.dll";
67 #else
68  const std::string libraryName = pathToModel + "\\" + runnerName + "_Release.dll";
69 #endif
70  m_Library = LoadLibrary(libraryName.c_str());
71 #else
72  const std::string libraryName = pathToModel + modelName + "_CODE/librunner.so";
73  m_Library = dlopen(libraryName.c_str(), RTLD_NOW);
74 #endif
75 
76  // If it fails throw
77  if(m_Library != nullptr) {
78  m_AllocateMem = (VoidFunction)getSymbol("allocateMem");
79  m_AllocateRecordingBuffers = (EGPFunction)getSymbol("allocateRecordingBuffers", true);
80  m_FreeMem = (VoidFunction)getSymbol("freeMem");
81  m_GetFreeDeviceMemBytes = (GetFreeMemFunction)getSymbol("getFreeDeviceMemBytes");
82 
83  m_Initialize = (VoidFunction)getSymbol("initialize");
84  m_InitializeSparse = (VoidFunction)getSymbol("initializeSparse");
85 
86  m_StepTime = (VoidFunction)getSymbol("stepTime");
87  m_PullRecordingBuffersFromDevice = (VoidFunction)getSymbol("pullRecordingBuffersFromDevice", true);
88 
89  m_T = (scalar*)getSymbol("t");
90  m_Timestep = (unsigned long long*)getSymbol("iT");
91 
92  m_NCCLGenerateUniqueID = (VoidFunction)getSymbol("ncclGenerateUniqueID", true);
93  m_NCCLGetUniqueID = (UCharPtrFunction)getSymbol("ncclGetUniqueID", true);
94  m_NCCLInitCommunicator = (NCCLInitCommunicatorFunction)getSymbol("ncclInitCommunicator", true);
95  m_NCCLUniqueIDBytes = (unsigned int*)getSymbol("ncclUniqueIDBytes", true);
96  return true;
97  }
98  else {
99 #ifdef _WIN32
100  std::cerr << "Unable to load library - error:" << std::to_string(GetLastError()) << std::endl;;
101 #else
102  std::cerr << "Unable to load library - error:" << dlerror() << std::endl;
103 #endif
104  return false;
105  }
106  }
107 
108  void close()
109  {
110  if(m_Library) {
111  freeMem();
112 #ifdef _WIN32
113  FreeLibrary(m_Library);
114 #else
115  dlclose(m_Library);
116 #endif
117  m_Library = nullptr;
118  }
119 
120  // Null all pointers
121  m_AllocateMem = nullptr;
122  m_AllocateRecordingBuffers = nullptr;
123  m_FreeMem = nullptr;
124  m_GetFreeDeviceMemBytes = nullptr;
125  m_Initialize = nullptr;
126  m_InitializeSparse = nullptr;
127  m_StepTime = nullptr;
128  m_PullRecordingBuffersFromDevice = nullptr;
129  m_NCCLGenerateUniqueID = nullptr;
130  m_NCCLGetUniqueID = nullptr;
131  m_NCCLInitCommunicator = nullptr;
132  m_NCCLUniqueIDBytes = nullptr;
133  m_T = nullptr;
134  m_Timestep = nullptr;
135 
136  // Empty all dictionaries
137  m_PopulationVars.clear();
138  m_PopulationEPGs.clear();
139  m_CustomUpdates.clear();
140  }
141 
142  void allocateExtraGlobalParam(const std::string &popName, const std::string &egpName, unsigned int count)
143  {
144  // Get EGP functions and check allocate exists
145  const auto funcs = getEGPFunctions(egpName + popName);
146  if(std::get<0>(funcs) == nullptr) {
147  throw std::runtime_error("You cannot allocate EGP '" + egpName + "' in population '" + popName + "'");
148  }
149 
150  // Call allocate
151  std::get<0>(funcs)(count);
152  }
153 
154  void allocateExtraGlobalParam(const std::string &popName, const std::string &varName, const std::string &egpName, unsigned int count)
155  {
156  // Get EGP functions and check allocate exists
157  const auto funcs = getEGPFunctions(egpName + varName + popName);
158  if(std::get<0>(funcs) == nullptr) {
159  throw std::runtime_error("You cannot allocate EGP '" + egpName + "' for initializing '" + varName + "'in population '" + popName + "'");
160  }
161 
162  // Call allocate
163  std::get<0>(funcs)(count);
164  }
165 
166  void freeExtraGlobalParam(const std::string &popName, const std::string &egpName)
167  {
168  // Get EGP functions and check free exists
169  const auto funcs = getEGPFunctions(egpName + popName);
170  if(std::get<1>(funcs) == nullptr) {
171  throw std::runtime_error("You cannot free EGP '" + egpName + "' in population '" + popName + "'");
172  }
173 
174  // Call free
175  std::get<1>(funcs)();
176  }
177 
178  void freeExtraGlobalParam(const std::string &popName, const std::string &varName, const std::string &egpName)
179  {
180  // Get EGP functions and check free exists
181  const auto funcs = getEGPFunctions(egpName + varName + popName);
182  if(std::get<1>(funcs) == nullptr) {
183  throw std::runtime_error("You cannot free EGP '" + egpName + "' for initializing '" + varName + "'in population '" + popName + "'");
184  }
185 
186  // Call free
187  std::get<1>(funcs)();
188  }
189 
190  void pullStateFromDevice(const std::string &popName)
191  {
192  // Get push and pull state functions and check pull exists
193  const auto pushPull = getPopPushPullFunction(popName + "State");
194  if(pushPull.second == nullptr) {
195  throw std::runtime_error("You cannot pull state from population '" + popName + "'");
196  }
197 
198  // Call pull
199  pushPull.second();
200  }
201 
202  void pullSpikesFromDevice(const std::string &popName)
203  {
204  // Get push and pull spikes functions and check pull exists
205  const auto pushPull = getPopPushPullFunction(popName + "Spikes");
206  if(pushPull.second == nullptr) {
207  throw std::runtime_error("You cannot pull spikes from population '" + popName + "'");
208  }
209 
210  // Call pull
211  pushPull.second();
212  }
213 
214  void pullSpikeEventsFromDevice(const std::string &popName)
215  {
216  // Get push and pull spike events functions and check pull exists
217  const auto pushPull = getPopPushPullFunction(popName + "SpikeEvents");
218  if(pushPull.second == nullptr) {
219  throw std::runtime_error("You cannot pull spike events from population '" + popName + "'");
220  }
221 
222  // Call pull
223  pushPull.second();
224  }
225 
226  void pullCurrentSpikesFromDevice(const std::string &popName)
227  {
228  // Get push and pull spikes functions and check pull exists
229  const auto pushPull = getPopPushPullFunction(popName + "CurrentSpikes");
230  if(pushPull.second == nullptr) {
231  throw std::runtime_error("You cannot pull current spikes from population '" + popName + "'");
232  }
233 
234  // Call pull
235  pushPull.second();
236  }
237 
238  void pullCurrentSpikesEventsFromDevice(const std::string &popName)
239  {
240  // Get push and pull spike events functions and check pull exists
241  const auto pushPull = getPopPushPullFunction(popName + "CurrentSpikeEvents");
242  if(pushPull.second == nullptr) {
243  throw std::runtime_error("You cannot pull current spike events from population '" + popName + "'");
244  }
245 
246  // Call pull
247  pushPull.second();
248  }
249 
250  void pullConnectivityFromDevice(const std::string &popName)
251  {
252  // Get push and pull connectivity functions and check pull exists
253  const auto pushPull = getPopPushPullFunction(popName + "Connectivity");
254  if(pushPull.second == nullptr) {
255  throw std::runtime_error("You cannot pull connectivity from population '" + popName + "'");
256  }
257 
258  // Call pull
259  pushPull.second();
260  }
261 
262  void pullVarFromDevice(const std::string &popName, const std::string &varName)
263  {
264  // Get push and pull connectivity functions and check pull exists
265  const auto pushPull = getPopPushPullFunction(varName + popName);
266  if(pushPull.second == nullptr) {
267  throw std::runtime_error("You cannot pull var '" + varName + "' from population '" + popName + "'");
268  }
269 
270  // Call pull
271  pushPull.second();
272  }
273 
274  void pullExtraGlobalParam(const std::string &popName, const std::string &egpName, unsigned int count)
275  {
276  // Get EGP functions and check pull exists
277  const auto funcs = getEGPFunctions(egpName + popName);
278  if(std::get<3>(funcs) == nullptr) {
279  throw std::runtime_error("You cannot pull EGP '" + egpName + "' from population '" + popName + "'");
280  }
281 
282  // Call pull
283  std::get<3>(funcs)(count);
284  }
285 
286  void pullExtraGlobalParam(const std::string &popName, const std::string &varName, const std::string &egpName, unsigned int count)
287  {
288  // Get EGP functions and check pull exists
289  const auto funcs = getEGPFunctions(egpName + varName + popName);
290  if(std::get<3>(funcs) == nullptr) {
291  throw std::runtime_error("You cannot pull EGP '" + egpName + "' for initializing '" + varName + "'in population '" + popName + "'");
292  }
293 
294  // Call pull
295  std::get<3>(funcs)(count);
296  }
297 
298  void pushStateToDevice(const std::string &popName, bool uninitialisedOnly = false)
299  {
300  // Get push and pull state functions and check pull exists
301  const auto pushPull = getPopPushPullFunction(popName + "State");
302  if(pushPull.first == nullptr) {
303  throw std::runtime_error("You cannot push state to population '" + popName + "'");
304  }
305 
306  // Call push
307  pushPull.first(uninitialisedOnly);
308  }
309 
310  void pushSpikesToDevice(const std::string &popName, bool uninitialisedOnly = false)
311  {
312  // Get push and pull spikes functions and check pull exists
313  const auto pushPull = getPopPushPullFunction(popName + "Spikes");
314  if(pushPull.first == nullptr) {
315  throw std::runtime_error("You cannot push spikes to population '" + popName + "'");
316  }
317 
318  // Call push
319  pushPull.first(uninitialisedOnly);
320  }
321 
322  void pushSpikeEventsToDevice(const std::string &popName, bool uninitialisedOnly = false)
323  {
324  // Get push and pull spike events functions and check pull exists
325  const auto pushPull = getPopPushPullFunction(popName + "SpikeEvents");
326  if(pushPull.first == nullptr) {
327  throw std::runtime_error("You cannot push spike events to population '" + popName + "'");
328  }
329 
330  // Call push
331  pushPull.first(uninitialisedOnly);
332  }
333 
334  void pushCurrentSpikesToDevice(const std::string &popName, bool uninitialisedOnly = false)
335  {
336  // Get push and pull spikes functions and check pull exists
337  const auto pushPull = getPopPushPullFunction(popName + "CurrentSpikes");
338  if(pushPull.first == nullptr) {
339  throw std::runtime_error("You cannot push current spikes to population '" + popName + "'");
340  }
341 
342  // Call push
343  pushPull.first(uninitialisedOnly);
344  }
345 
346  void pushCurrentSpikeEventsToDevice(const std::string &popName, bool uninitialisedOnly = false)
347  {
348  // Get push and pull spike events functions and check pull exists
349  const auto pushPull = getPopPushPullFunction(popName + "CurrentSpikeEvents");
350  if(pushPull.first == nullptr) {
351  throw std::runtime_error("You cannot push current spike events to population '" + popName + "'");
352  }
353 
354  // Call push
355  pushPull.first(uninitialisedOnly);
356  }
357 
358  void pushConnectivityToDevice(const std::string &popName, bool uninitialisedOnly = false)
359  {
360  // Get push and pull connectivity functions and check pull exists
361  const auto pushPull = getPopPushPullFunction(popName + "Connectivity");
362  if(pushPull.first == nullptr) {
363  throw std::runtime_error("You cannot push connectivity to population '" + popName + "'");
364  }
365 
366  // Call push
367  pushPull.first(uninitialisedOnly);
368  }
369 
370  void pushVarToDevice(const std::string &popName, const std::string &varName, bool uninitialisedOnly = false)
371  {
372  // Get push and pull connectivity functions and check pull exists
373  const auto pushPull = getPopPushPullFunction(varName + popName);
374  if(pushPull.first == nullptr) {
375  throw std::runtime_error("You cannot push var '" + varName + "' to population '" + popName + "'");
376  }
377 
378  // Call push
379  pushPull.first(uninitialisedOnly);
380  }
381 
382  void pushExtraGlobalParam(const std::string &popName, const std::string &egpName, unsigned int count)
383  {
384  // Get EGP functions and check push exists
385  const auto funcs = getEGPFunctions(egpName + popName);
386  if(std::get<2>(funcs) == nullptr) {
387  throw std::runtime_error("You cannot push EGP '" + egpName + "' to population '" + popName + "'");
388  }
389 
390  // Call push
391  std::get<2>(funcs)(count);
392  }
393 
394  void pushExtraGlobalParam(const std::string &popName, const std::string &varName, const std::string &egpName, unsigned int count)
395  {
396  // Get EGP functions and check push exists
397  const auto funcs = getEGPFunctions(egpName + varName + popName);
398  if(std::get<2>(funcs) == nullptr) {
399  throw std::runtime_error("You cannot push EGP '" + egpName + "' for initializing '" + varName + "'in population '" + popName + "'");
400  }
401 
402  // Call push
403  std::get<2>(funcs)(count);
404  }
405 
406  template<typename Writer, typename... WriterArgs>
407  SpikeRecorder<Writer> getSpikeRecorder(const std::string &popName, WriterArgs &&... writerArgs)
408  {
409  // Get functions to access spikes
410  auto getSpikesFn = (typename SpikeRecorder<Writer>::GetCurrentSpikesFunc)getSymbol("get" + popName + "CurrentSpikes");
411  auto getSpikeCountFn = (typename SpikeRecorder<Writer>::GetCurrentSpikeCountFunc)getSymbol("get" + popName + "CurrentSpikeCount");
412 
413  // Add cached recorder
414  return SpikeRecorder<Writer>(getSpikesFn, getSpikeCountFn, std::forward<WriterArgs>(writerArgs)...);
415  }
416 
417  // Gets a pointer to an array in the shared library
418  template<typename T>
419  T *getArray(const std::string &varName)
420  {
421  return *(static_cast<T**>(getSymbol(varName)));
422  }
423 
424  // Gets a scalar from the shared library
425  template<typename T>
426  T *getScalar(const std::string &varName)
427  {
428  return (static_cast<T*>(getSymbol(varName)));
429  }
430 
431  void allocateMem()
432  {
433  m_AllocateMem();
434  }
435 
436  void allocateRecordingBuffers(unsigned int timesteps)
437  {
438  if(m_AllocateRecordingBuffers == nullptr) {
439  throw std::runtime_error("Cannot allocate recording buffers - model may not have recording enabled");
440  }
441  m_AllocateRecordingBuffers(timesteps);
442  }
443 
444  void freeMem()
445  {
446  m_FreeMem();
447  }
448 
450  {
451  return m_GetFreeDeviceMemBytes();
452  }
453 
455  {
456  if(m_NCCLGenerateUniqueID == nullptr) {
457  throw std::runtime_error("Cannot generate NCCL unique ID - model may not have been built with NCCL support");
458  }
459  m_NCCLGenerateUniqueID();
460  }
461 
462  unsigned char *ncclGetUniqueID()
463  {
464  if(m_NCCLGetUniqueID == nullptr) {
465  throw std::runtime_error("Cannot get NCCL unique ID - model may not have been built with NCCL support");
466  }
467  return m_NCCLGetUniqueID();
468  }
469 
470  unsigned int ncclGetUniqueIDBytes() const
471  {
472  if(m_NCCLUniqueIDBytes == nullptr) {
473  throw std::runtime_error("Cannot get NCCL unique ID bytes - model may not have been built with NCCL support");
474  }
475 
476  return *m_NCCLUniqueIDBytes;
477  }
478 
479  void ncclInitCommunicator(int rank, int numRanks)
480  {
481  if(m_NCCLInitCommunicator == nullptr) {
482  throw std::runtime_error("Cannot initialise NCCL communicator - model may not have been built with NCCL support");
483  }
484  m_NCCLInitCommunicator(rank, numRanks);
485  }
486 
487 
488 
489  void initialize()
490  {
491  m_Initialize();
492  }
493 
495  {
496  m_InitializeSparse();
497  }
498 
499  void stepTime()
500  {
501  m_StepTime();
502  }
503 
504  void customUpdate(const std::string &name)
505  {
506  auto c = m_CustomUpdates.find(name);
507  if(c != m_CustomUpdates.cend()) {
508  c->second();
509  }
510  else {
511  auto customUpdateFn = (VoidFunction)getSymbol("update" + name);
512  m_CustomUpdates.emplace(name, customUpdateFn);
513  customUpdateFn();
514  }
515  }
516 
518  {
519  if(m_PullRecordingBuffersFromDevice == nullptr) {
520  throw std::runtime_error("Cannot pull recording buffers from device - model may not have recording enabled");
521  }
522  m_PullRecordingBuffersFromDevice();
523  }
524 
525  scalar getTime() const
526  {
527  return *m_T;
528  }
529 
530  unsigned long long getTimestep() const
531  {
532  return *m_Timestep;
533  }
534 
535  void setTime(scalar t)
536  {
537  *m_T = t;
538  }
539 
540  void setTimestep(unsigned long long iT)
541  {
542  *m_Timestep = iT;
543  }
544 
545  double getNeuronUpdateTime() const{ return *(double*)getSymbol("neuronUpdateTime"); }
546  double getInitTime() const{ return *(double*)getSymbol("initTime"); }
547  double getPresynapticUpdateTime() const{ return *(double*)getSymbol("presynapticUpdateTime"); }
548  double getPostsynapticUpdateTime() const{ return *(double*)getSymbol("postsynapticUpdateTime"); }
549  double getSynapseDynamicsTime() const{ return *(double*)getSymbol("synapseDynamicsTime"); }
550  double getInitSparseTime() const{ return *(double*)getSymbol("initSparseTime"); }
551  double getCustomUpdateTime(const std::string &name)const{ return *(double*)getSymbol("customUpdate" + name + "Time"); }
552  double getCustomUpdateTransposeTime(const std::string &name)const{ return *(double*)getSymbol("customUpdate" + name + "TransposeTime"); }
553 
554  void *getSymbol(const std::string &symbolName, bool allowMissing = false, void *defaultSymbol = nullptr) const
555  {
556 #ifdef _WIN32
557  void *symbol = GetProcAddress(m_Library, symbolName.c_str());
558 #else
559  void *symbol = dlsym(m_Library, symbolName.c_str());
560 #endif
561 
562  // If this symbol's missing
563  if(symbol == nullptr) {
564  // If this isn't allowed, throw error
565  if(!allowMissing) {
566  throw std::runtime_error("Cannot find symbol '" + symbolName + "'");
567  }
568  // Otherwise, return default
569  else {
570  return defaultSymbol;
571  }
572  }
573  // Otherwise, return symbolPopulationFuncs
574  else {
575  return symbol;
576  }
577  }
578 
579 private:
580  //----------------------------------------------------------------------------
581  // Typedefines
582  //----------------------------------------------------------------------------
583  typedef void (*VoidFunction)(void);
584  typedef unsigned char* (*UCharPtrFunction)(void);
585  typedef void (*PushFunction)(bool);
586  typedef void (*PullFunction)(void);
587  typedef void (*EGPFunction)(unsigned int);
588  typedef size_t (*GetFreeMemFunction)(void);
589  typedef void (*NCCLInitCommunicatorFunction)(int, int);
590 
591  typedef std::pair<PushFunction, PullFunction> PushPullFunc;
592  typedef std::tuple<EGPFunction, VoidFunction, EGPFunction, EGPFunction> EGPFunc;
593 
594  //----------------------------------------------------------------------------
595  // Private methods
596  //----------------------------------------------------------------------------
597  PushPullFunc getPopPushPullFunction(const std::string &description)
598  {
599  // If description is found, return associated push and pull functions
600  const auto popVar = m_PopulationVars.find(description);
601  if(popVar != m_PopulationVars.end()) {
602  return popVar->second;
603  }
604  else {
605  // Get symbols for push and pull functions
606  auto pushFunc = (PushFunction)getSymbol("push" + description + "ToDevice", true);
607  auto pullFunc = (PullFunction)getSymbol("pull" + description + "FromDevice", true);
608 
609  // Add to map
610  auto newPopVar = m_PopulationVars.emplace(std::piecewise_construct,
611  std::forward_as_tuple(description),
612  std::forward_as_tuple(pushFunc, pullFunc));
613 
614  // Return newly added push and pull functions
615  return newPopVar.first->second;
616  }
617  }
618 
619  EGPFunc getEGPFunctions(const std::string &description)
620  {
621  // If description is found, return associated EGP functions
622  const auto popEGP = m_PopulationEPGs.find(description);
623  if(popEGP != m_PopulationEPGs.end()) {
624  return popEGP->second;
625  }
626  else {
627  // Get symbols for push and pull functions
628  auto allocateFunc = (EGPFunction)getSymbol("allocate" + description, true);
629  auto freeFunc = (VoidFunction)getSymbol("free" + description, true);
630  auto pushFunc = (EGPFunction)getSymbol("push" + description + "ToDevice", true);
631  auto pullFunc = (EGPFunction)getSymbol("pull" + description + "FromDevice", true);
632 
633  // Add to map
634  auto newPopEGP = m_PopulationEPGs.emplace(std::piecewise_construct,
635  std::forward_as_tuple(description),
636  std::forward_as_tuple(allocateFunc, freeFunc,
637  pushFunc, pullFunc));
638 
639  // Return newly functions
640  return newPopEGP.first->second;
641  }
642  }
643 
644  //----------------------------------------------------------------------------
645  // Members
646  //----------------------------------------------------------------------------
647 #ifdef _WIN32
648  HMODULE m_Library;
649 #else
650  void *m_Library;
651 #endif
652 
653  VoidFunction m_AllocateMem;
654  EGPFunction m_AllocateRecordingBuffers;
655  VoidFunction m_FreeMem;
656  GetFreeMemFunction m_GetFreeDeviceMemBytes;
657  VoidFunction m_Initialize;
658  VoidFunction m_InitializeSparse;
659  VoidFunction m_StepTime;
660 
661  PullFunction m_PullRecordingBuffersFromDevice;
662 
663  VoidFunction m_NCCLGenerateUniqueID;
664  UCharPtrFunction m_NCCLGetUniqueID;
665  NCCLInitCommunicatorFunction m_NCCLInitCommunicator;
666  const unsigned int *m_NCCLUniqueIDBytes;
667 
668  std::unordered_map<std::string, PushPullFunc> m_PopulationVars;
669  std::unordered_map<std::string, EGPFunc> m_PopulationEPGs;
670  std::unordered_map<std::string, VoidFunction> m_CustomUpdates;
671  scalar *m_T;
672  unsigned long long *m_Timestep;
673 };
SharedLibraryModel()
Definition: sharedLibraryModel.h:34
double getNeuronUpdateTime() const
Definition: sharedLibraryModel.h:545
void * getSymbol(const std::string &symbolName, bool allowMissing=false, void *defaultSymbol=nullptr) const
Definition: sharedLibraryModel.h:554
void close()
Definition: sharedLibraryModel.h:108
void pushExtraGlobalParam(const std::string &popName, const std::string &varName, const std::string &egpName, unsigned int count)
Definition: sharedLibraryModel.h:394
unsigned char * ncclGetUniqueID()
Definition: sharedLibraryModel.h:462
void ncclInitCommunicator(int rank, int numRanks)
Definition: sharedLibraryModel.h:479
void setTimestep(unsigned long long iT)
Definition: sharedLibraryModel.h:540
void pushStateToDevice(const std::string &popName, bool uninitialisedOnly=false)
Definition: sharedLibraryModel.h:298
double getInitSparseTime() const
Definition: sharedLibraryModel.h:550
void allocateExtraGlobalParam(const std::string &popName, const std::string &egpName, unsigned int count)
Definition: sharedLibraryModel.h:142
void pullExtraGlobalParam(const std::string &popName, const std::string &varName, const std::string &egpName, unsigned int count)
Definition: sharedLibraryModel.h:286
void allocateRecordingBuffers(unsigned int timesteps)
Definition: sharedLibraryModel.h:436
SharedLibraryModel(const std::string &pathToModel, const std::string &modelName, bool includeModelNameInDLL=false)
Definition: sharedLibraryModel.h:43
double getSynapseDynamicsTime() const
Definition: sharedLibraryModel.h:549
void pushSpikeEventsToDevice(const std::string &popName, bool uninitialisedOnly=false)
Definition: sharedLibraryModel.h:322
Class to read spikes from neuron groups.
Definition: spikeRecorder.h:150
void freeMem()
Definition: sharedLibraryModel.h:444
void freeExtraGlobalParam(const std::string &popName, const std::string &varName, const std::string &egpName)
Definition: sharedLibraryModel.h:178
size_t getFreeDeviceMemBytes()
Definition: sharedLibraryModel.h:449
double getPresynapticUpdateTime() const
Definition: sharedLibraryModel.h:547
void pullCurrentSpikesFromDevice(const std::string &popName)
Definition: sharedLibraryModel.h:226
T * getArray(const std::string &varName)
Definition: sharedLibraryModel.h:419
double getCustomUpdateTransposeTime(const std::string &name) const
Definition: sharedLibraryModel.h:552
void pullCurrentSpikesEventsFromDevice(const std::string &popName)
Definition: sharedLibraryModel.h:238
double getPostsynapticUpdateTime() const
Definition: sharedLibraryModel.h:548
unsigned long long getTimestep() const
Definition: sharedLibraryModel.h:530
void pushCurrentSpikeEventsToDevice(const std::string &popName, bool uninitialisedOnly=false)
Definition: sharedLibraryModel.h:346
void initializeSparse()
Definition: sharedLibraryModel.h:494
bool open(const std::string &pathToModel, const std::string &modelName, bool includeModelNameInDLL=false)
Definition: sharedLibraryModel.h:60
void initialize()
Definition: sharedLibraryModel.h:489
Definition: sharedLibraryModel.h:31
void allocateMem()
Definition: sharedLibraryModel.h:431
void pullSpikeEventsFromDevice(const std::string &popName)
Definition: sharedLibraryModel.h:214
void pullRecordingBuffersFromDevice()
Definition: sharedLibraryModel.h:517
void pullConnectivityFromDevice(const std::string &popName)
Definition: sharedLibraryModel.h:250
void pushSpikesToDevice(const std::string &popName, bool uninitialisedOnly=false)
Definition: sharedLibraryModel.h:310
virtual ~SharedLibraryModel()
Definition: sharedLibraryModel.h:51
void customUpdate(const std::string &name)
Definition: sharedLibraryModel.h:504
void pullVarFromDevice(const std::string &popName, const std::string &varName)
Definition: sharedLibraryModel.h:262
void pullExtraGlobalParam(const std::string &popName, const std::string &egpName, unsigned int count)
Definition: sharedLibraryModel.h:274
void freeExtraGlobalParam(const std::string &popName, const std::string &egpName)
Definition: sharedLibraryModel.h:166
void pushCurrentSpikesToDevice(const std::string &popName, bool uninitialisedOnly=false)
Definition: sharedLibraryModel.h:334
void stepTime()
Definition: sharedLibraryModel.h:499
T * getScalar(const std::string &varName)
Definition: sharedLibraryModel.h:426
void ncclGenerateUniqueID()
Definition: sharedLibraryModel.h:454
void pushVarToDevice(const std::string &popName, const std::string &varName, bool uninitialisedOnly=false)
Definition: sharedLibraryModel.h:370
scalar getTime() const
Definition: sharedLibraryModel.h:525
void allocateExtraGlobalParam(const std::string &popName, const std::string &varName, const std::string &egpName, unsigned int count)
Definition: sharedLibraryModel.h:154
void setTime(scalar t)
Definition: sharedLibraryModel.h:535
void pullSpikesFromDevice(const std::string &popName)
Definition: sharedLibraryModel.h:202
void pullStateFromDevice(const std::string &popName)
Definition: sharedLibraryModel.h:190
SpikeRecorder< Writer > getSpikeRecorder(const std::string &popName, WriterArgs &&... writerArgs)
Definition: sharedLibraryModel.h:407
double getInitTime() const
Definition: sharedLibraryModel.h:546
void pushConnectivityToDevice(const std::string &popName, bool uninitialisedOnly=false)
Definition: sharedLibraryModel.h:358
double getCustomUpdateTime(const std::string &name) const
Definition: sharedLibraryModel.h:551
unsigned int ncclGetUniqueIDBytes() const
Definition: sharedLibraryModel.h:470
float scalar
Definition: modelProperty.h:27
void pushExtraGlobalParam(const std::string &popName, const std::string &egpName, unsigned int count)
Definition: sharedLibraryModel.h:382