Commit 408e13fe authored by K-H-Ismail's avatar K-H-Ismail Committed by Gauthier Quesnel
Browse files

benchmark: add lif and izhikevich models to network

parent f5aa0ca2
......@@ -92,7 +92,7 @@ dot_graph_save(const irt::simulation& sim, std::FILE* os)
}
}
struct neuron {
struct neuron_lif {
irt::dynamics_id sum;
irt::dynamics_id prod;
irt::dynamics_id integrator;
......@@ -100,8 +100,31 @@ struct neuron {
irt::dynamics_id constant;
irt::dynamics_id cross;
irt::dynamics_id constant_cross;
irt::output_port_id out_port;
};
struct neuron_gen {
irt::dynamics_id gen;
irt::output_port_id out_port;
};
struct neuron_izhikevich {
irt::dynamics_id sum1;
irt::dynamics_id sum2;
irt::dynamics_id sum3;
irt::dynamics_id sum4;
irt::dynamics_id prod;
irt::dynamics_id integrator1;
irt::dynamics_id integrator2;
irt::dynamics_id quantifier1;
irt::dynamics_id quantifier2;
irt::dynamics_id constant;
irt::dynamics_id cross1;
irt::dynamics_id cross2;
irt::dynamics_id constant_cross1;
irt::dynamics_id constant_cross2;
irt::output_port_id out_port;
};
struct synapse {
irt::dynamics_id sum_pre;
irt::dynamics_id prod_pre;
......@@ -118,19 +141,178 @@ struct synapse {
irt::dynamics_id constant_syn;
irt::dynamics_id accumulator_syn;
};
struct neuron_izhikevich
make_neuron_izhikevich(irt::simulation* sim, long unsigned int i, double a, double b, double c, double d, double I, double vini ) noexcept
{
using namespace boost::ut;
auto& constant = sim->constant_models.alloc();
auto& constant2 = sim->constant_models.alloc();
auto& constant3 = sim->constant_models.alloc();
auto& sum_a = sim->adder_2_models.alloc();
auto& sum_b = sim->adder_2_models.alloc();
auto& sum_c = sim->adder_4_models.alloc();
auto& sum_d = sim->adder_2_models.alloc();
auto& product = sim->mult_2_models.alloc();
auto& integrator_a = sim->integrator_models.alloc();
auto& integrator_b = sim->integrator_models.alloc();
auto& quantifier_a = sim->quantifier_models.alloc();
auto& quantifier_b = sim->quantifier_models.alloc();
auto& cross = sim->cross_models.alloc();
auto& cross2 = sim->cross_models.alloc();
double vt = 30.0;
constant.default_value = 1.0;
constant2.default_value = c;
constant3.default_value = I;
cross.default_threshold = vt;
cross2.default_threshold = vt;
integrator_a.default_current_value = vini;
quantifier_a.default_adapt_state =
irt::quantifier::adapt_state::possible;
quantifier_a.default_zero_init_offset = true;
quantifier_a.default_step_size = 0.1;
quantifier_a.default_past_length = 3;
integrator_b.default_current_value = 0.0;
quantifier_b.default_adapt_state =
irt::quantifier::adapt_state::possible;
quantifier_b.default_zero_init_offset = true;
quantifier_b.default_step_size = 0.01;
quantifier_b.default_past_length = 3;
product.default_input_coeffs[0] = 1.0;
product.default_input_coeffs[1] = 1.0;
sum_a.default_input_coeffs[0] = 1.0;
sum_a.default_input_coeffs[1] = -1.0;
sum_b.default_input_coeffs[0] = -a;
sum_b.default_input_coeffs[1] = a * b;
sum_c.default_input_coeffs[0] = 0.04;
sum_c.default_input_coeffs[1] = 5.0;
sum_c.default_input_coeffs[2] = 140.0;
sum_c.default_input_coeffs[3] = 1.0;
sum_d.default_input_coeffs[0] = 1.0;
sum_d.default_input_coeffs[1] = d;
sim->alloc(constant3, sim->constant_models.get_id(constant3));
sim->alloc(constant, sim->constant_models.get_id(constant));
sim->alloc(constant2, sim->constant_models.get_id(constant2));
sim->alloc(sum_a, sim->adder_2_models.get_id(sum_a));
sim->alloc(sum_b, sim->adder_2_models.get_id(sum_b));
sim->alloc(sum_c, sim->adder_4_models.get_id(sum_c));
sim->alloc(sum_d, sim->adder_2_models.get_id(sum_d));
sim->alloc(product, sim->mult_2_models.get_id(product));
sim->alloc(integrator_a, sim->integrator_models.get_id(integrator_a));
sim->alloc(integrator_b, sim->integrator_models.get_id(integrator_b));
sim->alloc(quantifier_a, sim->quantifier_models.get_id(quantifier_a));
sim->alloc(quantifier_b, sim->quantifier_models.get_id(quantifier_b));
sim->alloc(cross, sim->cross_models.get_id(cross));
sim->alloc(cross2, sim->cross_models.get_id(cross2));
struct neuron_izhikevich neuron_model = { sim->adder_2_models.get_id(sum_a),
sim->adder_2_models.get_id(sum_b),
sim->adder_2_models.get_id(sum_d),
sim->adder_4_models.get_id(sum_c),
sim->mult_2_models.get_id(product),
sim->integrator_models.get_id(integrator_a),
sim->integrator_models.get_id(integrator_b),
sim->quantifier_models.get_id(quantifier_a),
sim->quantifier_models.get_id(quantifier_b),
sim->constant_models.get_id(constant3),
sim->cross_models.get_id(cross),
sim->cross_models.get_id(cross2),
sim->constant_models.get_id(constant),
sim->constant_models.get_id(constant2),
cross.y[1]
};
expect(sim->connect(integrator_a.y[0], cross.x[0]) ==
irt::status::success);
expect(sim->connect(constant2.y[0], cross.x[1]) == irt::status::success);
expect(sim->connect(integrator_a.y[0], cross.x[2]) ==
irt::status::success);
expect(sim->connect(cross.y[0], quantifier_a.x[0]) ==
irt::status::success);
expect(sim->connect(cross.y[0], product.x[0]) == irt::status::success);
expect(sim->connect(cross.y[0], product.x[1]) == irt::status::success);
expect(sim->connect(product.y[0], sum_c.x[0]) == irt::status::success);
expect(sim->connect(cross.y[0], sum_c.x[1]) == irt::status::success);
expect(sim->connect(cross.y[0], sum_b.x[1]) == irt::status::success);
struct neuron
make_neuron(irt::simulation* sim, long unsigned int i) noexcept
expect(sim->connect(constant.y[0], sum_c.x[2]) == irt::status::success);
expect(sim->connect(constant3.y[0], sum_c.x[3]) == irt::status::success);
expect(sim->connect(sum_c.y[0], sum_a.x[0]) == irt::status::success);
expect(sim->connect(integrator_b.y[0], sum_a.x[1]) ==
irt::status::success);
expect(sim->connect(cross2.y[0], sum_a.x[1]) == irt::status::success);
expect(sim->connect(sum_a.y[0], integrator_a.x[1]) ==
irt::status::success);
expect(sim->connect(cross.y[0], integrator_a.x[2]) ==
irt::status::success);
expect(sim->connect(quantifier_a.y[0], integrator_a.x[0]) ==
irt::status::success);
expect(sim->connect(cross2.y[0], quantifier_b.x[0]) ==
irt::status::success);
expect(sim->connect(cross2.y[0], sum_b.x[0]) == irt::status::success);
expect(sim->connect(quantifier_b.y[0], integrator_b.x[0]) ==
irt::status::success);
expect(sim->connect(sum_b.y[0], integrator_b.x[1]) ==
irt::status::success);
expect(sim->connect(cross2.y[0], integrator_b.x[2]) ==
irt::status::success);
expect(sim->connect(integrator_a.y[0], cross2.x[0]) ==
irt::status::success);
expect(sim->connect(integrator_b.y[0], cross2.x[2]) ==
irt::status::success);
expect(sim->connect(sum_d.y[0], cross2.x[1]) == irt::status::success);
expect(sim->connect(integrator_b.y[0], sum_d.x[0]) ==
irt::status::success);
expect(sim->connect(constant.y[0], sum_d.x[1]) == irt::status::success);
return neuron_model;
}
struct neuron_gen
make_neuron_gen(irt::simulation* sim, long unsigned int i, double offset, double period ) noexcept
{
using namespace boost::ut;
double vt = -56*0.001;
double Vrest = -70*0.001;
double reset = -60*0.001;
double taum = 20.0*0.001;
auto& gen = sim->generator_models.alloc();
gen.default_value = 3.0;
gen.default_offset = offset;
gen.default_period = period;
sim->alloc(gen, sim->generator_models.get_id(gen));
struct neuron_gen neuron_model = {sim->generator_models.get_id(gen),
gen.y[0]
};
return neuron_model;
}
struct neuron_lif
make_neuron_lif(irt::simulation* sim, long unsigned int i) noexcept
{
using namespace boost::ut;
double tau_lif = 5.0 + static_cast <float> (rand()) /( static_cast <float> (RAND_MAX/(10.0-5.0)));
double Vr_lif = 0.0;
double Vt_lif = 1.0;
auto& sum_lif = sim->adder_2_models.alloc();
auto& prod_lif = sim->mult_2_models.alloc();
auto& prod_lif = sim->adder_2_models.alloc();
auto& integrator_lif = sim->integrator_models.alloc();
auto& quantifier_lif = sim->quantifier_models.alloc();
auto& constant_lif = sim->constant_models.alloc();
......@@ -139,47 +321,42 @@ make_neuron(irt::simulation* sim, long unsigned int i) noexcept
sum_lif.default_input_coeffs[0] = -1.0;
sum_lif.default_input_coeffs[1] = Vrest;
sum_lif.default_input_coeffs[1] = 2*Vt_lif;
prod_lif.default_input_coeffs[0] = 1.0;
prod_lif.default_input_coeffs[1] = 1.0/taum;
prod_lif.default_input_coeffs[0] = 1.0/tau_lif;
prod_lif.default_input_coeffs[1] = 0.0;
constant_lif.default_value = 1.0;
constant_cross_lif.default_value = reset;
constant_cross_lif.default_value = Vr_lif;
integrator_lif.default_current_value = 0.0;
quantifier_lif.default_adapt_state =
irt::quantifier::adapt_state::possible;
quantifier_lif.default_zero_init_offset = true;
quantifier_lif.default_step_size = 0.001;
quantifier_lif.default_step_size = 0.1;
quantifier_lif.default_past_length = 3;
cross_lif.default_threshold = vt;
char crosslif[7];char ctecrosslif[7];char intlif[7];
char quantlif[7];char sumlif[7];char prodlif[7];char ctelif[7];
cross_lif.default_threshold = Vt_lif;
snprintf(crosslif, 7,"croli%ld", i);snprintf(ctecrosslif, 7,"ctcli%ld", i);snprintf(intlif, 7,"intli%ld", i);
snprintf(quantlif, 7,"quali%ld", i);snprintf(sumlif, 7,"sumli%ld", i);snprintf(prodlif, 7,"prdli%ld", i);
snprintf(ctelif, 7,"cteli%ld", i);
sim->alloc(sum_lif, sim->adder_2_models.get_id(sum_lif), sumlif);
sim->alloc(prod_lif, sim->mult_2_models.get_id(prod_lif), prodlif);
sim->alloc(integrator_lif, sim->integrator_models.get_id(integrator_lif), intlif);
sim->alloc(quantifier_lif, sim->quantifier_models.get_id(quantifier_lif), quantlif);
sim->alloc(constant_lif, sim->constant_models.get_id(constant_lif), ctelif);
sim->alloc(cross_lif, sim->cross_models.get_id(cross_lif), crosslif);
sim->alloc(constant_cross_lif, sim->constant_models.get_id(constant_cross_lif), ctecrosslif);
sim->alloc(sum_lif, sim->adder_2_models.get_id(sum_lif));
sim->alloc(prod_lif, sim->adder_2_models.get_id(prod_lif));
sim->alloc(integrator_lif, sim->integrator_models.get_id(integrator_lif));
sim->alloc(quantifier_lif, sim->quantifier_models.get_id(quantifier_lif));
sim->alloc(constant_lif, sim->constant_models.get_id(constant_lif));
sim->alloc(cross_lif, sim->cross_models.get_id(cross_lif));
sim->alloc(constant_cross_lif, sim->constant_models.get_id(constant_cross_lif));
struct neuron neuron_model = {sim->adder_2_models.get_id(sum_lif),
sim->mult_2_models.get_id(prod_lif),
struct neuron_lif neuron_model = {sim->adder_2_models.get_id(sum_lif),
sim->adder_2_models.get_id(prod_lif),
sim->integrator_models.get_id(integrator_lif),
sim->quantifier_models.get_id(quantifier_lif),
sim->constant_models.get_id(constant_lif),
sim->cross_models.get_id(cross_lif),
sim->constant_models.get_id(constant_cross_lif),
sim->constant_models.get_id(constant_cross_lif),
cross_lif.y[1]
};
......@@ -201,14 +378,13 @@ make_neuron(irt::simulation* sim, long unsigned int i) noexcept
expect(sim->connect(constant_cross_lif.y[0],cross_lif.x[1]) ==
irt::status::success);
expect(sim->connect(constant_lif.y[0], sum_lif.x[1]) ==
irt::status::success);
irt::status::success);
expect(sim->connect(sum_lif.y[0],prod_lif.x[0]) ==
irt::status::success);
expect(sim->connect(constant_lif.y[0],prod_lif.x[1]) ==
irt::status::success);
return neuron_model;
}
struct synapse make_synapse(irt::simulation* sim, long unsigned int source, long unsigned int target,
irt::output_port_id presynaptic,irt::output_port_id postsynaptic,double quantum)
{
......@@ -390,33 +566,60 @@ void network(long unsigned int N, double simulation_duration, double quantum)
{
using namespace boost::ut;
irt::simulation sim;
// Neuron constants
//long unsigned int N = 10;
constexpr size_t base{ 10000000 };
constexpr size_t ten{ 10 };
constexpr size_t two{ 2 };
expect(irt::is_success(sim.model_list_allocator.init(base + (two * N * N + N) * ten)));
expect(irt::is_success(sim.message_list_allocator.init(base + (two * N * N + N) * ten)));
expect(irt::is_success(sim.input_port_list_allocator.init(base + (two * N * N + N) * ten * ten )));
expect(irt::is_success(sim.output_port_list_allocator.init(base + (two * N * N + N) * ten * ten)));
expect(irt::is_success(sim.emitting_output_port_allocator.init(base + (two * N * N + N) * ten)));
expect(irt::is_success(sim.sched.init(base + (two * N * N + N))) * ten);
expect(irt::is_success(sim.models.init(base + (two * N * N + N))));
expect(irt::is_success(sim.init_messages.init(base + (two * N * N + N))));
expect(irt::is_success(sim.messages.init(base + (two * N * N + N))));
expect(irt::is_success(sim.input_ports.init(base + (two * N * N + N) * 16)));
expect(irt::is_success(sim.output_ports.init(base + (two * N * N + N) * 7)));
expect(irt::is_success(sim.init(1000000lu, 1000000lu)));
expect(irt::is_success(sim.integrator_models.init(base +
two * N * N + N, base + (two * N * N + N) * ten)));
expect(irt::is_success(sim.quantifier_models.init(base +
two * N * N + N, base + (two * N * N + N) * ten)));
expect(irt::is_success(sim.adder_2_models.init(base + two*(two * N * N + N))));
//struct neuron neuron_model0 = make_neuron(&sim,0lu);
expect(irt::is_success(sim.constant_models.init(base + N * N + N)));
expect(irt::is_success(sim.cross_models.init(base + two * N * N + N)));
expect(irt::is_success(sim.accumulator_2_models.init(base + N * N)));
expect(irt::is_success(sim.generator_models.init(base + N )));
expect(irt::is_success(sim.adder_4_models.init(base + N )));
expect(irt::is_success(sim.mult_2_models.init(base + N )));
expect(irt::is_success(sim.observers.init(base + 3 * N * N)));
printf(">> Allocating neurones ... ");
auto start = std::chrono::steady_clock::now();
// Neurons
std::vector<irt::dynamics_id> generators;
for (long unsigned int i = 0 ; i < N; i++) {
auto& gen = sim.generator_models.alloc();
gen.default_value = 3.0;
gen.default_offset = i+1;
gen.default_period = N+1;
!expect(irt::is_success(sim.alloc(gen, sim.generator_models.get_id(gen))));
generators.emplace_back(sim.generator_models.get_id(gen));
}
/*std::vector<struct neuron_gen> neurons;
for (long unsigned int i = 0 ; i < N; i++) {
struct neuron_gen neuron_model = make_neuron_gen(&sim,i,i+1.0,N+1.0);
neurons.emplace_back(neuron_model);
}*/
std::vector<struct neuron_lif> neurons;
for (long unsigned int i = 0 ; i < N; i++) {
struct neuron_lif neuron_model = make_neuron_lif(&sim,i);
neurons.emplace_back(neuron_model);
}
/*std::vector<struct neuron_izhikevich> neurons;
for (long unsigned int i = 0 ; i < N; i++) {
struct neuron_izhikevich neuron_model = make_neuron_izhikevich(&sim,i,0.02,0.2,-65.0,8.0,10.0,0.0);
neurons.emplace_back(neuron_model);
}*/
auto end = std::chrono::steady_clock::now();
printf(" [%f] ms.\n" ,static_cast<double>(std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count()));
......@@ -427,9 +630,9 @@ void network(long unsigned int N, double simulation_duration, double quantum)
for (long unsigned int i = 0 ; i < N; i++) {
for (long unsigned int j = 0 ; j < N; j++) {
struct synapse synapse_model = make_synapse(&sim,i,j,
sim.generator_models.get(generators[i]).y[0],
sim.generator_models.get(generators[j]).y[0],quantum);
struct synapse synapse_model = make_synapse(&sim,i,j,
neurons[i].out_port,
neurons[i].out_port,quantum);
synapses.emplace_back(synapse_model);
}
}
......@@ -442,6 +645,7 @@ void network(long unsigned int N, double simulation_duration, double quantum)
printf(">> Initializing simulation ... \n");
start = std::chrono::steady_clock::now();
expect(irt::status::success == sim.initialize(t));
end = std::chrono::steady_clock::now();
printf(">> Simulation initialized in : %f ms.\n" ,static_cast<double>(std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count()));
......@@ -450,10 +654,8 @@ void network(long unsigned int N, double simulation_duration, double quantum)
start = std::chrono::steady_clock::now();
do {
irt::status st = sim.run(t);
expect(st == irt::status::success);
irt::status st = sim.run(t);
expect(st == irt::status::success);
} while (t < simulation_duration);
end = std::chrono::steady_clock::now();
......@@ -461,13 +663,13 @@ void network(long unsigned int N, double simulation_duration, double quantum)
}
BENCHMARK_P(Network, N, 10, 1,(long unsigned int N, double simulation_duration, double quantum))
BENCHMARK_P(Network, N, 1, 1,(long unsigned int N, double simulation_duration, double quantum))
{
network(N,simulation_duration,quantum);
}
BENCHMARK_P_INSTANCE(Network, N, (10,30,1e-5));
BENCHMARK_P_INSTANCE(Network, N, (10,70,1e-5));
BENCHMARK_P_INSTANCE(Network, N, (100,30,1e-5));
BENCHMARK_P_INSTANCE(Network, N, (500,30,1e-5));
//BENCHMARK_P_INSTANCE(Network, N, (500,30,1e-5));
int
main()
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment