Symbol COMPONENT_CLASS_CPP::event(Event* event) { switch(event->type) { case EVENT_STATE_SET: { // extract DataML EventStateSet* data = (EventStateSet*) event->data; XMLNode xmlNode(data->state); DataMLNode nodeState(&xmlNode); // obtain the parameters values = nodeState.getField("values").getArrayDOUBLE(); return C_OK; } // CREATE THE PORTS case EVENT_INIT_CONNECT: { // on first call if (event->flags & F_FIRST_CALL) { out.setName("out"); out.create(hComponent); out.setStructure(TYPE_DOUBLE | TYPE_REAL, Dims(values.size()).cdims()); } // on last call if (event->flags & F_LAST_CALL) { } // ok return C_OK; } case EVENT_RUN_SERVICE: { out.setContent(&(values[0])); // ok return C_OK; } } // if we service the event, we return C_OK // if we don't, we should return S_NULL to indicate that we didn't return S_NULL; }
Symbol COMPONENT_CLASS_CPP::event(Event* event) { switch(event->type) { case EVENT_STATE_SET: { // extract DataML EventStateSet* data = (EventStateSet*) event->data; XMLNode xmlNode(data->state); DataMLNode nodeState(&xmlNode); // obtain the parameters VDOUBLE size = nodeState.getField("sizeIn").getArrayDOUBLE(); numElementsIn = 1; for (unsigned int i = 0; i < size.size(); ++i) { numElementsIn *= size[i]; } size = nodeState.getField("sizeOut").getArrayDOUBLE(); numElementsOut = 1; for (unsigned int i = 0; i < size.size(); ++i) { numElementsOut *= size[i]; } string binpath = nodeState.getField("binpath").getSTRING(); bool _has_delay = false; // get the connectivity if (nodeState.hasField("_bin_file_name")) { string fileName = nodeState.getField("_bin_file_name").getSTRING(); int _num_conn = (int) nodeState.getField("_bin_num_conn").getDOUBLE(); _has_delay = (bool) nodeState.getField("_bin_has_delay").getDOUBLE(); // open the file for reading FILE * binfile; // FIXME: We really need an absolute path here, generated at runtime fileName = binpath + fileName; binfile = fopen(fileName.c_str(),"rb"); if (!binfile) { // That failed; try the default location for // spineml-2-brahms on a Unix system: fileName = "~/spineml-2-brahms/model/" + fileName; binfile = fopen(fileName.c_str(),"rb"); if (!binfile) { berr << "Could not open connectivity file"; } } VDOUBLE delayForConnTemp; srcInds.resize(_num_conn); dstInds.resize(_num_conn); if (_has_delay) { delayForConnTemp.resize(_num_conn); } for (int i_BRAHMS = 0; i_BRAHMS < _num_conn; ++i_BRAHMS) { size_t v = fread(&srcInds[i_BRAHMS], sizeof(unsigned int), 1, binfile); if (v == 0) { bout << "Read 0 bytes from binfile" << D_INFO; if (ferror(binfile)) { berr << "Error reading sources"; } } v = fread(&dstInds[i_BRAHMS], sizeof(unsigned int), 1, binfile); if (v == 0) { bout << "2. Read 0 bytes from binfile" << D_INFO; if (ferror(binfile)) { berr << "Error reading destinations"; } } if (_has_delay) { v = fread(&delayForConnTemp[i_BRAHMS], sizeof(unsigned int), 1, binfile); if (v == 0) { if (ferror(binfile)) { berr << "ferror. read " << v << " uints from " << fileName << " for delayForConnTemp[" << i_BRAHMS << "]"; } if (feof(binfile)) { berr << "feof trying to read delayForConnTemp[" << i_BRAHMS << "]"; } berr << "read " << v << " uints from " << fileName << " for delayForConnTemp[" << i_BRAHMS << "]"; } } } } else { srcInds = nodeState.getField("src").getArrayINT32(); dstInds = nodeState.getField("dst").getArrayINT32(); } if (srcInds.size() != dstInds.size()) berr << "Connectivity src and dst lists have different sizes"; // sanity check for (UINT32 i = 0; i < srcInds.size(); ++i) { if (srcInds[i] >= numElementsIn) { berr << "Index out of range for connection : srcInds[" << i << "] (" << srcInds[i] << ") >= numElementsIn ("<< numElementsIn <<")"; } if (dstInds[i] >= numElementsOut) { berr << "Index out of range for connection : dstInds[" << i << "] (" << dstInds[i] << ") >= numElementsOut ("<< numElementsOut <<")"; } } if (_has_delay) { berr << "Unfortunately, delays in Generic inputs are not supported by SpineML_2_BRAHMS." << D_WARN; } spikesIn = false; impulseIn = false; portFound = false; return C_OK; } // CREATE THE PORTS case EVENT_INIT_CONNECT: { // on each call int numInputs = iif.getNumberOfPorts(); if (numInputs == 1 && portFound == false) { portFound = true; if (in.tryAttach(hComponent, "in")) { out.setName("out"); out.create(hComponent); out.setStructure(TYPE_DOUBLE | TYPE_REAL, Dims(numElementsOut).cdims()); } if (ins.tryAttach(hComponent,"inSpike")) { spikesIn = true; outs.setName("out"); outs.create(hComponent); outs.setCapacity(numElementsIn*numElementsOut); // create lookup for spikes spikeInds.resize(numElementsIn); for (UINT32 i = 0; i < srcInds.size(); ++i) { spikeInds[srcInds[i]].push_back(dstInds[i]); } } if (ini.tryAttach(hComponent,"inImpulse")) { impulseIn = true; outi.setName("out"); outi.create(hComponent); outi.setCapacity(numElementsIn*numElementsOut*3); // create lookup for spikes spikeInds.resize(numElementsIn); for (UINT32 i = 0; i < srcInds.size(); ++i) { spikeInds[srcInds[i]].push_back(dstInds[i]); } } } // on last call if (event->flags & F_LAST_CALL) { } // ok return C_OK; } case EVENT_RUN_SERVICE: { if (!spikesIn && !impulseIn) { DOUBLE * inData; inData = (DOUBLE*) in.getContent(); DOUBLE * outData; outData = (DOUBLE *) out.getContent(); // clear old data memset(outData, 0, 8*numElementsOut); for (UINT32 i = 0; i < srcInds.size(); ++i) { outData[dstInds[i]] += inData[srcInds[i]]; } } if (spikesIn) { INT32 * spikeData; UINT32 numSpikes; numSpikes = ins.getContent(spikeData); VINT32 outData; // for each input spike for (UINT32 i = 0; i < numSpikes; ++i) { // for each target of the source of that spike for (UINT32 j = 0; j < spikeInds[spikeData[i]].size(); ++j) { // add output spike to the list outData.push_back(spikeInds[spikeData[i]][j]); } } outs.setContent(&(outData[0]), outData.size()); } if (impulseIn) { INT32 * data; UINT32 count; count = ini.getContent(data); //DOUBLE totalImpulse = 0; VINT32 outData; // for each impulse for (UINT32 i = 0; i < count; i+=3) { // extract impulses and sum INT32 index; DOUBLE value; getImpulse(data,i,index,value); // for each target of the source of that impulse for (UINT32 j = 0; j < spikeInds[index].size(); ++j) { // add output impulse to the list addImpulse(outData, spikeInds[index][j], value); } } outi.setContent(&(outData[0]), outData.size()); } // ok return C_OK; } } // if we service the event, we return C_OK // if we don't, we should return S_NULL to indicate that we didn't return S_NULL; }
Symbol COMPONENT_CLASS_CPP::event(Event* event) { switch(event->type) { case EVENT_STATE_SET: { // extract DataML EventStateSet* data = (EventStateSet*) event->data; XMLNode xmlNode(data->state); DataMLNode nodeState(&xmlNode); // obtain the parameters size = nodeState.getField("size").getINT32(); numElementsOut = size; // Hard-code dataType initialization. I don't know if theres a // way to set this in the XML. It doesn't seem to get set when // SpineCreator writes out the experiment.xml file. dataType = ANALOG; portno = nodeState.getField("port").getINT32(); // get the server name if (nodeState.hasField("host")) { server = nodeState.getField("host").getSTRING(); } else { server = "localhost"; } // get the connection name if (nodeState.hasField("name")) { conn_name = nodeState.getField("name").getSTRING(); } else { conn_name = "unknown"; } // how often to send an output if (nodeState.hasField("skip")) { skip = nodeState.getField("skip").getDOUBLE(); } else { skip = 0.01; } /*string command = nodeState.getField("command").getSTRING(); // launch the command if it is not blank if (!command.compare("")) { // use fork to run in new thread system(command.c_str()); }*/ // scale buffer buffer.resize(size,0); dt = 1000.0f * time->sampleRate.den / time->sampleRate.num; next_t = 0; return C_OK; } // CREATE THE PORTS case EVENT_INIT_CONNECT: { if (event->flags & F_FIRST_CALL) { switch (dataType) { case EVENT: outs.setName("out"); outs.create(hComponent); outs.setCapacity(numElementsOut); break; case ANALOG: out.setName("out"); out.create(hComponent); out.setStructure(TYPE_DOUBLE | TYPE_REAL, Dims(numElementsOut).cdims()); break; case IMPULSE: { berr << "Not implemented"; break; } default: { berr << "Unknown dataType: " << (int)dataType; break; } } } // on last call if (event->flags & F_LAST_CALL) { // connect the socket: // start client if (!client.createClient(server, portno, size, dataType, RESP_AM_TARGET, conn_name)) { berr << client.getLastError(); } /*client.connectClient(portno); // handshake client.handShake(RESP_AM_TARGET); // send data type bool ok; dataType = client.recvDataType(ok); // get size int confirmSize = client.recvSize(ok); if (size != confirmSize) berr << "Wrong size of data coming into External Source: " << double(confirmSize) << " should be: " << double(size); */ } // ok return C_OK; } case EVENT_RUN_SERVICE: { // current simulation time double t = float(time->now) * dt; //cout << "Input t = " << t << endl; // implement skipping if (t > next_t - dt + 0.00001) { next_t = t + skip; // only analog for now - will add spikes etc.. later switch (dataType) { case EVENT: { berr << "Not implemented"; break; } case ANALOG: client.recvData((char *) &(buffer[0]), buffer.size()*sizeof(double)); break; case IMPULSE: { berr << "Not implemented"; break; } default: { berr << "Bad value for dataType in EVENT_RUN_SERVICE"; break; } } } out.setContent(&(buffer[0])); // ok return C_OK; } case EVENT_RUN_STOP: { //client.sendEnd(); client.disconnectClient(); // ok return C_OK; } } // if we service the event, we return C_OK // if we don't, we should return S_NULL to indicate that we didn't return S_NULL; }