Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
root = true

# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true

[*.py]
charset = utf-8

# 4 space indentation
[*{.py,.cpp,.cu,.hpp}]
indent_style = space
indent_size = 4
4 changes: 2 additions & 2 deletions .github/workflows/test-matrix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ jobs:
- {
name: "Linux Min Clang",
os: "ubuntu-22.04",
cc: "clang-13",
cxx: "clang++-13",
cc: "clang-14",
cxx: "clang++-14",
py: "3.10",
cmake: "4.0.x",
mpi: "ON",
Expand Down
46 changes: 45 additions & 1 deletion arbor/adex_cell_group.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <arbor/arbexcept.hpp>

#include "arbor/math.hpp"
#include "util/maputil.hpp"
#include "util/rangeutil.hpp"
#include "util/span.hpp"
#include "label_resolution.hpp"
Expand Down Expand Up @@ -99,6 +100,49 @@ void adex_cell_group::reset() {
spikes_.clear();
}

void
adex_cell_group::edit_cell(cell_gid_type gid, std::any cell_edit) {
try {
auto adex_edit = std::any_cast<adex_cell_editor>(cell_edit);
auto lid = util::binary_search_index(gids_, gid);
if (!lid) throw arb::arbor_internal_error{"gid " + std::to_string(gid) + " erroneuosly dispatched to cell group."};
auto& lowered = cells_[*lid];
auto tmp = adex_cell {
.source = lowered.source, // Label of source
.target = lowered.target, // Label of target
.delta = lowered.delta * U::mV,
.V_th = lowered.V_th * U::mV,
.C_m = lowered.C_m * U::nF,
.E_L = lowered.E_L * U::mV,
.E_R = lowered.E_R * U::mV,
.V_m = lowered.V_m * U::mV,
.t_ref = lowered.t_ref * U::ms,
.g = lowered.g * U::uS,
.tau = lowered.tau * U::ms,
.w = lowered.w * U::pA,
.a = lowered.a * U::uS,
.b = lowered.b * U::nA,
};
adex_edit(tmp);
// NOTE: we forbid writing to V_m? Reasons
// * the cell might be in the refractory period which causes semantic issues
// - return to normal or not?
// - what should probes return
// * V_m is the _initial state_ only
if (tmp.V_m.value_as(U::mV) != lowered.V_m) throw bad_cell_edit(gid, "Initial voltage is not editable.");
if (tmp.w.value_as(U::pA) != lowered.w) throw bad_cell_edit(gid, "Adaption parameter is not editable.");
if (tmp.source != lowered.source) throw bad_cell_edit(gid, "Source is not editable.");
if (tmp.target != lowered.target) throw bad_cell_edit(gid, "Target is not editable.");
// Write back
lowered = adex_lowered_cell{tmp};

}
catch (const std::bad_any_cast& ){
throw bad_cell_edit(gid, "Not an AdEx editor (C++ type-id: '" + std::string{cell_edit.type().name()} + "')");
}
}


// integrate a single cell's state from current time `cur` tos final time `end`.
// Extra parameters
// * the cell cannot be updated until time `nxt`, which might be in the past or future.
Expand All @@ -118,7 +162,7 @@ void integrate_until(adex_lowered_cell& cell, const time_type end, const time_ty
auto delta = end - cur;
// membrane potential deviation from resting value
auto dE = cell.V_m - cell.E_L;
// leak current
// leak current
auto il = cell.g*dE;
// spike current
auto is = cell.g*cell.delta*exp((cell.V_m - cell.V_th)/cell.delta);
Expand Down
2 changes: 2 additions & 0 deletions arbor/adex_cell_group.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ struct ARB_ARBOR_API adex_cell_group: public cell_group {

static bool backend_supported(backend_kind kind) { return kind == backend_kind::multicore; }

void edit_cell(cell_gid_type gid, std::any edit) override;

private:
enum class adex_probe_kind { voltage, adaption };

Expand Down
17 changes: 11 additions & 6 deletions arbor/backends/multicore/shared_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@

#include "multicore_common.hpp"
#include "shared_state.hpp"
#include "fvm.hpp"

namespace arb {
namespace multicore {
Expand Down Expand Up @@ -183,7 +182,6 @@ void istim_state::add_current(const arb_value_type time, array& current_density)
}

// shared_state methods:

shared_state::shared_state(task_system_handle, // ignored in mc backend
arb_size_type n_cell,
arb_size_type n_cv_,
Expand Down Expand Up @@ -403,10 +401,8 @@ unsigned shared_state::instantiate(arb::mechanism& m,
bool peer_indices = !pos_data.peer_cv.empty();

// store indices for random number generation
if (m.mech_.n_random_variables) {
store.gid_ = pos_data.gid;
store.idx_ = pos_data.idx;
}
store.gid_ = pos_data.gid;
if (m.mech_.n_random_variables) store.idx_ = pos_data.idx;

// Allocate view pointers (except globals!)
store.state_vars_.resize(m.mech_.n_state_vars); m.ppack_.state_vars = store.state_vars_.data();
Expand Down Expand Up @@ -537,5 +533,14 @@ unsigned shared_state::instantiate(arb::mechanism& m,
return id;
}

void shared_state::update_range_parameter(arb_index_type lid, arb_mechanism_ppack& ppack, cell_gid_type pid, const std::vector<arb_value_type>& vals) {
auto off = 0;
for (auto idx = 0ul; idx < ppack.width; ++idx) {
if (lid != ppack.vec_ci[ppack.node_index[idx]]) continue;
ppack.parameters[pid][idx] = vals[off];
++off;
}
}

} // namespace multicore
} // namespace arb
4 changes: 4 additions & 0 deletions arbor/backends/multicore/shared_state.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,10 @@ struct ARB_ARBOR_API shared_state:
sample_time_host = util::range_pointer_view(sample_time);
sample_value_host = util::range_pointer_view(sample_value);
}

bool mechanism_matches();

void update_range_parameter(arb_index_type lid, arb_mechanism_ppack& ppack, cell_gid_type pid, const std::vector<arb_value_type>& val);
};

// For debugging only:
Expand Down
10 changes: 8 additions & 2 deletions arbor/backends/shared_state_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ struct shared_state_base {
// samples
auto n_samples = util::sum_by(samples, [] (const auto& s) {return s.size();});
if (d->sample_time.size() < n_samples) {
d->sample_time = array(n_samples);
d->sample_value = array(n_samples);
d->sample_time.resize(n_samples);
d->sample_value.resize(n_samples);
}
initialize(samples, d->sample_events);
// thresholds
Expand Down Expand Up @@ -80,6 +80,12 @@ struct shared_state_base {
}
}

// overwrite a RANGE-type parameter in the mechanism `ppack` is attached to.
void update_range_parameter(cell_gid_type lid, arb_mechanism_ppack& ppack, cell_gid_type pid, const std::vector<arb_value_type>& vals) {
auto d = static_cast<D*>(this);
d->update_range_parameter(lid, ppack, pid, vals);
}

arb_value_type* mechanism_state_data(const mechanism& m,
const std::string& key) {
auto d = static_cast<D*>(this);
Expand Down
51 changes: 29 additions & 22 deletions arbor/benchmark_cell_group.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "profile/profiler_macro.hpp"

#include "util/span.hpp"
#include "util/maputil.hpp"

template<typename K>
void serialize(arb::serializer& s, const K& k, const arb::benchmark_cell_group&);
Expand All @@ -23,8 +24,7 @@ benchmark_cell_group::benchmark_cell_group(const std::vector<cell_gid_type>& gid
const recipe& rec,
cell_label_range& cg_sources,
cell_label_range& cg_targets):
gids_(gids)
{
gids_(gids) {
for (auto gid: gids_) {
if (!rec.get_probes(gid).empty()) {
throw bad_cell_probe(cell_kind::benchmark, gid);
Expand All @@ -47,28 +47,39 @@ benchmark_cell_group::benchmark_cell_group(const std::vector<cell_gid_type>& gid
}

void benchmark_cell_group::reset() {
for (auto& c: cells_) {
c.time_sequence.reset();
}

for (auto& c: cells_) c.time_sequence.reset();
clear_spikes();
}

void benchmark_cell_group::t_serialize(serializer& ser, const std::string& k) const {
serialize(ser, k, *this);
}
void benchmark_cell_group::t_deserialize(serializer& ser, const std::string& k) {
deserialize(ser, k, *this);
void
benchmark_cell_group::edit_cell(cell_gid_type gid, std::any cell_edit) {
try {
auto bench_edit = std::any_cast<benchmark_cell_editor>(cell_edit);
auto lid = util::binary_search_index(gids_, gid);
if (!lid) throw arb::arbor_internal_error{"gid " + std::to_string(gid) + " erroneuosly dispatched to cell group."};
benchmark_cell& lowered = cells_[*lid];
auto tmp = benchmark_cell{.source=lowered.source, .target=lowered.target, .time_sequence=std::move(lowered.time_sequence), .realtime_ratio=lowered.realtime_ratio};
bench_edit(tmp);
if (tmp.source != lowered.source) throw bad_cell_edit(gid, "Source is not editable.");
if (tmp.target != lowered.target) throw bad_cell_edit(gid, "Target is not editable.");
// Write back
lowered.time_sequence = std::move(tmp.time_sequence);
lowered.realtime_ratio = tmp.realtime_ratio;
}
catch (const std::bad_any_cast&) {
throw bad_cell_edit(gid, "Not a Benchmark editor (C++ type-id: '" + std::string{cell_edit.type().name()} + "')");
}
}

cell_kind benchmark_cell_group::get_cell_kind() const {
return cell_kind::benchmark;
}
void benchmark_cell_group::t_serialize(serializer& ser, const std::string& k) const { serialize(ser, k, *this); }

void benchmark_cell_group::t_deserialize(serializer& ser, const std::string& k) { deserialize(ser, k, *this); }

cell_kind benchmark_cell_group::get_cell_kind() const { return cell_kind::benchmark; }

void benchmark_cell_group::advance(epoch ep,
time_type dt,
const event_lane_subrange& event_lanes)
{
const event_lane_subrange& event_lanes) {
using std::chrono::high_resolution_clock;
using duration_type = std::chrono::duration<double, std::micro>;

Expand Down Expand Up @@ -97,13 +108,9 @@ void benchmark_cell_group::advance(epoch ep,
PL(cell);
};

const std::vector<spike>& benchmark_cell_group::spikes() const {
return spikes_;
}
const std::vector<spike>& benchmark_cell_group::spikes() const { return spikes_; }

void benchmark_cell_group::clear_spikes() {
spikes_.clear();
}
void benchmark_cell_group::clear_spikes() { spikes_.clear(); }

void benchmark_cell_group::add_sampler(sampler_association_handle h,
cell_member_predicate probeset_ids,
Expand Down
2 changes: 2 additions & 0 deletions arbor/benchmark_cell_group.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ class benchmark_cell_group: public cell_group {

void remove_all_samplers() override {}

void edit_cell(cell_gid_type gid, std::any edit) override;

ARB_SERDES_ENABLE(benchmark_cell_group, cells_, spikes_, gids_);

void t_serialize(serializer& ser, const std::string& k) const override;
Expand Down
15 changes: 12 additions & 3 deletions arbor/cable_cell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ struct cable_cell_impl {
using index_type = cable_cell::index_type;
using size_type = cable_cell::size_type;

bool is_mut_ = false;

// The label dictionary.
label_dict dictionary;

Expand Down Expand Up @@ -117,7 +119,8 @@ struct cable_cell_impl {

// Discretization
std::optional<cv_policy> discretization_;
cable_cell_impl(const arb::morphology& m, const label_dict& labels, const decor& decorations, const std::optional<cv_policy>& cvp):
cable_cell_impl(const arb::morphology& m, const label_dict& labels, const decor& decorations, const std::optional<cv_policy>& cvp, cable_cell_mutability is_mut=cable_cell_mutability::disabled):
is_mut_(is_mut == cable_cell_mutability::enabled),
dictionary(labels),
provider(m, dictionary),
decorations(decorations),
Expand Down Expand Up @@ -239,8 +242,12 @@ void cable_cell_impl::init() {
}
}

cable_cell::cable_cell(const arb::morphology& m, const decor& decorations, const label_dict& dictionary, const std::optional<cv_policy>& cvp):
impl_(make_impl(new cable_cell_impl(m, dictionary, decorations, cvp)))
cable_cell::cable_cell(const arb::morphology& m,
const decor& decorations,
const label_dict& dictionary,
const std::optional<cv_policy>& cvp,
cable_cell_mutability is_mut):
impl_(make_impl(new cable_cell_impl(m, dictionary, decorations, cvp, is_mut)))
{}

cable_cell::cable_cell(): impl_(make_impl(new cable_cell_impl())) {}
Expand All @@ -249,6 +256,8 @@ cable_cell::cable_cell(const cable_cell& other):
impl_(make_impl(new cable_cell_impl(*other.impl_)))
{}

bool cable_cell::is_editable() const { return impl_->is_mut_; }

const label_dict& cable_cell::labels() const { return impl_->dictionary; }
const concrete_embedding& cable_cell::embedding() const { return impl_->provider.embedding(); }
const arb::morphology& cable_cell::morphology() const { return impl_->provider.morphology(); }
Expand Down
22 changes: 22 additions & 0 deletions arbor/cable_cell_group.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include <variant>
#include <vector>

#include <iostream>

#include <arbor/assert.hpp>
#include <arbor/common_types.hpp>
#include <arbor/cable_cell.hpp>
Expand All @@ -18,6 +20,7 @@
#include "util/partition.hpp"
#include "util/range.hpp"
#include "util/span.hpp"
#include "util/maputil.hpp"

namespace arb {

Expand Down Expand Up @@ -491,4 +494,23 @@ std::vector<probe_metadata> cable_cell_group::get_probe_metadata(const cell_addr
}
return result;
}

void
cable_cell_group::edit_cell(cell_gid_type gid, std::any cell_edit) {
auto lid = util::binary_search_index(gids_, gid);
if (!lid) throw arb::arbor_internal_error{"gid " + std::to_string(gid) + " erroneuosly dispatched to cell group."};
try {
auto cc_edit = std::any_cast<cable_cell_editor>(cell_edit);
lowered_->edit_cell(gid, *lid, cc_edit);
}
catch (std::bad_any_cast& ex) {
std::cerr << ex.what() << '\n';
throw bad_cell_edit(gid, "Not a Cable Cell editor (C++ type-id: '"
+ std::string{cell_edit.type().name()}
+ " ./. "
+ std::string{typeid(cable_cell_editor).name()}
+ "')");
}
}

} // namespace arb
5 changes: 4 additions & 1 deletion arbor/cable_cell_group.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ struct ARB_ARBOR_API cable_cell_group: public cell_group {

void remove_all_samplers() override;

void edit_cell(cell_gid_type gid, std::any edit) override;

std::vector<probe_metadata> get_probe_metadata(const cell_address_type&) const override;

ARB_SERDES_ENABLE(cable_cell_group, gids_, spikes_, lowered_);
Expand All @@ -52,10 +54,11 @@ struct ARB_ARBOR_API cable_cell_group: public cell_group {
void t_deserialize(serializer& ser, const std::string& k) override;

static bool backend_supported(backend_kind kind) { return kind == backend_kind::multicore || kind == backend_kind::gpu; }
private:
private:
// List of the gids of the cells in the group.
std::vector<cell_gid_type> gids_;


// The lowered cell state (e.g. FVM) of the cell.
fvm_lowered_cell_ptr lowered_;

Expand Down
Loading
Loading