Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make arbor-build-catalogue part of pyarb. #2416

Closed
Closed
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
2 changes: 0 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -269,9 +269,7 @@ add_library(arborio-public-deps INTERFACE)
install(TARGETS arborio-public-deps EXPORT arborio-targets)

# Add scripts and supporting CMake for setting up external catalogues

install(PROGRAMS scripts/arbor-build-catalogue DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES mechanisms/BuildModules.cmake DESTINATION ${ARB_INSTALL_DATADIR})

# Add all dependencies.

Expand Down
6 changes: 1 addition & 5 deletions arbor/include/arbor/util/expected.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -484,13 +484,9 @@ struct expected<void, E> {
// No emplace ops.

// Swap ops.

void swap(expected& other) {
data_.swap(other.data);
}
void swap(expected& other) { data_.swap(other.data_); }

// Accessors.

bool has_value() const noexcept { return !data_; }
explicit operator bool() const noexcept { return has_value(); }

Expand Down
13 changes: 3 additions & 10 deletions arbor/profile/profiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,23 +144,16 @@ const std::vector<profile_accumulator>& recorder::accumulators() const {
}

void recorder::enter(region_id_type index) {
if (index_!=npos) {
throw std::runtime_error("recorder::enter without matching recorder::leave");
}
if (index>=accumulators_.size()) {
accumulators_.resize(index+1);
}
if (index_!=npos) throw std::runtime_error("recorder::enter without matching recorder::leave.");
if (index>=accumulators_.size()) accumulators_.resize(index+1);
index_ = index;
start_time_ = timer::tic();
}

void recorder::leave() {
// calculate the elapsed time before any other steps, to increase accuracy.
auto delta = timer::toc(start_time_);

if (index_==npos) {
throw std::runtime_error("recorder::leave without matching recorder::enter");
}
if (index_==npos) throw std::runtime_error("recorder::leave without matching recorder::enter.");
accumulators_[index_].count++;
accumulators_[index_].time += delta;
index_ = npos;
Expand Down
61 changes: 59 additions & 2 deletions doc/contrib/test.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,65 @@ Tests
=====

C++ tests are located in ``/tests`` and Python (binding) tests in
``/python/test``. See the documentation on :ref:`building <building>` for the
C++ tests and ``/python/test/readme.md`` for the latter.
``/python/test``. See also the documentation on :ref:`building <building>` for
the C++ tests and ``/python/test/readme.md`` for the latter.

Building and Running Tests
--------------------------

The C++ tests need to be built using the usual proecdure via CMake + Ninja.
It is usually advisable to enable assertions for debugging.

.. code-block:: sh

# more arguments omitted
cmake .. -DCMAKE_BUILD_TYPE=debug -DARB_WITH_ASSERTIONS=ON [..]
ninja tests

This will produce three binaries

- ``bin/unit`` basic unit tests for Arbor.
- ``bin/unit-modcc`` unit tests for Arbor's NMODL compiler
- ``bin/unit-mpi`` unit tests for Arbor's MPI funcionality. Only produced if MPI
enabled.
- ``bin/unit-local`` local (i.e. without MPI) version of ``unit-mpi``.

All accept some arguments determined by the testing framework, among others
filters to include/exclude tests, try ``bin/unit --help`` for more information.
Some tests might be skipped if GPU-support is not enabled. Building with GPU and
failing to locate a GPU will register as failures. Except ``unit-mpi`` each
testsuite can be run like a normal executable; for MPI tests use

.. code-block:: sh

mpirun -n 2 bin/unit-mpi

If you are working on the MPI parts of Arbor, don't forget to try different
process counts.

There also is a collection of micro benchmarks; build these with ``ninja
ubenches``. Each benchmark will result in a separate executable which measures
the performance of a critical building block of Arbor.

For Python, two more testsuites are provided in ``python/test``. During
development these can be run like this

.. code-block:: sh

# Assuming we have built Arbor in ~/src/arbor/build
# and Arbor was cloned into ~/src/arbor
PYTHONPATH=$HOME/src/arbor/build/python python3 -munittest discover -v -s $HOME/src/arbor/python/

This will use Arbor's Python module without installing. If you did install Arbor
beforehand

.. code-block:: sh

# Assuming Arbor was cloned into ~/src/arbor
python3 -munittest discover -v -s $HOME/src/arbor/python/

is sufficient. However, this requires an install step after each change in
Arbor.

What to test?
-------------
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ dependencies = [
]

[project.scripts]
modcc = "arbor:modcc"
arbor-build-catalogue = "arbor:build_catalogue"
modcc = "arbor.modcc:cli"
arbor-build-catalogue = "arbor.build_catalogue:cli"

[tool.scikit-build]
cmake.args = [
Expand Down
22 changes: 20 additions & 2 deletions python/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,19 @@ set_target_properties(pyarb PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${python_mod_pa
file(COPY "${PROJECT_SOURCE_DIR}/python/__init__.py" DESTINATION "${python_mod_path}")
file(COPY "${PROJECT_SOURCE_DIR}/VERSION" DESTINATION "${python_mod_path}")

configure_file("${PROJECT_SOURCE_DIR}/scripts/arbor-build-catalogue"
"${CMAKE_BINARY_DIR}/bin/arbor-build-catalogue"
FILE_PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE WORLD_READ WORLD_EXECUTE GROUP_READ GROUP_EXECUTE
COPYONLY)
configure_file("${PROJECT_SOURCE_DIR}/scripts/arbor-build-catalogue"
"${python_mod_path}/build_catalogue.py"
NO_SOURCE_PERMISSIONS
COPYONLY)
configure_file("${PROJECT_SOURCE_DIR}/python/modcc.py"
"${python_mod_path}/modcc.py"
NO_SOURCE_PERMISSIONS
COPYONLY)

# Set the installation path

# Ask Python where it keeps its system (platform) packages.
Expand All @@ -106,7 +119,7 @@ mark_as_advanced(FORCE ARB_PYTHON_LIB_PATH)
if(ARB_BUILD_PYTHON_STUBS)
find_python_module(pybind11_stubgen REQUIRED)
else()
find_python_module(pybind11_stubgen)
find_python_module(pybind11_stubgen)
endif()
if(HAVE_PYBIND11_STUBGEN)
add_custom_command(TARGET pyarb POST_BUILD
Expand All @@ -117,7 +130,8 @@ if(HAVE_PYBIND11_STUBGEN)
COMMENT "Generating type stubs")
endif()

if(DEFINED SKBUILD_PROJECT_NAME)
if(DEFINED
SKBUILD_PROJECT_NAME)
# Building wheel through scikit-build-core
set(_python_module_install_path .)
else()
Expand All @@ -129,4 +143,8 @@ if(HAVE_PYBIND11_STUBGEN)
install(DIRECTORY ${CMAKE_BINARY_DIR}/stubs/arbor/ DESTINATION ${_python_module_install_path})
endif()
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/__init__.py DESTINATION ${_python_module_install_path})
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/modcc.py DESTINATION ${_python_module_install_path})
install(FILES ${PROJECT_SOURCE_DIR}/scripts/arbor-build-catalogue
DESTINATION ${_python_module_install_path}
RENAME build_catalogue.py)
install(FILES ${PROJECT_SOURCE_DIR}/VERSION ${PROJECT_SOURCE_DIR}/README.md ${PROJECT_SOURCE_DIR}/LICENSE DESTINATION ${_python_module_install_path})
27 changes: 0 additions & 27 deletions python/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,33 +16,6 @@ def get_version():
return version_file.read().strip()


def modcc():
import os
import sys
import subprocess

sys.exit(
subprocess.call(
[os.path.join(os.path.dirname(__file__), "bin", "modcc"), *sys.argv[1:]]
)
)


def build_catalogue():
import os
import sys
import subprocess

sys.exit(
subprocess.call(
[
os.path.join(os.path.dirname(__file__), "bin", "arbor-build-catalogue"),
*sys.argv[1:],
]
)
)


__version__ = get_version()
__config__ = config() # noqa:F405

Expand Down
11 changes: 11 additions & 0 deletions python/modcc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# NOTE this is a placeholder until we make pybind11 bindings for modcc
def cli():
import os
import sys
import subprocess

sys.exit(
subprocess.call(
[os.path.join(os.path.dirname(__file__), "bin", "modcc"), *sys.argv[1:]]
)
)
2 changes: 1 addition & 1 deletion python/strprintf.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ namespace impl {
for (auto& x: s.seq_) {
if (!first) o << s.sep_;
first = false;
o << s.f(x);
o << s.f_(x);
}
return o;
}
Expand Down
14 changes: 10 additions & 4 deletions python/test/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import subprocess
import atexit
import inspect
from unittest import SkipTest

_mpi_enabled = A.__config__["mpi"]
_mpi4py_enabled = A.__config__["mpi4py"]
Expand Down Expand Up @@ -155,7 +156,6 @@ def _build_cat(name, path, context):
"Building catalogue in an MPI context, but `mpi4py` not found."
" Concurrent identical catalogue builds might occur."
) from None

_build_cat_distributed(comm, name, path)
else:
_build_cat_local(name, path)
Expand All @@ -169,9 +169,15 @@ def dummy_catalogue(repo_path):
Fixture that returns a dummy `A.catalogue`
which contains the `dummy` mech.
"""
path = repo_path / "test" / "unit" / "dummy"
cat_path = _build_cat("dummy", path)
return A.load_catalogue(str(cat_path))
try:
path = repo_path / "test" / "unit" / "dummy"
cat_path = _build_cat("dummy", path)
cat = A.load_catalogue(str(cat_path))
except Exception:
raise SkipTest(
"Couldn't build catalogue, maybe need to install Arbor first?"
) from None
return cat


@_fixture
Expand Down
Loading
Loading