CARLsim  4.1.0
CARLsim: a GPU-accelerated SNN simulator
group_monitor_core.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 <group_monitor_core.h>
49 
50 #include <snn.h> // CARLsim private implementation
51 #include <snn_definitions.h> // KERNEL_ERROR, KERNEL_INFO, ...
52 
53 #include <algorithm> // std::sort
54 
55 // we aren't using namespace std so pay attention!
56 GroupMonitorCore::GroupMonitorCore(SNN* snn, int monitorId, int grpId) {
57  snn_ = snn;
58  grpId_= grpId;
59  monitorId_ = monitorId;
60 
61  groupFileId_ = NULL;
62  recordSet_ = false;
63  grpMonLastUpdated_ = 0;
64 
65  persistentData_ = false;
66 
67  needToWriteFileHeader_ = true;
68  groupFileSignature_ = 206661989;
69  groupFileVersion_ = 0.2f;
70 
71  // defer all unsafe operations to init function
72  init();
73 }
74 
75 void GroupMonitorCore::init() {
76  nNeurons_ = snn_->getGroupNumNeurons(grpId_);
77  assert(nNeurons_> 0);
78 
79  clear();
80 
81  // use KERNEL_{ERROR|WARNING|etc} typesetting (const FILE*)
82  fpInf_ = snn_->getLogFpInf();
83  fpErr_ = snn_->getLogFpErr();
84  fpDeb_ = snn_->getLogFpDeb();
85  fpLog_ = snn_->getLogFpLog();
86 }
87 
89  if (groupFileId_ != NULL) {
90  fclose(groupFileId_);
91  groupFileId_ = NULL;
92  }
93 }
94 
95 // +++++ PUBLIC METHODS: +++++++++++++++++++++++++++++++++++++++++++++++//
96 
98  assert(!isRecording());
99  recordSet_ = false;
100  startTime_ = -1;
101  startTimeLast_ = -1;
102  stopTime_ = -1;
103  accumTime_ = 0;
104  totalTime_ = -1;
105 
106  timeVector_.clear();
107  dataVector_.clear();
108 }
109 
110 void GroupMonitorCore::pushData(int time, float data) {
111  assert(isRecording());
112 
113  timeVector_.push_back(time);
114  dataVector_.push_back(data);
115 }
116 
117 std::vector<float> GroupMonitorCore::getDataVector(){
118  return dataVector_;
119 }
120 
122  return timeVector_;
123 }
124 
126  std::vector<int> peakTimeVector;
127 
128  int size = dataVector_.size() - 1;
129  for (int i = 1; i < size; i++) {
130  if (dataVector_[i-1] < dataVector_[i] && dataVector_[i] > dataVector_[i+1])
131  peakTimeVector.push_back(timeVector_[i]);
132  }
133 
134  return peakTimeVector;
135 }
136 
138  std::vector<int> sortedPeakTimeVector;
139 
140  int size = dataVector_.size() - 1;
141  for (int i = 1; i < size; i++) {
142  if (dataVector_[i-1] < dataVector_[i] && dataVector_[i] > dataVector_[i+1])
143  sortedPeakTimeVector.push_back(timeVector_[i]);
144  }
145 
146  std::sort(sortedPeakTimeVector.begin(), sortedPeakTimeVector.end());
147  std::reverse(sortedPeakTimeVector.begin(), sortedPeakTimeVector.end());
148 
149  return sortedPeakTimeVector;
150 }
151 
153  std::vector<float> peakValueVector;
154 
155  int size = dataVector_.size() - 1;
156  for (int i = 1; i < size; i++) {
157  if (dataVector_[i-1] < dataVector_[i] && dataVector_[i] > dataVector_[i+1])
158  peakValueVector.push_back(dataVector_[i]);
159  }
160 
161  return peakValueVector;
162 }
163 
165  std::vector<float> sortedPeakValueVector;
166 
167  int size = dataVector_.size() - 1;
168  for (int i = 1; i < size; i++) {
169  if (dataVector_[i-1] < dataVector_[i] && dataVector_[i] > dataVector_[i+1])
170  sortedPeakValueVector.push_back(dataVector_[i]);
171  }
172 
173  std::sort(sortedPeakValueVector.begin(), sortedPeakValueVector.end());
174  std::reverse(sortedPeakValueVector.begin(), sortedPeakValueVector.end());
175 
176  return sortedPeakValueVector;
177 }
178 
180  if (!persistentData_) {
181  // if persistent mode is off (default behavior), automatically call clear() here
182  clear();
183  }
184 
185  // call updateGroupMonitor to make sure group data file and the data vector are up-to-date
186  // Caution: must be called before recordSet_ is set to true!
187  snn_->updateGroupMonitor(grpId_);
188 
189  recordSet_ = true;
190  int currentTime = snn_->getSimTimeSec()*1000+snn_->getSimTimeMs();
191 
192  if (persistentData_) {
193  // persistent mode on: accumulate all times
194  // change start time only if this is the first time running it
195  startTime_ = (startTime_<0) ? currentTime : startTime_;
196  startTimeLast_ = currentTime;
197  accumTime_ = (totalTime_>0) ? totalTime_ : 0;
198  } else {
199  // persistent mode off: we only care about the last probe
200  startTime_ = currentTime;
201  startTimeLast_ = currentTime;
202  accumTime_ = 0;
203  }
204 }
205 
207  assert(isRecording());
208  assert(startTime_>-1 && startTimeLast_>-1 && accumTime_>-1);
209 
210  // call updateGroupMonitor to make sure group data file and the data vector are up-to-date
211  // Caution: must be called before recordSet_ is set to false!
212  snn_->updateGroupMonitor(grpId_);
213 
214  recordSet_ = false;
215  stopTime_ = snn_->getSimTimeSec()*1000+snn_->getSimTimeMs();
216 
217  // total time is the amount of time of the last probe plus all accumulated time from previous probes
218  totalTime_ = stopTime_-startTimeLast_ + accumTime_;
219  assert(totalTime_>=0);
220 }
221 
222 void GroupMonitorCore::setGroupFileId(FILE* groupFileId) {
223  assert(!isRecording());
224 
225  // \TODO consider the case where this function is called more than once
226  if (groupFileId_ != NULL)
227  KERNEL_ERROR("GroupMonitorCore: setGroupFileId() has already been called.");
228 
229  groupFileId_ = groupFileId;
230 
231  if (groupFileId_ == NULL)
232  needToWriteFileHeader_ = false;
233  else {
234  // for now: file pointer has changed, so we need to write header (again)
235  needToWriteFileHeader_ = true;
236  writeGroupFileHeader();
237  }
238 }
239 
240 // write the header section of the group data file
241 // this should be done once per file, and should be the very first entries in the file
242 void GroupMonitorCore::writeGroupFileHeader() {
243  if (!needToWriteFileHeader_)
244  return;
245 
246  // write file signature
247  if (!fwrite(&groupFileSignature_, sizeof(int), 1, groupFileId_))
248  KERNEL_ERROR("GroupMonitorCore: writeSpikeFileHeader has fwrite error");
249 
250  // write version number
251  if (!fwrite(&groupFileVersion_, sizeof(float), 1, groupFileId_))
252  KERNEL_ERROR("GroupMonitorCore: writeGroupFileHeader has fwrite error");
253 
254  // write grid dimensions
255  Grid3D grid = snn_->getGroupGrid3D(grpId_);
256  int tmpInt = grid.numX;
257  if (!fwrite(&tmpInt,sizeof(int), 1, groupFileId_))
258  KERNEL_ERROR("GroupMonitorCore: writeGroupFileHeader has fwrite error");
259 
260  tmpInt = grid.numY;
261  if (!fwrite(&tmpInt,sizeof(int),1,groupFileId_))
262  KERNEL_ERROR("GroupMonitorCore: writeGroupFileHeader has fwrite error");
263 
264  tmpInt = grid.numZ;
265  if (!fwrite(&tmpInt,sizeof(int),1,groupFileId_))
266  KERNEL_ERROR("GroupMonitorCore: writeGroupFileHeader has fwrite error");
267 
268 
269  needToWriteFileHeader_ = false;
270 }
SNN::getSimTimeSec
int getSimTimeSec()
Definition: snn.h:581
SNN::getGroupNumNeurons
int getGroupNumNeurons(int gGrpId)
Definition: snn.h:558
group_monitor_core.h
SNN::updateGroupMonitor
void updateGroupMonitor(int grpId=ALL)
access group status (currently the concentration of neuromodulator)
Definition: snn_manager.cpp:6279
GroupMonitorCore::startRecording
void startRecording()
starts recording group data
Definition: group_monitor_core.cpp:179
Grid3D::numX
int numX
Definition: carlsim_datastructures.h:547
GroupMonitorCore::getPeakTimeVector
std::vector< int > getPeakTimeVector()
get the timestamps for peak values
Definition: group_monitor_core.cpp:125
GroupMonitorCore::clear
void clear()
deletes the data vector
Definition: group_monitor_core.cpp:97
GroupMonitorCore::getSortedPeakValueVector
std::vector< float > getSortedPeakValueVector()
get the sorted peak values of group data
Definition: group_monitor_core.cpp:164
GroupMonitorCore::getDataVector
std::vector< float > getDataVector()
get the group data
Definition: group_monitor_core.cpp:117
GroupMonitorCore::stopRecording
void stopRecording()
stops recording group data
Definition: group_monitor_core.cpp:206
GroupMonitorCore::~GroupMonitorCore
~GroupMonitorCore()
destructor, cleans up all the memory upon object deletion
Definition: group_monitor_core.cpp:88
GroupMonitorCore::isRecording
bool isRecording()
returns recording status
Definition: group_monitor_core.h:99
snn_definitions.h
KERNEL_ERROR
#define KERNEL_ERROR(formatc,...)
Definition: snn_definitions.h:109
Grid3D::numY
int numY
Definition: carlsim_datastructures.h:547
GroupMonitorCore::getSortedPeakTimeVector
std::vector< int > getSortedPeakTimeVector()
get the sorted timestamps for peak values
Definition: group_monitor_core.cpp:137
SNN::getLogFpErr
const FILE * getLogFpErr()
returns file pointer to error log
Definition: snn.h:515
SNN::getSimTimeMs
int getSimTimeMs()
Definition: snn.h:582
SNN::getLogFpInf
const FILE * getLogFpInf()
function writes population weights from gIDpre to gIDpost to file fname in binary.
Definition: snn.h:513
Grid3D
A struct to arrange neurons on a 3D grid (a primitive cubic Bravais lattice with cubic side length 1)
Definition: carlsim_datastructures.h:489
SNN::getLogFpDeb
const FILE * getLogFpDeb()
returns file pointer to debug log
Definition: snn.h:517
GroupMonitorCore::GroupMonitorCore
GroupMonitorCore(SNN *snn, int monitorId, int grpId)
constructor (called by CARLsim::setGroupMonitor)
Definition: group_monitor_core.cpp:56
GroupMonitorCore::setGroupFileId
void setGroupFileId(FILE *groupFileId)
sets pointer to group data file
Definition: group_monitor_core.cpp:222
snn.h
SNN
Contains all of CARLsim's core functionality.
Definition: snn.h:114
GroupMonitorCore::getTimeVector
std::vector< int > getTimeVector()
get the timestamps for group data
Definition: group_monitor_core.cpp:121
GroupMonitorCore::getPeakValueVector
std::vector< float > getPeakValueVector()
get the peak values of group data
Definition: group_monitor_core.cpp:152
Grid3D::numZ
int numZ
Definition: carlsim_datastructures.h:547
SNN::getGroupGrid3D
Grid3D getGroupGrid3D(int grpId)
Definition: snn_manager.cpp:1845
SNN::getLogFpLog
const FILE * getLogFpLog()
returns file pointer to log file
Definition: snn.h:519
GroupMonitorCore::pushData
void pushData(int time, float data)
inserts group data (time, value) into the vectors
Definition: group_monitor_core.cpp:110