// apply a track template (primitive: no undo, folder states are lost, receives are removed) // _tmplt: the track template // _p: optional (to factorize chunk updates) // note: assumes _tmplt contains a single track (with items/envs already removed when _itemsFromTmplt/_envsFromTmplt are false) // i.e. use MakeSingleTrackTemplateChunk() first! bool ApplyTrackTemplatePrimitive(MediaTrack* _tr, WDL_FastString* _tmplt, bool _itemsFromTmplt, bool _envsFromTmplt, SNM_SendPatcher* _p) { bool updated = false; if (_tr && _tmplt) { WDL_FastString tmplt(_tmplt); // not to mod the input template.. SNM_ChunkParserPatcher* p = (_p ? _p : new SNM_ChunkParserPatcher(_tr)); // add current track items, if any if (!_itemsFromTmplt) { /*JFB!! works with SNM_ChunkParserPatcher v2 WDL_FastString curItems; if (p->GetSubChunk("ITEM", 2, -1, &curItems) >= 0) // -1 to get all items in one go newChunk.Insert(&curItems, newChunk.GetLength()-2); // -2: ">\n", */ // insert current items in template int posItems = p->GetSubChunk("ITEM", 2, 0); if (posItems >= 0) tmplt.Insert((char*)(p->GetChunk()->Get()+posItems), tmplt.GetLength()-2, p->GetChunk()->GetLength()-posItems-2); // -2: ">\n" } // safety: force items removal for master track //JFB REAPER BUG: test required, items would be added to the master (!) else if (_tr == GetMasterTrack(NULL)) { SNM_ChunkParserPatcher ptmplt(&tmplt); ptmplt.RemoveSubChunk("ITEM", 2, -1); } // add current track envs in template, if any if (!_envsFromTmplt) { /*JFB simple casting ko: _mode mess, etc... if (const char* envs = ((SNM_TrackEnvParserPatcher*)p)->GetTrackEnvelopes()) */ SNM_TrackEnvParserPatcher penv(p->GetChunk(), false); // no auto-commit! if (const char* envs = penv.GetTrackEnvelopes()) // get all track envs in one go, exclude fx param envs { SNM_ChunkParserPatcher ptmplt(&tmplt); // ">ITEM": best effort for the break keyword (fx chain might not exist, etc..) ptmplt.InsertAfterBefore(1, envs, "TRACK", "MAINSEND", 1, 0, "<ITEM"); } } // the meat, apply template! p->SetChunk(tmplt.Get()); updated = true; if (!_p) DELETE_NULL(p); // + auto-commit if needed } return updated; }
int builtin(char *argv[]) { if (strcmp(argv[0], "help") == 0) { help(); return 1; } if (strcmp(argv[0], "exit") == 0) /* exit command */ { int count = 0; //job_count(); if (count > 0) { printf("There are %d jobs still running.\n", count); } else { exit(0); } return 1; } if (strcmp(argv[0], "&") == 0) /* ignore singleton & */ { return 1; } if (strcmp(argv[0], "echo") == 0) /* echo command */ { argv++; for (; *argv != NULL; argv++) { printf("%s%s", *argv, " "); } printf("\n"); return 1; } if (strcmp(argv[0], "dir") == 0) /* dir command */ { /* some implementations of PATH_MAX are not compile time constants (appearantly) */ char* path = (char*) malloc(PATH_MAX * sizeof(char)); if (NULL == path || NULL == getcwd(path, PATH_MAX)) { /* path name exceeded the max length */ fprintf(stderr, "Error allocating space for getcwd: %s", strerror(errno)); exit(EXIT_FAILURE); } printf("%s\n", path); free(path); return 1; } if (strcmp(argv[0], "cdir") == 0) /* cdir command */ { cdir(argv); return 1; } if (strcmp(argv[0], "penv") == 0) /* penv command */ { penv(argv); return 1; } if (strcmp(argv[0], "senv") == 0) { senv(argv); return 1; } if (strcmp(argv[0], "unsenv") == 0) { unsenv(argv); return 1; } if (strcmp(argv[0], "pjobs") == 0) { pjobs(); return 1; } if (strcmp(argv[0], "set") == 0) { set(argv); return 1; } if (strcmp(argv[0], "limits") == 0) { limits(); return 1; } return 0; /* not a builtin command */ }
/** \fn content(po::variables_map const& vm) \brief Execute the NEST synapse Miniapp. \param vm encapsulate the command line and all needed informations */ void model_content(po::variables_map const& vm, subpragram& subprog) { int nSpikes = vm["nSpikes"].as<int>(); bool use_connection = subprog == connection; bool use_connector = subprog == connector; bool use_manager = subprog == manager; bool use_mpi = subprog == distributed; if (use_mpi) { std::stringstream command; std::string path = helper_build_path::mpi_bin_path(); size_t nthread = vm["nThreads"].as<int>(); std::string mpi_run = vm["run"].as<std::string>(); size_t nproc = vm["nProcesses"].as<int>(); //command line args size_t ncells = vm["nNeurons"].as<int>(); size_t fan = vm["fanout"].as<int>(); size_t mindelay = vm["min_delay"].as<int>(); size_t simtime = vm["simtime"].as<int>(); double rate = vm["rate"].as<double>(); if (rate>=0) { nSpikes = rate * ncells * simtime; std::cout << "WARNING: nSpikes is overwritten by rate. new value of nSpikes=" << nSpikes << std::endl; } std::string syn_model = vm["model"].as<std::string>(); double syn_delay = vm["delay"].as<double>(); double syn_weight = vm["weight"].as<double>(); double syn_U = vm["U"].as<double>(); double syn_u = vm["u"].as<double>(); double syn_x = vm["x"].as<double>(); double syn_tau_rec = vm["tau_rec"].as<double>(); double syn_tau_fac = vm["tau_fac"].as<double>(); bool pool = vm["pool"].as<bool>(); std::string exec ="nest_dist_exec"; command << "OMP_NUM_THREADS=" << nthread << " " << mpi_run <<" -n "<< nproc << " " << path << exec << " " << nthread << " " << simtime << " " << ncells << " " << fan << " " << nSpikes << " " << mindelay << " " << syn_model << " " << syn_delay << " " << syn_weight << " " << syn_U << " " << syn_u << " " << syn_x << " " << syn_tau_rec << " " << syn_tau_fac << " " << pool; std::cout<< "Running command " << command.str() <<std::endl; system(command.str().c_str()); return; } boost::chrono::system_clock::duration delay; if ( use_manager ) { const bool pool = vm["pool"].as<bool>(); const int thrd = vm["thread"].as<int>(); // thead_num const int min_delay=vm["min_delay"].as<int>(); const int simtime = vm["simtime"].as<int>(); const int nthreads = vm["nThreads"].as<int>(); const int rank = vm["rank"].as<int>(); const int size = vm["nProcesses"].as<int>(); const int ncells = vm["nNeurons"].as<int>(); const int fanout = vm["fanout"].as<int>(); //setup allocator nest::pool_env penv(nthreads, pool); //build connection manager connectionmanager cm(vm); environment::continousdistribution neuro_dist(size, rank, ncells); environment::presyn_maker presyns(fanout, environment::fixedoutdegree); presyns(thrd, &neuro_dist); //preallocate vector for results std::vector<spikedetector> detectors(ncells); std::vector<targetindex> detectors_targetindex(ncells); // register spike detectors for(unsigned int i=0; i < ncells; ++i) { detectors[i].set_lid(i); //give nodes a local id //scheduler stores pointers to the spike detectors detectors_targetindex[i] = scheduler::add_node(&detectors[i]); //add them to the scheduler } environment::continousdistribution neuro_vp_dist(nthreads, thrd, &neuro_dist); build_connections_from_neuron(thrd, neuro_vp_dist, presyns, detectors_targetindex, cm); // generate all events for one thread environment::event_generator generator(1); double mean = static_cast<double>(simtime) / static_cast<double>(nSpikes); double lambda = 1.0 / static_cast<double>(mean * size); //all events available environment::continousdistribution event_dist(1, 0, ncells); environment::generate_poisson_events(generator.begin(), simtime, nthreads, rank, size, lambda, &event_dist); const unsigned int stats_generated_spikes = generator.get_size(0); int t = 0; spikeevent se; boost::chrono::system_clock::time_point start = boost::chrono::system_clock::now(); while (t<simtime) { t+=min_delay; // get events from all threads while(generator.compare_top_lte(0, t)) { environment::gen_event g = generator.pop(0); index nid = g.first; se.set_stamp( Time(g.second) ); // in Network::send< SpikeEvent > se.set_sender_gid( nid ); // in Network::send< SpikeEvent > cm.send(thrd, nid, se); //send spike } } delay = boost::chrono::system_clock::now() - start; std::cout << "Connection manager simulated" << std::endl; std::cout << "Statistics:" << std::endl; std::cout << "\tgenerated spikes: " << stats_generated_spikes << std::endl; int recvSpikes=0; for (unsigned int i=0; i<detectors.size(); i++) recvSpikes+=detectors[i].spikes.size(); std::cout << "\trecv spikes: " << recvSpikes << std::endl; std::cout << "\tEvents left:" << std::endl; while (!generator.empty(0)) { // thread 0 environment::gen_event g = generator.pop(0); // thread 0 std::cout << "Event " << g.first << " " << g.second << std::endl; } } else if ( use_connector ) { const bool pool = vm["pool"].as<bool>(); const double syn_delay = vm["delay"].as<double>(); const double syn_weight = vm["weight"].as<double>(); const double syn_U = vm["U"].as<double>(); const double syn_u = vm["u"].as<double>(); const double syn_x = vm["x"].as<double>(); const double syn_tau_rec = vm["tau_rec"].as<double>(); const double syn_tau_fac = vm["tau_fac"].as<double>(); const int fanout = vm["fanout"].as<int>(); //setup allocator nest::pool_env penv(1, pool); // use one thread //preallocate vector for results std::vector<spikedetector> detectors(fanout); std::vector<targetindex> detectors_targetindex(fanout); for(unsigned int i=0; i < fanout; ++i) { detectors[i].set_lid(i); //give nodes a local id //scheduler stores pointers to the spike detectors detectors_targetindex[i] = scheduler::add_node(&detectors[i]); //add them to the scheduler } //create connector ptr //has to be set to NULL (check add_connection(..)) ConnectorBase* conn = NULL; //build connector for(unsigned int i=0; i < fanout; ++i) { //TODO permute parameters tsodyks2 synapse(syn_delay, syn_weight, syn_U, syn_u, syn_x, syn_tau_rec, syn_tau_fac, detectors_targetindex[i%fanout]); conn = add_connection(conn, synapse); //use static function from connectionmanager } //create a few events std::vector< spikeevent > events(nSpikes); for (unsigned int i=0; i<nSpikes; i++) { Time t(i*10.0); events[i].set_stamp( t ); // in Network::send< SpikeEvent > events[i].set_sender( NULL ); // in Network::send< SpikeEvent > } boost::chrono::system_clock::time_point start = boost::chrono::system_clock::now(); for (unsigned int i=0; i<nSpikes; i++) { conn->send(events[i]); //send spike } delay = boost::chrono::system_clock::now() - start; std::cout << "Connector simulated with " << fanout << " connections" << std::endl; } else { const double syn_delay = vm["delay"].as<double>(); const double syn_weight = vm["weight"].as<double>(); const double syn_U = vm["U"].as<double>(); const double syn_u = vm["u"].as<double>(); const double syn_x = vm["x"].as<double>(); const double syn_tau_rec = vm["tau_rec"].as<double>(); const double syn_tau_fac = vm["tau_fac"].as<double>(); //preallocate vector for results spikedetector detector; // register spike detectors targetindex detector_targetindex = scheduler::add_node(&detector); //add them to the scheduler tsodyks2 syn(syn_delay, syn_weight, syn_U, syn_u, syn_x, syn_tau_rec, syn_tau_fac, detector_targetindex); //create a few events std::vector< spikeevent > events(nSpikes); for (unsigned int i=0; i<nSpikes; i++) { Time t(i*10.0); events[i].set_stamp( t ); // in Network::send< SpikeEvent > events[i].set_sender( NULL ); // in Network::send< SpikeEvent > } double t_lastspike = 0.0; boost::chrono::system_clock::time_point start = boost::chrono::system_clock::now(); for (unsigned int i=0; i<nSpikes; i++) { syn.send(events[i], t_lastspike); //send spike t_lastspike += 0.2; // dt - time between spiks } delay = boost::chrono::system_clock::now() - start; std::cout << "Single connection simulated" << std::endl; std::cout << "Last weight " << detector.spikes.back().get_weight() << std::endl; } std::cout << "Duration: " << delay << std::endl; }