Ejemplo n.º 1
0
    /*
     * \fn build_connections_from_neuron(std::vector<targetindex>& detectors_targetindex, connectionmanager& cn, po::variables_map const& vm)
     * \brief build connections in connection manager using generator from coreneuron miniapp
     * \param detectors_targetindex vector of targetindexes to target nodes
     * \param cn reference to connection manager
     * \param vm refrence to boost variables map
     */
    void build_connections_from_neuron(std::vector<targetindex>& detectors_targetindex, connectionmanager& cm, po::variables_map const& vm) {
        const int size = vm["size"].as<int>(); //get all connections for all nodes
        const int rank = vm["rank"].as<int>();
        const int t = vm["thread"].as<int>(); // thread_num
        const int ngroups = vm["nGroups"].as<int>(); //one thread available
        const int fan = vm["nConnections"].as<int>();
        const int ncells = vm["nNeurons"].as<int>();

        //environment::event_generator generator(nSpikes, simtime, ngroups, rank, size, ncells);
        environment::presyn_maker presyns(ncells, fan, environment::fixedoutdegree);
        presyns(size, ngroups, rank);

        for (unsigned int s_gid=0; s_gid<ncells; s_gid++) {

            const environment::presyn* local_synapses = presyns.find_output(s_gid);
            if(local_synapses != NULL) {
                for(int i = 0; i<local_synapses->size(); ++i){
                   const unsigned int t_gid = (*local_synapses)[i];
                   //sort out locally stored connections
                   const unsigned int dest = t_gid % (ngroups * size);
                   if(dest == t) {
                       //local id out of global id
                       const unsigned int t_lid = t_gid / (ngroups * size);
                       targetindex target = detectors_targetindex[t_lid%detectors_targetindex.size()];
                       cm.connect(t, s_gid, target);
                   }
                }
            }
            const environment::presyn* global_synapses = presyns.find_input(s_gid);
            if(global_synapses != NULL) {
                for(int i = 0; i<global_synapses->size(); ++i){
                    const unsigned int t_gid = (*global_synapses)[i];
                    //sort out locally stored connections
                    const unsigned int dest = t_gid % (ngroups * size);
                    if(dest == t) {
                        //local id out of global id
                        const unsigned int t_lid = t_gid / (ngroups * size);
                        targetindex target = detectors_targetindex[t_lid%detectors_targetindex.size()];
                        cm.connect(t, s_gid, target);
                    }
                }
            }
        }
    }
Ejemplo n.º 2
0
int main(int argc, char* argv[]) {
    assert(argc == 8);

    MPI_Init(NULL, NULL);
    MPI_Datatype mpi_spike = create_spike_type();
    int rank, size;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    int ngroups = atoi(argv[1]);
    int simtime = atoi(argv[2]);
    int ncells = atoi(argv[3]);
    int fanin = atoi(argv[4]);
    int nSpikes = atoi(argv[5]);
    int mindelay = atoi(argv[6]);
    bool algebra = atoi(argv[7]);

    struct timeval start, end;

    int cellsper = ncells / size;

    //create environment
    environment::event_generator generator(ngroups);

    double mean = static_cast<double>(simtime) / static_cast<double>(nSpikes);
    double lambda = 1.0 / static_cast<double>(mean * size);

    environment::continousdistribution neuro_dist(size, rank, ncells);

    environment::generate_events_kai(generator.begin(),
                              simtime, ngroups, rank, size, lambda, &neuro_dist);

    environment::presyn_maker presyns(fanin);
    presyns(rank, &neuro_dist);
    spike::spike_interface s_interface(size);

    //run simulation
    MPI_Comm neighborhood = create_dist_graph(presyns, cellsper);
    queueing::pool pl(algebra, ngroups, mindelay, rank, s_interface);
    gettimeofday(&start, NULL);
    while(pl.get_time() <= simtime){
        pl.fixed_step(generator, presyns);
        distributed_spike(s_interface, mpi_spike, neighborhood);
        pl.filter(presyns);
    }
    gettimeofday(&end, NULL);

    long long diff_ms = (1000 * (end.tv_sec - start.tv_sec))
        + ((end.tv_usec - start.tv_usec) / 1000);

    if(rank == 0){
        std::cout<<"run time: "<<diff_ms<<" ms"<<std::endl;
    }

    pl.accumulate_stats();
    accumulate_stats(s_interface);

    MPI_Comm_free(&neighborhood);
    MPI_Type_free(&mpi_spike);
    MPI_Finalize();
    return 0;
}
Ejemplo n.º 3
0
    /** \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;

    }