00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "DeviceManager.h"
00025 #include "Debug.h"
00026 #include "Utilities.h"
00027 #include "DeviceTypes.h"
00028 #include "SimulationClock.h"
00029 #include "SpikeStreamSimulation.h"
00030
00031
00032 #include <math.h>
00033 #include <errno.h>
00034 #include <sys/shm.h>
00035 #include <iostream>
00036 #include <mysql++.h>
00037 using namespace mysqlpp;
00038 using namespace std;
00039
00040
00041
00042
00043
00044 DeviceManager::DeviceManager(unsigned int devID, unsigned int neurGrpID, double devFiringMode, DBInterface* devDBInter, DBInterface *netDBInter){
00045
00046 deviceDBInterface = devDBInter;
00047 networkDBInterface = netDBInter;
00048
00049
00050 deviceID = devID;
00051 neuronGrpID = neurGrpID;
00052
00053
00054 deviceType = UNKNOWN_DEVICE_VALUE;
00055 deviceOpen = false;
00056
00057
00058 for(int i=0; i<NUMBER_OF_DELAY_VALUES; ++i){
00059 deviceBuffer[i].set_empty_key(EMPTY_NEURON_ID_KEY);
00060 deviceBuffer[i].set_deleted_key(DELETED_NEURON_ID_KEY);
00061 }
00062
00063
00064 try{
00065 loadDeviceInformation();
00066 }
00067 catch (const BadQuery& er) {
00068 ostringstream errorStrStream;
00069 errorStrStream<<"Bad query when loading device information: \""<<er.what()<<"\"";
00070 SpikeStreamSimulation::systemError(errorStrStream.str());
00071 }
00072 catch (const Exception& er) {
00073 ostringstream errorStrStream;
00074 errorStrStream<<"Exception thrown loading device information: \""<<er.what()<<"\"";
00075 SpikeStreamSimulation::systemError(errorStrStream.str());
00076 }
00077 catch(std::exception& er){
00078 ostringstream errorStrStream;
00079 errorStrStream<<"Exception thrown loading device information: \""<<er.what()<<"\"";
00080 SpikeStreamSimulation::systemError(errorStrStream.str());
00081 }
00082
00083
00084
00085 if(DeviceTypes::isInputDevice(deviceType)){
00086 if(devFiringMode == INPUT_DIRECT_FIRING_MODE){
00087 directFiringMode = true;
00088 synapticWeight = 0.0;
00089 #ifdef DEVICE_FIRING_MODE_DEBUG
00090 cout<<"DEVICE FIRING MODE: Input device. Direct firing mode"<<endl;
00091 #endif//DEVICE_FIRING_MODE_DEBUG
00092 }
00093 else if (devFiringMode == OUTPUT_FIRING_MODE){
00094 SpikeStreamSimulation::systemError("Device firing mode is set to output device, but this is an input device!");
00095 }
00096 else{
00097 directFiringMode = false;
00098 synapticWeight = devFiringMode;
00099 #ifdef DEVICE_FIRING_MODE_DEBUG
00100 cout<<"DEVICE FIRING MODE: Input device. Synaptic firing mode with weight = "<<synapticWeight<<endl;
00101 #endif//DEVICE_FIRING_MODE_DEBUG
00102 }
00103 }
00104 else{
00105 directFiringMode = false;
00106 synapticWeight = 0.0;
00107 #ifdef DEVICE_FIRING_MODE_DEBUG
00108 cout<<"DEVICE FIRING MODE: Output device. No firing mode set"<<endl;
00109 #endif//DEVICE_FIRING_MODE_DEBUG
00110 }
00111
00112
00113 clearSynchronizationDelay();
00114 }
00115
00116
00117
00118
00119
00120 DeviceManager::DeviceManager(){
00121
00122 deviceDBInterface = NULL;
00123 deviceID = 0;
00124 neuronGrpID = 0;
00125 deviceType = UNKNOWN_DEVICE_VALUE;
00126 deviceOpen = false;
00127 }
00128
00129
00130
00131 DeviceManager::~DeviceManager(){
00132 #ifdef MEMORY_DEBUG
00133 cout<<"DESTROYING DEVICE MANAGER"<<endl;
00134 #endif//MEMORY_DEBUG
00135
00136 if(deviceOpen)
00137 closeDevice();
00138
00139
00140
00141 if(deviceDBInterface != NULL)
00142 clearSynchronizationDelay();
00143 }
00144
00145
00146
00147
00148
00149
00150
00151
00152 bool DeviceManager::closeDevice(){
00153 if(deviceOpen){
00154
00155 if(deviceType == DeviceTypes::syncUDPNetworkInput){
00156 if(udpSyncClient->closeDevice()){
00157 deviceOpen = false;
00158 return true;
00159 }
00160 }
00161 else if (deviceType == DeviceTypes::syncUDPNetworkOutput){
00162 if(udpSyncServer->closeDevice()){
00163 deviceOpen = false;
00164 return true;
00165 }
00166 }
00167 else if(deviceType == DeviceTypes::syncTCPNetworkInput || deviceType == DeviceTypes::syncTCPNetworkVisionInput){
00168 if(tcpSyncClient->closeDevice()){
00169 deviceOpen = false;
00170 return true;
00171 }
00172 }
00173 else if(deviceType == DeviceTypes::syncTCPNetworkOutput){
00174 if(tcpSyncServer->closeDevice()){
00175 deviceOpen = false;
00176 return true;
00177 }
00178 }
00179 else{
00180 SpikeStreamSimulation::systemError("DeviceManager: ATTEMPTING TO CLOSE AN UNRECOGNIZED DEVICE TYPE");
00181 return false;
00182 }
00183 }
00184 return true;
00185 }
00186
00187
00188
00189
00190 bool DeviceManager::fetchData(){
00191 if(deviceType == DeviceTypes::syncTCPNetworkInput || deviceType == DeviceTypes::syncTCPNetworkVisionInput){
00192 return tcpSyncClient->fetchData();
00193 }
00194 else if (deviceType == DeviceTypes::syncUDPNetworkInput){
00195 return udpSyncClient->clientThreadRunning();
00196 }
00197 else{
00198 SpikeStreamSimulation::systemError("DeviceManager: ATTEMPTING TO RECEIVE DATA FROM AN UNRECOGNIZED DEVICE TYPE");
00199 return false;
00200 }
00201 }
00202
00203
00204
00205 unsigned int DeviceManager::getDeviceType(){
00206 return deviceType;
00207 }
00208
00209
00210
00211
00212 unsigned int DeviceManager::getExternalComputeTime_us(){
00213 if(deviceType == DeviceTypes::syncUDPNetworkInput)
00214 return udpSyncClient->getExternalComputeTime_us();
00215 else{
00216 SpikeStreamSimulation::systemError("DeviceManager: CALLING GET EXTERNAL COMPUTE TIME WHEN IT IS NOT APPROPRIATE");
00217 return 0;
00218 }
00219 }
00220
00221
00222
00223
00224 bool DeviceManager::getExternalSyncDelay(){
00225 if(deviceType == DeviceTypes::syncUDPNetworkInput)
00226 return udpSyncClient->getExternalSyncDelay();
00227 else{
00228 SpikeStreamSimulation::systemError("DeviceManager: CALLING EXTERNAL SYNC DELAY WHEN IT IS NOT APPROPRIATE");
00229 return false;
00230 }
00231 }
00232
00233
00234
00235
00236 bool DeviceManager::isInputDevice(){
00237 if(deviceType % 2 == 1)
00238 return true;
00239 return false;
00240 }
00241
00242
00243
00244
00245 bool DeviceManager::isOutputDevice(){
00246 if(deviceType % 2 == 0)
00247 return true;
00248 return false;
00249 }
00250
00251
00252
00253 void DeviceManager::setNeuronArray(Neuron **neurArr){
00254 neuronArray = neurArr;
00255 }
00256
00257
00258
00259
00260 void DeviceManager::setNeuronUpdateMap(dense_hash_map<unsigned int, bool, hash<unsigned int> >* neurUdtMp){
00261 neuronUpdateMap = neurUdtMp;
00262 }
00263
00264
00265
00266
00267 void DeviceManager::setNeuronVector(vector<unsigned int> *neurVectPtr, unsigned int startNeurID){
00268 startNeuronID = startNeurID;
00269 if (deviceType == DeviceTypes::syncUDPNetworkOutput){
00270 udpSyncServer->setNeuronVector(neurVectPtr, startNeurID);
00271 }
00272 else if(deviceType == DeviceTypes::syncTCPNetworkOutput){
00273 tcpSyncServer->setNeuronVector(neurVectPtr, startNeurID);
00274 }
00275 }
00276
00277
00278
00279 bool DeviceManager::updateDevice(){
00280
00281
00282 if (deviceType == DeviceTypes::syncUDPNetworkOutput){
00283 return udpSyncServer->sendSpikeData();
00284 }
00285 else if (deviceType == DeviceTypes::syncTCPNetworkOutput){
00286 return tcpSyncServer->sendSpikeData();
00287 }
00288 else{
00289 SpikeStreamSimulation::systemError("DeviceManager: ATTEMPTING TO SEND DATA TO AN UNRECOGNIZED DEVICE TYPE");
00290 return false;
00291 }
00292 }
00293
00294
00295
00296 void DeviceManager::updateNeurons(){
00297
00298 fillDeviceBuffer();
00299
00300
00301
00302 for(dense_hash_map<unsigned int, bool, hash<unsigned int> >::iterator iter = deviceBuffer[bufferCounter].begin(); iter != deviceBuffer[bufferCounter].end(); ++iter){
00303 if(directFiringMode)
00304 neuronArray[iter->first]->fireNeuron();
00305 else{
00306 neuronArray[iter->first]->changePostSynapticPotential(synapticWeight, 0);
00307 (*neuronUpdateMap)[ iter->first + startNeuronID ] = true;
00308 }
00309 }
00310
00311
00312 deviceBuffer[bufferCounter].clear();
00313 ++bufferCounter;
00314 bufferCounter = bufferCounter % NUMBER_OF_DELAY_VALUES;
00315 }
00316
00317
00318
00319
00320
00321
00322
00323 void DeviceManager::clearSynchronizationDelay(){
00324 try{
00325 Query deviceQuery = deviceDBInterface->getQuery();
00326 deviceQuery.reset();
00327 deviceQuery<<"DELETE FROM SynchronizationDelay";
00328 deviceQuery.execute();
00329 }
00330 catch (const BadQuery& er) {
00331 ostringstream errorStrStream;
00332 errorStrStream<<"Bad query when clearing synchronization delay: \""<<er.what()<<"\"";
00333 SpikeStreamSimulation::systemError(errorStrStream.str());
00334 }
00335 catch (const Exception& er) {
00336 ostringstream errorStrStream;
00337 errorStrStream<<"Exception thrown clearing synchronization delay: \""<<er.what()<<"\"";
00338 SpikeStreamSimulation::systemError(errorStrStream.str());
00339 }
00340 }
00341
00342
00343
00344 void DeviceManager::fillDeviceBuffer(){
00345 if(deviceType == DeviceTypes::syncUDPNetworkInput){
00346
00347 udpSyncClient->lockMutex();
00348
00349
00350 for(unsigned int i=0; i<udpSyncClient->spikeCount; ++i){
00351
00352
00353 unsigned int xPos = udpSyncClient->spikeBuffer[i * 3];
00354 unsigned int yPos = udpSyncClient->spikeBuffer[i * 3 + 1];
00355 unsigned int delay = udpSyncClient->spikeBuffer[i * 3 + 2];
00356
00357
00358 int arrayIndex = xPos + yPos*neuronGrpWidth;
00359 int insertionPosition = (bufferCounter + delay) % NUMBER_OF_DELAY_VALUES;
00360 deviceBuffer[insertionPosition][arrayIndex] = true;
00361 }
00362
00363
00364 udpSyncClient->spikeCount = 0;
00365
00366
00367 udpSyncClient->unlockMutex();
00368 }
00369 else if(deviceType == DeviceTypes::syncTCPNetworkInput || deviceType == DeviceTypes::syncTCPNetworkVisionInput){
00370
00371
00372 for(unsigned int i=0; i<tcpSyncClient->spikeCount; ++i){
00373
00374
00375 unsigned int xPos = tcpSyncClient->spikeBuffer[i * 3];
00376 unsigned int yPos = tcpSyncClient->spikeBuffer[i * 3 + 1];
00377 unsigned int delay = tcpSyncClient->spikeBuffer[i * 3 + 2];
00378
00379
00380 int arrayIndex = xPos + yPos*neuronGrpWidth;
00381 int insertionPosition = (bufferCounter + delay) % NUMBER_OF_DELAY_VALUES;
00382 deviceBuffer[insertionPosition][arrayIndex] = true;
00383 }
00384 }
00385 else{
00386 SpikeStreamSimulation::systemError("DeviceManager: DEVICE TYPE NOT RECOGNIZED");
00387 }
00388 }
00389
00390
00391
00392
00393
00394 void DeviceManager::loadDeviceInformation(){
00395 deviceOpen = false;
00396
00397 #ifdef DEVICE_DEBUG
00398 cout<<"DeviceManager: Loading Device information"<<endl;
00399 #endif//DEVICE_DEBUG
00400
00401
00402 Query networkQuery = networkDBInterface->getQuery();
00403 networkQuery.reset();
00404 networkQuery<<"SELECT Width, Length FROM NeuronGroups WHERE NeuronGrpID = "<<neuronGrpID;
00405 Result networkResults = networkQuery.store();
00406 Row networkRow(*networkResults.begin());
00407 neuronGrpWidth = Utilities::getUInt((std::string)networkRow["Width"]);
00408 neuronGrpLength = Utilities::getUInt((std::string)networkRow["Length"]);
00409
00410
00411 Query deviceQuery = deviceDBInterface->getQuery();
00412 deviceQuery.reset();
00413 deviceQuery<<"SELECT IPAddress, Port, TotalNumColumns, TotalNumRows, Type FROM Devices WHERE DeviceID = "<<deviceID;
00414 Result deviceResults = deviceQuery.store();
00415 Row deviceRow(*deviceResults.begin());
00416 deviceType = Utilities::getUInt((std::string)deviceRow["Type"]);
00417 unsigned int deviceWidth = Utilities::getUInt((std::string)deviceRow["TotalNumColumns"]);
00418 unsigned int deviceLength = Utilities::getUInt((std::string)deviceRow["TotalNumRows"]);
00419 unsigned int devicePort = Utilities::getUInt((std::string)deviceRow["Port"]);
00420
00421 #ifdef DEVICE_DEBUG
00422 cout<<"Creating device with type="<<deviceType<<"; IPAddress="<<deviceRow["IPAddress"]<<"; Port="<<devicePort<<"; deviceWidth="<<deviceWidth<<"; deviceLength="<<deviceLength<<endl;
00423 #endif//DEVICE_DEBUG
00424
00425
00426 if(deviceType == DeviceTypes::syncUDPNetworkInput){
00427
00428 udpSyncClient = new UDPSynchronizedClient(neuronGrpWidth, neuronGrpLength);
00429
00430
00431 if(udpSyncClient->openSocket((std::string)deviceRow["IPAddress"], devicePort))
00432 udpSyncClient->start();
00433 else
00434 return;
00435 }
00436 else if(deviceType == DeviceTypes::syncUDPNetworkOutput){
00437 udpSyncServer = new UDPSynchronizedServer(deviceDBInterface, neuronGrpWidth);
00438 if(!udpSyncServer->openSocket((std::string)deviceRow["IPAddress"], devicePort))
00439 return;
00440 }
00441 else if(deviceType == DeviceTypes::syncTCPNetworkInput || deviceType == DeviceTypes::syncTCPNetworkVisionInput){
00442
00443 tcpSyncClient = new TCPSynchronizedClient(neuronGrpWidth, neuronGrpLength);
00444
00445
00446
00447 if(deviceType == DeviceTypes::syncTCPNetworkVisionInput){
00448 tcpSyncClient->setTwoByteCoords(true);
00449 }
00450
00451
00452 if(!tcpSyncClient->openSocket((std::string)deviceRow["IPAddress"], devicePort))
00453 return;
00454 }
00455 else if(deviceType == DeviceTypes::syncTCPNetworkOutput){
00456 tcpSyncServer = new TCPSynchronizedServer(neuronGrpWidth);
00457 if(!tcpSyncServer->openSocket((std::string)deviceRow["IPAddress"], devicePort))
00458 return;
00459 }
00460 else {
00461 SpikeStreamSimulation::systemError("DeviceManager: DEVICE TYPE NOT RECOGNIZED");
00462 }
00463
00464
00465 if(neuronGrpWidth == deviceWidth && neuronGrpLength == deviceLength){
00466 rotatePattern = false;
00467 }
00468 else if(neuronGrpWidth == deviceLength && neuronGrpLength == deviceWidth){
00469 rotatePattern = true;
00470 SpikeStreamSimulation::systemError("DeviceManager: ROTATE PATTERN NOT IMPLEMENTED.\nDEVICE WIDTH AND LENGTH DO NOT MATCH NEURON GROUP WIDTH AND LENGTH");
00471 return;
00472 }
00473 else{
00474 SpikeStreamSimulation::systemError("DeviceManager: DEVICE WIDTH AND LENGTH DO NOT MATCH NEURON GROUP WIDTH AND LENGTH");
00475 return;
00476 }
00477
00478
00479 deviceOpen = true;
00480
00481 #ifdef DEVICE_DEBUG
00482 cout<<"DeviceManager: Device information loaded"<<endl;
00483 #endif//DEVICE_DEBUG
00484 }
00485
00486