📄 node.cpp
字号:
/*************************************************************************** node.cpp - description ------------------- begin : Thu Dec 13 2001 copyright : (C) 2001 by Rudiger Koch email : rkoch@rkoch.org ***************************************************************************//*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/using namespace std;#include <amygdala/node.h>#include <amygdala/mpspikeinput.h>#include <amygdala/mpnetwork.h>#include <amygdala/netloader.h>#include <amygdala/netloader.h>#include <amygdala/layer.h>#include <amygdala/utilities.h>#include <amygdala/types.h>#include <iostream.h>#include <stdlib.h>#include <time.h>#include <pthread.h>#include <unistd.h>#include <stdexcept>#include <sys/stat.h>#include <sys/types.h>#ifdef HAVE_CONFIG_H#include <config.h>#endif#if HAVE_DIRENT_H# include <dirent.h># define NAMLEN(dirent) strlen((dirent)->d_name)#else# define dirent direct# define NAMLEN(dirent) (dirent)->d_namlen# if HAVE_SYS_NDIR_H# include <sys/ndir.h># endif# if HAVE_SYS_DIR_H# include <sys/dir.h># endif# if HAVE_NDIR_H# include <ndir.h># endif#endifNode Node::theNode;Node::Node(){ srand(time(0));}Node::~Node(){}/** create a Network instance */MpNetwork* Node::MakeNetwork(int instId){ instances[instId] = new Instance(instId); MpNetwork *net = instances[instId]->GetNetwork(); return net;}/** Run all instances in this node */void Node::Run(unsigned int _maxRunTime){ maxRunTime = _maxRunTime; NNthreads = instances.size(); sleepers = 0; pthread_mutex_init(&mut_sleeper, NULL); pthread_cond_init(&cond_sleeper, NULL); for(hash_map <AmIdInt, Instance*>::iterator inst = instances.begin(); inst != instances.end(); inst++){ pthread_t *theThread = new pthread_t; Instance *instance = inst->second; instance->SetNetworkThread(theThread); pthread_create (theThread, NULL, NetworkThread, (void*)instance->GetNetwork()); } NNthreadWakeUp(); for(hash_map <AmIdInt, Instance*>::iterator inst = instances.begin(); inst != instances.end(); inst++){ Instance *instance = inst->second; int *retval; pthread_t *theThread = instance->GetNetworkThread(); pthread_join (*theThread, (void**)&retval); cout << "Amygdala instance " << instance->GetId() << " exited with status " << *retval << endl; delete theThread; instance->SetNetworkThread(NULL); delete retval; }}void Node::ConnectNeurons(AmIdInt preInstId, AmIdInt preNId, AmIdInt postInstId, AmIdInt postNId, float weight, AmTimeInt delay){ if(preInstId == postInstId) { Network *net = instances[preInstId]->GetNetwork(); net->ConnectNeurons(preNId, postNId, weight, delay); } else { instances[preInstId]->GetNetwork()->ConnectNeurons(instances[postInstId], preNId, postNId, weight, delay); }}Node* Node::GetNodeRef(){ return &theNode;}void Node::UdpListener(int port){ // TODO: Implement this to enable clustering}void* Node::NetworkThread(void* net){ cout << "Running Amygdala instance: " << static_cast<MpNetwork*>(net)->GetInstance()->GetId() << endl; GetNodeRef()->NNthreadSleep(0); // wait here until all threads are started static_cast<MpNetwork*>(net)->Run(GetNodeRef()->GetMaxRunTime()); return new int(0);}unsigned int Node::GetMaxRunTime() { return maxRunTime; }bool Node::NNthreadSleep(unsigned int simTime){ if (simTime >= maxRunTime) return false; // FIXME: job termination is not clean pthread_mutex_lock(&mut_sleeper); if(NNthreads - sleepers == 1) { // we are the last thread pthread_mutex_unlock(&mut_sleeper); return false; } else { sleepers++; pthread_cond_wait (&cond_sleeper, &mut_sleeper); pthread_mutex_unlock(&mut_sleeper); return true; }}void Node::NNthreadWakeUp(){ pthread_mutex_lock(&mut_sleeper); pthread_cond_broadcast (&cond_sleeper); sleepers = 0; pthread_mutex_unlock(&mut_sleeper);}void Node::Save(string filename){ string tmpdir = Utilities::MkTempDir(); string filedir = string(tmpdir) + "/amygdala"; mkdir(filedir.c_str(), S_IXUSR|S_IRUSR|S_IWUSR); for(hash_map <AmIdInt, Instance*>::iterator inst = instances.begin(); inst != instances.end(); inst++){ Instance *instance = inst->second; if(instance->GetNetworkThread() != NULL) throw runtime_error("Instance " + Utilities::itostr(instance->GetId()) + " running"); Network *net = instance->GetNetwork(); NetLoader *loader = new NetLoader(net); string xmlFilename = filedir + "/" + Utilities::itostr(instance->GetId()); loader->SaveXML(xmlFilename.c_str()); delete loader; } if(system(("tar --remove-files -C " + string(tmpdir) + " -c -f " + filename + " amygdala").c_str())) throw runtime_error("could not tar " + filename); if(rmdir((filedir).c_str()) || rmdir((tmpdir).c_str())) cerr << "Could not remove " << tmpdir << endl;}void Node::Load(string filename){ struct dirent *netInstance; string tmpdir = Utilities::MkTempDir(); string filedir = tmpdir + "/amygdala"; if(system(("tar -C " + string(tmpdir) + " -x -f " + filename ).c_str())) throw runtime_error("could not un-tar " + filename); DIR * cdir = opendir(filedir.c_str()); while ((netInstance = readdir(cdir))){ string instFile = netInstance->d_name; if(instFile[0] != '.') { AmIdInt instId = atoi(instFile.c_str()); MpNetwork *net = MakeNetwork(instId); NetLoader nl(net); nl.LoadXML((filedir + "/" + instFile).c_str()); unlink((filedir + "/" + instFile).c_str()); } } if(closedir(cdir)) throw runtime_error(filedir + "couldn't close"); if(rmdir((filedir).c_str()) || rmdir((tmpdir).c_str())) cerr << "Could not remove " << tmpdir << endl;}void Node::ConnectLayers(AmIdInt preInstanceId, AmIdInt preLayerId, AmIdInt postInstanceId, AmIdInt postLayerId, GaussConnectType parms, float pctInhibitory){ float weight; Neuron *postNrn, *preNrn; Layer::iterator postItr, preItr; bool enforceSign = Neuron::EnforceSign(); if ( parms.meanWeight < 0.0 ) throw runtime_error("GaussConnectType.meanWeight must be > 0!"); Instance *postInstance = instances[postInstanceId]; if(postInstance == NULL) throw runtime_error("No such post InstanceID: " + Utilities::itostr(postInstanceId)); Instance *preInstance = instances[preInstanceId]; if(preInstance == NULL) throw runtime_error("No such pre InstanceID: " + Utilities::itostr(preInstanceId)); Layer *postLayer = postInstance->GetNetwork()->GetLayer(postLayerId); if(postLayer == NULL) throw runtime_error("No such post LayerID: " + Utilities::itostr(postLayerId)); Layer *preLayer = preInstance->GetNetwork()->GetLayer(preLayerId); if(preLayer == NULL) throw runtime_error("No such pre LayerID: " + Utilities::itostr(preLayerId)); postItr = postLayer->begin(); while (postItr != postLayer->end()) { postNrn = *(postItr++); preItr = preLayer->begin(); while (preItr != preLayer->end()) { preNrn = *(preItr++); if ( Utilities::RandPercent() < parms.pctConnect ) { weight = Utilities::GaussRand(parms.meanWeight, parms.stdDev); if ( weight > 1.0 ) { weight = 1.0; } else if ( weight < 0.0 ) { weight = 1e-10; } if (enforceSign) { if ( preNrn->Inhibitory() ) { weight = ( -1.0 * weight ); } } else if ( Utilities::RandPercent() < pctInhibitory ) { weight = ( -1.0 * weight ); } // get the neuron IDs AmIdInt pre = preNrn->GetID(); AmIdInt post = postNrn->GetID(); AmTimeInt delay = preLayer->GetSynapticDelay(); ConnectNeurons(preInstanceId, pre, postInstanceId, post, weight, delay); } } }}void Node::DeleteInstance(AmIdInt instId){ Instance *inst = instances[instId]; if(inst == NULL) throw string("No such instance: ") + Utilities::itostr(instId); MpNetwork *net = inst->GetNetwork(); delete inst; delete net; instances.erase(instId);}Network* Node::GetNetwork(AmIdInt instId){ Instance *inst = instances[instId]; return inst->GetNetwork();}hash_map <AmIdInt, Instance*>::iterator Node::instance_begin(){ return instances.begin();}hash_map <AmIdInt, Instance*>::iterator Node::instance_end(){ return instances.end();}Instance * Node::GetInstance(AmIdInt instId){ return instances[instId];}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -