CARLsim  4.1.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 *
45 * CARLsim available from http://socsci.uci.edu/~jkrichma/CARLsim/
46 * Ver 12/31/2016
47 */
48 #include <spikegen_from_file.h>
49 
50 #include <carlsim.h>
51 //#include <user_errors.h> // fancy user error messages
52 
53 #include <stdio.h> // fopen, fread, fclose
54 #include <string.h> // std::string
55 #include <assert.h> // assert
56 
57 // #define VERBOSE
58 
59 SpikeGeneratorFromFile::SpikeGeneratorFromFile(std::string fileName, int offsetTimeMs) {
60  fileName_ = fileName;
61  fpBegin_ = NULL;
62 
63  nNeur_ = -1;
64  szByteHeader_ = -1;
65  offsetTimeMs_ = offsetTimeMs;
66 
67  // move unsafe operations out of constructor
68  openFile();
69  init();
70 }
71 
73  if (fpBegin_ != NULL) {
74  fclose(fpBegin_);
75  }
76  fpBegin_ = NULL;
77 }
78 
79 void SpikeGeneratorFromFile::loadFile(std::string fileName, int offsetTimeMs) {
80  // close previously opened file (if any)
81  if (fpBegin_ != NULL) {
82  fclose(fpBegin_);
83  }
84  fpBegin_ = NULL;
85 
86  // update file name and open
87  fileName_ = fileName;
88  offsetTimeMs_ = offsetTimeMs;
89  openFile();
90  init();
91 }
92 
93 // rewind file pointers to beginning
94 void SpikeGeneratorFromFile::rewind(int offsetTimeMs) {
95  offsetTimeMs_ = offsetTimeMs;
96 
97  // reset all iterators
98  spikesIt_.clear();
99  for (int i=0; i<nNeur_; i++) {
100  spikesIt_.push_back(spikes_[i].begin());
101  }
102 }
103 
104 void SpikeGeneratorFromFile::openFile() {
105  std::string funcName = "openFile("+fileName_+")";
106  fpBegin_ = fopen(fileName_.c_str(),"rb");
107  UserErrors::assertTrue(fpBegin_!=NULL, UserErrors::FILE_CANNOT_OPEN, funcName, fileName_);
108 
109  // \TODO there should be a common/standard way to read spike files
110  // \FIXME: this is a hack...to get the size of the header section
111  // needs to be updated every time header changes
112  FILE* fp = fpBegin_;
113  szByteHeader_ = 4*sizeof(int)+1*sizeof(float);
114  fseek(fp, sizeof(int)+sizeof(float), SEEK_SET); // skipping signature+version
115 
116  // get number of neurons from header
117  nNeur_ = 1;
118  int grid;
119  for (int i=1; i<=3; i++) {
120  size_t result = fread(&grid, sizeof(int), 1, fp);
121  UserErrors::assertTrue(result == 1, UserErrors::FILE_CANNOT_READ, funcName, fileName_);
122  nNeur_ *= grid;
123  }
124 
125  // make sure number of neurons is now valid
126  assert(nNeur_>0);
127 }
128 
129 void SpikeGeneratorFromFile::init() {
130  assert(nNeur_>0);
131 
132  // allocate spike vector
133  // we organize AER format into a 2D spike vector: first dim=neuron, second dim=spike times
134  // then we just need to maintain an iterator for each neuron to know which spike to schedule next
135  spikes_.clear();
136  for (int i=0; i<nNeur_; i++) {
137  spikes_.push_back(std::vector<int>());
138  }
139 
140  // read spike file
141  FILE* fp = fpBegin_;
142  fseek(fp, szByteHeader_, SEEK_SET); // skip header section
143 
144  std::string funcName = "readFile("+fileName_+")";
145  int tmpTime = -1;
146  int tmpNeurId = -1;
147  size_t result1, result2;
148 
149  while (!feof(fp)) {
150  result1 = fread(&tmpTime, sizeof(int), 1, fp); // i-th time
151  //UserErrors::assertTrue(result == 1, UserErrors::FILE_CANNOT_READ, funcName, fileName_);
152  result2 = fread(&tmpNeurId, sizeof(int), 1, fp); // i-th nid
153  //UserErrors::assertTrue(result == 1, UserErrors::FILE_CANNOT_READ, funcName, fileName_);
154  if (result1 + result2 == 2) // validate the size of reading
155  spikes_[tmpNeurId].push_back(tmpTime); // add spike time to 2D vector
156  }
157 
158 #ifdef VERBOSE
159  for (int neurId=0; neurId<1; neurId++) {
160  printf("[%d]: ",neurId);
161  for (int i=0; i<spikes_[neurId].size(); i++) {
162  printf("%d ",spikes_[neurId][i]);
163  }
164  printf("\n");
165  }
166 #endif
167 
168  // initialize iterators
169  rewind(offsetTimeMs_);
170 }
171 
172 int SpikeGeneratorFromFile::nextSpikeTime(CARLsim* sim, int grpId, int nid, int currentTime, int lastScheduledSpikeTime, int endOfTimeSlice) {
173  assert(nNeur_>0);
174  assert(nid < nNeur_);
175 
176  if (spikesIt_[nid] != spikes_[nid].end()) {
177  // if there are spikes left in the vector ...
178 
179  if (*(spikesIt_[nid])+offsetTimeMs_ < endOfTimeSlice) {
180  // ... and if the next spike time is in the current scheduling time slice:
181 #ifdef VERBOSE
182  if (nid==0) {
183  printf("[%d][%d]: currTime=%u, lastTime=%u, endOfTime=%u, offsetTimeMs=%u, nextSpike=%u\n", grpId, nid,
184  currentTime, lastScheduledSpikeTime, endOfTimeSlice, offsetTimeMs_,
185  (unsigned int) (*(spikesIt_[nid])+offsetTimeMs_));
186  }
187 #endif
188  // return the next spike time and update iterator
189  return (unsigned int)(*(spikesIt_[nid]++)+offsetTimeMs_);
190  }
191  }
192 
193  // if the next spike time is not a valid number, return a large positive number instead
194  // this will signal CARLsim to break the nextSpikeTime loop
195  return -1; // large positive number
196 }
SpikeGeneratorFromFile::~SpikeGeneratorFromFile
~SpikeGeneratorFromFile()
SpikeGeneratorFromFile destructor.
Definition: spikegen_from_file.cpp:72
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:172
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:137
SpikeGeneratorFromFile::rewind
void rewind(int offsetTimeMs)
Rewinds the spike file to beginning of file.
Definition: spikegen_from_file.cpp:94
SpikeGeneratorFromFile::loadFile
void loadFile(std::string fileName, int offsetTimeMs=0)
Loads a new spike file.
Definition: spikegen_from_file.cpp:79
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:59
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