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 "ClassLoader.h"
00025 #include "Debug.h"
00026 #include "Utilities.h"
00027 #include "SpikeStreamSimulation.h"
00028
00029
00030 #include <dlfcn.h>
00031 #include <mysql++.h>
00032 #include <iostream>
00033 using namespace std;
00034 using namespace mysqlpp;
00035
00036
00037
00038 class NeuronTypeNotFoundException : public exception{
00039 virtual const char* what() const throw(){
00040 return "Neuron type not found.";
00041 }
00042 } neuronTypeNotFoundException;
00043
00044
00045
00046 class SynapseTypeNotFoundException : public exception{
00047 virtual const char* what() const throw(){
00048 return "Synapse type not found.";
00049 }
00050 } synapseTypeNotFoundException;
00051
00052
00053
00054 class SpikeStreamRootNotFoundException : public exception{
00055 virtual const char* what() const throw(){
00056 return "Environment variable SPIKESTREAM_ROOT is not defined.";
00057 }
00058 } spikestreamRootNotFoundException;
00059
00060
00061
00062 ClassLoader::ClassLoader(DBInterface *netDBInter){
00063
00064 networkDBInterface = netDBInter;
00065
00066
00067 loadNeuronClasses();
00068 loadSynapseClasses();
00069 }
00070
00071
00072
00073 ClassLoader::~ ClassLoader(){
00074 #ifdef MEMORY_DEBUG
00075 cout<<"DESTROYING CLASS LOADER"<<endl;
00076 #endif//MEMORY_DEBUG
00077 }
00078
00079
00080
00081
00082
00083
00084
00085 string ClassLoader::getConnGrpParameterTableName(unsigned int connGrpID){
00086 if(synapseParameterTableMap.count(connGrpID)){
00087 #ifdef CLASSLOADER_DEBUG
00088 cout<<"ClassLoader: Found synapse parameter table "<<synapseParameterTableMap[connGrpID]<<endl;
00089 #endif//CLASSLOADER_DEBUG
00090 return synapseParameterTableMap[connGrpID];
00091 }
00092 SpikeStreamSimulation::systemError("ClassLoader: CANNOT FIND CONNECTION GRP ID IN PARAMETER TABLE MAP", connGrpID);
00093 throw synapseTypeNotFoundException;
00094 }
00095
00096
00097
00098 string ClassLoader::getNeuronParameterTableName(unsigned short neuronType){
00099 if(neuronParameterTableMap.count(neuronType)){
00100 #ifdef CLASSLOADER_DEBUG
00101 cout<<"ClassLoader: Found parameter table "<<neuronParameterTableMap[neuronType]<<endl;
00102 #endif//CLASSLOADER_DEBUG
00103 return neuronParameterTableMap[neuronType];
00104 }
00105 SpikeStreamSimulation::systemError("ClassLoader: CANNOT FIND NEURON TYPE IN PARAMETER TABLE MAP", neuronType);
00106 throw neuronTypeNotFoundException;
00107 }
00108
00109
00110
00111 Neuron* ClassLoader::getNewNeuron(unsigned short neuronType){
00112 if(neuronFunctionMap.count(neuronType)){
00113 Neuron* tempNeuron = neuronFunctionMap[neuronType]();
00114 #ifdef CLASSLOADER_DEBUG
00115 cout<<"ClassLoader: Getting new neuron of type "<<(*tempNeuron->getDescription())<<endl;
00116 #endif//CLASSLOADER_DEBUG
00117 return tempNeuron;
00118 }
00119 else{
00120 SpikeStreamSimulation::systemError("ClassLoader: CANNOT FIND OR RESOLVE CLASS FOR NEURON TYPE: ", neuronType);
00121 throw neuronTypeNotFoundException;
00122 }
00123 }
00124
00125
00126
00127 Synapse* ClassLoader::getNewSynapse(unsigned short synapseType){
00128 if(synapseFunctionMap.count(synapseType)){
00129 Synapse* tempSynapse = synapseFunctionMap[synapseType]();
00130 #ifdef CLASSLOADER_DEBUG
00131 cout<<"ClassLoader: Getting new synapse of type "<<(*tempSynapse->getDescription())<<endl;
00132 #endif//CLASSLOADER_DEBUG
00133 return tempSynapse;
00134 }
00135 else{
00136 SpikeStreamSimulation::systemError("ClassLoader: CANNOT FIND OR RESOLVE CLASS FOR SYNAPSE TYPE: ", synapseType);
00137 throw synapseTypeNotFoundException;
00138 }
00139 }
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 void ClassLoader::loadNeuronClasses(){
00150 try{
00151 Query query= networkDBInterface->getQuery();
00152 query.reset();
00153 query<<"SELECT TypeID, ParameterTableName, ClassLibrary FROM NeuronTypes";
00154 Result neurTypesResult = query.store();
00155
00156 for(Result::iterator iter = neurTypesResult.begin(); iter != neurTypesResult.end(); ++iter){
00157 Row neurTypeRow(*iter);
00158 unsigned int neuronType = Utilities::getUShort((std::string) neurTypeRow["TypeID"]);
00159
00160
00161 if(neuronFunctionMap.count(neuronType)){
00162 SpikeStreamSimulation::systemError("ClassLoader: NEURON TYPE HAS ALREADY BEEN LOADED!", neuronType);
00163 return;
00164 }
00165
00166
00167 char* neurLibPath_char = getenv("SPIKESTREAM_ROOT");
00168 string neuronLibraryPath;
00169 if(neurLibPath_char != NULL){
00170 neuronLibraryPath = neurLibPath_char;
00171 }
00172 else{
00173 throw spikestreamRootNotFoundException;
00174 }
00175 neuronLibraryPath += "/lib/";
00176 neuronLibraryPath += (std::string)neurTypeRow["ClassLibrary"];
00177 #ifdef CLASSLOADER_DEBUG
00178 cout<<"ClassLoader: Neuron library path = "<<neuronLibraryPath<<endl;
00179 #endif//CLASSLOADER_DEBUG
00180
00181
00182 void *hndl = dlopen(neuronLibraryPath.data() , RTLD_NOW);
00183 if(hndl == NULL){
00184 SpikeStreamSimulation::systemError(dlerror());
00185 return;
00186 }
00187 CreateNeuronFunctionType createNeuronFunction = (CreateNeuronFunctionType) dlsym(hndl, "getClass");
00188 if ( createNeuronFunction ) {
00189
00190
00191 #ifdef CLASSLOADER_DEBUG
00192 Neuron* tempNeuron = createNeuronFunction();
00193 cout<<"ClassLoader: Loading neuron of type "<<(*tempNeuron->getDescription())<<endl;
00194 #endif//CLASSLOADER_DEBUG
00195
00196
00197 neuronFunctionMap[neuronType] = createNeuronFunction;
00198 }
00199 else{
00200 SpikeStreamSimulation::systemError("ClassLoader: CANNOT FIND OR RESOLVE CLASS WHEN LOADING ALL NEURON CLASSES");
00201 return;
00202 }
00203
00204
00205 neuronParameterTableMap[neuronType] = (std::string) neurTypeRow["ParameterTableName"];
00206 #ifdef CLASSLOADER_DEBUG
00207 cout<<"ClassLoader: Neuron parameter table name is "<<neuronParameterTableMap[neuronType]<<endl;
00208 #endif//CLASSLOADER_DEBUG
00209 }
00210 }
00211 catch (const BadQuery& er) {
00212 ostringstream errorStrStream;
00213 errorStrStream<<"Bad query when loading neuron classes: \""<<er.what()<<"\"";
00214 SpikeStreamSimulation::systemError(errorStrStream.str());
00215 }
00216 catch (const Exception& er) {
00217 ostringstream errorStrStream;
00218 errorStrStream<<"Exception thrown loading neuron classes: \""<<er.what()<<"\"";
00219 SpikeStreamSimulation::systemError(errorStrStream.str());
00220 }
00221 catch(std::exception& er){
00222 ostringstream errorStrStream;
00223 errorStrStream<<"Exception thrown loading neuron classes: \""<<er.what()<<"\"";
00224 SpikeStreamSimulation::systemError(errorStrStream.str());
00225 }
00226 }
00227
00228
00229
00230
00231
00232 void ClassLoader::loadSynapseClasses(){
00233 try{
00234 Query query= networkDBInterface->getQuery();
00235 query.reset();
00236 query<<"SELECT TypeID, ParameterTableName, ClassLibrary FROM SynapseTypes";
00237 Result synTypesResult = query.store();
00238
00239
00240 for(Result::iterator iter = synTypesResult.begin(); iter != synTypesResult.end(); ++iter){
00241 Row synTypeRow(*iter);
00242 unsigned int synapseType = Utilities::getUShort((std::string) synTypeRow["TypeID"]);
00243
00244
00245 if(synapseFunctionMap.count(synapseType)){
00246 SpikeStreamSimulation::systemError("ClassLoader: SYNAPSE TYPE HAS ALREADY BEEN LOADED!", synapseType);
00247 return;
00248 }
00249
00250
00251 string synapseLibraryPath = getenv("SPIKESTREAM_ROOT");
00252 synapseLibraryPath += "/lib/";
00253 synapseLibraryPath += (std::string)synTypeRow["ClassLibrary"];
00254 #ifdef CLASSLOADER_DEBUG
00255 cout<<"ClassLoader: Synapse library path = "<<synapseLibraryPath<<endl;
00256 #endif//CLASSLOADER_DEBUG
00257
00258
00259 void *hndl = dlopen(synapseLibraryPath.data() , RTLD_NOW);
00260 if(hndl == NULL){
00261 SpikeStreamSimulation::systemError(dlerror());
00262 return;
00263 }
00264 CreateSynapseFunctionType createSynapseFunction = (CreateSynapseFunctionType) dlsym(hndl, "getClass");
00265 if ( createSynapseFunction ) {
00266
00267
00268 #ifdef CLASSLOADER_DEBUG
00269 Synapse* tempSynapse = createSynapseFunction();
00270 cout<<"ClassLoader: Loading synapse of type "<<(*tempSynapse->getDescription())<<endl;
00271 #endif//CLASSLOADER_DEBUG
00272
00273
00274 synapseFunctionMap[synapseType] = createSynapseFunction;
00275 }
00276 else{
00277 SpikeStreamSimulation::systemError("ClassLoader: CANNOT FIND OR RESOLVE CLASS WHEN LOADING ALL SYNAPSE CLASSES");
00278 return;
00279 }
00280
00281
00282
00283
00284 query.reset();
00285 query<<"SELECT ConnGrpID FROM "<<(std::string) synTypeRow["ParameterTableName"];
00286 Result connGrpIDRes = query.store();
00287 for(Result::iterator cGrpIter = connGrpIDRes.begin(); cGrpIter != connGrpIDRes.end(); ++cGrpIter){
00288 Row connGrpIDRow(*cGrpIter);
00289 unsigned int tempConnGrpID = Utilities::getUInt((std::string)connGrpIDRow["ConnGrpID"]);
00290 synapseParameterTableMap[tempConnGrpID] = (std::string) synTypeRow["ParameterTableName"];
00291 #ifdef CLASSLOADER_DEBUG
00292 cout<<"ClassLoader: Synapse parameter table name for ConnGrpID "<<tempConnGrpID<<" = "<<synapseParameterTableMap[tempConnGrpID]<<endl;
00293 #endif//CLASSLOADER_DEBUG
00294 }
00295 }
00296 }
00297 catch (const BadQuery& er) {
00298 ostringstream errorStrStream;
00299 errorStrStream<<"Bad query when loading synapse classes: \""<<er.what()<<"\"";
00300 SpikeStreamSimulation::systemError(errorStrStream.str());
00301 }
00302 catch (const Exception& er) {
00303 ostringstream errorStrStream;
00304 errorStrStream<<"Exception thrown loading synapse classes: \""<<er.what()<<"\"";
00305 SpikeStreamSimulation::systemError(errorStrStream.str());
00306 }
00307 catch(std::exception& er){
00308 ostringstream errorStrStream;
00309 errorStrStream<<"Exception thrown loading synapse classes: \""<<er.what()<<"\"";
00310 SpikeStreamSimulation::systemError(errorStrStream.str());
00311 }
00312 }
00313
00314