From 85d171056b0e13962857c4ea8f245eb67c150122 Mon Sep 17 00:00:00 2001 From: boeschf <48126478+boeschf@users.noreply.github.com> Date: Tue, 18 Jul 2023 13:23:56 +0200 Subject: [PATCH 1/9] fix lint pipleine (#2151) bump versions --- .github/workflows/lint.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 743f145d9e..0cf9fd3bd8 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -7,14 +7,15 @@ on: jobs: build: name: Lint - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 strategy: fail-fast: false steps: + - uses: actions/checkout@v3 - name: Set up Python uses: actions/setup-python@v4 with: - python-version: 3.7 + python-version: '3.10' - name: Get packages run: | python -m pip install --upgrade pip From 031aa2fc8d6ee88f9bbab7e487e2b22694023845 Mon Sep 17 00:00:00 2001 From: boeschf <48126478+boeschf@users.noreply.github.com> Date: Tue, 18 Jul 2023 13:25:47 +0200 Subject: [PATCH 2/9] Fix documentation (#2152) Addresses #2136 and fixes some more warnings --- doc/concepts/interconnectivity.rst | 6 +++--- doc/concepts/simulation.rst | 4 ++-- doc/cpp/hardware.rst | 4 ++-- doc/python/cable_cell.rst | 6 +----- doc/python/hardware.rst | 1 + 5 files changed, 9 insertions(+), 12 deletions(-) diff --git a/doc/concepts/interconnectivity.rst b/doc/concepts/interconnectivity.rst index b267f98da9..a7fda3b4d3 100644 --- a/doc/concepts/interconnectivity.rst +++ b/doc/concepts/interconnectivity.rst @@ -115,11 +115,11 @@ similarly weight, delay)]] -Note that Arbor now recognizes two sets of ``GID``: An external and an internal +Note that Arbor now recognizes two sets of ``GID``\: An external and an internal set. This allows both Arbor and the coupled simulation to keep their own numbering schemes. However, internally Arbor will tag external cells and spikes -by setting their ``GID``s' most significant bit. This _halves_ the effecively -available ``GID``s. +by setting their ``GID``\s' most significant bit. This _halves_ the effecively +available ``GID``\s. To consume external spike events, a specialised ``context`` must be created by calling diff --git a/doc/concepts/simulation.rst b/doc/concepts/simulation.rst index da6c74f8e9..0786fd8c14 100644 --- a/doc/concepts/simulation.rst +++ b/doc/concepts/simulation.rst @@ -25,8 +25,8 @@ Configuring data extraction Two kinds of data extraction can be set up: -1. certain state variables can be :ref:`sampled ` by attaching a sampler to a probe. -2. spikes can be recorded by either a callback (C++) or a preset recording model (Python), see the API docs linked below. +#. certain state variables can be :ref:`sampled ` by attaching a sampler to a probe. +#. spikes can be recorded by either a callback (C++) or a preset recording model (Python), see the API docs linked below. Simulation execution and interaction ------------------------------------ diff --git a/doc/cpp/hardware.rst b/doc/cpp/hardware.rst index 87de485733..f4d07fd208 100644 --- a/doc/cpp/hardware.rst +++ b/doc/cpp/hardware.rst @@ -199,9 +199,9 @@ libarbor The core Arbor library *libarbor* provides an API for: * prescribing which hardware resources are to be used by a -simulation using :cpp:class:`arb::proc_allocation`. + simulation using :cpp:class:`arb::proc_allocation`. * opaque handles to hardware resources used by simulations called -:cpp:class:`arb::context`. + :cpp:class:`arb::context`. .. cpp:namespace:: arb diff --git a/doc/python/cable_cell.rst b/doc/python/cable_cell.rst index 7a26860ce6..23cf266be1 100644 --- a/doc/python/cable_cell.rst +++ b/doc/python/cable_cell.rst @@ -108,11 +108,7 @@ Cable cells Return a read-only view onto all settings. - .. function:: set_ion(name, - charge, - internal_concentration, external_concentration, - reversal_potential, reversal_potential_method, - diffusivty) + .. function:: set_ion(name, charge, internal_concentration, external_concentration, reversal_potential, reversal_potential_method, diffusivty) Add a new ion to the global set of known species. diff --git a/doc/python/hardware.rst b/doc/python/hardware.rst index ca5df8eebe..a2ee7061ef 100644 --- a/doc/python/hardware.rst +++ b/doc/python/hardware.rst @@ -193,6 +193,7 @@ The Python wrapper provides an API for: using :py:func:`~arbor.env.default_allocation()`. .. method:: context(threads=threads, gpu_id=gpu_id, mpi=mpi_comm, inter=mpi_comm) + :noindex: Create a context. From 71e28b8919179a85c6620f57e203bf0776d69414 Mon Sep 17 00:00:00 2001 From: Brent Huisman Date: Wed, 19 Jul 2023 09:43:28 +0200 Subject: [PATCH 3/9] Address missing logo on all but front page (#2155) See comment 2 on #2136 --- doc/conf.py | 2 +- doc/scripts/divio_docs_theme/layout.html | 10 ++-------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/doc/conf.py b/doc/conf.py index 424686cf44..e4a1678800 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -37,7 +37,7 @@ def setup(app): } project = "Arbor" -copyright = "2017-2022, ETHZ & FZJ" +copyright = "2017-2023, ETHZ & FZJ" author = "ETHZ & FZJ" todo_include_todos = True diff --git a/doc/scripts/divio_docs_theme/layout.html b/doc/scripts/divio_docs_theme/layout.html index d6cee7855b..056f8c71fd 100755 --- a/doc/scripts/divio_docs_theme/layout.html +++ b/doc/scripts/divio_docs_theme/layout.html @@ -40,14 +40,8 @@ {% endif %} + - - - - - - - {%- for css in css_files %} {%- if css|attr("rel") %} @@ -131,7 +125,7 @@
{{ project }}{% if READTHEDOCS %} v: {{ current_version }}{% endif %}
- + {% include "breadcrumbs.html" %} From 2f804e9094e20d8bec0f2f2ab403cd3f33cc969e Mon Sep 17 00:00:00 2001 From: Thorsten Hater <24411438+thorstenhater@users.noreply.github.com> Date: Wed, 26 Jul 2023 11:28:48 +0200 Subject: [PATCH 4/9] Ward against probing the void. (#2139) Fixes #2137 by returning empty results on non-existent probes. Note: Dear reviewer you might not like this (nor do I, really), but it's consistent with the rest of probing. --- arbor/fvm_lowered_cell_impl.hpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/arbor/fvm_lowered_cell_impl.hpp b/arbor/fvm_lowered_cell_impl.hpp index 19ad5d573c..3ae8cf8a3c 100644 --- a/arbor/fvm_lowered_cell_impl.hpp +++ b/arbor/fvm_lowered_cell_impl.hpp @@ -826,15 +826,17 @@ void resolve_probe(const cable_probe_stimulus_current_cell& p, probe_resolution_ template void resolve_probe(const cable_probe_density_state& p, probe_resolution_data& R) { - const arb_value_type* data = R.mechanism_state(p.mechanism, p.state); + const auto& mech = p.mechanism; + if (!R.mech_instance_by_name.count(mech)) return; + const arb_value_type* data = R.mechanism_state(mech, p.state); if (!data) return; - auto support = R.mechanism_support(p.mechanism); + auto support = R.mechanism_support(mech); for (mlocation loc: thingify(p.locations, R.cell.provider())) { if (!support.intersects(loc)) continue; arb_index_type cv = R.D.geometry.location_cv(R.cell_idx, loc, cv_prefer::cv_nonempty); - auto opt_i = util::binary_search_index(R.M.mechanisms.at(p.mechanism).cv, cv); + auto opt_i = util::binary_search_index(R.M.mechanisms.at(mech).cv, cv); if (!opt_i) continue; R.result.push_back(fvm_probe_scalar{{data+*opt_i}, loc}); @@ -849,6 +851,7 @@ void resolve_probe(const cable_probe_density_state_cell& p, probe_resolution_dat if (!data) return; mextent support = R.mechanism_support(p.mechanism); + if (!R.M.mechanisms.count(p.mechanism)) return; auto& mech_cvs = R.M.mechanisms.at(p.mechanism).cv; mcable_list cables; @@ -891,6 +894,7 @@ void resolve_probe(const cable_probe_point_state& p, probe_resolution_data& R const auto& state = p.state; const auto& target = p.target; const auto& data = R.mechanism_state(mech, state); + if (!R.mech_instance_by_name.count(mech)) return; const auto mech_id = R.mech_instance_by_name.at(mech)->mechanism_id(); const auto& synapses = R.cell.synapses(); if (!synapses.count(mech)) return; @@ -919,7 +923,7 @@ void resolve_probe(const cable_probe_point_state_cell& p, probe_resolution_data< const auto& data = R.mechanism_state(mech, state); if (!data) return; - + if (!R.mech_instance_by_name.count(mech)) return; auto mech_id = R.mech_instance_by_name.at(mech)->mechanism_id(); const auto& multiplicity = R.M.mechanisms.at(mech).multiplicity; @@ -964,7 +968,6 @@ void resolve_probe(const cable_probe_ion_current_density& p, probe_resolution_da template void resolve_probe(const cable_probe_ion_current_cell& p, probe_resolution_data& R) { if (!R.state->ion_data.count(p.ion)) return; - auto& ion_cvs = R.M.ions.at(p.ion).cv; const arb_value_type* src = R.state->ion_data.at(p.ion).iX_.data(); From ad1fd65a6a34a84aba4f760521ad2095f4b692e5 Mon Sep 17 00:00:00 2001 From: Thorsten Hater <24411438+thorstenhater@users.noreply.github.com> Date: Wed, 26 Jul 2023 13:59:56 +0200 Subject: [PATCH 5/9] Apply some polish to model construction. (#2134) Make single cell model a bit more convenient by allowing to build from {morph | segment_tree, decor, {labels}. Allow kwargs to construct mechanisms (density, scaled, junction, synapse, voltage), thus we can write ```py mech = arbor.mechanism('mech_name', param1=1.2, param2=3.14) ``` instead of ```py mech = arbor.mechanism('mech_name', {'param1': 1.2, 'param2': 3.14}) ``` --- doc/python/mechanisms.rst | 8 +++++-- python/cells.cpp | 21 +++++++++++++++++-- python/example/diffusion.py | 2 +- .../network_two_cells_gap_junctions.py | 4 ++-- python/example/probe_lfpykit.py | 2 +- python/example/single_cell_cable.py | 2 +- python/example/single_cell_detailed.py | 2 +- python/example/single_cell_detailed_recipe.py | 2 +- python/example/single_cell_stdp.py | 2 +- python/mechanism.cpp | 18 ++++++++++++++++ python/pyarb.cpp | 2 +- python/single_cell_model.cpp | 16 +++++++++++++- python/util.hpp | 12 +++++++++++ 13 files changed, 79 insertions(+), 14 deletions(-) diff --git a/doc/python/mechanisms.rst b/doc/python/mechanisms.rst index 9634a0dd33..6a3c33ce69 100644 --- a/doc/python/mechanisms.rst +++ b/doc/python/mechanisms.rst @@ -30,7 +30,7 @@ Cable cell mechanisms If global parameters change, we are effectively defining a new type of mechanism, so global parameter information is encoded in the name. - Range parameters are set using a dictionary of name-value pairs. + Range parameters are set using a dictionary of name-value pairs or as kwargs. .. code-block:: Python @@ -46,7 +46,11 @@ Cable cell mechanisms pas_2 = arbor.mechanism('pas/e=-45') # A passive leaky channel with custom reversal potential (global), and custom conductance (range). - pas_3 = arbor.mechanism('pas/e=-45', {'g', 0.1}) + pas_3a = arbor.mechanism('pas/e=-45', {'g', 0.1}) + + # A passive leaky channel with custom reversal potential (global), and custom conductance (range) + # written as keyword args. + pas_3b = arbor.mechanism('pas/e=-45', g=0.1) # This is an equivalent to pas_3, using set method to specify range parameters. pas_4 = arbor.mechanism('pas/e=-45') diff --git a/python/cells.cpp b/python/cells.cpp index 7a0c24c094..f723b29697 100644 --- a/python/cells.cpp +++ b/python/cells.cpp @@ -38,6 +38,7 @@ #include "pybind11/pytypes.h" #include "schedule.hpp" #include "strprintf.hpp" +#include "util.hpp" namespace pyarb { @@ -472,6 +473,8 @@ void register_cells(pybind11::module& m) { .def(pybind11::init([](arb::mechanism_desc mech) {return arb::density(mech);})) .def(pybind11::init([](const std::string& name, const std::unordered_map& params) {return arb::density(name, params);})) .def(pybind11::init([](arb::mechanism_desc mech, const std::unordered_map& params) {return arb::density(mech, params);})) + .def(pybind11::init([](const std::string& name, pybind11::kwargs parms) {return arb::density(name, util::dict_to_map(parms));})) + .def(pybind11::init([](arb::mechanism_desc mech, pybind11::kwargs params) {return arb::density(mech, util::dict_to_map(params));})) .def_readonly("mech", &arb::density::mech, "The underlying mechanism.") .def("__repr__", [](const arb::density& d){return "";}) .def("__str__", [](const arb::density& d){return "";}); @@ -482,6 +485,8 @@ void register_cells(pybind11::module& m) { .def(pybind11::init([](arb::mechanism_desc mech) {return arb::voltage_process(mech);})) .def(pybind11::init([](const std::string& name, const std::unordered_map& params) {return arb::voltage_process(name, params);})) .def(pybind11::init([](arb::mechanism_desc mech, const std::unordered_map& params) {return arb::voltage_process(mech, params);})) + .def(pybind11::init([](arb::mechanism_desc mech, pybind11::kwargs params) {return arb::voltage_process(mech, util::dict_to_map(params));})) + .def(pybind11::init([](const std::string& name, pybind11::kwargs parms) {return arb::voltage_process(name, util::dict_to_map(parms));})) .def_readonly("mech", &arb::voltage_process::mech, "The underlying mechanism.") .def("__repr__", [](const arb::voltage_process& d){return "";}) .def("__str__", [](const arb::voltage_process& d){return "";}); @@ -496,8 +501,16 @@ void register_cells(pybind11::module& m) { .def(pybind11::init( [](arb::density dens, const std::unordered_map& scales) { auto s = arb::scaled_mechanism(std::move(dens)); - for (const auto& it: scales) { - s.scale(it.first, arborio::parse_iexpr_expression(it.second).unwrap()); + for (const auto& [k, v]: scales) { + s.scale(k, arborio::parse_iexpr_expression(v).unwrap()); + } + return s; + })) + .def(pybind11::init( + [](arb::density dens, pybind11::kwargs scales) { + auto s = arb::scaled_mechanism(std::move(dens)); + for (const auto& [k, v]: util::dict_to_map(scales)) { + s.scale(k, arborio::parse_iexpr_expression(v).unwrap()); } return s; })) @@ -526,6 +539,8 @@ void register_cells(pybind11::module& m) { .def(pybind11::init([](arb::mechanism_desc mech) {return arb::synapse(mech);})) .def(pybind11::init([](const std::string& name, const std::unordered_map& params) {return arb::synapse(name, params);})) .def(pybind11::init([](arb::mechanism_desc mech, const std::unordered_map& params) {return arb::synapse(mech, params);})) + .def(pybind11::init([](const std::string& name, pybind11::kwargs parms) {return arb::synapse(name, util::dict_to_map(parms));})) + .def(pybind11::init([](arb::mechanism_desc mech, pybind11::kwargs params) {return arb::synapse(mech, util::dict_to_map(params));})) .def_readonly("mech", &arb::synapse::mech, "The underlying mechanism.") .def("__repr__", [](const arb::synapse& s){return "";}) .def("__str__", [](const arb::synapse& s){return "";}); @@ -537,7 +552,9 @@ void register_cells(pybind11::module& m) { .def(pybind11::init([](const std::string& name) {return arb::junction(name);})) .def(pybind11::init([](arb::mechanism_desc mech) {return arb::junction(mech);})) .def(pybind11::init([](const std::string& name, const std::unordered_map& params) {return arb::junction(name, params);})) + .def(pybind11::init([](const std::string& name, pybind11::kwargs parms) {return arb::junction(name, util::dict_to_map(parms));})) .def(pybind11::init([](arb::mechanism_desc mech, const std::unordered_map& params) {return arb::junction(mech, params);})) + .def(pybind11::init([](arb::mechanism_desc mech, pybind11::kwargs params) {return arb::junction(mech, util::dict_to_map(params));})) .def_readonly("mech", &arb::junction::mech, "The underlying mechanism.") .def("__repr__", [](const arb::junction& j){return "";}) .def("__str__", [](const arb::junction& j){return "";}); diff --git a/python/example/diffusion.py b/python/example/diffusion.py index 7ef2d2107c..e03860b063 100644 --- a/python/example/diffusion.py +++ b/python/example/diffusion.py @@ -38,7 +38,7 @@ def event_generators(self, gid): dec = A.decor() dec.set_ion("na", int_con=0.0, diff=0.005) -dec.place("(location 0 0.5)", A.synapse("inject/x=na", {"alpha": 200.0}), "Zap") +dec.place("(location 0 0.5)", A.synapse("inject/x=na", alpha=200.0), "Zap") dec.paint("(all)", A.density("decay/x=na")) dec.discretization(A.cv_policy("(max-extent 5)")) diff --git a/python/example/network_two_cells_gap_junctions.py b/python/example/network_two_cells_gap_junctions.py index 06221bb801..fd8e2b140c 100755 --- a/python/example/network_two_cells_gap_junctions.py +++ b/python/example/network_two_cells_gap_junctions.py @@ -88,8 +88,8 @@ def cell_description(self, gid): .set_property(cm=self.cm) .set_property(rL=self.rL) # add a gap junction mechanism at the "gj_site" location and label that specific mechanism on that location "gj_label" - .place('"gj_site"', arbor.junction("gj", {"g": self.gj_g}), "gj_label") - .paint('"cell"', arbor.density(f"pas/e={self.Vms[gid]}", {"g": self.g})) + .place('"gj_site"', arbor.junction("gj", g=self.gj_g), "gj_label") + .paint('"cell"', arbor.density(f"pas/e={self.Vms[gid]}", g=self.g)) ) if self.cv_policy_max_extent is not None: diff --git a/python/example/probe_lfpykit.py b/python/example/probe_lfpykit.py index 75bf731082..d7870f6adf 100644 --- a/python/example/probe_lfpykit.py +++ b/python/example/probe_lfpykit.py @@ -88,7 +88,7 @@ def make_cable_cell(morphology, clamp_location): ) # set passive mechanism all over # passive mech w. leak reversal potential (mV) - .paint("(all)", arbor.density("pas/e=-65", {"g": 0.0001})) + .paint("(all)", arbor.density("pas/e=-65", g=0.0001)) ) # set number of CVs per branch diff --git a/python/example/single_cell_cable.py b/python/example/single_cell_cable.py index 2a8b61c68c..23b61edb3e 100755 --- a/python/example/single_cell_cable.py +++ b/python/example/single_cell_cable.py @@ -95,7 +95,7 @@ def cell_description(self, gid): decor = ( arbor.decor() .set_property(Vm=self.Vm, cm=self.cm, rL=self.rL) - .paint('"cable"', arbor.density(f"pas/e={self.Vm}", {"g": self.g})) + .paint('"cable"', arbor.density(f"pas/e={self.Vm}", g=self.g)) .place( '"start"', arbor.iclamp( diff --git a/python/example/single_cell_detailed.py b/python/example/single_cell_detailed.py index 0d2222edd0..5c77f9cec4 100755 --- a/python/example/single_cell_detailed.py +++ b/python/example/single_cell_detailed.py @@ -56,7 +56,7 @@ # Paint density mechanisms. decor.paint('"all"', density("pas")) decor.paint('"custom"', density("hh")) -decor.paint('"dend"', density("Ih", {"gbar": 0.001})) +decor.paint('"dend"', density("Ih", gbar=0.001)) # Place stimuli and detectors. decor.place('"root"', arbor.iclamp(10, 1, current=2), "iclamp0") decor.place('"root"', arbor.iclamp(30, 1, current=2), "iclamp1") diff --git a/python/example/single_cell_detailed_recipe.py b/python/example/single_cell_detailed_recipe.py index 436f80f641..adedca2ef2 100644 --- a/python/example/single_cell_detailed_recipe.py +++ b/python/example/single_cell_detailed_recipe.py @@ -55,7 +55,7 @@ # Paint density mechanisms. .paint('"all"', density("pas")) .paint('"custom"', density("hh")) - .paint('"dend"', density("Ih", {"gbar": 0.001})) + .paint('"dend"', density("Ih", gbar=0.001)) # Place stimuli and detectors. .place('"root"', arbor.iclamp(10, 1, current=2), "iclamp0") .place('"root"', arbor.iclamp(30, 1, current=2), "iclamp1") diff --git a/python/example/single_cell_stdp.py b/python/example/single_cell_stdp.py index b67d45f24d..d1bfe56c95 100755 --- a/python/example/single_cell_stdp.py +++ b/python/example/single_cell_stdp.py @@ -36,7 +36,7 @@ def cell_description(self, gid): .place('"center"', arbor.synapse("expsyn"), "synapse") .place( '"center"', - arbor.synapse("expsyn_stdp", {"max_weight": 1.0}), + arbor.synapse("expsyn_stdp", max_weight=1.0), "stpd_synapse", ) ) diff --git a/python/mechanism.cpp b/python/mechanism.cpp index 471d241609..5092b17e83 100644 --- a/python/mechanism.cpp +++ b/python/mechanism.cpp @@ -228,6 +228,24 @@ void register_mechanisms(pybind11::module& m) { "(as defined in NMODL) is used.\n\n" "Example overriding a global parameter:\n" " m = arbor.mechanism('nernst/R=8.3145,F=96485')") + // allow construction of a description with parameters provided in kwargs: + // mech = arbor.mechanism('mech_name', param1=1.2, param2=3.14) + .def(pybind11::init( + [](const char* name, pybind11::kwargs kws) { + arb::mechanism_desc md(name); + auto params = util::dict_to_map(kws); + for (const auto& [k, v]: params) md.set(k, v); + return md; + }), + "name"_a, "The name of the mechanism", + "Example usage setting parameters:\n" + " m = arbor.mechanism('expsyn', tau=1.4})\n" + "will create parameters for the 'expsyn' mechanism, with the provided value\n" + "for 'tau' overrides the default. If a parameter is not set, the default\n" + "(as defined in NMODL) is used.\n\n" + "Example overriding a global parameter:\n" + " m = arbor.mechanism('nernst/R=8.3145,F=96485')") + .def("set", [](arb::mechanism_desc& md, std::string name, double value) { md.set(name, value); diff --git a/python/pyarb.cpp b/python/pyarb.cpp index 57e503b07a..e15194f29a 100644 --- a/python/pyarb.cpp +++ b/python/pyarb.cpp @@ -28,8 +28,8 @@ void register_profiler(pybind11::module& m); void register_recipe(pybind11::module& m); void register_schedules(pybind11::module& m); void register_simulation(pybind11::module& m, pyarb_global_ptr); -void register_single_cell(pybind11::module& m); void register_arborenv(pybind11::module& m); +void register_single_cell(pybind11::module& m); #ifdef ARB_MPI_ENABLED void register_mpi(pybind11::module& m); diff --git a/python/single_cell_model.cpp b/python/single_cell_model.cpp index 486b030791..bb68ad876c 100644 --- a/python/single_cell_model.cpp +++ b/python/single_cell_model.cpp @@ -18,6 +18,7 @@ #include "event_generator.hpp" #include "error.hpp" #include "strprintf.hpp" +#include "proxy.hpp" using arb::util::any_cast; @@ -236,8 +237,21 @@ void register_single_cell(pybind11::module& m) { pybind11::class_ model(m, "single_cell_model", "Wrapper for simplified description, and execution, of single cell models."); - model + .def(pybind11::init([](const arb::segment_tree& m, + const arb::decor& d, + const label_dict_proxy& l) -> single_cell_model { + return single_cell_model(arb::cable_cell({m}, d, l.dict)); + }), + "tree"_a, "decor"_a, "labels"_a=arb::decor{}, + "Build single cell model from cable cell components") + .def(pybind11::init([](const arb::morphology& m, + const arb::decor& d, + const label_dict_proxy& l) -> single_cell_model { + return single_cell_model(arb::cable_cell(m, d, l.dict)); + }), + "morph"_a, "decor"_a, "labels"_a=arb::decor{}, + "Build single cell model from cable cell components") .def(pybind11::init(), "cell"_a, "Initialise a single cell model for a cable cell.") .def("run", diff --git a/python/util.hpp b/python/util.hpp index 4a096f6f0a..846b62cc18 100644 --- a/python/util.hpp +++ b/python/util.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include @@ -46,5 +47,16 @@ std::string read_file_or_buffer(py::object fn) { } } +template +std::unordered_map dict_to_map(pybind11::dict d) { + std::unordered_map result; + for (const auto& [k, v]: d) { + std::string key = k.template cast(); + T val = v.template cast(); + result[key] = val; + } + return result; +} + } } From acba341c6f0817db24dd181e40eb85c18317291b Mon Sep 17 00:00:00 2001 From: Thorsten Hater <24411438+thorstenhater@users.noreply.github.com> Date: Wed, 26 Jul 2023 16:31:47 +0200 Subject: [PATCH 6/9] Fix GPU/NVC problems (#2143) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix GPU compilation of `ion-state` - Rename `ls::restrict` -> `ls::restrict_to` as _some_ compilers might take offense - Fix some(!) of the warnings issued by `nvc` ⚠️ Breaking ⚠️ `restrict` is now called `restrict-to`. --------- Co-authored-by: boeschf <48126478+boeschf@users.noreply.github.com> Co-authored-by: Brent Huisman --- CMakeLists.txt | 12 ++++--- arbor/backends/gpu/forest.hpp | 9 ++--- arbor/backends/gpu/shared_state.cpp | 5 ++- arbor/backends/gpu/shared_state.hpp | 8 ++--- arbor/communication/communicator.cpp | 6 ++-- arbor/cv_policy.cpp | 6 ++-- arbor/iexpr.cpp | 1 - arbor/include/arbor/load_balance.hpp | 2 +- arbor/include/arbor/morph/locset.hpp | 2 +- arbor/morph/embed_pwlin.cpp | 8 ++--- arbor/morph/locset.cpp | 4 +-- arbor/threading/threading.cpp | 6 ++-- arbor/threading/threading.hpp | 2 ++ arbor/util/piecewise.hpp | 2 +- arborio/label_parse.cpp | 4 +-- arborio/nml_parse_morphology.cpp | 4 +-- doc/concepts/labels.rst | 6 ++-- doc/scripts/gen-labels.py | 6 ++-- doc/tutorial/single_cell_bluepyopt.rst | 2 +- ext/tinyopt/include/tinyopt/tinyopt.h | 4 ++- modcc/errorvisitor.hpp | 2 ++ modcc/expression.cpp | 7 +--- modcc/expression.hpp | 35 +++++++++++++------ modcc/lexer.cpp | 4 +-- modcc/modcc.cpp | 2 +- modcc/parser.cpp | 12 +++---- modcc/perfvisitor.hpp | 2 ++ modcc/printer/cexpr_emit.hpp | 4 +-- modcc/printer/cprinter.hpp | 4 +-- modcc/printer/gpuprinter.hpp | 1 + modcc/solvers.cpp | 2 +- modcc/symdiff.cpp | 3 ++ modcc/visitor.hpp | 2 ++ python/example/single_cell_bluepyopt_l5pc.py | 2 +- python/example/single_cell_detailed.py | 4 +-- python/example/single_cell_detailed_recipe.py | 4 +-- python/example/single_cell_nml.py | 2 +- python/example/single_cell_swc.py | 2 +- test/unit/test_abi.cpp | 7 ++-- test/unit/test_morph_expr.cpp | 26 +++++++------- test/unit/test_s_expr.cpp | 2 +- test/unit/test_simd.cpp | 2 +- 42 files changed, 125 insertions(+), 105 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d2a7d20acc..2aa4b7726e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,11 +19,13 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON) # Have LTO where possible, ie add -flto check_ipo_supported(RESULT HAVE_LTO OUTPUT ERR_LTO) -if(HAVE_LTO AND NOT DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION) - message (STATUS "LTO support found, enabling") - set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) -else() - message(STATUS "No LTO: ${ERR_LTO}") +if(NOT DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION) + if(HAVE_LTO) + message (STATUS "LTO support found, enabling") + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) + else() + message(STATUS "No LTO: ${ERR_LTO}") + endif() endif() # Turn on this option to force the compilers to produce color output when output is diff --git a/arbor/backends/gpu/forest.hpp b/arbor/backends/gpu/forest.hpp index 7fc8be0cf9..24da59a099 100644 --- a/arbor/backends/gpu/forest.hpp +++ b/arbor/backends/gpu/forest.hpp @@ -58,6 +58,8 @@ struct ARB_ARBOR_API forest { struct level_iterator { + constexpr static unsigned npos = unsigned(-1); + level_iterator(tree* t, unsigned level) { tree_ = t; only_on_level = level; @@ -94,16 +96,15 @@ struct level_iterator { next_children = index + 1; } else { // we are done with the iteration - current_level = -1; - current_node = -1; - next_children = -1; + current_level = npos; + current_node = npos; + next_children = npos; } } } unsigned next() { - constexpr unsigned npos = unsigned(-1); if (!valid()) { // we are done return npos; diff --git a/arbor/backends/gpu/shared_state.cpp b/arbor/backends/gpu/shared_state.cpp index a074ae70c2..9e1218cc9c 100644 --- a/arbor/backends/gpu/shared_state.cpp +++ b/arbor/backends/gpu/shared_state.cpp @@ -43,8 +43,7 @@ std::pair minmax_value_impl(arb_size_type n, con // Ion state methods: -ion_state::ion_state(int charge, - const fvm_ion_config& ion_data, +ion_state::ion_state(const fvm_ion_config& ion_data, unsigned, // alignment/padding ignored. solver_ptr ptr): write_eX_(ion_data.revpot_written), @@ -62,7 +61,7 @@ ion_state::ion_state(int charge, reset_Xi_(make_const_view(ion_data.reset_iconc)), reset_Xo_(make_const_view(ion_data.reset_econc)), init_eX_(make_const_view(ion_data.init_revpot)), - charge(1u, charge), + charge(1u, static_cast(ion_data.charge)), solver(std::move(ptr)) { arb_assert(node_index_.size()==init_Xi_.size()); arb_assert(node_index_.size()==init_Xo_.size()); diff --git a/arbor/backends/gpu/shared_state.hpp b/arbor/backends/gpu/shared_state.hpp index 03d2a02a77..1749c5e2fb 100644 --- a/arbor/backends/gpu/shared_state.hpp +++ b/arbor/backends/gpu/shared_state.hpp @@ -64,11 +64,9 @@ struct ARB_ARBOR_API ion_state { ion_state() = default; - ion_state( - int charge, - const fvm_ion_config& ion_data, - unsigned align, - solver_ptr ptr); + ion_state(const fvm_ion_config& ion_data, + unsigned align, + solver_ptr ptr); // Set ion concentrations to weighted proportion of default concentrations. void init_concentration(); diff --git a/arbor/communication/communicator.cpp b/arbor/communication/communicator.cpp index 0fa2798e70..bb206f7989 100644 --- a/arbor/communication/communicator.cpp +++ b/arbor/communication/communicator.cpp @@ -36,21 +36,21 @@ communicator::communicator(const recipe& rec, constexpr inline bool is_external(cell_gid_type c) { // index of the MSB of cell_gid_type in bits - constexpr auto msb = 1 << (std::numeric_limits::digits - 1); + constexpr auto msb = static_cast(1 << (std::numeric_limits::digits - 1)); // If set, we are external return bool(c & msb); } constexpr inline cell_member_type global_cell_of(const cell_remote_label_type& c) { - constexpr auto msb = 1 << (std::numeric_limits::digits - 1); + constexpr auto msb = static_cast(1 << (std::numeric_limits::digits - 1)); // set the MSB return {c.rid | msb, c.index}; } constexpr inline cell_member_type global_cell_of(const cell_member_type& c) { - constexpr auto msb = 1 << (std::numeric_limits::digits - 1); + constexpr auto msb = static_cast(1 << (std::numeric_limits::digits - 1)); // set the MSB return {c.gid | msb, c.index}; } diff --git a/arbor/cv_policy.cpp b/arbor/cv_policy.cpp index b2962c7fa4..fcd8170547 100644 --- a/arbor/cv_policy.cpp +++ b/arbor/cv_policy.cpp @@ -57,7 +57,7 @@ struct cv_policy_bar_: cv_policy_base { } locset cv_boundary_points(const cable_cell& c) const override { - return unique_sum(ls::restrict(lhs_.cv_boundary_points(c), complement(rhs_.domain())), rhs_.cv_boundary_points(c)); + return unique_sum(ls::restrict_to(lhs_.cv_boundary_points(c), complement(rhs_.domain())), rhs_.cv_boundary_points(c)); } region domain() const override { return join(lhs_.domain(), rhs_.domain()); } @@ -82,7 +82,7 @@ locset cv_policy_explicit::cv_boundary_points(const cable_cell& cell) const { ls::support( util::foldl( [this](locset l, const auto& comp) { - return sum(std::move(l), ls::restrict(locs_, comp)); + return sum(std::move(l), ls::restrict_to(locs_, comp)); }, ls::boundary(domain_), components(cell.morphology(), thingify(domain_, cell.provider())))); @@ -190,7 +190,7 @@ locset cv_policy_every_segment::cv_boundary_points(const cable_cell& cell) const return unique_sum( ls::cboundary(domain_), - ls::restrict(ls::segment_boundaries(), domain_)); + ls::restrict_to(ls::segment_boundaries(), domain_)); } cv_policy_base_ptr cv_policy_every_segment::clone() const { return cv_policy_base_ptr(new cv_policy_every_segment(*this)); diff --git a/arbor/iexpr.cpp b/arbor/iexpr.cpp index eaaba7cd07..355d35b504 100644 --- a/arbor/iexpr.cpp +++ b/arbor/iexpr.cpp @@ -551,7 +551,6 @@ iexpr_ptr thingify(const iexpr& expr, const mprovider& m) { } throw std::runtime_error("thingify iexpr: Unknown iexpr type"); - return nullptr; } std::ostream& operator<<(std::ostream& o, const iexpr& e) { diff --git a/arbor/include/arbor/load_balance.hpp b/arbor/include/arbor/load_balance.hpp index 31614403a4..009960adff 100644 --- a/arbor/include/arbor/load_balance.hpp +++ b/arbor/include/arbor/load_balance.hpp @@ -11,7 +11,7 @@ namespace arb { struct partition_hint { - constexpr static std::size_t max_size = -1; + constexpr static std::size_t max_size = std::numeric_limits::max(); std::size_t cpu_group_size = 1; std::size_t gpu_group_size = max_size; diff --git a/arbor/include/arbor/morph/locset.hpp b/arbor/include/arbor/morph/locset.hpp index ec127aea16..ebf952323b 100644 --- a/arbor/include/arbor/morph/locset.hpp +++ b/arbor/include/arbor/morph/locset.hpp @@ -151,7 +151,7 @@ ARB_ARBOR_API locset boundary(region reg); ARB_ARBOR_API locset cboundary(region reg); // Returns all locations in a locset that are also in the region. -ARB_ARBOR_API locset restrict(locset ls, region reg); +ARB_ARBOR_API locset restrict_to(arb::locset ls, region reg); // Returns locations that mark the segments. ARB_ARBOR_API locset segment_boundaries(); diff --git a/arbor/morph/embed_pwlin.cpp b/arbor/morph/embed_pwlin.cpp index c3b6d39615..945dffdf6b 100644 --- a/arbor/morph/embed_pwlin.cpp +++ b/arbor/morph/embed_pwlin.cpp @@ -197,20 +197,20 @@ double embed_pwlin::integrate_ixa(const mcable& c) const { // Integrate piecewise function over a cable: -static pw_constant_fn restrict(const pw_constant_fn& g, double left, double right) { +static pw_constant_fn restrict_to(const pw_constant_fn& g, double left, double right) { return pw_zip_with(g, pw_elements{{left, right}}); } double embed_pwlin::integrate_length(const mcable& c, const pw_constant_fn& g) const { - return integrate_length(c.branch, restrict(g, c.prox_pos, c.dist_pos)); + return integrate_length(c.branch, restrict_to(g, c.prox_pos, c.dist_pos)); } double embed_pwlin::integrate_area(const mcable& c, const pw_constant_fn& g) const { - return integrate_area(c.branch, restrict(g, c.prox_pos, c.dist_pos)); + return integrate_area(c.branch, restrict_to(g, c.prox_pos, c.dist_pos)); } double embed_pwlin::integrate_ixa(const mcable& c, const pw_constant_fn& g) const { - return integrate_ixa(c.branch, restrict(g, c.prox_pos, c.dist_pos)); + return integrate_ixa(c.branch, restrict_to(g, c.prox_pos, c.dist_pos)); } // Subregions defined by geometric inequalities: diff --git a/arbor/morph/locset.cpp b/arbor/morph/locset.cpp index 2cd745f096..d576647e08 100644 --- a/arbor/morph/locset.cpp +++ b/arbor/morph/locset.cpp @@ -686,12 +686,12 @@ mlocation_list thingify_(const lrestrict_& P, const mprovider& p) { return L; } -ARB_ARBOR_API locset restrict(locset ls, region reg) { +ARB_ARBOR_API locset restrict_to(locset ls, region reg) { return locset{lrestrict_{std::move(ls), std::move(reg)}}; } std::ostream& operator<<(std::ostream& o, const lrestrict_& x) { - return o << "(restrict " << x.ls << " " << x.reg << ")"; + return o << "(restrict-to " << x.ls << " " << x.reg << ")"; } } // namespace ls diff --git a/arbor/threading/threading.cpp b/arbor/threading/threading.cpp index e43f13655a..9b7c639ca8 100644 --- a/arbor/threading/threading.cpp +++ b/arbor/threading/threading.cpp @@ -89,7 +89,7 @@ void task_system::run(priority_task ptsk) { } void task_system::run_tasks_loop(int index) { - auto guard = util::on_scope_exit([] { current_task_queue_ = -1; }); + auto guard = util::on_scope_exit([] { current_task_queue_ = nil; }); current_task_queue_ = index; if (bind_) set_affinity(index, count_, affinity_kind::thread); while (true) { @@ -128,7 +128,7 @@ void task_system::try_run_task(int lowest_priority) { } thread_local int task_system::current_task_priority_ = -1; -thread_local unsigned task_system::current_task_queue_ = -1; +thread_local unsigned task_system::current_task_queue_ = task_system::nil; // Default construct with one thread. task_system::task_system(): task_system(1) {} @@ -161,7 +161,7 @@ task_system::task_system(int nthreads, bool bind): task_system::~task_system() { current_task_priority_ = -1; - current_task_queue_ = -1; + current_task_queue_ = nil; for (auto& e: q_) e.quit(); for (auto& e: threads_) e.join(); } diff --git a/arbor/threading/threading.hpp b/arbor/threading/threading.hpp index 35afa04e9c..c690781e89 100644 --- a/arbor/threading/threading.hpp +++ b/arbor/threading/threading.hpp @@ -124,6 +124,8 @@ class ARB_ARBOR_API notification_queue { class ARB_ARBOR_API task_system { private: + static constexpr unsigned nil = static_cast(-1); + // Number of notification queues. unsigned count_; // Attempt to bind threads? diff --git a/arbor/util/piecewise.hpp b/arbor/util/piecewise.hpp index 144fc7c034..ff83d6ea01 100644 --- a/arbor/util/piecewise.hpp +++ b/arbor/util/piecewise.hpp @@ -110,7 +110,7 @@ namespace arb { namespace util { using pw_size_type = unsigned; -constexpr pw_size_type pw_npos = -1; +constexpr pw_size_type pw_npos = static_cast(-1); template struct pw_element { diff --git a/arborio/label_parse.cpp b/arborio/label_parse.cpp index 22df96481c..bc392e0999 100644 --- a/arborio/label_parse.cpp +++ b/arborio/label_parse.cpp @@ -107,8 +107,8 @@ std::unordered_multimap eval_map { "'support' with 1 argument (ls:locset)")}, {"locset", make_call(arb::ls::named, "'locset' with 1 argument: (name:string)")}, - {"restrict", make_call(arb::ls::restrict, - "'restrict' with 2 arguments: (ls:locset, reg:region)")}, + {"restrict-to", make_call(arb::ls::restrict_to, + "'restrict-to' with 2 arguments: (ls:locset, reg:region)")}, {"join", make_fold(static_cast(arb::join), "'join' with at least 2 arguments: (locset locset [...locset])")}, {"sum", make_fold(static_cast(arb::sum), diff --git a/arborio/nml_parse_morphology.cpp b/arborio/nml_parse_morphology.cpp index 84201e49d5..8bcfcf1682 100644 --- a/arborio/nml_parse_morphology.cpp +++ b/arborio/nml_parse_morphology.cpp @@ -89,8 +89,8 @@ expected, cycle_detected> topological_sort(std::size_t using std::begin; using std::end; - constexpr std::size_t unknown = -1; - constexpr std::size_t cycle = -2; + constexpr std::size_t unknown = static_cast(-1); + constexpr std::size_t cycle = static_cast(-2); std::vector depth(n, unknown); std::stack stack; diff --git a/doc/concepts/labels.rst b/doc/concepts/labels.rst index d0e6ec74cb..8b879431d0 100644 --- a/doc/concepts/labels.rst +++ b/doc/concepts/labels.rst @@ -335,7 +335,7 @@ Locset expressions Refer to a locset by its label. For example, ``(locset "synapse-sites")`` could be used in an expression to refer to a locset with the name ``"synapse-sites"``. -.. label:: (restrict locations:locset reg:region) +.. label:: (restrict-to locations:locset reg:region) The set of locations in the locset ``loc`` that are in the region ``reg``. @@ -347,7 +347,7 @@ Locset expressions .. code-block:: lisp - (restrict (terminal) (tag 3)) + (restrict-to (terminal) (tag 3)) .. label:: (join lhs:locset rhs:locset [...locset]) @@ -869,7 +869,7 @@ the regions, locsets or iexpr defined in the label dictionary by referring to th 'dend': '(tag 3)', # dend is every cable with tab 3 in the morphology 'root': '(root)', # typically the start of the soma is at the root of the cell. 'stim_site': '(location 0 0.5)', # site for the stimulus, in the middle of branch 0. - 'axon_end': '(restrict (terminal) (region "axon"))', # end of the axon. + 'axon_end': '(restrict-to (terminal) (region "axon"))', # end of the axon. 'rad_expr': '(radius 0.5)' # iexpr evaluating the radius scaled by 0.5 }) diff --git a/doc/scripts/gen-labels.py b/doc/scripts/gen-labels.py index caab422f79..45c6f67f52 100644 --- a/doc/scripts/gen-labels.py +++ b/doc/scripts/gen-labels.py @@ -213,7 +213,7 @@ def write_morphology(name, morph): "distint_in": "(sum (location 1 0.5) (location 2 0.7) (location 5 0.1))", "proxint_in": "(sum (location 1 0.8) (location 2 0.3))", "loctest": "(distal (complete (join (branch 1) (branch 0))))", - "restrict": "(restrict (terminal) (tag 3))", + "restrict": "(restrict-to (terminal) (tag 3))", "proximal_translate": "(proximal-translate (terminal) 10)", "distal_translate_single": "(distal-translate (location 0 0.5) 5)", "distal_translate_multi": "(distal-translate (location 0 0.5) 15)", @@ -255,8 +255,8 @@ def write_morphology(name, morph): tutorial_locsets = { "root": "(root)", "terminal": "(terminal)", - "custom_terminal": '(restrict (locset "terminal") (region "custom"))', - "axon_terminal": '(restrict (locset "terminal") (region "axon"))', + "custom_terminal": '(restrict-to (locset "terminal") (region "custom"))', + "axon_terminal": '(restrict-to (locset "terminal") (region "axon"))', } tutorial_labels = {**tutorial_regions, **tutorial_locsets} diff --git a/doc/tutorial/single_cell_bluepyopt.rst b/doc/tutorial/single_cell_bluepyopt.rst index c1f18dbbac..5fcfc5bb51 100644 --- a/doc/tutorial/single_cell_bluepyopt.rst +++ b/doc/tutorial/single_cell_bluepyopt.rst @@ -191,7 +191,7 @@ The first extra recording of the ``bAP`` protocol is located at 660 µm from the (distal-translate (on-components 0.5 (region "soma")) 660) -and since we're only interested in the apical dendrite, we can wrap this in ``(restrict ... (region "apic"))``. +and since we're only interested in the apical dendrite, we can wrap this in ``(restrict-to ... (region "apic"))``. Unfortunately, for this particular morphology, this does not result in a concrete location as can be seen in the Arbor GUI below (Locset A, violet, is empty). Alternatively, the method :func:`arbor.cable_cell.locations` will also return an empty list of concrete locations for this expression. To obtain a valid location instead, we can replace ``(on-components 0.5 (region "soma"))`` by the proximal boundary of the apical dendrite with ``(proximal (region "apic"))`` (Locset B, orange). The restrict operation to the apical region is no longer necessary. But now, the resulting concrete location is non-unique. diff --git a/ext/tinyopt/include/tinyopt/tinyopt.h b/ext/tinyopt/include/tinyopt/tinyopt.h index 8845e51c3d..e9d55c8d96 100644 --- a/ext/tinyopt/include/tinyopt/tinyopt.h +++ b/ext/tinyopt/include/tinyopt/tinyopt.h @@ -568,7 +568,9 @@ using unary_argument_type_t = typename unary_argument_type::type; struct sink { // Tag class for constructor. - static struct action_t {} action; + struct action_t {}; + + constexpr static action_t action{}; sink(): sink(action, [](const char*) { return true; }) diff --git a/modcc/errorvisitor.hpp b/modcc/errorvisitor.hpp index c12cfe6617..a371aac0a2 100644 --- a/modcc/errorvisitor.hpp +++ b/modcc/errorvisitor.hpp @@ -11,6 +11,8 @@ class ARB_LIBMODCC_API ErrorVisitor : public Visitor { : module_name_(m) {} + using Visitor::visit; + void visit(Expression *e) override; void visit(ProcedureExpression *e) override; void visit(FunctionExpression *e) override; diff --git a/modcc/expression.cpp b/modcc/expression.cpp index 5178059c4d..82ec3ac679 100644 --- a/modcc/expression.cpp +++ b/modcc/expression.cpp @@ -606,10 +606,7 @@ void ProcedureExpression::semantic(scope_type::symbol_map &global_symbols) { *******************************************************************************/ std::string APIMethod::to_string() const { - auto namestr = [] (Symbol* e) -> std::string { - return yellow(e->name()); - return ""; - }; + auto namestr = [] (Symbol* e) -> std::string { return yellow(e->name()); }; std::string str = blue("API method") + " " + yellow(name()) + "\n"; str += blue(" locals") + " : "; @@ -1229,7 +1226,6 @@ ARB_LIBMODCC_API expression_ptr unary_expression( Location loc, << std::endl;; return nullptr; } - return nullptr; } ARB_LIBMODCC_API expression_ptr binary_expression( tok op, @@ -1294,5 +1290,4 @@ ARB_LIBMODCC_API expression_ptr binary_expression(Location loc, << std::endl; return nullptr; } - return nullptr; } diff --git a/modcc/expression.hpp b/modcc/expression.hpp index 4d3cd6aff6..9f9cb19410 100644 --- a/modcc/expression.hpp +++ b/modcc/expression.hpp @@ -294,7 +294,7 @@ class ARB_LIBMODCC_API IdentifierExpression : public Expression { } expression_ptr clone() const override; - + using Expression::semantic; void semantic(scope_ptr scp) override; void symbol(Symbol* sym) { symbol_ = sym; } @@ -326,6 +326,7 @@ class ARB_LIBMODCC_API IdentifierExpression : public Expression { // an identifier for a derivative class ARB_LIBMODCC_API DerivativeExpression : public IdentifierExpression { public: + DerivativeExpression(Location loc, std::string const& name) : IdentifierExpression(loc, name) {} @@ -336,6 +337,7 @@ class ARB_LIBMODCC_API DerivativeExpression : public IdentifierExpression { expression_ptr clone() const override; + using Expression::semantic; void semantic(scope_ptr scp) override; DerivativeExpression* is_derivative() override { return this; } @@ -363,6 +365,7 @@ class ARB_LIBMODCC_API NumberExpression : public Expression { } // do nothing for number semantic analysis + using Expression::semantic; void semantic(scope_ptr scp) override {}; expression_ptr clone() const override; @@ -393,6 +396,7 @@ class ARB_LIBMODCC_API IntegerExpression : public NumberExpression { } // do nothing for number semantic analysis + using Expression::semantic; void semantic(scope_ptr scp) override {}; expression_ptr clone() const override; @@ -424,6 +428,7 @@ class ARB_LIBMODCC_API LocalDeclaration : public Expression { bool add_variable(Token name); LocalDeclaration* is_local_declaration() override {return this;} + using Expression::semantic; void semantic(scope_ptr scp) override; std::vector& symbols() {return symbols_;} std::map& variables() {return vars_;} @@ -449,6 +454,7 @@ class ARB_LIBMODCC_API ArgumentExpression : public Expression { bool add_variable(Token name); ArgumentExpression* is_argument() override {return this;} + using Expression::semantic; void semantic(scope_ptr scp) override; Token token() {return token_;} std::string const& name() {return name_;} @@ -710,7 +716,7 @@ class ARB_LIBMODCC_API SolveExpression : public Expression { } expression_ptr clone() const override; - + using Expression::semantic; void semantic(scope_ptr scp) override; void accept(Visitor *v) override; @@ -752,7 +758,7 @@ class ARB_LIBMODCC_API ConductanceExpression : public Expression { } expression_ptr clone() const override; - + using Expression::semantic; void semantic(scope_ptr scp) override; void accept(Visitor *v) override; @@ -810,7 +816,7 @@ class ARB_LIBMODCC_API BlockExpression : public Expression { bool is_nested() const { return is_nested_; } - + using Expression::semantic; void semantic(scope_ptr scp) override; void accept(Visitor* v) override; @@ -841,6 +847,7 @@ class ARB_LIBMODCC_API IfExpression : public Expression { std::string to_string() const override; void replace_condition(expression_ptr&& other); + using Expression::semantic; void semantic(scope_ptr scp) override; void accept(Visitor* v) override; @@ -894,6 +901,7 @@ class ReactionExpression : public Expression { ReactionExpression* is_reaction() override {return this;} std::string to_string() const override; + using Expression::semantic; void semantic(scope_ptr scp) override; expression_ptr clone() const override; void accept(Visitor *v) override; @@ -927,6 +935,7 @@ class ARB_LIBMODCC_API CompartmentExpression : public Expression { CompartmentExpression* is_compartment() override {return this;} std::string to_string() const override; + using Expression::semantic; void semantic(scope_ptr scp) override; expression_ptr clone() const override; void accept(Visitor *v) override; @@ -958,6 +967,7 @@ class ARB_LIBMODCC_API StoichTermExpression : public Expression { std::string to_string() const override { return pprintf("% %", coeff()->to_string(), ident()->to_string()); } + using Expression::semantic; void semantic(scope_ptr scp) override; expression_ptr clone() const override; void accept(Visitor *v) override; @@ -991,6 +1001,7 @@ class ARB_LIBMODCC_API StoichExpression : public Expression { StoichExpression* is_stoich() override {return this;} std::string to_string() const override; + using Expression::semantic; void semantic(scope_ptr scp) override; expression_ptr clone() const override; void accept(Visitor *v) override; @@ -1015,7 +1026,7 @@ class ARB_LIBMODCC_API CallExpression : public Expression { std::string& name() { return spelling_; } std::string const& name() const { return spelling_; } - + using Expression::semantic; void semantic(scope_ptr scp) override; expression_ptr clone() const override; @@ -1150,7 +1161,7 @@ class ARB_LIBMODCC_API NetReceiveExpression : public ProcedureExpression { expression_ptr&& body) : ProcedureExpression(loc, std::move(name), std::move(args), std::move(body), procedureKind::net_receive) {} - + using Expression::semantic; void semantic(scope_type::symbol_map &scp) override; NetReceiveExpression* is_net_receive() override {return this;} /// hard code the kind @@ -1171,7 +1182,7 @@ class ARB_LIBMODCC_API PostEventExpression : public ProcedureExpression { expression_ptr&& body) : ProcedureExpression(loc, std::move(name), std::move(args), std::move(body), procedureKind::post_event) {} - + using Expression::semantic; void semantic(scope_type::symbol_map &scp) override; PostEventExpression* is_post_event() override {return this;} /// hard code the kind @@ -1216,6 +1227,7 @@ class ARB_LIBMODCC_API FunctionExpression : public Symbol { } FunctionExpression* is_function() override {return this;} + using Expression::semantic; void semantic(scope_type::symbol_map&) override; std::string to_string() const override; void accept(Visitor *v) override; @@ -1253,6 +1265,7 @@ class ARB_LIBMODCC_API UnaryExpression : public Expression { UnaryExpression* is_unary() override {return this;}; Expression* expression() {return expression_.get();} const Expression* expression() const {return expression_.get();} + using Expression::semantic; void semantic(scope_ptr scp) override; void accept(Visitor *v) override; void replace_expression(expression_ptr&& other); @@ -1453,6 +1466,7 @@ class ARB_LIBMODCC_API BinaryExpression : public Expression { const Expression* lhs() const {return lhs_.get();} const Expression* rhs() const {return rhs_.get();} BinaryExpression* is_binary() override {return this;} + using Expression::semantic; void semantic(scope_ptr scp) override; expression_ptr clone() const override; void replace_rhs(expression_ptr&& other); @@ -1468,7 +1482,7 @@ class ARB_LIBMODCC_API AssignmentExpression : public BinaryExpression { {} AssignmentExpression* is_assignment() override {return this;} - + using Expression::semantic; void semantic(scope_ptr scp) override; void accept(Visitor *v) override; @@ -1482,7 +1496,7 @@ class ARB_LIBMODCC_API ConserveExpression : public BinaryExpression { ConserveExpression* is_conserve() override {return this;} expression_ptr clone() const override; - + using Expression::semantic; void semantic(scope_ptr scp) override; void accept(Visitor *v) override; @@ -1496,7 +1510,7 @@ class ARB_LIBMODCC_API LinearExpression : public BinaryExpression { LinearExpression* is_linear() override {return this;} expression_ptr clone() const override; - + using Expression::semantic; void semantic(scope_ptr scp) override; void accept(Visitor *v) override; @@ -1593,6 +1607,7 @@ class ARB_LIBMODCC_API PDiffExpression : public Expression { std::string to_string() const override; void accept(Visitor *v) override; + using Expression::semantic; void semantic(scope_ptr scp) override; expression_ptr clone() const override; diff --git a/modcc/lexer.cpp b/modcc/lexer.cpp index f89c3d323f..2ad992e62d 100644 --- a/modcc/lexer.cpp +++ b/modcc/lexer.cpp @@ -270,9 +270,7 @@ Token Lexer::parse() { return t; } } - - // return the token - return t; + // unreachable! } Token Lexer::peek() { diff --git a/modcc/modcc.cpp b/modcc/modcc.cpp index 0934c21afa..a459090216 100644 --- a/modcc/modcc.cpp +++ b/modcc/modcc.cpp @@ -177,7 +177,7 @@ int main(int argc, char **argv) { { to::action(enable_simd), to::flag, "-s", "--simd" }, { popt.simd, "-S", "--simd-abi" }, { to::set(popt.trace_codegen), to::flag, "-T", "--trace-codegen"}, - { {to::action(add_target, to::keywords(targetKindMap))}, "-t", "--target" }, + { to::action(add_target, to::keywords(targetKindMap)), "-t", "--target" }, { to::action(help), to::flag, to::exit, "-h", "--help" } }; diff --git a/modcc/parser.cpp b/modcc/parser.cpp index 067bb67c15..842b0edcde 100644 --- a/modcc/parser.cpp +++ b/modcc/parser.cpp @@ -1066,7 +1066,6 @@ expression_ptr Parser::parse_statement() { switch (token_.type) { case tok::if_stmt: return parse_if(); - break; case tok::conductance: return parse_conductance(); case tok::solve: @@ -1090,7 +1089,7 @@ expression_ptr Parser::parse_statement() { error(pprintf("unexpected token type % '%'", token_string(token_.type), token_.spelling)); return nullptr; } - return nullptr; + // unreachable! } expression_ptr Parser::parse_identifier() { @@ -1393,9 +1392,7 @@ expression_ptr Parser::parse_expression(int prec, tok stop_token) { // Combine all sub-expressions with precedence greater than prec. for (;;) { - if (token_.type == stop_token) { - return lhs; - } + if (token_.type == stop_token) return lhs; auto op = token_; auto p_op = binop_precedence(op.type); @@ -1410,8 +1407,7 @@ expression_ptr Parser::parse_expression(int prec, tok stop_token) { lhs = parse_binop(std::move(lhs), op); if (!lhs) return nullptr; } - - return lhs; + // unreachable! } expression_ptr Parser::parse_expression() { @@ -1467,7 +1463,7 @@ expression_ptr Parser::parse_unaryop() { default: return parse_primary(); } - return nullptr; + // unreachable! } /// parse a primary expression node diff --git a/modcc/perfvisitor.hpp b/modcc/perfvisitor.hpp index 80c3088c3c..313d3b8789 100644 --- a/modcc/perfvisitor.hpp +++ b/modcc/perfvisitor.hpp @@ -41,6 +41,7 @@ static std::ostream& operator << (std::ostream& os, FlopAccumulator const& f) { class FlopVisitor : public Visitor { public: + using Visitor::visit; void visit(Expression *e) override {} // traverse the statements in an API method @@ -183,6 +184,7 @@ class FlopVisitor : public Visitor { class MemOpVisitor : public Visitor { public: + using Visitor::visit; void visit(Expression *e) override {} // traverse the statements in an API method diff --git a/modcc/printer/cexpr_emit.hpp b/modcc/printer/cexpr_emit.hpp index 86b5f957e8..4e5fa873fa 100644 --- a/modcc/printer/cexpr_emit.hpp +++ b/modcc/printer/cexpr_emit.hpp @@ -17,6 +17,7 @@ class ARB_LIBMODCC_API CExprEmitter: public Visitor { out_(out), fallback_(fallback) {} + using Visitor::visit; void visit(Expression* e) override { e->accept(fallback_); } void visit(UnaryExpression *e) override; @@ -39,7 +40,6 @@ inline void cexpr_emit(Expression* e, std::ostream& out, Visitor* fallback) { } class ARB_LIBMODCC_API SimdExprEmitter: public CExprEmitter { - using CExprEmitter::visit; public: SimdExprEmitter( std::ostream& out, @@ -48,7 +48,7 @@ class ARB_LIBMODCC_API SimdExprEmitter: public CExprEmitter { const std::unordered_set& scalars, Visitor* fallback): CExprEmitter(out, fallback), is_indirect_(is_indirect), input_mask_(input_mask), scalars_(scalars), fallback_(fallback) {} - + using CExprEmitter::visit; void visit(BlockExpression *e) override; void visit(CallExpression *e) override; void visit(UnaryExpression *e) override; diff --git a/modcc/printer/cprinter.hpp b/modcc/printer/cprinter.hpp index 010d1398b0..725356ba81 100644 --- a/modcc/printer/cprinter.hpp +++ b/modcc/printer/cprinter.hpp @@ -21,7 +21,7 @@ class ARB_LIBMODCC_API CPrinter: public Visitor { void visit(Expression* e) override { throw compiler_exception("CPrinter cannot translate expression "+e->to_string()); } - + using Visitor::visit; void visit(BlockExpression*) override; void visit(CallExpression*) override; void visit(IdentifierExpression*) override; @@ -79,7 +79,7 @@ class ARB_LIBMODCC_API SimdPrinter: public Visitor { void save_scalar_names(const std::unordered_set& scalars) { scalars_ = scalars; } - + using Visitor::visit; void visit(BlockExpression*) override; void visit(CallExpression*) override; void visit(IdentifierExpression*) override; diff --git a/modcc/printer/gpuprinter.hpp b/modcc/printer/gpuprinter.hpp index b413adb2c8..6f7149a77f 100644 --- a/modcc/printer/gpuprinter.hpp +++ b/modcc/printer/gpuprinter.hpp @@ -14,6 +14,7 @@ class ARB_LIBMODCC_API GpuPrinter: public CPrinter { public: GpuPrinter(std::ostream& out): CPrinter(out) {} + using Visitor::visit; void visit(CallExpression*) override; void visit(VariableExpression*) override; void visit(WhiteNoise*) override; diff --git a/modcc/solvers.cpp b/modcc/solvers.cpp index 2ddc9fbfb7..8bd3a992b4 100644 --- a/modcc/solvers.cpp +++ b/modcc/solvers.cpp @@ -230,7 +230,7 @@ std::vector SystemSolver::generate_solution_assignments(std::vec for (unsigned i = 0; i < nrow; ++i) { const symge::sym_row& row = A_[i]; unsigned rhs_col = A_.augcol(); - unsigned lhs_col = -1; + unsigned lhs_col = static_cast(-1); for (unsigned r = 0; r < A_.nrow(); ++r) { if (row[r]) { lhs_col = r; diff --git a/modcc/symdiff.cpp b/modcc/symdiff.cpp index 4ea0ea6e63..ea7a7e7b4d 100644 --- a/modcc/symdiff.cpp +++ b/modcc/symdiff.cpp @@ -13,6 +13,7 @@ class FindIdentifierVisitor: public Visitor { public: + using Visitor::visit; explicit FindIdentifierVisitor(const identifier_set& ids): ids_(ids) {} void reset() { found_ = false; } @@ -102,6 +103,7 @@ ARB_LIBMODCC_API bool involves_identifier(Expression* e, const std::string& id) class SymPDiffVisitor: public Visitor, public error_stack { public: + using Visitor::visit; explicit SymPDiffVisitor(std::string id): id_(std::move(id)) {} void reset() { result_ = nullptr; } @@ -713,6 +715,7 @@ ARB_LIBMODCC_API expression_ptr symbolic_pdiff(Expression* e, const std::string& class SubstituteVisitor: public Visitor { public: + using Visitor::visit; explicit SubstituteVisitor(const substitute_map& sub): sub_(sub) {} diff --git a/modcc/visitor.hpp b/modcc/visitor.hpp index 8a638547b9..ef29e45bed 100644 --- a/modcc/visitor.hpp +++ b/modcc/visitor.hpp @@ -105,6 +105,8 @@ class BlockRewriterBase : public Visitor, public error_stack { statements_.push_back(e->clone()); } + using Visitor::visit; + virtual void visit(UnaryExpression *e) override { visit((Expression*)e); } virtual void visit(BinaryExpression *e) override { visit((Expression*)e); } diff --git a/python/example/single_cell_bluepyopt_l5pc.py b/python/example/single_cell_bluepyopt_l5pc.py index 502a608464..90e0e31adc 100755 --- a/python/example/single_cell_bluepyopt_l5pc.py +++ b/python/example/single_cell_bluepyopt_l5pc.py @@ -23,7 +23,7 @@ labels["soma_center"] = "(location 0 0.5)" labels["dend1"] = ( - '(restrict (distal-translate (proximal (region "apic")) 660)' + '(restrict-to (distal-translate (proximal (region "apic")) 660)' " (proximal-interval (distal (branch 123))))" ) diff --git a/python/example/single_cell_detailed.py b/python/example/single_cell_detailed.py index 5c77f9cec4..f2e29067ff 100755 --- a/python/example/single_cell_detailed.py +++ b/python/example/single_cell_detailed.py @@ -36,9 +36,9 @@ "root": "(root)", "terminal": "(terminal)", # Add a label for the terminal locations in the "custom" region: - "custom_terminal": '(restrict (locset "terminal") (region "custom"))', + "custom_terminal": '(restrict-to (locset "terminal") (region "custom"))', # Add a label for the terminal locations in the "axon" region: - "axon_terminal": '(restrict (locset "terminal") (region "axon"))', + "axon_terminal": '(restrict-to (locset "terminal") (region "axon"))', } ).add_swc_tags() diff --git a/python/example/single_cell_detailed_recipe.py b/python/example/single_cell_detailed_recipe.py index adedca2ef2..bb7f1972ee 100644 --- a/python/example/single_cell_detailed_recipe.py +++ b/python/example/single_cell_detailed_recipe.py @@ -35,9 +35,9 @@ "root": "(root)", "terminal": "(terminal)", # Add a label for the terminal locations in the "custom" region: - "custom_terminal": '(restrict (locset "terminal") (region "custom"))', + "custom_terminal": '(restrict-to (locset "terminal") (region "custom"))', # Add a label for the terminal locations in the "axon" region: - "axon_terminal": '(restrict (locset "terminal") (region "axon"))', + "axon_terminal": '(restrict-to (locset "terminal") (region "axon"))', } ).add_swc_tags() # Add SWC pre-defined regions diff --git a/python/example/single_cell_nml.py b/python/example/single_cell_nml.py index 8992ca1e5c..b506ef53a4 100755 --- a/python/example/single_cell_nml.py +++ b/python/example/single_cell_nml.py @@ -31,7 +31,7 @@ labels = arbor.label_dict( { "stim_site": "(location 1 0.5)", # site for the stimulus, in the middle of branch 1. - "axon_end": '(restrict (terminal) (region "axon"))', # end of the axon. + "axon_end": '(restrict-to (terminal) (region "axon"))', # end of the axon. "root": "(root)", # the start of the soma in this morphology is at the root of the cell. } ) diff --git a/python/example/single_cell_swc.py b/python/example/single_cell_swc.py index febfe774c5..ea830594cb 100755 --- a/python/example/single_cell_swc.py +++ b/python/example/single_cell_swc.py @@ -29,7 +29,7 @@ { "root": "(root)", # the start of the soma in this morphology is at the root of the cell. "stim_site": "(location 0 0.5)", # site for the stimulus, in the middle of branch 0. - "axon_end": '(restrict (terminal) (region "axon"))', + "axon_end": '(restrict-to (terminal) (region "axon"))', } # end of the axon. ).add_swc_tags() # Finally, add the SWC default labels. diff --git a/test/unit/test_abi.cpp b/test/unit/test_abi.cpp index 7cbf537f4f..ebabe05ab3 100644 --- a/test/unit/test_abi.cpp +++ b/test/unit/test_abi.cpp @@ -201,11 +201,12 @@ TEST(abi, gpu_initialisation) { std::vector cv_to_cell(ncv, 0); std::vector temp(ncv, 23); std::vector diam(ncv, 1.); + std::vector area(ncv, 1.); std::vector vinit(ncv, -65); std::vector src_to_spike = {}; arb::gpu::shared_state shared_state(thread_pool, ncell, ncv, cv_to_cell, - vinit, temp, diam, src_to_spike, + vinit, temp, diam, area, src_to_spike, arb::fvm_detector_info{}, 1); @@ -280,11 +281,13 @@ TEST(abi, gpu_null) { std::vector cv_to_cell(ncv, 0); std::vector temp(ncv, 23); std::vector diam(ncv, 1.); + std::vector area(ncv, 1.); std::vector vinit(ncv, -65); std::vector src_to_spike = {}; arb::gpu::shared_state shared_state(thread_pool, ncell, ncv, cv_to_cell, - vinit, temp, diam, src_to_spike, + vinit, temp, diam, area, + src_to_spike, arb::fvm_detector_info{}, 1); diff --git a/test/unit/test_morph_expr.cpp b/test/unit/test_morph_expr.cpp index 8cf3569aa5..2e5652ffd8 100644 --- a/test/unit/test_morph_expr.cpp +++ b/test/unit/test_morph_expr.cpp @@ -664,39 +664,39 @@ TEST(region, thingify_moderate_morphologies) { EXPECT_TRUE(region_eq(mp, radius_gt(reg_c_, 2), cl{{0,0.55,0.7},{2,0,0.5},{3,0.1,0.375},{3,0.9,1}})); EXPECT_TRUE(region_eq(mp, radius_gt(reg_d_, 2), cl{{0,0.55,0.7},{2,0,0.5},{3,0.1,0.375},{3,0.75,0.9}})); - // Test restriction + // Test restrict_to { using ll = mlocation_list; // two empty inputs -> empty output - EXPECT_TRUE(locset_eq(mp, ls::restrict(ll{}, {}), ll{})); + EXPECT_TRUE(locset_eq(mp, ls::restrict_to(ll{}, {}), ll{})); // empty locset + non-empty region -> empty output - EXPECT_TRUE(locset_eq(mp, ls::restrict(ll{}, reg::all()), ll{})); + EXPECT_TRUE(locset_eq(mp, ls::restrict_to(ll{}, reg::all()), ll{})); // non-empty locset + empty region -> empty output - EXPECT_TRUE(locset_eq(mp, ls::restrict(ll{{0,0.4}, {3, 0.1}}, {}), ll{})); + EXPECT_TRUE(locset_eq(mp, ls::restrict_to(ll{{0,0.4}, {3, 0.1}}, {}), ll{})); ll locs{{0,0.4}, {3,0.1}}; // none of locs in region -> empty output - EXPECT_TRUE(locset_eq(mp, ls::restrict(locs, branch(1)), ll{})); + EXPECT_TRUE(locset_eq(mp, ls::restrict_to(locs, branch(1)), ll{})); // some but not all locs in region -> correct subset - EXPECT_TRUE(locset_eq(mp, ls::restrict(locs, branch(0)), ll{{0,0.4}})); + EXPECT_TRUE(locset_eq(mp, ls::restrict_to(locs, branch(0)), ll{{0,0.4}})); // all locs in region -> locs in output - EXPECT_TRUE(locset_eq(mp, ls::restrict(locs, join(branch(0), branch(3))), locs)); + EXPECT_TRUE(locset_eq(mp, ls::restrict_to(locs, join(branch(0), branch(3))), locs)); // all locs in region -> locs in output - EXPECT_TRUE(locset_eq(mp, ls::restrict(locs, join(branch(0), branch(1), branch(3))), locs)); + EXPECT_TRUE(locset_eq(mp, ls::restrict_to(locs, join(branch(0), branch(1), branch(3))), locs)); // should also work with non-ordered input locset std::reverse(locs.begin(), locs.end()); - EXPECT_TRUE(locset_eq(mp, ls::restrict(locs, join(branch(0), branch(3))), locs)); + EXPECT_TRUE(locset_eq(mp, ls::restrict_to(locs, join(branch(0), branch(3))), locs)); mlocation loc{1,0.5}; // location at end of cable - EXPECT_TRUE(locset_eq(mp, ls::restrict(loc, cable(1, 0.2, 0.5)), loc)); + EXPECT_TRUE(locset_eq(mp, ls::restrict_to(loc, cable(1, 0.2, 0.5)), loc)); // location at start of cable - EXPECT_TRUE(locset_eq(mp, ls::restrict(loc, cable(1, 0.5, 0.7)), loc)); + EXPECT_TRUE(locset_eq(mp, ls::restrict_to(loc, cable(1, 0.5, 0.7)), loc)); // location in zero-length cable - EXPECT_TRUE(locset_eq(mp, ls::restrict(loc, cable(1, 0.5, 0.5)), loc)); + EXPECT_TRUE(locset_eq(mp, ls::restrict_to(loc, cable(1, 0.5, 0.5)), loc)); // location between cable end points - EXPECT_TRUE(locset_eq(mp, ls::restrict(loc, cable(1, 0.2, 0.7)), loc)); + EXPECT_TRUE(locset_eq(mp, ls::restrict_to(loc, cable(1, 0.2, 0.7)), loc)); } diff --git a/test/unit/test_s_expr.cpp b/test/unit/test_s_expr.cpp index f1e9237833..1e73e5e66b 100644 --- a/test/unit/test_s_expr.cpp +++ b/test/unit/test_s_expr.cpp @@ -372,7 +372,7 @@ TEST(regloc, round_tripping) { "(distal (tag 2))", "(proximal (join (tag 1) (tag 2)))", "(uniform (tag 1) 0 100 52)", - "(restrict (terminal) (tag 12))", + "(restrict-to (terminal) (tag 12))", "(on-components 0.3 (segment 2))", "(join (terminal) (root))", "(sum (terminal) (root))", diff --git a/test/unit/test_simd.cpp b/test/unit/test_simd.cpp index e04485105b..23e254be20 100644 --- a/test/unit/test_simd.cpp +++ b/test/unit/test_simd.cpp @@ -1761,7 +1761,7 @@ TYPED_TEST_P(sizeless_api, arithmetic) { } // cmp_eq { - indirect(m, N) = cmp_eq(av, bv); + indirect(m, N) = arb::simd::cmp_eq(av, bv); for (unsigned i = 0; i Date: Mon, 31 Jul 2023 09:38:21 +0200 Subject: [PATCH 7/9] fix ODR violation (#2154) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While linking unit tests, examples, pyarb I get the following warnings about ODR violations: ``` arbor/arbor/util/maputil.hpp:21:6: warning: ‘keys’ violates the C++ One Definition Rule [-Wodr] 21 | auto keys(Seq&& m) { | ^ arbor/arbor/util/maputil.hpp:21:6: note: return value type mismatch 21 | auto keys(Seq&& m) { | ^ arbor/arbor/util/range.hpp:40:8: note: type ‘struct range’ defined in anonymous namespace cannot match across the translation unit boundary 40 | struct range { | ^ arbor/arbor/util/maputil.hpp:21:6: note: ‘keys’ was previously declared here 21 | auto keys(Seq&& m) { | ^ arbor/arbor/util/maputil.hpp:21:6: note: code may be misoptimized unless ‘-fno-strict-aliasing’ is used ``` This seems related to the return type deduction of two function templates with `auto` return type which return a `range` template instantiation. The type of the latter is deduced based on a `constexpr if` expression. I am not entirely sure where the ODR violation happens, but by using trailing return types for the former functions the problem is avoided. --- arbor/fvm_lowered_cell.hpp | 4 +++- arbor/merge_events.cpp | 6 +++--- arbor/merge_events.hpp | 6 +++--- arbor/util/maputil.hpp | 4 +++- arbor/util/tourney_tree.cpp | 2 +- arbor/util/tourney_tree.hpp | 2 +- 6 files changed, 14 insertions(+), 10 deletions(-) diff --git a/arbor/fvm_lowered_cell.hpp b/arbor/fvm_lowered_cell.hpp index 899f073f43..c23f21932a 100644 --- a/arbor/fvm_lowered_cell.hpp +++ b/arbor/fvm_lowered_cell.hpp @@ -185,7 +185,9 @@ struct probe_association_map { } // Return range of fvm_probe_data values associated with probeset_id. - auto data_on(cell_member_type probeset_id) const { + // Trailing return type added here to avoid warnings about ODR violations when building shared + // lib together with LTO - needs to be re-checked in the future + auto data_on(cell_member_type probeset_id) const -> decltype(util::transform_view(util::make_range(data.equal_range(probeset_id)), util::second)) { return util::transform_view(util::make_range(data.equal_range(probeset_id)), util::second); } }; diff --git a/arbor/merge_events.cpp b/arbor/merge_events.cpp index 061aa8c8b3..9dd71ef488 100644 --- a/arbor/merge_events.cpp +++ b/arbor/merge_events.cpp @@ -14,7 +14,7 @@ namespace arb { // k-way linear merge: // Pick stream with the minimum element, pop that and push into output. // Repeat. -void linear_merge_events(std::vector& sources, pse_vector& out) { +void ARB_ARBOR_API linear_merge_events(std::vector& sources, pse_vector& out) { // Consume all events. for (;;) { // Now find the minimum @@ -38,7 +38,7 @@ void linear_merge_events(std::vector& sources, pse_vector& out) { } // priority-queue based merge. -void pqueue_merge_events(std::vector& sources, pse_vector& out) { +void ARB_ARBOR_API pqueue_merge_events(std::vector& sources, pse_vector& out) { // Min heap tracking the minimum element from each span using kv_type = std::pair; std::priority_queue, std::greater<>> heap; @@ -68,7 +68,7 @@ void pqueue_merge_events(std::vector& sources, pse_vector& out) { } } -void merge_events(std::vector& sources, pse_vector &out) { +void ARB_ARBOR_API merge_events(std::vector& sources, pse_vector &out) { // Count events, bail if none; else allocate enough space to store them. auto n_evts = std::accumulate(sources.begin(), sources.end(), 0, diff --git a/arbor/merge_events.hpp b/arbor/merge_events.hpp index c8c42634d1..69dbae9cad 100644 --- a/arbor/merge_events.hpp +++ b/arbor/merge_events.hpp @@ -16,9 +16,9 @@ namespace arb { using event_span = util::range; -void linear_merge_events(std::vector& sources, pse_vector& out); -void pqueue_merge_events(std::vector& sources, pse_vector& out); +void ARB_ARBOR_API linear_merge_events(std::vector& sources, pse_vector& out); +void ARB_ARBOR_API pqueue_merge_events(std::vector& sources, pse_vector& out); -void merge_events(std::vector& sources, pse_vector& out); +void ARB_ARBOR_API merge_events(std::vector& sources, pse_vector& out); } // namespace arb diff --git a/arbor/util/maputil.hpp b/arbor/util/maputil.hpp index 54ecd2f95a..b6c054de4a 100644 --- a/arbor/util/maputil.hpp +++ b/arbor/util/maputil.hpp @@ -17,8 +17,10 @@ namespace util { // View over the keys (first elements) in a sequence of pairs or tuples. +// Trailing return type added here to avoid warnings about ODR violations when building shared +// lib together with LTO - needs to be re-checked in the future template -auto keys(Seq&& m) { +auto keys(Seq&& m) -> decltype(util::transform_view(std::forward(m), util::first)) { return util::transform_view(std::forward(m), util::first); } diff --git a/arbor/util/tourney_tree.cpp b/arbor/util/tourney_tree.cpp index e26416816f..e1487d9d2a 100644 --- a/arbor/util/tourney_tree.cpp +++ b/arbor/util/tourney_tree.cpp @@ -136,7 +136,7 @@ const spike_event& tourney_tree::event(unsigned i) const { return heap_[i].second; } -void tree_merge_events(std::vector& sources, pse_vector& out) { +void ARB_ARBOR_API tree_merge_events(std::vector& sources, pse_vector& out) { tourney_tree tree(sources); while (!tree.empty()) { out.push_back(tree.head()); diff --git a/arbor/util/tourney_tree.hpp b/arbor/util/tourney_tree.hpp index 85c3109137..b684e0a449 100644 --- a/arbor/util/tourney_tree.hpp +++ b/arbor/util/tourney_tree.hpp @@ -41,6 +41,6 @@ class ARB_ARBOR_API tourney_tree { unsigned n_lanes_; }; -void tree_merge_events(std::vector& sources, pse_vector& out); +void ARB_ARBOR_API tree_merge_events(std::vector& sources, pse_vector& out); } From 60c864e3f5217eb324a663d050e6852f17d67f49 Mon Sep 17 00:00:00 2001 From: Brent Huisman Date: Mon, 31 Jul 2023 09:56:45 +0200 Subject: [PATCH 8/9] Document features (#2158) 1. Document neuroscientific features better. Often requested, now urgently needed. 2. Remove stale matplotlib check, addressing https://github.com/arbor-sim/arbor/pull/2157 --- doc/concepts/decor.rst | 4 ++++ doc/concepts/interconnectivity.rst | 5 +++++ doc/concepts/morphology.rst | 2 ++ doc/features/index.rst | 32 ++++++++++++++++++++++++++++++ doc/fileformat/nmodl.rst | 2 ++ doc/index.rst | 9 ++------- doc/modelling/index.rst | 10 ---------- doc/python/probe_sample.rst | 3 +++ scripts/tsplot | 6 ------ 9 files changed, 50 insertions(+), 23 deletions(-) create mode 100644 doc/features/index.rst delete mode 100644 doc/modelling/index.rst diff --git a/doc/concepts/decor.rst b/doc/concepts/decor.rst index aa5501742c..bb7f1fffad 100644 --- a/doc/concepts/decor.rst +++ b/doc/concepts/decor.rst @@ -194,6 +194,8 @@ Currently, only parameters of :ref:`density mechanisms # paint a scaled density mechanism, where 'g' is scaled with the distance from the root. decor.paint('"dend"', arbor.scaled_mechanism(arbor.density(m), {'g': '(distance 1.0 (root))'})) +.. _cablecell-ions: + 5. Ion species ~~~~~~~~~~~~~~ @@ -285,6 +287,8 @@ using the *paint* interface: # Alternatively, one can selectively overwrite the global defaults. decor.paint('(tag 2)', arbor.ion('ca', rev_pot=126) +.. _cablecell-ions-diffusion: + To enable diffusion of ion species along the morphology (axial diffusion) one sets the per-species diffusivity to a positive value. It can be changed per region and defaults to zero. This is strictly passive transport according to the diff --git a/doc/concepts/interconnectivity.rst b/doc/concepts/interconnectivity.rst index a7fda3b4d3..8b7de20c46 100644 --- a/doc/concepts/interconnectivity.rst +++ b/doc/concepts/interconnectivity.rst @@ -18,6 +18,11 @@ These sites as such are not connected yet, however the :ref:`recipe `, including :ref:`formatnmodl` and NeuroML by way of `NMLCC `_, a fully featured NeuroML converter for Arbor targets. +* `Nascent SONATA format support `_. The Allen mechanism database :ref:`is already included in Arbor `, so currently, with some manual work executing Allen models is already possible, see :ref:`tutorialsinglecellallen`. +* :ref:`Voltage Processes ` in the form of a mechanism kind. Useful for e.g. implementing voltage clamps. +* :ref:`Stochastic Differential Equations `: both point and density mechanisms may now use white noise as part of the state updates, turning the ODEs effectively into SDEs. +* :ref:`Mutable connection table `: the connection table can be redefined between successive phases of simulation. +* :ref:`Edit morphologies ` using Arbor API, useful for e.g. merging segment trees. +* `BluePyOpt integration `_. Parameter optimization using BluePyOpt can be done through an Arbor backend and exported to an Arbor cable cell, see :ref:`this tutorial `. +* :ref:`Wide range of cable cell probes`, :ref:`plus LIF cell probes `. +* :ref:`Inhomogeneous parameters `: enables :ref:`painting of scaled density mechanisms `, e.g. scale with the distance from the root. (nmodl: ``iexpr``.) +* :ref:`LFPyKit integration `: extract extracellular signals from an Arbor cable cell. +* :ref:`Axial Diffusion `: ions can now propagate along the dendrite by diffusion and be received by other synapses, modifying their weight upon reception.Xd can be read from and written to by NMODL density and point mechanisms. See `this LaTeX file `_ for a mathematical description of Arbor's implementation. +* :ref:`Gap Junction Mechanisms `. +* :ref:`Mechanism ABI `, allowing for users to package their mechanism catalogues. +* :ref:`Built-in profiler `, which enables users to quickly understand where their experiment is spending most of its time. +* :ref:`Faster NMODL programming guide `: helps users write NMODL with performance and fewer bugs in mind. + +Modelling +--------- + +Most of the Arbor community lives in our `Gitter channel `_\, and modellers convene `weekly `_ to discuss how to use or identify missing features in a vide chat. Please join! + +Under the `arbor-contrib `_ organisation, some users have shared their models. You can peruse these at your leisure, and of course add yours if you like to share! `Please contact us `_ to have your model added to our list. diff --git a/doc/fileformat/nmodl.rst b/doc/fileformat/nmodl.rst index 73cf686dd8..4787c719f9 100644 --- a/doc/fileformat/nmodl.rst +++ b/doc/fileformat/nmodl.rst @@ -320,6 +320,8 @@ contain full ``segments``). Modelers are encouraged to verify the expected behavior of the reversal potentials of ions as it can lead to vastly different model behavior. +.. _formatnmodl-faster: + Tips for Faster NMODL --------------------- diff --git a/doc/index.rst b/doc/index.rst index d3498687fb..2bdc207244 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -34,10 +34,10 @@ Arbor is open source and openly developed, and we use development practices such Documentation organisation -------------------------- +* :ref:`features-overview` is an index of Arbor's major neuroscientific features and a collection of best practices and experiences collected from the Arbor modelling community, meant to spread information on how to solve common modelling questions in Arbor. * :ref:`tutorial` contains a few ready-made examples you can use to quickly get started using Arbor. In the tutorial descriptions we link to the relevant Arbor concepts. * :ref:`modelintro` describes the design and concepts used in Arbor. The breakdown of concepts is mirrored (as much as possible) in the :ref:`pyoverview` and :ref:`cppoverview`, so you can easily switch between languages and concepts. * The API section details our :ref:`pyoverview` and :ref:`cppoverview` API. The :ref:`dev-overview` describes Arbor code that is not user-facing; convenience classes, architecture abstractions, and other information that is relevant to understanding the inner workings of Arbor and the mathematical foundations underpinning the engine. -* :ref:`modelling-overview` is a collection of best practices and experiences collected from the Arbor modelling community, meant to spread information on how to solve common modelling questions in Arbor. * Contributions to Arbor are very welcome! Under :ref:`contribindex` you'll find the conventions and procedures for all kinds of contributions. Citing Arbor @@ -126,6 +126,7 @@ A full list of our software attributions can be found `here `_. - -Under the `arbor-contrib `_ organisation, some users have already shared their models. You can peruse these at your leisure, and of course add yours if you like to share! `Please contact us `_ to have your model added to our list. diff --git a/doc/python/probe_sample.rst b/doc/python/probe_sample.rst index bc2bd59522..107080af79 100644 --- a/doc/python/probe_sample.rst +++ b/doc/python/probe_sample.rst @@ -134,6 +134,7 @@ The script is complete and can be run with Arbor installed, and will output: * Meta: (location 0 1) * Payload: (10, 2) +.. _pycablecell-probesample-api: API --- @@ -314,6 +315,8 @@ Ionic diffusion concrentration Metadata: the list of corresponding :class:`cable` objects. +.. _pycablecell-probesample-lif: + LIF Cell probing ================ diff --git a/scripts/tsplot b/scripts/tsplot index c64e7b1816..ee0f839cf4 100755 --- a/scripts/tsplot +++ b/scripts/tsplot @@ -11,14 +11,8 @@ import matplotlib as M import matplotlib.pyplot as P import numbers from functools import reduce -from distutils.version import LooseVersion from itertools import chain, islice, cycle -# Run-time check for matplot lib version for line style functionality. -if LooseVersion(M.__version__) Date: Wed, 2 Aug 2023 12:49:11 +0200 Subject: [PATCH 9/9] Break out pip and doc tests, exclude doc-change from eating up precious runner cycles (#2160) - Break out pip and doc tests from `test-everything.yaml` - Only trigger docs build on docs changes, and not trigger code-CI on docs-only changes. - Remove monthly submodule check. This will be handled differently, see #1731 - Enable Pypy wheel builds (they pass testing, see https://github.com/brenthuisman/arbor/actions/runs/5725359772) --- .github/workflows/benchmarks.yml | 1 + .../{release.yml => build-pip-wheels.yml} | 0 .github/workflows/check-submodules.yml | 28 -------- .github/workflows/sanitize.yml | 1 + .github/workflows/test-docs.yaml | 41 +++++++++++ .../{test-everything.yml => test-matrix.yml} | 68 +------------------ .github/workflows/test-pip.yaml | 44 ++++++++++++ .../workflows/{spack.yml => test-spack.yml} | 2 + README.md | 6 +- doc/index.rst | 16 +++-- pyproject.toml | 7 +- 11 files changed, 110 insertions(+), 104 deletions(-) rename .github/workflows/{release.yml => build-pip-wheels.yml} (100%) delete mode 100644 .github/workflows/check-submodules.yml create mode 100644 .github/workflows/test-docs.yaml rename .github/workflows/{test-everything.yml => test-matrix.yml} (75%) create mode 100644 .github/workflows/test-pip.yaml rename .github/workflows/{spack.yml => test-spack.yml} (95%) diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index 084f15fe40..0f2921b72a 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -3,6 +3,7 @@ name: Benchmarks on: pull_request: branches: [ master ] + paths-ignore: 'doc/**' jobs: build: diff --git a/.github/workflows/release.yml b/.github/workflows/build-pip-wheels.yml similarity index 100% rename from .github/workflows/release.yml rename to .github/workflows/build-pip-wheels.yml diff --git a/.github/workflows/check-submodules.yml b/.github/workflows/check-submodules.yml deleted file mode 100644 index 48878c991f..0000000000 --- a/.github/workflows/check-submodules.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: Update submodules - -on: - schedule: - # - cron: '0 2 * * 0' # run at 2 AM every sunday - - cron: '5 4 2 * *' # 04:05 every 2nd of month - push: - branches: [ 'ci/auto-update-submodules' ] - -jobs: - update_submodules: - runs-on: ubuntu-latest - steps: - - name: Clone w/ submodules - uses: actions/checkout@v3 - with: - submodules: recursive - fetch-depth: 0 - - name: Check submodules for updates - run: scripts/submodule-diff.sh - - name: Create Issue From File - uses: peter-evans/create-issue-from-file@v3 - with: - title: '[AUTOMATED] Git submodule updates found' - content-filepath: ./diff.log - labels: | - dependency update - assignees: brenthuisman diff --git a/.github/workflows/sanitize.yml b/.github/workflows/sanitize.yml index 788e5d219a..6762039add 100644 --- a/.github/workflows/sanitize.yml +++ b/.github/workflows/sanitize.yml @@ -3,6 +3,7 @@ name: Sanitize on: pull_request: branches: [ master ] + paths-ignore: 'doc/**' jobs: build: diff --git a/.github/workflows/test-docs.yaml b/.github/workflows/test-docs.yaml new file mode 100644 index 0000000000..7c6918f2fd --- /dev/null +++ b/.github/workflows/test-docs.yaml @@ -0,0 +1,41 @@ +name: Test docs + +on: + push: + branches: [ master ] + paths: 'doc/**' + pull_request: + branches: [ master ] + paths: 'doc/**' + +jobs: + testdocs: + name: "Docs build test" + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-20.04] + python-version: [3.7] + steps: + - name: Set up cmake + uses: jwlawson/actions-setup-cmake@v1.13 + with: + cmake-version: ${{ matrix.config.cmake }} + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: Update pip and setup venv + run: python -m pip install --upgrade pip && python -m venv ~/env && . ~/env/bin/activate && echo "PATH=$PATH" >> $GITHUB_ENV + - name: Clone w/ submodules + uses: actions/checkout@v3 + with: + submodules: recursive + - name: Install Python packages + run: python -m pip install -r doc/requirements.txt -U + - name: Build Arbor Docs + run: | + mkdir build + cd build + cmake .. -DARB_WITH_PYTHON=ON -DPython3_EXECUTABLE=`which python` -DARB_USE_BUNDLED_LIBS=ON + make html diff --git a/.github/workflows/test-everything.yml b/.github/workflows/test-matrix.yml similarity index 75% rename from .github/workflows/test-everything.yml rename to .github/workflows/test-matrix.yml index 2f8a7ce201..c760b4d8c2 100644 --- a/.github/workflows/test-everything.yml +++ b/.github/workflows/test-matrix.yml @@ -1,10 +1,12 @@ -name: Test Everything +name: Test Matrix on: push: branches: [ master ] + paths-ignore: 'doc/**' pull_request: branches: [ master ] + paths-ignore: 'doc/**' jobs: testallconfigs: @@ -191,67 +193,3 @@ jobs: # run: scripts/run_python_examples.sh - name: Test executables run: ./scripts/test_executables.sh - testpip: - name: "Pip build test + Python examples test" - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-20.04] - python-version: [3.7] - steps: - - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python-version }} - - name: Clone w/ submodules - uses: actions/checkout@v3 - with: - submodules: recursive - - name: Update pip and setup venv - run: python -m pip install --upgrade pip && python -m venv ~/env && . ~/env/bin/activate && echo PATH=$PATH >> $GITHUB_ENV - - name: Debug info Python - run: | - which python - python --version - pip --version - - name: Build and install Arbor using pip + build flags - run: CMAKE_ARGS="-DARB_VECTORIZE=ON -DARB_ARCH=native" pip install . --user - - name: Check that build flags match - run: | - python -c "import arbor; print(arbor.config())" | grep -q "'arch': 'native'" - - name: Run Python tests - run: python -m unittest discover -v -s python - - name: Run Python examples - run: scripts/run_python_examples.sh - - name: Test executables - run: scripts/test_executables.sh - testdocs: - name: "Docs build test" - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-20.04] - python-version: [3.7] - steps: - - name: Set up cmake - uses: jwlawson/actions-setup-cmake@v1.13 - with: - cmake-version: ${{ matrix.config.cmake }} - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python-version }} - - name: Update pip and setup venv - run: python -m pip install --upgrade pip && python -m venv ~/env && . ~/env/bin/activate && echo "PATH=$PATH" >> $GITHUB_ENV - - name: Clone w/ submodules - uses: actions/checkout@v3 - with: - submodules: recursive - - name: Install Python packages - run: python -m pip install -r doc/requirements.txt -U - - name: Build Arbor Docs - run: | - mkdir build - cd build - cmake .. -DARB_WITH_PYTHON=ON -DPython3_EXECUTABLE=`which python` -DARB_USE_BUNDLED_LIBS=ON - make html - diff --git a/.github/workflows/test-pip.yaml b/.github/workflows/test-pip.yaml new file mode 100644 index 0000000000..f65f1ca08d --- /dev/null +++ b/.github/workflows/test-pip.yaml @@ -0,0 +1,44 @@ +name: Test pip + +on: + push: + branches: [ master ] + paths-ignore: 'doc/**' + pull_request: + branches: [ master ] + paths-ignore: 'doc/**' + +jobs: + testpip: + name: "Pip build test + Python examples test" + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-20.04] + python-version: [3.7] + steps: + - uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: Clone w/ submodules + uses: actions/checkout@v3 + with: + submodules: recursive + - name: Update pip and setup venv + run: python -m pip install --upgrade pip && python -m venv ~/env && . ~/env/bin/activate && echo PATH=$PATH >> $GITHUB_ENV + - name: Debug info Python + run: | + which python + python --version + pip --version + - name: Build and install Arbor using pip + build flags + run: CMAKE_ARGS="-DARB_VECTORIZE=ON -DARB_ARCH=native" pip install . --user + - name: Check that build flags match + run: | + python -c "import arbor; print(arbor.config())" | grep -q "'arch': 'native'" + - name: Run Python tests + run: python -m unittest discover -v -s python + - name: Run Python examples + run: scripts/run_python_examples.sh + - name: Test executables + run: scripts/test_executables.sh diff --git a/.github/workflows/spack.yml b/.github/workflows/test-spack.yml similarity index 95% rename from .github/workflows/spack.yml rename to .github/workflows/test-spack.yml index bd5ed162d0..f9978bda1e 100644 --- a/.github/workflows/spack.yml +++ b/.github/workflows/test-spack.yml @@ -3,8 +3,10 @@ name: Spack on: push: branches: [ master ] + paths-ignore: 'doc/**' pull_request: branches: [ master ] + paths-ignore: 'doc/**' jobs: build: diff --git a/README.md b/README.md index fe29e5f908..955b07554a 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ -[![ci](https://github.com/arbor-sim/arbor/actions/workflows/test-everything.yml/badge.svg)](https://github.com/arbor-sim/arbor/actions/workflows/test-everything.yml) -[![pythonwheels](https://github.com/arbor-sim/arbor/actions/workflows/release.yml/badge.svg)](https://github.com/arbor-sim/arbor/actions/workflows/release.yml) +[![ci](https://github.com/arbor-sim/arbor/actions/workflows/test-matrix.yml/badge.svg)](https://github.com/arbor-sim/arbor/actions/workflows/test-matrix.yml) +[![spack](https://github.com/arbor-sim/arbor/actions/workflows/test-spack.yml/badge.svg)](https://github.com/arbor-sim/arbor/actions/workflows/test-spack.yml) +[![pip](https://github.com/arbor-sim/arbor/actions/workflows/test-pip.yml/badge.svg)](https://github.com/arbor-sim/arbor/actions/workflows/test-pip.yml) +[![pythonwheels](https://github.com/arbor-sim/arbor/actions/workflows/build-pip-wheels.yml/badge.svg)](https://github.com/arbor-sim/arbor/actions/workflows/build-pip-wheels.yml) [![gitpod](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/arbor-sim/arbor) [![docs](https://readthedocs.org/projects/arbor/badge/?version=latest)](https://docs.arbor-sim.org/en/latest/) [![gitter](https://badges.gitter.im/arbor-sim/community.svg)](https://gitter.im/arbor-sim/community) diff --git a/doc/index.rst b/doc/index.rst index 2bdc207244..f1032a29e8 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -1,13 +1,19 @@ Arbor ===== -|ci| |pythonwheels| |zlatest| |gitter| |matrix| +|ci| |spack| |pip| |pythonwheels| |zlatest| |gitter| |matrix| -.. |ci| image:: https://github.com/arbor-sim/arbor/actions/workflows/test-everything.yml/badge.svg - :target: https://github.com/arbor-sim/arbor/actions/workflows/test-everything.yml +.. |ci| image:: https://github.com/arbor-sim/arbor/actions/workflows/test-matrix.yml/badge.svg + :target: https://github.com/arbor-sim/arbor/actions/workflows/test-matrix.yml -.. |pythonwheels| image:: https://github.com/arbor-sim/arbor/actions/workflows/release.yml/badge.svg - :target: https://github.com/arbor-sim/arbor/actions/workflows/release.yml +.. |spack| image:: https://github.com/arbor-sim/arbor/actions/workflows/test-spack.yml/badge.svg + :target: https://github.com/arbor-sim/arbor/actions/workflows/test-spack.yml + +.. |pip| image:: https://github.com/arbor-sim/arbor/actions/workflows/test-pip.yml/badge.svg + :target: https://github.com/arbor-sim/arbor/actions/workflows/test-pip.yml + +.. |pythonwheels| image:: https://github.com/arbor-sim/arbor/actions/workflows/build-pip-wheels.yml/badge.svg + :target: https://github.com/arbor-sim/arbor/actions/workflows/build-pip-wheels.yml .. |gitter| image:: https://badges.gitter.im/arbor-sim/community.svg :target: https://gitter.im/arbor-sim/community diff --git a/pyproject.toml b/pyproject.toml index 7de88c9d18..a98bf0db40 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -61,11 +61,10 @@ build-backend = "scikit_build_core.build" [tool.cibuildwheel] build-frontend = "build" -build = ["cp3*-*linux*","cp3*-macosx*"] -skip = ["cp36*", "pp*", "*musllinux*"] +build = ["*linux*","*macosx*"] +skip = ["cp36*", "*musllinux*"] test-command = "python -m unittest discover -v -s {project}/python" -before-build = "python -m pip install pip --upgrade" -before-test = "python -m pip install pip --upgrade" +dependency-versions = "latest" [tool.cibuildwheel.macos] archs = ["universal2"]