67 grpIdPost_ = grpIdPost;
68 monitorId_ = monitorId;
75 needToWriteFileHeader_ =
true;
77 connFileSignature_ = 202029319;
78 connFileVersion_ = 0.3f;
83 connFileTimeIntervalSec_ = 1;
97 maxWt_ = fabs(connInfo.
maxWt);
100 assert(nNeurPost_>0);
109 for (
int i = 0; i < nNeurPre_; i++) {
110 std::vector<float> wt;
111 for (
int j = 0; j < nNeurPost_; j++) {
114 wtMat_.push_back(wt);
115 wtMatLast_.push_back(wt);
119 updateStoredWeights();
123 if (connFileId_!=NULL) {
125 if (connFileTimeIntervalSec_ > 0) {
135 needToWriteFileHeader_ =
true;
153 updateStoredWeights();
154 std::vector< std::vector<float> > wtChange(nNeurPre_, std::vector<float>(nNeurPost_));
157 for (
int i=0; i<nNeurPre_; i++) {
158 for (
int j=0; j<nNeurPost_; j++) {
159 wtChange[i][j] = wtMat_[i][j] - wtMatLast_[i][j];
169 for (
int i=0; i<nNeurPre_; i++) {
170 for (
int j=0; j<nNeurPost_; j++) {
172 wtMatLast_[i][j] = NAN;
179 assert(neurPostId<nNeurPost_);
181 for (
int i=0; i<nNeurPre_; i++) {
182 if (!std::isnan(wtMat_[i][neurPostId])) {
191 assert(neurPreId<nNeurPre_);
193 for (
int j=0; j<nNeurPost_; j++) {
194 if (!std::isnan(wtMat_[neurPreId][j])) {
202 float maxVal = minWt_;
204 updateStoredWeights();
207 for (
int i=0; i<nNeurPre_; i++) {
208 for (
int j=0; j<nNeurPost_; j++) {
210 if (std::isnan(wtMat_[i][j]))
213 if (wtMat_[i][j] > maxVal) {
214 maxVal = wtMat_[i][j];
227 float minVal = maxWt_;
229 updateStoredWeights();
232 for (
int i=0; i<nNeurPre_; i++) {
233 for (
int j=0; j<nNeurPost_; j++) {
235 if (std::isnan(wtMat_[i][j]))
238 if (wtMat_[i][j] < minVal) {
239 minVal = wtMat_[i][j];
253 assert(minAbsChange>=0.0);
257 for (
int i=0; i<nNeurPre_; i++) {
258 for (
int j=0; j<nNeurPost_; j++) {
260 if (std::isnan(wtMat_[i][j]))
263 if (fabs(wtChange[i][j]) >= minAbsChange) {
273 assert(maxVal>=minVal);
275 updateStoredWeights();
283 for (
int i=0; i<nNeurPre_; i++) {
284 for (
int j=0; j<nNeurPost_; j++) {
286 if (std::isnan(wtMat_[i][j]))
289 if (wtMat_[i][j]>=minVal && wtMat_[i][j]<=maxVal) {
311 double wtTotalChange = 0.0;
312 for (
int i=0; i<nNeurPre_; i++) {
313 for (
int j=0; j<nNeurPost_; j++) {
315 if (std::isnan(wtMat_[i][j]))
317 wtTotalChange += fabs(wtChange[i][j]);
320 return wtTotalChange;
324 updateStoredWeights();
326 KERNEL_INFO(
"(t=%.3fs) ConnectionMonitor ID=%d: %d(%s) => %d(%s)",
332 std::stringstream header, header2;
333 header <<
" pre\\post |";
334 header2 <<
"----------|";
335 for (
int j=0; j<nNeurPost_; j++) {
336 header << std::setw(9) << std::setfill(
' ') << j <<
" |";
337 header2 <<
"-----------";
342 for (
int i=0; i<nNeurPre_; i++) {
343 std::stringstream line;
344 line << std::setw(9) << std::setfill(
' ') << i <<
" |";
345 for (
int j=0; j<nNeurPost_; j++) {
346 line << std::fixed << std::setprecision(4) << (std::isnan(wtMat_[i][j])?
" ":(wtMat_[i][j]>=0?
" ":
" "))
347 << wtMat_[i][j] <<
" ";
354 assert(neurPostId<nNeurPost_);
356 assert(connPerLine>0);
359 std::vector< std::vector<float> > wtNew, wtOld;
360 long int timeNew, timeOld;
361 if (!storeNewSnapshot) {
366 timeOld = wtTimeLast_;
369 updateStoredWeights();
370 KERNEL_INFO(
"(t=%.3fs) ConnectionMonitor ID=%d %d(%s) => %d(%s): [preId,postId] wt (+/-wtChange in %ldms) " 376 if (neurPostId==
ALL) {
378 postZ = nNeurPost_ - 1;
384 std::vector< std::vector<float> > wtChange;
389 std::stringstream line;
391 int maxIntDigits = ceil(log10((
double)std::max<int>(nNeurPre_,nNeurPost_)));
392 for (
int i=0; i<nNeurPre_; i++) {
393 for (
int j = postA; j <= postZ; j++) {
398 if (!std::isnan(wtMat_[i][j])) {
399 line <<
"[" << std::setw(maxIntDigits) << i <<
"," << std::setw(maxIntDigits) << j <<
"] " 400 << std::fixed << std::setprecision(4) << wtMat_[i][j];
402 line <<
" (" << ((wtChange[i][j]<0)?
"":
"+");
403 line << std::setprecision(4) << wtChange[i][j] <<
")";
406 if (!(++nConn % connPerLine)) {
408 line.str(std::string());
414 if (nConn % connPerLine)
417 if (!storeNewSnapshot) {
421 wtTimeLast_ = timeOld;
428 if (connFileId_!=NULL)
429 KERNEL_ERROR(
"ConnectionMonitorCore: setConnectFileId has already been called.");
431 connFileId_=connFileId;
433 if (connFileId_==NULL) {
434 needToWriteFileHeader_ =
false;
438 needToWriteFileHeader_ =
true;
439 writeConnectFileHeader();
444 assert(intervalSec==-1 || intervalSec>=1);
445 connFileTimeIntervalSec_ = intervalSec;
449 void ConnectionMonitorCore::updateStoredWeights() {
453 wtTimeLast_ = wtTime_;
462 updateStoredWeights();
469 void ConnectionMonitorCore::writeConnectFileHeader() {
472 if (!needToWriteFileHeader_)
476 if (!fwrite(&connFileSignature_,
sizeof(
int),1,connFileId_))
477 KERNEL_ERROR(
"ConnectionMonitorCore: writeConnectFileHeader has fwrite error");
480 if (!fwrite(&connFileVersion_,
sizeof(
float),1,connFileId_))
481 KERNEL_ERROR(
"ConnectionMonitorCore: writeConnectFileHeader has fwrite error");
484 if (!fwrite(&connId_,
sizeof(
short int),1,connFileId_))
485 KERNEL_ERROR(
"ConnectionMonitor: writeConnectFileHeader has fwrite error");
489 if (!fwrite(&grpIdPre_,
sizeof(
int),1,connFileId_))
490 KERNEL_ERROR(
"ConnectionMonitor: writeConnectFileHeader has fwrite error");
491 if (!fwrite(&(gridPre.
numX),
sizeof(
int),1,connFileId_))
492 KERNEL_ERROR(
"ConnectionMonitor: writeConnectFileHeader has fwrite error");
493 if (!fwrite(&(gridPre.
numY),
sizeof(
int),1,connFileId_))
494 KERNEL_ERROR(
"ConnectionMonitor: writeConnectFileHeader has fwrite error");
495 if (!fwrite(&(gridPre.
numZ),
sizeof(
int),1,connFileId_))
496 KERNEL_ERROR(
"ConnectionMonitor: writeConnectFileHeader has fwrite error");
500 if (!fwrite(&grpIdPost_,
sizeof(
int),1,connFileId_))
501 KERNEL_ERROR(
"ConnectionMonitor: writeConnectFileHeader has fwrite error");
502 if (!fwrite(&(gridPost.
numX),
sizeof(
int),1,connFileId_))
503 KERNEL_ERROR(
"ConnectionMonitor: writeConnectFileHeader has fwrite error");
504 if (!fwrite(&(gridPost.
numY),
sizeof(
int),1,connFileId_))
505 KERNEL_ERROR(
"ConnectionMonitor: writeConnectFileHeader has fwrite error");
506 if (!fwrite(&(gridPost.
numZ),
sizeof(
int),1,connFileId_))
507 KERNEL_ERROR(
"ConnectionMonitor: writeConnectFileHeader has fwrite error");
510 if (!fwrite(&nSynapses_,
sizeof(
int),1,connFileId_))
511 KERNEL_ERROR(
"ConnectionMonitor: writeConnectFileHeader has fwrite error");
514 if (!fwrite(&isPlastic_,
sizeof(
bool),1,connFileId_))
515 KERNEL_ERROR(
"ConnectionMonitor: writeConnectFileHeader has fwrite error");
518 if (!fwrite(&minWt_,
sizeof(
float),1,connFileId_))
519 KERNEL_ERROR(
"ConnectionMonitorCore: writeConnectFileHeader has fwrite error");
520 if (!fwrite(&maxWt_,
sizeof(
float),1,connFileId_))
521 KERNEL_ERROR(
"ConnectionMonitorCore: writeConnectFileHeader has fwrite error");
526 needToWriteFileHeader_ =
false;
531 if ((
long long)simTimeMs <= wtTimeWrite_ || connFileId_==NULL) {
535 wtTimeWrite_ = (
long long)simTimeMs;
538 if (!fwrite(&wtTimeWrite_,
sizeof(
long long),1,connFileId_))
539 KERNEL_ERROR(
"ConnectionMonitor: writeConnectFileSnapshot has fwrite error");
542 for (
int i=0; i<nNeurPre_; i++) {
543 for (
int j=0; j<nNeurPost_; j++) {
544 if (!fwrite(&wts[i][j],
sizeof(
float),1,connFileId_)) {
545 KERNEL_ERROR(
"ConnectionMonitor: writeConnectFileSnapshot has fwrite error");
#define ALL
CARLsim common definitions.
long int getTimeMsSinceLastSnapshot()
returns the time passed between current and last snapshot
std::vector< std::vector< float > > getWeights()
LN20201118 returns calculates current and reports them in 2D weight matrix.
float getMinWeight(bool getCurrent=false)
returns min weight in the connection (getCurrent=false: RangeWeight.min, true: current smallest) ...
std::vector< std::vector< float > > takeSnapshot()
ConnectionMonitorCore(SNN *snn, int monitorId, short int connId, int grpIdPre, int grpIdPost)
constructor, created by CARLsim::setConnectionMonitor
float getMaxWeight(bool getCurrent=false)
returns max weight in the connection (getCurrent=false: RangeWeight.max, true: current largest) ...
~ConnectionMonitorCore()
destructor, cleans up all the memory upon object deletion
int getFanIn(int neurPostId)
returns number of incoming synapses to post-synaptic neuron
std::vector< std::vector< float > > getPrevWeights()
LN20201118 returns calculates previous weights and reports them in 2D weight matrix.
double getTotalAbsWeightChange()
returns absolute sum of all weight changes since last snapshot
#define KERNEL_ERROR(formatc,...)
The configuration of a connection.
void setConnectFileId(FILE *connFileId)
sets pointer to connection file
Grid3D getGroupGrid3D(int grpId)
#define KERNEL_INFO(formatc,...)
A struct to arrange neurons on a 3D grid (a primitive cubic Bravais lattice with cubic side length 1)...
int getNumWeightsInRange(double minVal, double maxVal)
returns number of weights with values in range e[minVal,maxVal] (inclusive)
int getNumSynapses()
returns number of synapses that exist in the connection
std::string getGroupName(int grpId)
const FILE * getLogFpLog()
returns file pointer to log file
void print()
prints current weight state as 2D matrix (non-existent synapses: NAN, existent but zero weigth: 0...
void writeConnectFileSnapshot(int simTimeMs, std::vector< std::vector< float > > wts)
writes each snapshot to connect file
int getNumSynapticConnections(short int connectionId)
gets number of connections associated with a connection ID
void printSparse(int neurPostId=ALL, int maxConn=100, int connPerLine=4, bool storeNewSnapshot=true)
const FILE * getLogFpErr()
returns file pointer to error log
Contains all of CARLsim's core functionality.
int getNumWeightsChanged(double minAbsChanged=1e-5)
returns number of weights with >=minAbsChanged weight change since last snapshot
int getNumWeightsWithValue(double value)
returns number of weights that have a certain value
void setUpdateTimeIntervalSec(int intervalSec)
sets time update interval (seconds) for periodically storing weights to file
std::vector< std::vector< float > > getWeightMatrix2D(short int connId)
void clear()
deletes data from the 2D weight matrix
const FILE * getLogFpDeb()
returns file pointer to debug log
std::vector< std::vector< float > > calcWeightChanges()
calculates weight changes since last snapshot and reports them in 2D weight change matrix ...
long int getTimeMsCurrentSnapshot()
returns the timestamp of the current snapshot (not necessarily CARLsim::getSimTime) ...
bool isConnectionPlastic(short int connId)
returns whether synapses in connection are fixed (false) or plastic (true)
int getGroupNumNeurons(int gGrpId)
ConnectConfig getConnectConfig(short int connectId)
required for homeostasis
const FILE * getLogFpInf()
function writes population weights from gIDpre to gIDpost to file fname in binary.
int getFanOut(int neurPreId)
returns number of outgoing synapses of pre-synaptic neuron