CARLsim  5.0.0
CARLsim: a GPU-accelerated SNN simulator
spikegen_from_file.cpp
Go to the documentation of this file.
1 /* * Copyright (c) 2016 Regents of the University of California. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions
5 * are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * 3. The names of its contributors may not be used to endorse or promote
15 * products derived from this software without specific prior written
16 * permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * *********************************************************************************************** *
31 * CARLsim
32 * created by: (MDR) Micah Richert, (JN) Jayram M. Nageswaran
33 * maintained by:
34 * (MA) Mike Avery <averym@uci.edu>
35 * (MB) Michael Beyeler <mbeyeler@uci.edu>,
36 * (KDC) Kristofor Carlson <kdcarlso@uci.edu>
37 * (TSC) Ting-Shuo Chou <tingshuc@uci.edu>
38 * (HK) Hirak J Kashyap <kashyaph@uci.edu>
39 *
40 * CARLsim v1.0: JM, MDR
41 * CARLsim v2.0/v2.1/v2.2: JM, MDR, MA, MB, KDC
42 * CARLsim3: MB, KDC, TSC
43 * CARLsim4: TSC, HK
44 * CARLsim5: HK, JX, KC
45 *
46 * CARLsim available from http://socsci.uci.edu/~jkrichma/CARLsim/
47 * Ver 12/31/2016
48 */
49 #include <spikegen_from_file.h>
50 
51 #include <carlsim.h>
52 //#include <user_errors.h> // fancy user error messages
53 
54 #include <stdio.h> // fopen, fread, fclose
55 #include <string.h> // std::string
56 #include <assert.h> // assert
57 
58 // #define VERBOSE
59 
60 SpikeGeneratorFromFile::SpikeGeneratorFromFile(std::string fileName, int offsetTimeMs) {
61  fileName_ = fileName;
62  fpBegin_ = NULL;
63 
64  nNeur_ = -1;
65  szByteHeader_ = -1;
66  offsetTimeMs_ = offsetTimeMs;
67 
68  // move unsafe operations out of constructor
69  openFile();
70  init();
71 }
72 
74  if (fpBegin_ != NULL) {
75  fclose(fpBegin_);
76  }
77  fpBegin_ = NULL;
78 }
79 
80 void SpikeGeneratorFromFile::loadFile(std::string fileName, int offsetTimeMs) {
81  // close previously opened file (if any)
82  if (fpBegin_ != NULL) {
83  fclose(fpBegin_);
84  }
85  fpBegin_ = NULL;
86 
87  // update file name and open
88  fileName_ = fileName;
89  offsetTimeMs_ = offsetTimeMs;
90  openFile();
91  init();
92 }
93 
94 // rewind file pointers to beginning
95 void SpikeGeneratorFromFile::rewind(int offsetTimeMs) {
96  offsetTimeMs_ = offsetTimeMs;
97 
98  // reset all iterators
99  spikesIt_.clear();
100  for (int i=0; i<nNeur_; i++) {
101  spikesIt_.push_back(spikes_[i].begin());
102  }
103 }
104 
105 void SpikeGeneratorFromFile::openFile() {
106  std::string funcName = "openFile("+fileName_+")";
107  fpBegin_ = fopen(fileName_.c_str(),"rb");
108  UserErrors::assertTrue(fpBegin_!=NULL, UserErrors::FILE_CANNOT_OPEN, funcName, fileName_);
109 
110  // \TODO there should be a common/standard way to read spike files
111  // \FIXME: this is a hack...to get the size of the header section
112  // needs to be updated every time header changes
113  FILE* fp = fpBegin_;
114  szByteHeader_ = 4*sizeof(int)+1*sizeof(float);
115  fseek(fp, sizeof(int)+sizeof(float), SEEK_SET); // skipping signature+version
116 
117  // get number of neurons from header
118  nNeur_ = 1;
119  int grid;
120  for (int i=1; i<=3; i++) {
121  size_t result = fread(&grid, sizeof(int), 1, fp);
122  UserErrors::assertTrue(result == 1, UserErrors::FILE_CANNOT_READ, funcName, fileName_);
123  nNeur_ *= grid;
124  }
125 
126  // make sure number of neurons is now valid
127  assert(nNeur_>0);
128 }
129 
130 void SpikeGeneratorFromFile::init() {
131  assert(nNeur_>0);
132 
133  // allocate spike vector
134  // we organize AER format into a 2D spike vector: first dim=neuron, second dim=spike times
135  // then we just need to maintain an iterator for each neuron to know which spike to schedule next
136  spikes_.clear();
137  for (int i=0; i<nNeur_; i++) {
138  spikes_.push_back(std::vector<int>());
139  }
140 
141  // read spike file
142  FILE* fp = fpBegin_;
143  fseek(fp, szByteHeader_, SEEK_SET); // skip header section
144 
145  std::string funcName = "readFile("+fileName_+")";
146  int tmpTime = -1;
147  int tmpNeurId = -1;
148  size_t result1, result2;
149 
150  while (!feof(fp)) {
151  result1 = fread(&tmpTime, sizeof(int), 1, fp); // i-th time
152  //UserErrors::assertTrue(result == 1, UserErrors::FILE_CANNOT_READ, funcName, fileName_);
153  result2 = fread(&tmpNeurId, sizeof(int), 1, fp); // i-th nid
154  //UserErrors::assertTrue(result == 1, UserErrors::FILE_CANNOT_READ, funcName, fileName_);
155  if (result1 + result2 == 2) // validate the size of reading
156  spikes_[tmpNeurId].push_back(tmpTime); // add spike time to 2D vector
157  }
158 
159 #ifdef VERBOSE
160  for (int neurId=0; neurId<1; neurId++) {
161  printf("[%d]: ",neurId);
162  for (int i=0; i<spikes_[neurId].size(); i++) {
163  printf("%d ",spikes_[neurId][i]);
164  }
165  printf("\n");
166  }
167 #endif
168 
169  // initialize iterators
170  rewind(offsetTimeMs_);
171 }
172 
173 int SpikeGeneratorFromFile::nextSpikeTime(CARLsim* sim, int grpId, int nid, int currentTime, int lastScheduledSpikeTime, int endOfTimeSlice) {
174  assert(nNeur_>0);
175  assert(nid < nNeur_);
176 
177  if (spikesIt_[nid] != spikes_[nid].end()) {
178  // if there are spikes left in the vector ...
179 
180  if (*(spikesIt_[nid])+offsetTimeMs_ < endOfTimeSlice) {
181  // ... and if the next spike time is in the current scheduling time slice:
182 #ifdef VERBOSE
183  if (nid==0) {
184  printf("[%d][%d]: currTime=%u, lastTime=%u, endOfTime=%u, offsetTimeMs=%u, nextSpike=%u\n", grpId, nid,
185  currentTime, lastScheduledSpikeTime, endOfTimeSlice, offsetTimeMs_,
186  (unsigned int) (*(spikesIt_[nid])+offsetTimeMs_));
187  }
188 #endif
189  // return the next spike time and update iterator
190  return (unsigned int)(*(spikesIt_[nid]++)+offsetTimeMs_);
191  }
192  }
193 
194  // if the next spike time is not a valid number, return a large positive number instead
195  // this will signal CARLsim to break the nextSpikeTime loop
196  return -1; // large positive number
197 }
SpikeGeneratorFromFile::~SpikeGeneratorFromFile
~SpikeGeneratorFromFile()
SpikeGeneratorFromFile destructor.
Definition: spikegen_from_file.cpp:73
SpikeGeneratorFromFile::nextSpikeTime
int nextSpikeTime(CARLsim *sim, int grpId, int nid, int currentTime, int lastScheduledSpikeTime, int endOfTimeSlice)
schedules the next spike time
Definition: spikegen_from_file.cpp:173
UserErrors::FILE_CANNOT_OPEN
@ FILE_CANNOT_OPEN
could not open file
Definition: user_errors.h:44
CARLsim
CARLsim User Interface This class provides a user interface to the public sections of CARLsimCore sou...
Definition: carlsim.h:138
SpikeGeneratorFromFile::rewind
void rewind(int offsetTimeMs)
Rewinds the spike file to beginning of file.
Definition: spikegen_from_file.cpp:95
SpikeGeneratorFromFile::loadFile
void loadFile(std::string fileName, int offsetTimeMs=0)
Loads a new spike file.
Definition: spikegen_from_file.cpp:80
UserErrors::FILE_CANNOT_READ
@ FILE_CANNOT_READ
could not read file
Definition: user_errors.h:45
carlsim.h
SpikeGeneratorFromFile::SpikeGeneratorFromFile
SpikeGeneratorFromFile(std::string fileName, int offsetTimeMs=0)
SpikeGeneratorFromFile constructor.
Definition: spikegen_from_file.cpp:60
UserErrors::assertTrue
static void assertTrue(bool statement, errorType errorIfAssertionFails, std::string errorFunc, std::string errorMsgPrefix="", std::string errorMsgSuffix="")
simple wrapper for assert statement
Definition: user_errors.cpp:15
spikegen_from_file.h