diff --git a/.github/workflows/test-everything.yml b/.github/workflows/test-everything.yml index 2f51916e2ef07e3773bc93247b04588523b3f866..3a829fa6974395922f91756302b58f85fc35eb98 100644 --- a/.github/workflows/test-everything.yml +++ b/.github/workflows/test-everything.yml @@ -83,6 +83,7 @@ jobs: mpi: "ON", simd: "OFF" } + variant: [static, shared] env: CC: ${{ matrix.config.cc }} CXX: ${{ matrix.config.cxx }} @@ -149,13 +150,22 @@ jobs: mpic++ --show mpicc --show echo $PYTHONPATH - - name: Build arbor + - if: ${{ matrix.variant == 'static' }} + name: Build arbor run: | mkdir build cd build cmake .. -DCMAKE_CXX_COMPILER=$CXX -DCMAKE_C_COMPILER=$CC -DARB_WITH_PYTHON=ON -DARB_VECTORIZE=${{ matrix.config.simd }} -DPython3_EXECUTABLE=`which python` -DARB_WITH_MPI=${{ matrix.config.mpi }} -DARB_USE_BUNDLED_LIBS=ON -DARB_WITH_NEUROML=ON make -j4 tests examples pyarb html cd - + - if: ${{ matrix.variant == 'shared' }} + name: Build arbor + run: | + mkdir build + cd build + cmake .. -DCMAKE_CXX_COMPILER=$CXX -DCMAKE_C_COMPILER=$CC -DARB_WITH_PYTHON=ON -DARB_VECTORIZE=${{ matrix.config.simd }} -DPython3_EXECUTABLE=`which python` -DARB_WITH_MPI=${{ matrix.config.mpi }} -DARB_USE_BUNDLED_LIBS=ON -DARB_WITH_NEUROML=ON -DBUILD_SHARED_LIBS=ON + make -j4 tests examples pyarb html + cd - - name: Install arbor run: | cd build diff --git a/.gitignore b/.gitignore index ee3b410fd70106ea214de3851302036bda6cda97..036ba49182d024c4de5daf45f4026bf7184de43d 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ __pycache__ *.swq *.swm *.swl +*~ .cache diff --git a/CMakeLists.txt b/CMakeLists.txt index d1a95db559e5f07afe811f3653df7f66c8d4a7ce..04a6c9b57c10cc3431a8ba583281f1b7ffd2820a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -172,8 +172,11 @@ set(CMAKE_CXX_EXTENSIONS OFF) # Data and internal scripts go here set(ARB_INSTALL_DATADIR ${CMAKE_INSTALL_FULL_DATAROOTDIR}/arbor) # Derived paths for arbor-build-catalogue -file(RELATIVE_PATH ARB_REL_DATADIR ${CMAKE_INSTALL_FULL_BINDIR} ${CMAKE_INSTALL_FULL_DATAROOTDIR}/arbor) -file(RELATIVE_PATH ARB_REL_PACKAGEDIR ${CMAKE_INSTALL_FULL_BINDIR} ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/arbor) +get_filename_component(absolute_full_bindir ${CMAKE_INSTALL_FULL_BINDIR} REALPATH) +get_filename_component(absolute_full_datarootdir ${CMAKE_INSTALL_FULL_DATAROOTDIR} REALPATH) +get_filename_component(absolute_full_libdir ${CMAKE_INSTALL_FULL_LIBDIR} REALPATH) +file(RELATIVE_PATH ARB_REL_DATADIR ${absolute_full_bindir} ${absolute_full_datarootdir}/arbor) +file(RELATIVE_PATH ARB_REL_PACKAGEDIR ${absolute_full_bindir} ${absolute_full_libdir}/cmake/arbor) # Interface library `arbor-config-defs` collects configure-time defines # for arbor, arborenv, arborio, of the form ARB_HAVE_XXX. These diff --git a/arbor/CMakeLists.txt b/arbor/CMakeLists.txt index db81edbbd89510d908d677f7dbc5f4b6843a5b8f..7a1fb7a4fda8a9d9c22f55f24d5e5b0550047147 100644 --- a/arbor/CMakeLists.txt +++ b/arbor/CMakeLists.txt @@ -136,5 +136,10 @@ endif() set_target_properties(arbor PROPERTIES CUDA_RESOLVE_DEVICE_SYMBOLS ON) +export_visibility(arbor) + +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/arbor/export.hpp + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/arbor) + install(TARGETS arbor EXPORT arbor-targets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/arbor/assert.cpp b/arbor/assert.cpp index b17fa3251e1cbc423bf27aecbcd4639a184dc7c5..4205f641132add2c4e5b65e142dbc26d28012323 100644 --- a/arbor/assert.cpp +++ b/arbor/assert.cpp @@ -6,7 +6,7 @@ namespace arb { -void abort_on_failed_assertion( +void ARB_ARBOR_API abort_on_failed_assertion( const char* assertion, const char* file, int line, @@ -22,7 +22,7 @@ void abort_on_failed_assertion( std::abort(); } -void ignore_failed_assertion( +void ARB_ARBOR_API ignore_failed_assertion( const char* assertion, const char* file, int line, diff --git a/arbor/backends/gpu/forest.hpp b/arbor/backends/gpu/forest.hpp index 1bc13bc858151a904b7b2c65ca5b1b55ff0343fe..7fc8be0cf94ea51b5044fedcdfe03aa91269cb46 100644 --- a/arbor/backends/gpu/forest.hpp +++ b/arbor/backends/gpu/forest.hpp @@ -2,6 +2,7 @@ #include <vector> +#include <arbor/export.hpp> #include "tree.hpp" namespace arb { @@ -9,7 +10,7 @@ namespace gpu { using size_type = int; -struct forest { +struct ARB_ARBOR_API forest { forest(const std::vector<size_type>& p, const std::vector<size_type>& cell_cv_divs); void optimize(); diff --git a/arbor/backends/gpu/matrix_assemble.cu b/arbor/backends/gpu/matrix_assemble.cu index 0f99eec5334cf05395c5e9bca07aa087ac18fd84..e1c385e4af930483bee6c0a9a9ad332192042334 100644 --- a/arbor/backends/gpu/matrix_assemble.cu +++ b/arbor/backends/gpu/matrix_assemble.cu @@ -154,7 +154,7 @@ void assemble_matrix_interleaved( } // namespace kernels -void assemble_matrix_flat( +ARB_ARBOR_API void assemble_matrix_flat( fvm_value_type* d, fvm_value_type* rhs, const fvm_value_type* invariant_d, diff --git a/arbor/backends/gpu/matrix_fine.cu b/arbor/backends/gpu/matrix_fine.cu index ca3592f15fd624a0678c56ffb358bd685af9bd38..675f6312c57977dde53594b591530872053eaf0c 100644 --- a/arbor/backends/gpu/matrix_fine.cu +++ b/arbor/backends/gpu/matrix_fine.cu @@ -245,7 +245,7 @@ void solve_matrix_fine( } // namespace kernels -void gather( +ARB_ARBOR_API void gather( const fvm_value_type* from, fvm_value_type* to, const fvm_index_type* p, @@ -257,7 +257,7 @@ void gather( kernels::gather<<<griddim, blockdim>>>(from, to, p, n); } -void scatter( +ARB_ARBOR_API void scatter( const fvm_value_type* from, fvm_value_type* to, const fvm_index_type* p, @@ -269,7 +269,7 @@ void scatter( kernels::scatter<<<griddim, blockdim>>>(from, to, p, n); } -void assemble_matrix_fine( +ARB_ARBOR_API void assemble_matrix_fine( fvm_value_type* d, fvm_value_type* rhs, const fvm_value_type* invariant_d, @@ -308,7 +308,7 @@ void assemble_matrix_fine( // num_levels = [3, 2, 3, ...] // num_cells = [2, 3, ...] // num_blocks = level_start.size() - 1 = num_levels.size() = num_cells.size() -void solve_matrix_fine( +ARB_ARBOR_API void solve_matrix_fine( fvm_value_type* rhs, fvm_value_type* d, // diagonal values const fvm_value_type* u, // upper diagonal (and lower diagonal as the matrix is SPD) diff --git a/arbor/backends/gpu/matrix_fine.hpp b/arbor/backends/gpu/matrix_fine.hpp index 74b34906632a5047c6b4fe26b180166fd7895460..02c549039a591d2492202ce42cce702b25431ae7 100644 --- a/arbor/backends/gpu/matrix_fine.hpp +++ b/arbor/backends/gpu/matrix_fine.hpp @@ -1,5 +1,6 @@ #include <arbor/fvm_types.hpp> +#include <arbor/export.hpp> #include <ostream> namespace arb { @@ -13,19 +14,19 @@ struct level_metadata { }; // C wrappers around kernels -void gather( +ARB_ARBOR_API void gather( const fvm_value_type* from, fvm_value_type* to, const fvm_index_type* p, unsigned n); -void scatter( +ARB_ARBOR_API void scatter( const fvm_value_type* from, fvm_value_type* to, const fvm_index_type* p, unsigned n); -void assemble_matrix_fine( +ARB_ARBOR_API void assemble_matrix_fine( fvm_value_type* d, fvm_value_type* rhs, const fvm_value_type* invariant_d, @@ -39,7 +40,7 @@ void assemble_matrix_fine( const fvm_index_type* perm, unsigned n); -void solve_matrix_fine( +ARB_ARBOR_API void solve_matrix_fine( fvm_value_type* rhs, fvm_value_type* d, // diagonal values const fvm_value_type* u, // upper diagonal (and lower diagonal as the matrix is SPD) diff --git a/arbor/backends/gpu/matrix_solve.cu b/arbor/backends/gpu/matrix_solve.cu index 576f88e96f10b19bbe70ea61ec6fc1adfa6012bb..6a0a383ce0ab6791470a8da07935b86de40e1327 100644 --- a/arbor/backends/gpu/matrix_solve.cu +++ b/arbor/backends/gpu/matrix_solve.cu @@ -86,7 +86,7 @@ void solve_matrix_interleaved( } // namespace kernels -void solve_matrix_flat( +ARB_ARBOR_API void solve_matrix_flat( fvm_value_type* rhs, fvm_value_type* d, const fvm_value_type* u, diff --git a/arbor/backends/gpu/matrix_state_flat.hpp b/arbor/backends/gpu/matrix_state_flat.hpp index c5a6d98c6920b1165995682cb96aaa79b8ccb2d8..bc50b7fce3ea10aa7c8a1bccf319c58e4b42f3f1 100644 --- a/arbor/backends/gpu/matrix_state_flat.hpp +++ b/arbor/backends/gpu/matrix_state_flat.hpp @@ -1,5 +1,6 @@ #pragma once +#include <arbor/export.hpp> #include <arbor/fvm_types.hpp> #include "memory/memory.hpp" @@ -13,7 +14,7 @@ namespace gpu { // CUDA implementation entry points: -void solve_matrix_flat( +ARB_ARBOR_API void solve_matrix_flat( fvm_value_type* rhs, fvm_value_type* d, const fvm_value_type* u, @@ -21,7 +22,7 @@ void solve_matrix_flat( const fvm_index_type* cell_cv_divs, int num_mtx); -void assemble_matrix_flat( +ARB_ARBOR_API void assemble_matrix_flat( fvm_value_type* d, fvm_value_type* rhs, const fvm_value_type* invariant_d, diff --git a/arbor/backends/gpu/multi_event_stream.hpp b/arbor/backends/gpu/multi_event_stream.hpp index 929c325d0938859e786ec192e46d32b79d02ef30..83681db9fa41b920a488bea1b06a56e6e8d975b8 100644 --- a/arbor/backends/gpu/multi_event_stream.hpp +++ b/arbor/backends/gpu/multi_event_stream.hpp @@ -2,6 +2,7 @@ // Indexed collection of pop-only event queues --- CUDA back-end implementation. +#include <arbor/export.hpp> #include <arbor/arbexcept.hpp> #include <arbor/common_types.hpp> #include <arbor/fvm_types.hpp> @@ -18,7 +19,7 @@ namespace arb { namespace gpu { // Base class provides common implementations across event types. -class multi_event_stream_base { +class ARB_ARBOR_API multi_event_stream_base { public: using size_type = cell_size_type; using value_type = fvm_value_type; diff --git a/arbor/backends/gpu/shared_state.cpp b/arbor/backends/gpu/shared_state.cpp index 44acd5e474cc27277022ee60a52424494a9a6e0f..bed738bc86b5d74e45105a932147621477d79ff7 100644 --- a/arbor/backends/gpu/shared_state.cpp +++ b/arbor/backends/gpu/shared_state.cpp @@ -459,7 +459,7 @@ void shared_state::take_samples(const sample_event_stream::state& s, array& samp } // Debug interface -std::ostream& operator<<(std::ostream& o, shared_state& s) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, shared_state& s) { o << " cv_to_intdom " << s.cv_to_intdom << "\n"; o << " time " << s.time << "\n"; o << " time_to " << s.time_to << "\n"; diff --git a/arbor/backends/gpu/shared_state.hpp b/arbor/backends/gpu/shared_state.hpp index eb3301abcd8f2d6bd1456d8d04290209f07cc4e6..e0cacfc78d95acf1bf62d81d9d9cc01cf16d07a0 100644 --- a/arbor/backends/gpu/shared_state.hpp +++ b/arbor/backends/gpu/shared_state.hpp @@ -28,7 +28,7 @@ namespace gpu { * Xo_ cao external calcium concentration */ -struct ion_state { +struct ARB_ARBOR_API ion_state { iarray node_index_; // Instance to CV map. array iX_; // (A/m²) current density array eX_; // (mV) reversal potential @@ -62,7 +62,7 @@ struct ion_state { void reset(); }; -struct istim_state { +struct ARB_ARBOR_API istim_state { // Immutable data (post construction/initialization): iarray accu_index_; // Instance to accumulator index (accu_stim_ index) map. iarray accu_to_cv_; // Accumulator index to CV map. @@ -99,7 +99,7 @@ struct istim_state { istim_state() = default; }; -struct shared_state { +struct ARB_ARBOR_API shared_state { struct mech_storage { array data_; iarray indices_; @@ -202,7 +202,7 @@ struct shared_state { }; // For debugging only -std::ostream& operator<<(std::ostream& o, shared_state& s); +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, shared_state& s); } // namespace gpu } // namespace arb diff --git a/arbor/backends/gpu/stimulus.cu b/arbor/backends/gpu/stimulus.cu index ea7262958900575612a20783087b2c189a339f25..f6aa6036003110e133f091e679a774c0b0d7a43b 100644 --- a/arbor/backends/gpu/stimulus.cu +++ b/arbor/backends/gpu/stimulus.cu @@ -52,7 +52,7 @@ void istim_add_current_impl(int n, istim_pp pp) { } // namespace kernel -void istim_add_current_impl(int n, const istim_pp& pp) { +ARB_ARBOR_API void istim_add_current_impl(int n, const istim_pp& pp) { constexpr unsigned block_dim = 128; const unsigned grid_dim = impl::block_count(n, block_dim); if (!grid_dim) return; diff --git a/arbor/backends/gpu/stimulus.hpp b/arbor/backends/gpu/stimulus.hpp index 97447f6edef653aa3fa716694a62e0ac7eaa6238..736c0a160748ddf2bc2cbcc4ecc54366c7c2329f 100644 --- a/arbor/backends/gpu/stimulus.hpp +++ b/arbor/backends/gpu/stimulus.hpp @@ -1,5 +1,6 @@ #pragma once +#include <arbor/export.hpp> #include <arbor/fvm_types.hpp> namespace arb { @@ -25,7 +26,7 @@ struct istim_pp { fvm_value_type* current_density; }; -void istim_add_current_impl(int n, const istim_pp& pp); +ARB_ARBOR_API void istim_add_current_impl(int n, const istim_pp& pp); } // namespace gpu } // namespace arb diff --git a/arbor/backends/multicore/shared_state.cpp b/arbor/backends/multicore/shared_state.cpp index b282186f16657b9ded74a292f6f546e19312a33a..538f7718d56db69592d5dc0bd76b86b42a7f12e6 100644 --- a/arbor/backends/multicore/shared_state.cpp +++ b/arbor/backends/multicore/shared_state.cpp @@ -347,7 +347,7 @@ void shared_state::take_samples( } // (Debug interface only.) -std::ostream& operator<<(std::ostream& out, const shared_state& s) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& out, const shared_state& s) { using io::csv; out << "n_intdom " << s.n_intdom << "\n"; diff --git a/arbor/backends/multicore/shared_state.hpp b/arbor/backends/multicore/shared_state.hpp index 4d12e0f414d5be33dec4bd26d3a2687a633aa763..ab9fa7f5342bd463b5ec015dc695b73f641f4aab 100644 --- a/arbor/backends/multicore/shared_state.hpp +++ b/arbor/backends/multicore/shared_state.hpp @@ -7,6 +7,7 @@ #include <utility> #include <vector> +#include <arbor/export.hpp> #include <arbor/assert.hpp> #include <arbor/common_types.hpp> #include <arbor/fvm_types.hpp> @@ -38,7 +39,7 @@ namespace multicore { * Xo_ cao external calcium concentration */ -struct ion_state { +struct ARB_ARBOR_API ion_state { unsigned alignment = 1; // Alignment and padding multiple. iarray node_index_; // Instance to CV map. @@ -73,7 +74,7 @@ struct ion_state { void reset(); }; -struct istim_state { +struct ARB_ARBOR_API istim_state { unsigned alignment = 1; // Alignment and padding multiple. // Immutable data (post initialization): @@ -105,7 +106,7 @@ struct istim_state { istim_state() = default; }; -struct shared_state { +struct ARB_ARBOR_API shared_state { struct mech_storage { array data_; iarray indices_; @@ -207,7 +208,7 @@ struct shared_state { }; // For debugging only: -std::ostream& operator<<(std::ostream& o, const shared_state& s); +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const shared_state& s); } // namespace multicore diff --git a/arbor/cable_cell_param.cpp b/arbor/cable_cell_param.cpp index c238a48e57ee927133de5606f07d911614faee4d..36b17d9d70962d8baba60b65c7765f754d67d6f5 100644 --- a/arbor/cable_cell_param.cpp +++ b/arbor/cable_cell_param.cpp @@ -12,7 +12,7 @@ namespace arb { -void check_global_properties(const cable_cell_global_properties& G) { +ARB_ARBOR_API void check_global_properties(const cable_cell_global_properties& G) { auto& param = G.default_parameters; if (!param.init_membrane_potential) { diff --git a/arbor/cell_group_factory.cpp b/arbor/cell_group_factory.cpp index 1351299fc8dfc5d1c3bfe20e0c915081b378dae9..69af0ffdcba1ef98c2ba8f8edd64ce27e2ed7cce 100644 --- a/arbor/cell_group_factory.cpp +++ b/arbor/cell_group_factory.cpp @@ -19,7 +19,7 @@ cell_group_ptr make_cell_group(Args&&... args) { return cell_group_ptr(new Impl(std::forward<Args>(args)...)); } -cell_group_factory cell_kind_implementation( +ARB_ARBOR_API cell_group_factory cell_kind_implementation( cell_kind ck, backend_kind bk, const execution_context& ctx) { using gid_vector = std::vector<cell_gid_type>; diff --git a/arbor/cell_group_factory.hpp b/arbor/cell_group_factory.hpp index 7723d822b4af4f8978af8f4d4737deb3da40b720..b8a321c423c53891673bd7900c47bc8702e00761 100644 --- a/arbor/cell_group_factory.hpp +++ b/arbor/cell_group_factory.hpp @@ -10,6 +10,7 @@ #include <vector> #include <arbor/common_types.hpp> +#include <arbor/export.hpp> #include <arbor/recipe.hpp> #include "cell_group.hpp" @@ -20,7 +21,7 @@ namespace arb { using cell_group_factory = std::function< cell_group_ptr(const std::vector<cell_gid_type>&, const recipe&, cell_label_range& cg_sources, cell_label_range& cg_targets)>; -cell_group_factory cell_kind_implementation( +ARB_ARBOR_API cell_group_factory cell_kind_implementation( cell_kind, backend_kind, const execution_context&); inline bool cell_kind_supported( diff --git a/arbor/common_types_io.cpp b/arbor/common_types_io.cpp index 366ba114f8ab323ce74e029a12fffa7adb4ac331..81cbc05d35cce691bfdbefd00fe3797a59fd1539 100644 --- a/arbor/common_types_io.cpp +++ b/arbor/common_types_io.cpp @@ -4,7 +4,7 @@ namespace arb { -std::ostream& operator<<(std::ostream& o, lid_selection_policy policy) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, lid_selection_policy policy) { switch (policy) { case lid_selection_policy::round_robin: return o << "round_robin"; @@ -14,11 +14,11 @@ std::ostream& operator<<(std::ostream& o, lid_selection_policy policy) { return o; } -std::ostream& operator<<(std::ostream& o, arb::cell_member_type m) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, arb::cell_member_type m) { return o << m.gid << ':' << m.index; } -std::ostream& operator<<(std::ostream& o, arb::cell_kind k) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, arb::cell_kind k) { o << "cell_kind::"; switch (k) { case arb::cell_kind::spike_source: @@ -33,7 +33,7 @@ std::ostream& operator<<(std::ostream& o, arb::cell_kind k) { return o; } -std::ostream& operator<<(std::ostream& o, arb::backend_kind k) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, arb::backend_kind k) { o << "backend_kind::"; switch (k) { case arb::backend_kind::multicore: diff --git a/arbor/communication/communicator.hpp b/arbor/communication/communicator.hpp index 33e8f2f743971e083c3a9d2f6875121f2e54c093..fa93adfc2fde1a763476588333fb36572700a9c9 100644 --- a/arbor/communication/communicator.hpp +++ b/arbor/communication/communicator.hpp @@ -2,6 +2,7 @@ #include <vector> +#include <arbor/export.hpp> #include <arbor/common_types.hpp> #include <arbor/domain_decomposition.hpp> #include <arbor/recipe.hpp> @@ -25,7 +26,7 @@ namespace arb { // to build the data structures required for efficient spike communication and // event generation. -class communicator { +class ARB_ARBOR_API communicator { public: communicator() {} diff --git a/arbor/communication/dry_run_context.cpp b/arbor/communication/dry_run_context.cpp index e3a12d28c144258d41995446d28dee5a99f4454b..fcfe4f9f568f9a7d52e71e08dff1e2f3b92cb9e6 100644 --- a/arbor/communication/dry_run_context.cpp +++ b/arbor/communication/dry_run_context.cpp @@ -130,7 +130,7 @@ struct dry_run_context_impl { unsigned num_cells_per_tile_; }; -std::shared_ptr<distributed_context> make_dry_run_context(unsigned num_ranks, unsigned num_cells_per_tile) { +ARB_ARBOR_API std::shared_ptr<distributed_context> make_dry_run_context(unsigned num_ranks, unsigned num_cells_per_tile) { return std::make_shared<distributed_context>(dry_run_context_impl(num_ranks, num_cells_per_tile)); } diff --git a/arbor/communication/mpi.cpp b/arbor/communication/mpi.cpp index 92619e050479874b8ef3e85ed5fd408d009f6529..1a8a9111889046138db520a270f0e69d944e899c 100644 --- a/arbor/communication/mpi.cpp +++ b/arbor/communication/mpi.cpp @@ -5,19 +5,19 @@ namespace arb { namespace mpi { -int rank(MPI_Comm comm) { +ARB_ARBOR_API int rank(MPI_Comm comm) { int r; MPI_OR_THROW(MPI_Comm_rank, comm, &r); return r; } -int size(MPI_Comm comm) { +ARB_ARBOR_API int size(MPI_Comm comm) { int s; MPI_OR_THROW(MPI_Comm_size, comm, &s); return s; } -void barrier(MPI_Comm comm) { +ARB_ARBOR_API void barrier(MPI_Comm comm) { MPI_OR_THROW(MPI_Barrier, comm); } diff --git a/arbor/communication/mpi.hpp b/arbor/communication/mpi.hpp index 7a3546ff1fc78ae8d0eed95137d6791ba149ee64..df3eaecb85e0453ed967a38eaf227698cf9998c8 100644 --- a/arbor/communication/mpi.hpp +++ b/arbor/communication/mpi.hpp @@ -7,6 +7,7 @@ #include <mpi.h> +#include <arbor/export.hpp> #include <arbor/assert.hpp> #include <arbor/communication/mpi_error.hpp> @@ -19,9 +20,9 @@ namespace arb { namespace mpi { // prototypes -int rank(MPI_Comm); -int size(MPI_Comm); -void barrier(MPI_Comm); +ARB_ARBOR_API int rank(MPI_Comm); +ARB_ARBOR_API int size(MPI_Comm); +ARB_ARBOR_API void barrier(MPI_Comm); #define MPI_OR_THROW(fn, ...)\ while (int r_ = fn(__VA_ARGS__)) throw mpi_error(r_, #fn) diff --git a/arbor/communication/mpi_error.cpp b/arbor/communication/mpi_error.cpp index de511c216673245531e696b7cf6bf39090f549d1..78ffed257f23efd53efa0eac6c5c2339add0d94d 100644 --- a/arbor/communication/mpi_error.cpp +++ b/arbor/communication/mpi_error.cpp @@ -4,7 +4,7 @@ namespace arb { -const mpi_error_category_impl& mpi_error_category() { +ARB_ARBOR_API const mpi_error_category_impl& mpi_error_category() { static mpi_error_category_impl the_category; return the_category; } diff --git a/arbor/cv_policy.cpp b/arbor/cv_policy.cpp index 11135cf7b16d1f41f7e6d827db61b1f64edbb2fb..b2962c7fa4f51ed0d9503bbf3af8f95b8b6bd18f 100644 --- a/arbor/cv_policy.cpp +++ b/arbor/cv_policy.cpp @@ -44,7 +44,7 @@ struct cv_policy_plus_: cv_policy_base { cv_policy lhs_, rhs_; }; -cv_policy operator+(const cv_policy& lhs, const cv_policy& rhs) { +ARB_ARBOR_API cv_policy operator+(const cv_policy& lhs, const cv_policy& rhs) { return cv_policy_plus_(lhs, rhs); } @@ -70,7 +70,7 @@ struct cv_policy_bar_: cv_policy_base { cv_policy lhs_, rhs_; }; -cv_policy operator|(const cv_policy& lhs, const cv_policy& rhs) { +ARB_ARBOR_API cv_policy operator|(const cv_policy& lhs, const cv_policy& rhs) { return cv_policy_bar_(lhs, rhs); } diff --git a/arbor/distributed_context.hpp b/arbor/distributed_context.hpp index 2cea04e58fcf79c09c2360ba9c0d9310c26c7c2e..58ca11c318e3c754c32e9aacc4aba7949e268484 100644 --- a/arbor/distributed_context.hpp +++ b/arbor/distributed_context.hpp @@ -3,6 +3,7 @@ #include <memory> #include <string> +#include <arbor/export.hpp> #include <arbor/spike.hpp> #include <arbor/util/pp_util.hpp> @@ -236,7 +237,7 @@ distributed_context_handle make_local_context() { return std::make_shared<distributed_context>(); } -distributed_context_handle make_dry_run_context(unsigned num_ranks, unsigned num_cells_per_rank); +ARB_ARBOR_API distributed_context_handle make_dry_run_context(unsigned num_ranks, unsigned num_cells_per_rank); // MPI context creation functions only provided if built with MPI support. template <typename MPICommType> diff --git a/arbor/event_binner.hpp b/arbor/event_binner.hpp index 7d12526457dc0365d57f7a93196a376ca4581938..fbec4cb5c4bb14bbca6ba9851f5e19902dbd1b83 100644 --- a/arbor/event_binner.hpp +++ b/arbor/event_binner.hpp @@ -4,12 +4,13 @@ #include <optional> #include <unordered_map> +#include <arbor/export.hpp> #include <arbor/common_types.hpp> #include <arbor/spike.hpp> namespace arb { -class event_binner { +class ARB_ARBOR_API event_binner { public: event_binner(): policy_(binning_kind::none), bin_interval_(0) {} diff --git a/arbor/execution_context.cpp b/arbor/execution_context.cpp index 3e4cd629c35246d9072e682d56d02b95cb808f4c..0437024b7b759d336a097ed79773570bc9122c69 100644 --- a/arbor/execution_context.cpp +++ b/arbor/execution_context.cpp @@ -25,7 +25,7 @@ execution_context::execution_context(const proc_allocation& resources): : std::make_shared<gpu_context>()) {} -context make_context(const proc_allocation& p) { +ARB_ARBOR_API context make_context(const proc_allocation& p) { return context(new execution_context(p)); } @@ -39,7 +39,7 @@ execution_context::execution_context(const proc_allocation& resources, MPI_Comm {} template <> -context make_context<MPI_Comm>(const proc_allocation& p, MPI_Comm comm) { +ARB_ARBOR_API context make_context<MPI_Comm>(const proc_allocation& p, MPI_Comm comm) { return context(new execution_context(p, comm)); } #endif @@ -54,31 +54,31 @@ execution_context::execution_context( {} template <> -context make_context(const proc_allocation& p, dry_run_info d) { +ARB_ARBOR_API context make_context(const proc_allocation& p, dry_run_info d) { return context(new execution_context(p, d)); } -std::string distribution_type(const context& ctx) { +ARB_ARBOR_API std::string distribution_type(const context& ctx) { return ctx->distributed->name(); } -bool has_gpu(const context& ctx) { +ARB_ARBOR_API bool has_gpu(const context& ctx) { return ctx->gpu->has_gpu(); } -unsigned num_threads(const context& ctx) { +ARB_ARBOR_API unsigned num_threads(const context& ctx) { return ctx->thread_pool->get_num_threads(); } -unsigned num_ranks(const context& ctx) { +ARB_ARBOR_API unsigned num_ranks(const context& ctx) { return ctx->distributed->size(); } -unsigned rank(const context& ctx) { +ARB_ARBOR_API unsigned rank(const context& ctx) { return ctx->distributed->id(); } -bool has_mpi(const context& ctx) { +ARB_ARBOR_API bool has_mpi(const context& ctx) { return ctx->distributed->name() == "MPI"; } diff --git a/arbor/execution_context.hpp b/arbor/execution_context.hpp index 79935f75fae75ecfe7ce5abf3cc55c405707d757..0035e39d69d692aca423092fa4b768e30fe7a236 100644 --- a/arbor/execution_context.hpp +++ b/arbor/execution_context.hpp @@ -2,6 +2,7 @@ #include <memory> +#include <arbor/export.hpp> #include <arbor/context.hpp> #include "distributed_context.hpp" @@ -19,7 +20,7 @@ namespace arb { // execution_context, to hide implementation details of the // container and its constituent contexts from the public API. -struct execution_context { +struct ARB_ARBOR_API execution_context { distributed_context_handle distributed; task_system_handle thread_pool; gpu_context_handle gpu; diff --git a/arbor/fvm_layout.cpp b/arbor/fvm_layout.cpp index f574615c67e2e0f7bb2d5b9e1bccf0383cd284b7..f231defdabf62d9678dba21a9730f34e566fc3f8 100644 --- a/arbor/fvm_layout.cpp +++ b/arbor/fvm_layout.cpp @@ -170,7 +170,7 @@ namespace impl { // Merge CV geometry lists in-place. -cv_geometry& append(cv_geometry& geom, const cv_geometry& right) { +ARB_ARBOR_API cv_geometry& append(cv_geometry& geom, const cv_geometry& right) { using util::append; using impl::tail; using impl::append_offset; @@ -204,7 +204,7 @@ cv_geometry& append(cv_geometry& geom, const cv_geometry& right) { // Combine two fvm_cv_geometry groups in-place. -fvm_cv_discretization& append(fvm_cv_discretization& dczn, const fvm_cv_discretization& right) { +ARB_ARBOR_API fvm_cv_discretization& append(fvm_cv_discretization& dczn, const fvm_cv_discretization& right) { using util::append; append(dczn.geometry, right.geometry); @@ -224,7 +224,7 @@ fvm_cv_discretization& append(fvm_cv_discretization& dczn, const fvm_cv_discreti // FVM discretization // ------------------ -fvm_cv_discretization fvm_cv_discretize(const cable_cell& cell, const cable_cell_parameter_set& global_dflt) { +ARB_ARBOR_API fvm_cv_discretization fvm_cv_discretize(const cable_cell& cell, const cable_cell_parameter_set& global_dflt) { const auto& dflt = cell.default_parameters(); fvm_cv_discretization D; @@ -345,7 +345,7 @@ fvm_cv_discretization fvm_cv_discretize(const cable_cell& cell, const cable_cell return D; } -fvm_cv_discretization fvm_cv_discretize(const std::vector<cable_cell>& cells, +ARB_ARBOR_API fvm_cv_discretization fvm_cv_discretize(const std::vector<cable_cell>& cells, const cable_cell_parameter_set& global_defaults, const arb::execution_context& ctx) { @@ -515,7 +515,7 @@ voltage_reference_pair fvm_voltage_reference_points(const morphology& morph, con // Interpolate membrane voltage from reference points in adjacent CVs. -fvm_voltage_interpolant fvm_interpolate_voltage(const cable_cell& cell, const fvm_cv_discretization& D, fvm_size_type cell_idx, mlocation site) { +ARB_ARBOR_API fvm_voltage_interpolant fvm_interpolate_voltage(const cable_cell& cell, const fvm_cv_discretization& D, fvm_size_type cell_idx, mlocation site) { auto& embedding = cell.embedding(); fvm_voltage_interpolant vi; @@ -556,7 +556,7 @@ fvm_voltage_interpolant fvm_interpolate_voltage(const cable_cell& cell, const fv // Axial current as linear combination of membrane voltages at reference points in adjacent CVs. -fvm_voltage_interpolant fvm_axial_current(const cable_cell& cell, const fvm_cv_discretization& D, fvm_size_type cell_idx, mlocation site) { +ARB_ARBOR_API fvm_voltage_interpolant fvm_axial_current(const cable_cell& cell, const fvm_cv_discretization& D, fvm_size_type cell_idx, mlocation site) { auto& embedding = cell.embedding(); fvm_voltage_interpolant vi; @@ -653,7 +653,7 @@ fvm_mechanism_data& append(fvm_mechanism_data& left, const fvm_mechanism_data& r return left; } -std::unordered_map<cell_member_type, fvm_size_type> fvm_build_gap_junction_cv_map( +ARB_ARBOR_API std::unordered_map<cell_member_type, fvm_size_type> fvm_build_gap_junction_cv_map( const std::vector<cable_cell>& cells, const std::vector<cell_gid_type>& gids, const fvm_cv_discretization& D) @@ -670,7 +670,7 @@ std::unordered_map<cell_member_type, fvm_size_type> fvm_build_gap_junction_cv_ma return gj_cvs; } -std::unordered_map<cell_gid_type, std::vector<fvm_gap_junction>> fvm_resolve_gj_connections( +ARB_ARBOR_API std::unordered_map<cell_gid_type, std::vector<fvm_gap_junction>> fvm_resolve_gj_connections( const std::vector<cell_gid_type>& gids, const cell_label_range& gj_data, const std::unordered_map<cell_member_type, fvm_size_type>& gj_cvs, @@ -705,7 +705,7 @@ fvm_mechanism_data fvm_build_mechanism_data( const fvm_cv_discretization& D, fvm_size_type cell_idx); -fvm_mechanism_data fvm_build_mechanism_data( +ARB_ARBOR_API fvm_mechanism_data fvm_build_mechanism_data( const cable_cell_global_properties& gprop, const std::vector<cable_cell>& cells, const std::vector<cell_gid_type>& gids, diff --git a/arbor/fvm_layout.hpp b/arbor/fvm_layout.hpp index 7d178dc6112fc04df372fbc4669ea791200c37c3..1ebe0827aa4dd06d0e5cfb043055b1a7075abbd4 100644 --- a/arbor/fvm_layout.hpp +++ b/arbor/fvm_layout.hpp @@ -4,6 +4,7 @@ #include <utility> #include <vector> +#include <arbor/export.hpp> #include <arbor/cable_cell.hpp> #include <arbor/mechanism.hpp> #include <arbor/mechinfo.hpp> @@ -55,7 +56,7 @@ namespace cv_prefer { }; } -struct cv_geometry: public cell_cv_data_impl { +struct ARB_ARBOR_API cv_geometry: public cell_cv_data_impl { using base = cell_cv_data_impl; using size_type = fvm_size_type; @@ -119,7 +120,7 @@ struct cv_geometry: public cell_cv_data_impl { // Combine two cv_geometry groups in-place. // (Returns reference to first argument.) -cv_geometry& append(cv_geometry&, const cv_geometry&); +ARB_ARBOR_API cv_geometry& append(cv_geometry&, const cv_geometry&); // Discretization of morphologies and physical properties. Contains cv_geometry // as above. @@ -161,11 +162,11 @@ struct fvm_cv_discretization { // Combine two fvm_cv_geometry groups in-place. // (Returns reference to first argument.) -fvm_cv_discretization& append(fvm_cv_discretization&, const fvm_cv_discretization&); +ARB_ARBOR_API fvm_cv_discretization& append(fvm_cv_discretization&, const fvm_cv_discretization&); // Construct fvm_cv_discretization from one or more cells. -fvm_cv_discretization fvm_cv_discretize(const cable_cell& cell, const cable_cell_parameter_set& global_dflt); -fvm_cv_discretization fvm_cv_discretize(const std::vector<cable_cell>& cells, const cable_cell_parameter_set& global_defaults, const arb::execution_context& ctx={}); +ARB_ARBOR_API fvm_cv_discretization fvm_cv_discretize(const cable_cell& cell, const cable_cell_parameter_set& global_dflt); +ARB_ARBOR_API fvm_cv_discretization fvm_cv_discretize(const std::vector<cable_cell>& cells, const cable_cell_parameter_set& global_defaults, const arb::execution_context& ctx={}); // Interpolant data for voltage, axial current probes. @@ -179,10 +180,10 @@ struct fvm_voltage_interpolant { }; // Interpolated membrane voltage. -fvm_voltage_interpolant fvm_interpolate_voltage(const cable_cell& cell, const fvm_cv_discretization& D, fvm_size_type cell_idx, mlocation site); +ARB_ARBOR_API fvm_voltage_interpolant fvm_interpolate_voltage(const cable_cell& cell, const fvm_cv_discretization& D, fvm_size_type cell_idx, mlocation site); // Axial current as linear combiantion of voltages. -fvm_voltage_interpolant fvm_axial_current(const cable_cell& cell, const fvm_cv_discretization& D, fvm_size_type cell_idx, mlocation site); +ARB_ARBOR_API fvm_voltage_interpolant fvm_axial_current(const cable_cell& cell, const fvm_cv_discretization& D, fvm_size_type cell_idx, mlocation site); // Post-discretization data for point and density mechanism instantiation. @@ -257,13 +258,13 @@ struct fvm_stimulus_config { }; // Maps gj {gid, lid} locations on a cell to their CV indices. -std::unordered_map<cell_member_type, fvm_size_type> fvm_build_gap_junction_cv_map( +ARB_ARBOR_API std::unordered_map<cell_member_type, fvm_size_type> fvm_build_gap_junction_cv_map( const std::vector<cable_cell>& cells, const std::vector<cell_gid_type>& gids, const fvm_cv_discretization& D); // Resolves gj_connections into {gid, lid} pairs, then to CV indices and a weight. -std::unordered_map<cell_gid_type, std::vector<fvm_gap_junction>> fvm_resolve_gj_connections( +ARB_ARBOR_API std::unordered_map<cell_gid_type, std::vector<fvm_gap_junction>> fvm_resolve_gj_connections( const std::vector<cell_gid_type>& gids, const cell_label_range& gj_data, const std::unordered_map<cell_member_type, fvm_size_type>& gj_cv, @@ -289,7 +290,7 @@ struct fvm_mechanism_data { bool post_events = false; }; -fvm_mechanism_data fvm_build_mechanism_data( +ARB_ARBOR_API fvm_mechanism_data fvm_build_mechanism_data( const cable_cell_global_properties& gprop, const std::vector<cable_cell>& cells, const std::vector<cell_gid_type>& gids, diff --git a/arbor/fvm_lowered_cell.hpp b/arbor/fvm_lowered_cell.hpp index 6aec640a426f8a956f1b051a6cf4c2393f7fdf9b..a3bff57d86d425d91ada0a000d26fc3d61f64a7d 100644 --- a/arbor/fvm_lowered_cell.hpp +++ b/arbor/fvm_lowered_cell.hpp @@ -7,6 +7,7 @@ #include <variant> #include <vector> +#include <arbor/export.hpp> #include <arbor/assert.hpp> #include <arbor/common_types.hpp> #include <arbor/cable_cell.hpp> @@ -235,6 +236,6 @@ struct fvm_lowered_cell { using fvm_lowered_cell_ptr = std::unique_ptr<fvm_lowered_cell>; -fvm_lowered_cell_ptr make_fvm_lowered_cell(backend_kind p, const execution_context& ctx); +ARB_ARBOR_API fvm_lowered_cell_ptr make_fvm_lowered_cell(backend_kind p, const execution_context& ctx); } // namespace arb diff --git a/arbor/gpu_context.cpp b/arbor/gpu_context.cpp index 273c00585198604abcdb11538f54ff46f29261d1..baad4acfea3028fc96593d87738cdae4cb65d245 100644 --- a/arbor/gpu_context.cpp +++ b/arbor/gpu_context.cpp @@ -14,7 +14,7 @@ enum gpu_flags { has_atomic_double = 1 }; -gpu_context_handle make_gpu_context(int id) { +ARB_ARBOR_API gpu_context_handle make_gpu_context(int id) { return std::make_shared<gpu_context>(id); } diff --git a/arbor/gpu_context.hpp b/arbor/gpu_context.hpp index d394e4d2066b04d158347a9b39c3ee59b488331a..6d8965558b212ccfae13067f2749eca01ce17d00 100644 --- a/arbor/gpu_context.hpp +++ b/arbor/gpu_context.hpp @@ -3,9 +3,11 @@ #include <cstdlib> #include <memory> +#include <arbor/export.hpp> + namespace arb { -class gpu_context { +class ARB_ARBOR_API gpu_context { int id_ = -1; std::size_t attributes_ = 0; @@ -21,6 +23,6 @@ public: }; using gpu_context_handle = std::shared_ptr<gpu_context>; -gpu_context_handle make_gpu_context(int id); +ARB_ARBOR_API gpu_context_handle make_gpu_context(int id); } // namespace arb diff --git a/arbor/include/arbor/arbexcept.hpp b/arbor/include/arbor/arbexcept.hpp index 2574c71febadec29959f5ac51b063333edb9159e..dee6b57e990d48ddd95afc23ba26ca33ecc5cdab 100644 --- a/arbor/include/arbor/arbexcept.hpp +++ b/arbor/include/arbor/arbexcept.hpp @@ -5,6 +5,7 @@ #include <string> #include <arbor/common_types.hpp> +#include <arbor/export.hpp> // Arbor-specific exception hierarchy. @@ -13,7 +14,7 @@ namespace arb { // Arbor internal logic error (if these are thrown, // there is a bug in the library.) -struct arbor_internal_error: std::logic_error { +struct ARB_SYMBOL_VISIBLE arbor_internal_error: std::logic_error { arbor_internal_error(const std::string& what_arg): std::logic_error(what_arg) {} @@ -22,7 +23,7 @@ struct arbor_internal_error: std::logic_error { // Common base-class for arbor run-time errors. -struct arbor_exception: std::runtime_error { +struct ARB_SYMBOL_VISIBLE arbor_exception: std::runtime_error { arbor_exception(const std::string& what_arg): std::runtime_error(what_arg) {} @@ -31,52 +32,52 @@ struct arbor_exception: std::runtime_error { // Logic errors // Argument violates domain constraints, eg ln(-1) -struct domain_error: arbor_exception { +struct ARB_SYMBOL_VISIBLE domain_error: arbor_exception { domain_error(const std::string&); }; // Recipe errors: -struct bad_cell_probe: arbor_exception { +struct ARB_SYMBOL_VISIBLE bad_cell_probe: arbor_exception { bad_cell_probe(cell_kind kind, cell_gid_type gid); cell_gid_type gid; cell_kind kind; }; -struct bad_cell_description: arbor_exception { +struct ARB_SYMBOL_VISIBLE bad_cell_description: arbor_exception { bad_cell_description(cell_kind kind, cell_gid_type gid); cell_gid_type gid; cell_kind kind; }; -struct bad_connection_source_gid: arbor_exception { +struct ARB_SYMBOL_VISIBLE bad_connection_source_gid: arbor_exception { bad_connection_source_gid(cell_gid_type gid, cell_gid_type src_gid, cell_size_type num_cells); cell_gid_type gid, src_gid; cell_size_type num_cells; }; -struct bad_connection_label: arbor_exception { +struct ARB_SYMBOL_VISIBLE bad_connection_label: arbor_exception { bad_connection_label(cell_gid_type gid, const cell_tag_type& label, const std::string& msg); cell_gid_type gid; cell_tag_type label; }; -struct bad_global_property: arbor_exception { +struct ARB_SYMBOL_VISIBLE bad_global_property: arbor_exception { explicit bad_global_property(cell_kind kind); cell_kind kind; }; -struct bad_probe_id: arbor_exception { +struct ARB_SYMBOL_VISIBLE bad_probe_id: arbor_exception { explicit bad_probe_id(cell_member_type id); cell_member_type probe_id; }; -struct gj_kind_mismatch: arbor_exception { +struct ARB_SYMBOL_VISIBLE gj_kind_mismatch: arbor_exception { gj_kind_mismatch(cell_gid_type gid_0, cell_gid_type gid_1); cell_gid_type gid_0, gid_1; }; -struct gj_unsupported_lid_selection_policy: arbor_exception { +struct ARB_SYMBOL_VISIBLE gj_unsupported_lid_selection_policy: arbor_exception { gj_unsupported_lid_selection_policy(cell_gid_type gid, cell_tag_type label); cell_gid_type gid; cell_tag_type label; @@ -84,21 +85,21 @@ struct gj_unsupported_lid_selection_policy: arbor_exception { // Context errors: -struct zero_thread_requested_error: arbor_exception { +struct ARB_SYMBOL_VISIBLE zero_thread_requested_error: arbor_exception { zero_thread_requested_error(unsigned nbt); unsigned nbt; }; // Domain decomposition errors: -struct gj_unsupported_domain_decomposition: arbor_exception { +struct ARB_SYMBOL_VISIBLE gj_unsupported_domain_decomposition: arbor_exception { gj_unsupported_domain_decomposition(cell_gid_type gid_0, cell_gid_type gid_1); cell_gid_type gid_0, gid_1; }; // Simulation errors: -struct bad_event_time: arbor_exception { +struct ARB_SYMBOL_VISIBLE bad_event_time: arbor_exception { explicit bad_event_time(time_type event_time, time_type sim_time); time_type event_time; time_type sim_time; @@ -106,28 +107,28 @@ struct bad_event_time: arbor_exception { // Mechanism catalogue errors: -struct no_such_mechanism: arbor_exception { +struct ARB_SYMBOL_VISIBLE no_such_mechanism: arbor_exception { explicit no_such_mechanism(const std::string& mech_name); std::string mech_name; }; -struct duplicate_mechanism: arbor_exception { +struct ARB_SYMBOL_VISIBLE duplicate_mechanism: arbor_exception { explicit duplicate_mechanism(const std::string& mech_name); std::string mech_name; }; -struct fingerprint_mismatch: arbor_exception { +struct ARB_SYMBOL_VISIBLE fingerprint_mismatch: arbor_exception { explicit fingerprint_mismatch(const std::string& mech_name); std::string mech_name; }; -struct no_such_parameter: arbor_exception { +struct ARB_SYMBOL_VISIBLE no_such_parameter: arbor_exception { no_such_parameter(const std::string& mech_name, const std::string& param_name); std::string mech_name; std::string param_name; }; -struct invalid_parameter_value: arbor_exception { +struct ARB_SYMBOL_VISIBLE invalid_parameter_value: arbor_exception { invalid_parameter_value(const std::string& mech_name, const std::string& param_name, const std::string& value_str); invalid_parameter_value(const std::string& mech_name, const std::string& param_name, double value); std::string mech_name; @@ -136,32 +137,32 @@ struct invalid_parameter_value: arbor_exception { double value; }; -struct invalid_ion_remap: arbor_exception { +struct ARB_SYMBOL_VISIBLE invalid_ion_remap: arbor_exception { explicit invalid_ion_remap(const std::string& mech_name); invalid_ion_remap(const std::string& mech_name, const std::string& from_ion, const std::string& to_ion); std::string from_ion; std::string to_ion; }; -struct no_such_implementation: arbor_exception { +struct ARB_SYMBOL_VISIBLE no_such_implementation: arbor_exception { explicit no_such_implementation(const std::string& mech_name); std::string mech_name; }; // Run-time value bounds check: -struct range_check_failure: arbor_exception { +struct ARB_SYMBOL_VISIBLE range_check_failure: arbor_exception { explicit range_check_failure(const std::string& whatstr, double value); double value; }; -struct file_not_found_error: arbor_exception { +struct ARB_SYMBOL_VISIBLE file_not_found_error: arbor_exception { file_not_found_error(const std::string& fn); std::string filename; }; // -struct bad_catalogue_error: arbor_exception { +struct ARB_SYMBOL_VISIBLE bad_catalogue_error: arbor_exception { bad_catalogue_error(const std::string&); bad_catalogue_error(const std::string&, const std::any&); std::any platform_error; @@ -169,12 +170,12 @@ struct bad_catalogue_error: arbor_exception { // ABI errors -struct bad_alignment: arbor_exception { +struct ARB_SYMBOL_VISIBLE bad_alignment: arbor_exception { bad_alignment(size_t); size_t alignment; }; -struct unsupported_abi_error: arbor_exception { +struct ARB_SYMBOL_VISIBLE unsupported_abi_error: arbor_exception { unsupported_abi_error(size_t); size_t version; }; diff --git a/arbor/include/arbor/assert.hpp b/arbor/include/arbor/assert.hpp index ac52566964b3c64306ce098bea29d926acebab3d..a400e335ed358e877dc69fde714c08295eb223ac 100644 --- a/arbor/include/arbor/assert.hpp +++ b/arbor/include/arbor/assert.hpp @@ -1,5 +1,6 @@ #pragma once +#include <arbor/export.hpp> #include <arbor/assert_macro.hpp> namespace arb { @@ -7,10 +8,10 @@ namespace arb { using failed_assertion_handler_t = void (*)(const char* assertion, const char* file, int line, const char* func); -void abort_on_failed_assertion(const char* assertion, const char* file, int line, const char* func); -void ignore_failed_assertion(const char* assertion, const char* file, int line, const char* func); +ARB_ARBOR_API void abort_on_failed_assertion(const char* assertion, const char* file, int line, const char* func); +ARB_ARBOR_API void ignore_failed_assertion(const char* assertion, const char* file, int line, const char* func); // defaults to abort_on_failed_assertion; -extern failed_assertion_handler_t global_failed_assertion_handler; +ARB_ARBOR_API extern failed_assertion_handler_t global_failed_assertion_handler; } // namespace arb diff --git a/arbor/include/arbor/benchmark_cell.hpp b/arbor/include/arbor/benchmark_cell.hpp index 49d93d9f4f8e5d37d8d0e73284e406e909f67a72..30719fd947653885c18cbd59f583b7f044d10711 100644 --- a/arbor/include/arbor/benchmark_cell.hpp +++ b/arbor/include/arbor/benchmark_cell.hpp @@ -1,5 +1,6 @@ #pragma once +#include <arbor/export.hpp> #include <arbor/schedule.hpp> namespace arb { @@ -7,7 +8,7 @@ namespace arb { // Cell description returned by recipe::cell_description(gid) for cells with // recipe::cell_kind(gid) returning cell_kind::benchmark -struct benchmark_cell { +struct ARB_SYMBOL_VISIBLE benchmark_cell { cell_tag_type source; // Label of source. cell_tag_type target; // Label of target. diff --git a/arbor/include/arbor/cable_cell.hpp b/arbor/include/arbor/cable_cell.hpp index 38331263102f1adf8d9f6e82eaaf1ce3ca9f5a61..5b8ef76bacaf143045d3beafe3da3355b5a0393c 100644 --- a/arbor/include/arbor/cable_cell.hpp +++ b/arbor/include/arbor/cable_cell.hpp @@ -6,6 +6,7 @@ #include <variant> #include <vector> +#include <arbor/export.hpp> #include <arbor/arbexcept.hpp> #include <arbor/cable_cell_param.hpp> #include <arbor/common_types.hpp> @@ -49,7 +50,7 @@ using cable_sample_range = std::pair<const double*, const double*>; // calls to an attached sampler, one per valid location matched by the expression. // // Metadata for point process probes. -struct cable_probe_point_info { +struct ARB_SYMBOL_VISIBLE cable_probe_point_info { cell_lid_type target; // Target number of point process instance on cell. unsigned multiplicity; // Number of combined instances at this site. mlocation loc; // Point on cell morphology where instance is placed. @@ -58,48 +59,48 @@ struct cable_probe_point_info { // Voltage estimate [mV] at `location`, interpolated. // Sample value type: `double` // Sample metadata type: `mlocation` -struct cable_probe_membrane_voltage { +struct ARB_SYMBOL_VISIBLE cable_probe_membrane_voltage { locset locations; }; // Voltage estimate [mV], reported against each cable in each control volume. Not interpolated. // Sample value type: `cable_sample_range` // Sample metadata type: `mcable_list` -struct cable_probe_membrane_voltage_cell {}; +struct ARB_SYMBOL_VISIBLE cable_probe_membrane_voltage_cell {}; // Axial current estimate [nA] at `location`, interpolated. // Sample value type: `double` // Sample metadata type: `mlocation` -struct cable_probe_axial_current { +struct ARB_SYMBOL_VISIBLE cable_probe_axial_current { locset locations; }; // Total current density [A/m²] across membrane _excluding_ capacitive and stimulus current at `location`. // Sample value type: `cable_sample_range` // Sample metadata type: `mlocation` -struct cable_probe_total_ion_current_density { +struct ARB_SYMBOL_VISIBLE cable_probe_total_ion_current_density { locset locations; }; // Total ionic current [nA] across membrane _excluding_ capacitive current across components of the cell. // Sample value type: `cable_sample_range` // Sample metadata type: `mcable_list` -struct cable_probe_total_ion_current_cell {}; +struct ARB_SYMBOL_VISIBLE cable_probe_total_ion_current_cell {}; // Total membrane current [nA] across components of the cell _excluding_ stimulus currents. // Sample value type: `cable_sample_range` // Sample metadata type: `mcable_list` -struct cable_probe_total_current_cell {}; +struct ARB_SYMBOL_VISIBLE cable_probe_total_current_cell {}; // Stimulus currents [nA] across components of the cell. // Sample value type: `cable_sample_range` // Sample metadata type: `mcable_list` -struct cable_probe_stimulus_current_cell {}; +struct ARB_SYMBOL_VISIBLE cable_probe_stimulus_current_cell {}; // Value of state variable `state` in density mechanism `mechanism` in CV at `location`. // Sample value type: `double` // Sample metadata type: `mlocation` -struct cable_probe_density_state { +struct ARB_SYMBOL_VISIBLE cable_probe_density_state { locset locations; std::string mechanism; std::string state; @@ -108,7 +109,7 @@ struct cable_probe_density_state { // Value of state variable `state` in density mechanism `mechanism` across components of the cell. // Sample value type: `cable_sample_range` // Sample metadata type: `mcable_list` -struct cable_probe_density_state_cell { +struct ARB_SYMBOL_VISIBLE cable_probe_density_state_cell { std::string mechanism; std::string state; }; @@ -116,7 +117,7 @@ struct cable_probe_density_state_cell { // Value of state variable `key` in point mechanism `source` at target `target`. // Sample value type: `double` // Sample metadata type: `cable_probe_point_info` -struct cable_probe_point_state { +struct ARB_SYMBOL_VISIBLE cable_probe_point_state { cell_lid_type target; std::string mechanism; std::string state; @@ -126,7 +127,7 @@ struct cable_probe_point_state { // Metadata has one entry of type cable_probe_point_info for each matched (possibly coalesced) instance. // Sample value type: `cable_sample_range` // Sample metadata type: `std::vector<cable_probe_point_info>` -struct cable_probe_point_state_cell { +struct ARB_SYMBOL_VISIBLE cable_probe_point_state_cell { std::string mechanism; std::string state; }; @@ -134,7 +135,7 @@ struct cable_probe_point_state_cell { // Current density [A/m²] across membrane attributed to the ion `source` at `location`. // Sample value type: `double` // Sample metadata type: `mlocation` -struct cable_probe_ion_current_density { +struct ARB_SYMBOL_VISIBLE cable_probe_ion_current_density { locset locations; std::string ion; }; @@ -142,14 +143,14 @@ struct cable_probe_ion_current_density { // Total ionic current [nA] attributed to the ion `source` across components of the cell. // Sample value type: `cable_sample_range` // Sample metadata type: `mcable_list` -struct cable_probe_ion_current_cell { +struct ARB_SYMBOL_VISIBLE cable_probe_ion_current_cell { std::string ion; }; // Ionic internal concentration [mmol/L] of ion `source` at `location`. // Sample value type: `double` // Sample metadata type: `mlocation` -struct cable_probe_ion_int_concentration { +struct ARB_SYMBOL_VISIBLE cable_probe_ion_int_concentration { locset locations; std::string ion; }; @@ -157,14 +158,14 @@ struct cable_probe_ion_int_concentration { // Ionic internal concentration [mmol/L] of ion `source` across components of the cell. // Sample value type: `cable_sample_range` // Sample metadata type: `mcable_list` -struct cable_probe_ion_int_concentration_cell { +struct ARB_SYMBOL_VISIBLE cable_probe_ion_int_concentration_cell { std::string ion; }; // Ionic external concentration [mmol/L] of ion `source` at `location`. // Sample value type: `double` // Sample metadata type: `mlocation` -struct cable_probe_ion_ext_concentration { +struct ARB_SYMBOL_VISIBLE cable_probe_ion_ext_concentration { locset locations; std::string ion; }; @@ -172,7 +173,7 @@ struct cable_probe_ion_ext_concentration { // Ionic external concentration [mmol/L] of ion `source` across components of the cell. // Sample value type: `cable_sample_range` // Sample metadata type: `mcable_list` -struct cable_probe_ion_ext_concentration_cell { +struct ARB_SYMBOL_VISIBLE cable_probe_ion_ext_concentration_cell { std::string ion; }; @@ -220,7 +221,7 @@ using cable_cell_location_map = static_typed_map<location_assignment, synapse, junction, i_clamp, threshold_detector>; // High-level abstract representation of a cell. -class cable_cell { +class ARB_SYMBOL_VISIBLE cable_cell { public: using index_type = cell_lid_type; using size_type = cell_local_size_type; diff --git a/arbor/include/arbor/cable_cell_param.hpp b/arbor/include/arbor/cable_cell_param.hpp index d1ad2bfa66ec931b53572d2bee91527a39b933c5..7ab612f6b47750a0cf4987c1950d3a6784695fd8 100644 --- a/arbor/include/arbor/cable_cell_param.hpp +++ b/arbor/include/arbor/cable_cell_param.hpp @@ -7,6 +7,7 @@ #include <string> #include <variant> +#include <arbor/export.hpp> #include <arbor/arbexcept.hpp> #include <arbor/cv_policy.hpp> #include <arbor/mechcat.hpp> @@ -16,7 +17,7 @@ namespace arb { // Specialized arbor exception for errors in cell building. -struct cable_cell_error: arbor_exception { +struct ARB_SYMBOL_VISIBLE cable_cell_error: arbor_exception { cable_cell_error(const std::string& what): arbor_exception("cable_cell: "+what) {} }; @@ -47,7 +48,7 @@ struct cable_cell_ion_data { // Periodic envelopes are not supported, but may well be a feature worth // considering in the future. -struct i_clamp { +struct ARB_SYMBOL_VISIBLE i_clamp { struct envelope_point { double t; // [ms] double amplitude; // [nA] @@ -83,40 +84,40 @@ struct i_clamp { }; // Threshold detector description. -struct threshold_detector { +struct ARB_SYMBOL_VISIBLE threshold_detector { double threshold; }; // Setter types for painting physical and ion parameters or setting // cell-wide default: -struct init_membrane_potential { +struct ARB_SYMBOL_VISIBLE init_membrane_potential { double value = NAN; // [mV] }; -struct temperature_K { +struct ARB_SYMBOL_VISIBLE temperature_K { double value = NAN; // [K] }; -struct axial_resistivity { +struct ARB_SYMBOL_VISIBLE axial_resistivity { double value = NAN; // [Ω·cm] }; -struct membrane_capacitance { +struct ARB_SYMBOL_VISIBLE membrane_capacitance { double value = NAN; // [F/m²] }; -struct init_int_concentration { +struct ARB_SYMBOL_VISIBLE init_int_concentration { std::string ion = ""; double value = NAN; // [mM] }; -struct init_ext_concentration { +struct ARB_SYMBOL_VISIBLE init_ext_concentration { std::string ion = ""; double value = NAN; // [mM] }; -struct init_reversal_potential { +struct ARB_SYMBOL_VISIBLE init_reversal_potential { std::string ion = ""; double value = NAN; // [mV] }; @@ -126,7 +127,7 @@ struct init_reversal_potential { // density and point mechanisms to segments and // reversal potential computations to cells. -struct mechanism_desc { +struct ARB_SYMBOL_VISIBLE mechanism_desc { struct field_proxy { mechanism_desc* m; std::string key; @@ -185,7 +186,7 @@ private: }; // Tagged mechanism types for dispatching decor::place() and decor::paint() calls -struct junction { +struct ARB_SYMBOL_VISIBLE junction { mechanism_desc mech; explicit junction(mechanism_desc m): mech(std::move(m)) {} junction(mechanism_desc m, const std::unordered_map<std::string, double>& params): mech(std::move(m)) { @@ -195,7 +196,7 @@ struct junction { } }; -struct synapse { +struct ARB_SYMBOL_VISIBLE synapse { mechanism_desc mech; explicit synapse(mechanism_desc m): mech(std::move(m)) {} synapse(mechanism_desc m, const std::unordered_map<std::string, double>& params): mech(std::move(m)) { @@ -205,7 +206,7 @@ struct synapse { } }; -struct density { +struct ARB_SYMBOL_VISIBLE density { mechanism_desc mech; explicit density(mechanism_desc m): mech(std::move(m)) {} density(mechanism_desc m, const std::unordered_map<std::string, double>& params): mech(std::move(m)) { @@ -215,7 +216,7 @@ struct density { } }; -struct ion_reversal_potential_method { +struct ARB_SYMBOL_VISIBLE ion_reversal_potential_method { std::string ion; mechanism_desc method; }; @@ -257,7 +258,7 @@ using defaultable = // be set locally witihin a cell using the `cable_cell::paint()`, and the // cell defaults can be individually set with `cable_cell:set_default()`. -struct cable_cell_parameter_set { +struct ARB_ARBOR_API cable_cell_parameter_set { std::optional<double> init_membrane_potential; // [mV] std::optional<double> temperature_K; // [K] std::optional<double> axial_resistivity; // [Ω·cm] @@ -273,7 +274,7 @@ struct cable_cell_parameter_set { // A flat description of defaults, paintings and placings that // are to be applied to a morphology in a cable_cell. -class decor { +class ARB_ARBOR_API decor { std::vector<std::pair<region, paintable>> paintings_; std::vector<std::tuple<locset, placeable, cell_tag_type>> placements_; cable_cell_parameter_set defaults_; @@ -288,11 +289,11 @@ public: void set_default(defaultable); }; -extern cable_cell_parameter_set neuron_parameter_defaults; +ARB_ARBOR_API extern cable_cell_parameter_set neuron_parameter_defaults; // Global cable cell data. -struct cable_cell_global_properties { +struct ARB_SYMBOL_VISIBLE cable_cell_global_properties { mechanism_catalogue catalogue = global_default_catalogue(); // If >0, check membrane voltage magnitude is less than limit @@ -329,6 +330,6 @@ struct cable_cell_global_properties { // Throw cable_cell_error if any default parameters are left unspecified, // or if the supplied ion data is incomplete. -void check_global_properties(const cable_cell_global_properties&); +ARB_ARBOR_API void check_global_properties(const cable_cell_global_properties&); } // namespace arb diff --git a/arbor/include/arbor/common_types.hpp b/arbor/include/arbor/common_types.hpp index 75141c0626cd3ace24ee2980c16bfb413f4a2702..7db5bcde5af2b840cfd8c8e87d0964bf09a15aaf 100644 --- a/arbor/include/arbor/common_types.hpp +++ b/arbor/include/arbor/common_types.hpp @@ -15,6 +15,7 @@ #include <arbor/util/lexcmp_def.hpp> #include <arbor/util/hash_def.hpp> +#include <arbor/export.hpp> namespace arb { @@ -121,7 +122,7 @@ enum class backend_kind { // Enumeration used to indentify the cell type/kind, used by the model to // group equal kinds in the same cell group. -enum class cell_kind { +enum class ARB_SYMBOL_VISIBLE cell_kind { cable, // Our own special mc neuron. lif, // Leaky-integrate and fire neuron. spike_source, // Cell that generates spikes at a user-supplied sequence of time points. @@ -136,10 +137,10 @@ enum class binning_kind { following, // => round times down to previous event if within binning interval. }; -std::ostream& operator<<(std::ostream& o, lid_selection_policy m); -std::ostream& operator<<(std::ostream& o, cell_member_type m); -std::ostream& operator<<(std::ostream& o, cell_kind k); -std::ostream& operator<<(std::ostream& o, backend_kind k); +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, lid_selection_policy m); +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, cell_member_type m); +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, cell_kind k); +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, backend_kind k); } // namespace arb diff --git a/arbor/include/arbor/communication/mpi_error.hpp b/arbor/include/arbor/communication/mpi_error.hpp index 911447a1a0357e20e278709704769c5d32101cc7..626c1a5a24c4b3de90cc9b41c121601d1aa14ba4 100644 --- a/arbor/include/arbor/communication/mpi_error.hpp +++ b/arbor/include/arbor/communication/mpi_error.hpp @@ -5,6 +5,8 @@ #include <mpi.h> +#include <arbor/export.hpp> + namespace arb { enum class mpi_errc { @@ -79,9 +81,9 @@ template <> struct is_error_condition_enum<arb::mpi_errc>: true_type {}; namespace arb { class mpi_error_category_impl; -const mpi_error_category_impl& mpi_error_category(); +ARB_ARBOR_API const mpi_error_category_impl& mpi_error_category(); -class mpi_error_category_impl: public std::error_category { +class ARB_SYMBOL_VISIBLE mpi_error_category_impl: public std::error_category { const char* name() const noexcept override; std::string message(int) const override; std::error_condition default_error_condition(int) const noexcept override; @@ -91,7 +93,7 @@ inline std::error_condition make_error_condition(mpi_errc ec) { return std::error_condition(static_cast<int>(ec), mpi_error_category()); } -struct mpi_error: std::system_error { +struct ARB_SYMBOL_VISIBLE mpi_error: std::system_error { explicit mpi_error(int mpi_err): std::system_error(mpi_err, mpi_error_category()) {} diff --git a/arbor/include/arbor/context.hpp b/arbor/include/arbor/context.hpp index a61461ef65cf1b7a80a97a3bec281e727f4f00b5..75ba004bc5c5a92a86a1c58aaddbf2d0d2459bdb 100644 --- a/arbor/include/arbor/context.hpp +++ b/arbor/include/arbor/context.hpp @@ -2,6 +2,8 @@ #include <memory> +#include <arbor/export.hpp> + namespace arb { // Requested dry-run parameters. @@ -49,7 +51,7 @@ struct execution_context; // // As execution_context is an incomplete type, an explicit deleter must be // provided. -struct execution_context_deleter { +struct ARB_ARBOR_API execution_context_deleter { void operator()(execution_context*) const; }; using context = std::unique_ptr<execution_context, execution_context_deleter>; @@ -57,20 +59,20 @@ using context = std::unique_ptr<execution_context, execution_context_deleter>; // Helpers for creating contexts. These are implemented in the back end. // Non-distributed context using the requested resources. -context make_context(const proc_allocation& resources = proc_allocation{}); +ARB_ARBOR_API context make_context(const proc_allocation& resources = proc_allocation{}); // Distributed context that uses MPI communicator comm, and local resources // described by resources. Or dry run context that uses dry_run_info. template <typename Comm> -context make_context(const proc_allocation& resources, Comm comm); +ARB_ARBOR_API context make_context(const proc_allocation& resources, Comm comm); // Queries for properties of execution resources in a context. -std::string distribution_type(const context&); -bool has_gpu(const context&); -unsigned num_threads(const context&); -bool has_mpi(const context&); -unsigned num_ranks(const context&); -unsigned rank(const context&); +ARB_ARBOR_API std::string distribution_type(const context&); +ARB_ARBOR_API bool has_gpu(const context&); +ARB_ARBOR_API unsigned num_threads(const context&); +ARB_ARBOR_API bool has_mpi(const context&); +ARB_ARBOR_API unsigned num_ranks(const context&); +ARB_ARBOR_API unsigned rank(const context&); } diff --git a/arbor/include/arbor/cv_policy.hpp b/arbor/include/arbor/cv_policy.hpp index 917610a1d18ff5ff1ced7f04ab28604453747080..a1a5077cf17dde69e9c21e5489bff15c1f17bc05 100644 --- a/arbor/include/arbor/cv_policy.hpp +++ b/arbor/include/arbor/cv_policy.hpp @@ -3,6 +3,7 @@ #include <memory> #include <utility> +#include <arbor/export.hpp> #include <arbor/morph/region.hpp> #include <arbor/morph/locset.hpp> @@ -70,7 +71,7 @@ struct cv_policy_base { using cv_policy_base_ptr = std::unique_ptr<cv_policy_base>; -struct cv_policy { +struct ARB_SYMBOL_VISIBLE cv_policy { cv_policy(const cv_policy_base& ref) { // implicit policy_ptr = ref.clone(); } @@ -102,8 +103,8 @@ private: cv_policy_base_ptr policy_ptr; }; -cv_policy operator+(const cv_policy&, const cv_policy&); -cv_policy operator|(const cv_policy&, const cv_policy&); +ARB_ARBOR_API cv_policy operator+(const cv_policy&, const cv_policy&); +ARB_ARBOR_API cv_policy operator|(const cv_policy&, const cv_policy&); // Common flags for CV policies; bitwise composable. @@ -115,7 +116,7 @@ namespace cv_policy_flag { }; } -struct cv_policy_explicit: cv_policy_base { +struct ARB_ARBOR_API cv_policy_explicit: cv_policy_base { explicit cv_policy_explicit(locset locs, region domain = reg::all()): locs_(std::move(locs)), domain_(std::move(domain)) {} @@ -132,7 +133,7 @@ private: region domain_; }; -struct cv_policy_single: cv_policy_base { +struct ARB_ARBOR_API cv_policy_single: cv_policy_base { explicit cv_policy_single(region domain = reg::all()): domain_(domain) {} @@ -148,7 +149,7 @@ private: region domain_; }; -struct cv_policy_max_extent: cv_policy_base { +struct ARB_ARBOR_API cv_policy_max_extent: cv_policy_base { cv_policy_max_extent(double max_extent, region domain, cv_policy_flag::value flags = cv_policy_flag::none): max_extent_(max_extent), domain_(std::move(domain)), flags_(flags) {} @@ -169,7 +170,7 @@ private: cv_policy_flag::value flags_; }; -struct cv_policy_fixed_per_branch: cv_policy_base { +struct ARB_ARBOR_API cv_policy_fixed_per_branch: cv_policy_base { cv_policy_fixed_per_branch(unsigned cv_per_branch, region domain, cv_policy_flag::value flags = cv_policy_flag::none): cv_per_branch_(cv_per_branch), domain_(std::move(domain)), flags_(flags) {} @@ -190,7 +191,7 @@ private: cv_policy_flag::value flags_; }; -struct cv_policy_every_segment: cv_policy_base { +struct ARB_ARBOR_API cv_policy_every_segment: cv_policy_base { explicit cv_policy_every_segment(region domain = reg::all()): domain_(std::move(domain)) {} diff --git a/arbor/include/arbor/domain_decomposition.hpp b/arbor/include/arbor/domain_decomposition.hpp index c79800503542064977af8ca539f0b0d64a891b7c..0de6383ae7bf77341008386413eb890c4715a6d3 100644 --- a/arbor/include/arbor/domain_decomposition.hpp +++ b/arbor/include/arbor/domain_decomposition.hpp @@ -7,6 +7,7 @@ #include <arbor/assert.hpp> #include <arbor/common_types.hpp> #include <arbor/context.hpp> +#include <arbor/export.hpp> #include <arbor/recipe.hpp> namespace arb { @@ -32,7 +33,7 @@ struct group_description { /// distribution of cells across cell_groups and domains. /// A load balancing algorithm is responsible for generating the /// domain_decomposition, e.g. arb::partitioned_load_balancer(). -class domain_decomposition { +class ARB_ARBOR_API domain_decomposition { public: domain_decomposition() = delete; domain_decomposition(const recipe& rec, const context& ctx, const std::vector<group_description>& groups); diff --git a/arbor/include/arbor/domdecexcept.hpp b/arbor/include/arbor/domdecexcept.hpp index 206f1c7628c2dba7eee780ca5cc37c5627cd9085..aac8490733eaf257b6ee37e298f112fb2cdbe276 100644 --- a/arbor/include/arbor/domdecexcept.hpp +++ b/arbor/include/arbor/domdecexcept.hpp @@ -2,41 +2,42 @@ #include <string> +#include <arbor/export.hpp> #include <arbor/arbexcept.hpp> #include <arbor/domain_decomposition.hpp> namespace arb { -struct dom_dec_exception: public arbor_exception { +struct ARB_SYMBOL_VISIBLE dom_dec_exception: public arbor_exception { dom_dec_exception(const std::string& what): arbor_exception("Invalid domain decomposition: " + what) {} }; -struct invalid_gj_cell_group: dom_dec_exception { +struct ARB_SYMBOL_VISIBLE invalid_gj_cell_group: dom_dec_exception { invalid_gj_cell_group(cell_gid_type gid_0, cell_gid_type gid_1); cell_gid_type gid_0, gid_1; }; -struct invalid_sum_local_cells: dom_dec_exception { +struct ARB_SYMBOL_VISIBLE invalid_sum_local_cells: dom_dec_exception { invalid_sum_local_cells(unsigned gc_wrong, unsigned gc_right); unsigned gc_wrong, gc_right; }; -struct duplicate_gid: dom_dec_exception { +struct ARB_SYMBOL_VISIBLE duplicate_gid: dom_dec_exception { duplicate_gid(cell_gid_type gid); cell_gid_type gid; }; -struct out_of_bounds: dom_dec_exception { +struct ARB_SYMBOL_VISIBLE out_of_bounds: dom_dec_exception { out_of_bounds(cell_gid_type gid, unsigned num_cells); cell_gid_type gid; unsigned num_cells; }; -struct invalid_backend: dom_dec_exception { +struct ARB_SYMBOL_VISIBLE invalid_backend: dom_dec_exception { invalid_backend(int rank); int rank; }; -struct incompatible_backend: dom_dec_exception { +struct ARB_SYMBOL_VISIBLE incompatible_backend: dom_dec_exception { incompatible_backend(int rank, cell_kind kind); int rank; cell_kind kind; diff --git a/arbor/include/arbor/gpu/cuda_api.hpp b/arbor/include/arbor/gpu/cuda_api.hpp index 12bfa476afe30d7ed67dcfc8fb4e9330d99ef7e5..eaf4c5005dea796d5d5f963117f0556586db6e1a 100644 --- a/arbor/include/arbor/gpu/cuda_api.hpp +++ b/arbor/include/arbor/gpu/cuda_api.hpp @@ -5,6 +5,8 @@ #include <cuda_runtime.h> #include <cuda_runtime_api.h> +#include <arbor/export.hpp> + namespace arb { namespace gpu { @@ -12,7 +14,7 @@ namespace gpu { using DeviceProp = cudaDeviceProp; -struct api_error_type { +struct ARB_SYMBOL_VISIBLE api_error_type { cudaError_t value; api_error_type(cudaError_t e): value(e) {} diff --git a/arbor/include/arbor/gpu/hip_api.hpp b/arbor/include/arbor/gpu/hip_api.hpp index 283f68bf4a90ff16e87f99dbbbd3dc92a0850161..55c27c3e95221c07838af2bb1e79083ada83d279 100644 --- a/arbor/include/arbor/gpu/hip_api.hpp +++ b/arbor/include/arbor/gpu/hip_api.hpp @@ -4,6 +4,8 @@ #include <hip/hip_runtime.h> #include <hip/hip_runtime_api.h> +#include <arbor/export.hpp> + namespace arb { namespace gpu { @@ -11,7 +13,7 @@ namespace gpu { using DeviceProp = hipDeviceProp_t; -struct api_error_type { +struct ARB_SYMBOL_VISIBLE api_error_type { hipError_t value; api_error_type(hipError_t e): value(e) {} diff --git a/arbor/include/arbor/lif_cell.hpp b/arbor/include/arbor/lif_cell.hpp index 35c2fa98809bf6c0c2c0c4987132fc09b2c129af..cff3eeb55104b4b6da453d661e6a8b467a61c297 100644 --- a/arbor/include/arbor/lif_cell.hpp +++ b/arbor/include/arbor/lif_cell.hpp @@ -1,11 +1,12 @@ #pragma once #include <arbor/common_types.hpp> +#include <arbor/export.hpp> namespace arb { // Model parameters of leaky integrate and fire neuron model. -struct lif_cell { +struct ARB_SYMBOL_VISIBLE lif_cell { cell_tag_type source; // Label of source. cell_tag_type target; // Label of target. diff --git a/arbor/include/arbor/load_balance.hpp b/arbor/include/arbor/load_balance.hpp index 44d966e4cf7d81f17d7a304f97f5136d6aef427c..b9e8e71b25a9bd75e6aa7487e897c5cc099f3191 100644 --- a/arbor/include/arbor/load_balance.hpp +++ b/arbor/include/arbor/load_balance.hpp @@ -3,6 +3,7 @@ #include <cstddef> #include <unordered_map> +#include <arbor/export.hpp> #include <arbor/context.hpp> #include <arbor/domain_decomposition.hpp> #include <arbor/recipe.hpp> @@ -19,7 +20,7 @@ struct partition_hint { using partition_hint_map = std::unordered_map<cell_kind, partition_hint>; -domain_decomposition partition_load_balance( +ARB_ARBOR_API domain_decomposition partition_load_balance( const recipe& rec, const context& ctx, partition_hint_map hint_map = {}); diff --git a/arbor/include/arbor/mechcat.hpp b/arbor/include/arbor/mechcat.hpp index 224437049ffaffce172d7005ad43694f78747231..c7811725bea6b7051292ef13a569048e6edbbf16 100644 --- a/arbor/include/arbor/mechcat.hpp +++ b/arbor/include/arbor/mechcat.hpp @@ -6,6 +6,7 @@ #include <typeindex> #include <vector> +#include <arbor/export.hpp> #include <arbor/mechinfo.hpp> #include <arbor/mechanism.hpp> #include <arbor/mechanism_abi.h> @@ -39,7 +40,7 @@ namespace arb { // catalogue_state comprises the private implementation of mechanism_catalogue. struct catalogue_state; -class mechanism_catalogue { +class ARB_ARBOR_API mechanism_catalogue { public: using value_type = double; @@ -109,11 +110,11 @@ private: }; // References to global mechanism catalogues. -const mechanism_catalogue& global_default_catalogue(); -const mechanism_catalogue& global_allen_catalogue(); -const mechanism_catalogue& global_bbp_catalogue(); +ARB_ARBOR_API const mechanism_catalogue& global_default_catalogue(); +ARB_ARBOR_API const mechanism_catalogue& global_allen_catalogue(); +ARB_ARBOR_API const mechanism_catalogue& global_bbp_catalogue(); // Load catalogue from disk. -const mechanism_catalogue& load_catalogue(const std::string&); +ARB_ARBOR_API const mechanism_catalogue& load_catalogue(const std::string&); } // namespace arb diff --git a/arbor/include/arbor/mechinfo.hpp b/arbor/include/arbor/mechinfo.hpp index f0b552957a08e802ee99c90bc2aaa4beae63444c..39678e4c4964a49243c77c30ee708098a6da1be1 100644 --- a/arbor/include/arbor/mechinfo.hpp +++ b/arbor/include/arbor/mechinfo.hpp @@ -10,6 +10,7 @@ #include <utility> #include <vector> +#include <arbor/export.hpp> #include <arbor/mechanism_abi.h> namespace arb { @@ -52,7 +53,7 @@ struct ion_dependency { // Use a textual representation to ease readability. using mechanism_fingerprint = std::string; -struct mechanism_info { +struct ARB_ARBOR_API mechanism_info { // mechanism_info is a convenient subset of the ABI mech description mechanism_info(const arb_mechanism_type&); mechanism_info() = default; diff --git a/arbor/include/arbor/morph/cv_data.hpp b/arbor/include/arbor/morph/cv_data.hpp index 58dc1e7c139d04abe9ef3856a79e15bc5a12ef9a..38f24e72c19ef1cdf670fa3a8c8c7882ceb188a1 100644 --- a/arbor/include/arbor/morph/cv_data.hpp +++ b/arbor/include/arbor/morph/cv_data.hpp @@ -2,6 +2,7 @@ #include <vector> +#include <arbor/export.hpp> #include <arbor/cable_cell.hpp> #include <arbor/fvm_types.hpp> #include <arbor/morph/embed_pwlin.hpp> @@ -14,7 +15,7 @@ namespace arb { struct cell_cv_data_impl; // Stores info about the CV geometry of a discretized cable-cell -class cell_cv_data { +class ARB_ARBOR_API cell_cv_data { public: // Returns mcables comprising the CV at a given index. mcable_list cables(fvm_size_type index) const; @@ -47,8 +48,8 @@ struct cv_proportion { }; // Construct cell_cv_geometry for cell from default cell discretization if it exists. -std::optional<cell_cv_data> cv_data(const cable_cell& cell); +ARB_ARBOR_API std::optional<cell_cv_data> cv_data(const cable_cell& cell); -std::vector<cv_proportion> intersect_region(const region& reg, const cell_cv_data& cvs, bool intergrate_by_length = false); +ARB_ARBOR_API std::vector<cv_proportion> intersect_region(const region& reg, const cell_cv_data& cvs, bool intergrate_by_length = false); } //namespace arb diff --git a/arbor/include/arbor/morph/embed_pwlin.hpp b/arbor/include/arbor/morph/embed_pwlin.hpp index 412e8997e91ea7c29515b85560ca3590a03da8ad..0fe4bf8dc43dcbe9c8b335c871b245fe84e7fa55 100644 --- a/arbor/include/arbor/morph/embed_pwlin.hpp +++ b/arbor/include/arbor/morph/embed_pwlin.hpp @@ -4,6 +4,7 @@ #include <vector> +#include <arbor/export.hpp> #include <arbor/morph/morphology.hpp> #include <arbor/morph/primitives.hpp> @@ -19,7 +20,7 @@ template <typename X> struct pw_elements; // values defined over contiguous intervals. using pw_constant_fn = util::pw_elements<double>; -struct embed_pwlin { +struct ARB_ARBOR_API embed_pwlin { explicit embed_pwlin(const arb::morphology& m); // Segment queries. diff --git a/arbor/include/arbor/morph/label_dict.hpp b/arbor/include/arbor/morph/label_dict.hpp index a68bab2b46d70e6fa68444ba74b873816b3a1924..6b590b7c44d3594c42cb3985251db245d6a35d54 100644 --- a/arbor/include/arbor/morph/label_dict.hpp +++ b/arbor/include/arbor/morph/label_dict.hpp @@ -4,12 +4,13 @@ #include <optional> #include <unordered_map> +#include <arbor/export.hpp> #include <arbor/morph/locset.hpp> #include <arbor/morph/region.hpp> namespace arb { -class label_dict { +class ARB_ARBOR_API label_dict { using ps_map = std::unordered_map<std::string, arb::locset>; using reg_map = std::unordered_map<std::string, arb::region>; ps_map locsets_; diff --git a/arbor/include/arbor/morph/locset.hpp b/arbor/include/arbor/morph/locset.hpp index e449df768a35107c14caa9487eeb3128835751ad..ec127aea168532b7262d620d40b429f4b02d737c 100644 --- a/arbor/include/arbor/morph/locset.hpp +++ b/arbor/include/arbor/morph/locset.hpp @@ -8,6 +8,7 @@ #include <utility> #include <vector> +#include <arbor/export.hpp> #include <arbor/morph/primitives.hpp> #include <arbor/morph/morphology.hpp> @@ -18,7 +19,7 @@ struct mprovider; class locset; class locset_tag {}; -class locset { +class ARB_SYMBOL_VISIBLE locset { public: template <typename Impl, typename = std::enable_if_t<std::is_base_of<locset_tag, std::decay_t<Impl>>::value>> @@ -116,66 +117,66 @@ class region; namespace ls { // Explicit location on morphology. -locset location(msize_t branch, double pos); +ARB_ARBOR_API locset location(msize_t branch, double pos); // Set of terminal nodes on a morphology. -locset terminal(); +ARB_ARBOR_API locset terminal(); // The root node of a morphology. -locset root(); +ARB_ARBOR_API locset root(); // Named locset. -locset named(std::string); +ARB_ARBOR_API locset named(std::string); // The null (empty) set. -locset nil(); +ARB_ARBOR_API locset nil(); // Most distal points of a region. -locset most_distal(region reg); +ARB_ARBOR_API locset most_distal(region reg); // Most proximal points of a region. -locset most_proximal(region reg); +ARB_ARBOR_API locset most_proximal(region reg); // Translate locations in locset distance μm in the distal direction -locset distal_translate(locset ls, double distance); +ARB_ARBOR_API locset distal_translate(locset ls, double distance); // Translate locations in locset distance μm in the proximal direction -locset proximal_translate(locset ls, double distance); +ARB_ARBOR_API locset proximal_translate(locset ls, double distance); // Boundary points of a region. -locset boundary(region reg); +ARB_ARBOR_API locset boundary(region reg); // Completed boundary points of a region. // (Boundary of completed components.) -locset cboundary(region reg); +ARB_ARBOR_API locset cboundary(region reg); // Returns all locations in a locset that are also in the region. -locset restrict(locset ls, region reg); +ARB_ARBOR_API locset restrict(locset ls, region reg); // Returns locations that mark the segments. -locset segment_boundaries(); +ARB_ARBOR_API locset segment_boundaries(); // A range `left` to `right` of randomly selected locations with a // uniform distribution from region `reg` generated using `seed` -locset uniform(region reg, unsigned left, unsigned right, uint64_t seed); +ARB_ARBOR_API locset uniform(region reg, unsigned left, unsigned right, uint64_t seed); // Proportional location on every branch. -locset on_branches(double pos); +ARB_ARBOR_API locset on_branches(double pos); // Proportional locations on each component: // For each component C of the region, find locations L // s.t. dist(h, L) = r * max {dist(h, t) | t is a distal point in C}. -locset on_components(double relpos, region reg); +ARB_ARBOR_API locset on_components(double relpos, region reg); // Set of locations in the locset with duplicates removed, i.e. the support of the input multiset -locset support(locset); +ARB_ARBOR_API locset support(locset); } // namespace ls // Union of two locsets. -locset join(locset, locset); +ARB_ARBOR_API locset join(locset, locset); // Multiset sum of two locsets. -locset sum(locset, locset); +ARB_ARBOR_API locset sum(locset, locset); } // namespace arb diff --git a/arbor/include/arbor/morph/morphexcept.hpp b/arbor/include/arbor/morph/morphexcept.hpp index 13963c207c7fd8f07b0814a2f4a148f2b0a163ba..8d1f8f5ce8f68eb0115e9f98217a951194721ae6 100644 --- a/arbor/include/arbor/morph/morphexcept.hpp +++ b/arbor/include/arbor/morph/morphexcept.hpp @@ -2,82 +2,83 @@ #include <string> +#include <arbor/export.hpp> #include <arbor/arbexcept.hpp> #include <arbor/morph/primitives.hpp> namespace arb { -struct morphology_error: public arbor_exception { +struct ARB_SYMBOL_VISIBLE morphology_error: public arbor_exception { morphology_error(const std::string& what): arbor_exception(what) {} }; -struct invalid_mlocation: morphology_error { +struct ARB_SYMBOL_VISIBLE invalid_mlocation: morphology_error { invalid_mlocation(mlocation loc); mlocation loc; }; -struct no_such_branch: morphology_error { +struct ARB_SYMBOL_VISIBLE no_such_branch: morphology_error { no_such_branch(msize_t bid); msize_t bid; }; -struct no_such_segment: arbor_exception { +struct ARB_SYMBOL_VISIBLE no_such_segment: arbor_exception { explicit no_such_segment(msize_t sid); msize_t sid; }; -struct invalid_mcable: morphology_error { +struct ARB_SYMBOL_VISIBLE invalid_mcable: morphology_error { invalid_mcable(mcable cable); mcable cable; }; -struct invalid_mcable_list: morphology_error { +struct ARB_SYMBOL_VISIBLE invalid_mcable_list: morphology_error { invalid_mcable_list(); }; -struct invalid_segment_parent: morphology_error { +struct ARB_SYMBOL_VISIBLE invalid_segment_parent: morphology_error { invalid_segment_parent(msize_t parent, msize_t tree_size); msize_t parent; msize_t tree_size; }; -struct duplicate_stitch_id: morphology_error { +struct ARB_SYMBOL_VISIBLE duplicate_stitch_id: morphology_error { duplicate_stitch_id(const std::string& id); std::string id; }; -struct no_such_stitch: morphology_error { +struct ARB_SYMBOL_VISIBLE no_such_stitch: morphology_error { no_such_stitch(const std::string& id); std::string id; }; -struct missing_stitch_start: morphology_error { +struct ARB_SYMBOL_VISIBLE missing_stitch_start: morphology_error { missing_stitch_start(const std::string& id); std::string id; }; -struct invalid_stitch_position: morphology_error { +struct ARB_SYMBOL_VISIBLE invalid_stitch_position: morphology_error { invalid_stitch_position(const std::string& id, double along); std::string id; double along; }; -struct label_type_mismatch: morphology_error { +struct ARB_SYMBOL_VISIBLE label_type_mismatch: morphology_error { label_type_mismatch(const std::string& label); std::string label; }; -struct incomplete_branch: morphology_error { +struct ARB_SYMBOL_VISIBLE incomplete_branch: morphology_error { incomplete_branch(msize_t bid); msize_t bid; }; -struct unbound_name: morphology_error { +struct ARB_SYMBOL_VISIBLE unbound_name: morphology_error { unbound_name(const std::string& name); std::string name; }; -struct circular_definition: morphology_error { +struct ARB_SYMBOL_VISIBLE circular_definition: morphology_error { circular_definition(const std::string& name); std::string name; }; diff --git a/arbor/include/arbor/morph/morphology.hpp b/arbor/include/arbor/morph/morphology.hpp index 18da8ee386fdf2fadc6cd495f065d26a90eea8e6..b12f9b982732ed82079c283ccb794870372bf00d 100644 --- a/arbor/include/arbor/morph/morphology.hpp +++ b/arbor/include/arbor/morph/morphology.hpp @@ -4,6 +4,7 @@ #include <ostream> #include <vector> +#include <arbor/export.hpp> #include <arbor/morph/primitives.hpp> #include <arbor/morph/segment_tree.hpp> #include <arbor/util/lexcmp_def.hpp> @@ -12,7 +13,7 @@ namespace arb { struct morphology_impl; -class morphology { +class ARB_ARBOR_API morphology { // Hold an immutable copy of the morphology implementation. std::shared_ptr<const morphology_impl> impl_; @@ -54,7 +55,7 @@ public: // without a morphology. // A morphology is required to assert the invariant that an mextent does // not contain branches not in the morphology. -struct mextent { +struct ARB_ARBOR_API mextent { mextent() = default; mextent(const mextent&) = default; mextent(mextent&&) = default; @@ -107,19 +108,15 @@ private: // Morphology utility functions. -mlocation canonical(const morphology&, mlocation); +ARB_ARBOR_API mlocation canonical(const morphology&, mlocation); // Find the set of locations in an mlocation_list for which there // are no other locations that are more proximal in that list. -mlocation_list minset(const morphology&, const mlocation_list&); +ARB_ARBOR_API mlocation_list minset(const morphology&, const mlocation_list&); // Find the set of locations in an mlocation_list for which there // are no other locations that are more distal in the list. -mlocation_list maxset(const morphology&, const mlocation_list&); - -// Reduced representation of an extent, excluding zero-length cables -// that are covered by more proximal or non-zero-length cables. -mcable_list canonical(const morphology& m, const mextent& a); +ARB_ARBOR_API mlocation_list maxset(const morphology&, const mlocation_list&); // Determine the components of an extent. // @@ -148,7 +145,7 @@ mcable_list canonical(const morphology& m, const mextent& a); // directed-path-connected in X, and such that for all x in E_i and all y in // E_j, with i not equal to j, x and y are not directed-path-connected in X. -std::vector<mextent> components(const morphology& m, const mextent&); +ARB_ARBOR_API std::vector<mextent> components(const morphology& m, const mextent&); } // namespace arb diff --git a/arbor/include/arbor/morph/mprovider.hpp b/arbor/include/arbor/morph/mprovider.hpp index 7cc3e1262c17de511bf5b326d3534f29c9616bdc..441ca2b580ad2bff2d912928162164541ac0506e 100644 --- a/arbor/include/arbor/morph/mprovider.hpp +++ b/arbor/include/arbor/morph/mprovider.hpp @@ -3,6 +3,7 @@ #include <string> #include <unordered_map> +#include <arbor/export.hpp> #include <arbor/morph/embed_pwlin.hpp> #include <arbor/morph/primitives.hpp> #include <arbor/morph/label_dict.hpp> @@ -12,7 +13,7 @@ namespace arb { using concrete_embedding = embed_pwlin; -struct mprovider { +struct ARB_ARBOR_API mprovider { mprovider(arb::morphology m, const label_dict& dict): mprovider(m, &dict) {} explicit mprovider(arb::morphology m): mprovider(m, nullptr) {} diff --git a/arbor/include/arbor/morph/place_pwlin.hpp b/arbor/include/arbor/morph/place_pwlin.hpp index 223c287acbdf0b9f60bfc17bc0655aa0b6ed06e4..73c0d5e0b5a532ee488d1e4fabc4de5c9c9d6ace 100644 --- a/arbor/include/arbor/morph/place_pwlin.hpp +++ b/arbor/include/arbor/morph/place_pwlin.hpp @@ -7,6 +7,7 @@ #include <limits> #include <utility> +#include <arbor/export.hpp> #include <arbor/morph/morphology.hpp> #include <arbor/morph/primitives.hpp> #include <arbor/math.hpp> @@ -70,7 +71,7 @@ public: struct place_pwlin_data; -struct place_pwlin { +struct ARB_ARBOR_API place_pwlin { explicit place_pwlin(const morphology& m, const isometry& iso = isometry{}); // Any point corresponding to the location loc. diff --git a/arbor/include/arbor/morph/primitives.hpp b/arbor/include/arbor/morph/primitives.hpp index 919730a1e9c79642dddfa0e44773496f5373a6a6..2cfff2ef4f507f221f237fcc48a59edbe9be0f5d 100644 --- a/arbor/include/arbor/morph/primitives.hpp +++ b/arbor/include/arbor/morph/primitives.hpp @@ -5,6 +5,7 @@ #include <ostream> #include <vector> +#include <arbor/export.hpp> #include <arbor/util/hash_def.hpp> #include <arbor/util/lexcmp_def.hpp> @@ -18,7 +19,7 @@ using msize_t = std::uint32_t; constexpr msize_t mnpos = msize_t(-1); // a morphology sample point: a 3D location and radius. -struct mpoint { +struct ARB_SYMBOL_VISIBLE mpoint { double x, y, z; // [µm] double radius; // [μm] @@ -32,9 +33,9 @@ struct mpoint { } }; -mpoint lerp(const mpoint& a, const mpoint& b, double u); -bool is_collocated(const mpoint& a, const mpoint& b); -double distance(const mpoint& a, const mpoint& b); +ARB_ARBOR_API mpoint lerp(const mpoint& a, const mpoint& b, double u); +ARB_ARBOR_API bool is_collocated(const mpoint& a, const mpoint& b); +ARB_ARBOR_API double distance(const mpoint& a, const mpoint& b); // Indicate allowed comparison operations for classifying regions enum class comp_op { @@ -45,7 +46,7 @@ enum class comp_op { }; // Describe a cable segment between two adjacent samples. -struct msegment { +struct ARB_SYMBOL_VISIBLE msegment { msize_t id; mpoint prox; mpoint dist; @@ -56,7 +57,7 @@ struct msegment { // Describe a specific location on a morpholology. -struct mlocation { +struct ARB_SYMBOL_VISIBLE mlocation { // The id of the branch. msize_t branch; // The relative position on the branch ∈ [0,1]. @@ -66,21 +67,21 @@ struct mlocation { }; // branch ≠npos and 0 ≤ pos ≤ 1 -bool test_invariants(const mlocation&); +ARB_ARBOR_API bool test_invariants(const mlocation&); ARB_DEFINE_LEXICOGRAPHIC_ORDERING(mlocation, (a.branch,a.pos), (b.branch,b.pos)); using mlocation_list = std::vector<mlocation>; -std::ostream& operator<<(std::ostream& o, const mlocation_list& l); +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const mlocation_list& l); -// Tests whether each location in the list satisfies the invariants for a location, -// and that the locations in the vector are ordered. -bool test_invariants(const mlocation_list&); +//// Tests whether each location in the list satisfies the invariants for a location, +//// and that the locations in the vector are ordered. +//bool test_invariants(const mlocation_list&); // Multiset operations on location lists. -mlocation_list sum(const mlocation_list&, const mlocation_list&); -mlocation_list join(const mlocation_list&, const mlocation_list&); -mlocation_list intersection(const mlocation_list&, const mlocation_list&); -mlocation_list support(mlocation_list); +ARB_ARBOR_API mlocation_list sum(const mlocation_list&, const mlocation_list&); +ARB_ARBOR_API mlocation_list join(const mlocation_list&, const mlocation_list&); +ARB_ARBOR_API mlocation_list intersection(const mlocation_list&, const mlocation_list&); +ARB_ARBOR_API mlocation_list support(mlocation_list); // Describe an unbranched cable in the morphology. // @@ -88,7 +89,7 @@ mlocation_list support(mlocation_list); // They may be zero-length, and fork points in the morphology may have multiple, // equivalent zero-length cable representations. -struct mcable { +struct ARB_SYMBOL_VISIBLE mcable { // The id of the branch on which the cable lies. msize_t branch; @@ -112,10 +113,10 @@ struct mcable { ARB_DEFINE_LEXICOGRAPHIC_ORDERING(mcable, (a.branch,a.prox_pos,a.dist_pos), (b.branch,b.prox_pos,b.dist_pos)); using mcable_list = std::vector<mcable>; -std::ostream& operator<<(std::ostream& o, const mcable_list& c); +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const mcable_list& c); // Tests whether each cable in the list satisfies the invariants for a cable, // and that the cables in the vector are ordered. -bool test_invariants(const mcable_list&); +ARB_ARBOR_API bool test_invariants(const mcable_list&); } // namespace arb diff --git a/arbor/include/arbor/morph/region.hpp b/arbor/include/arbor/morph/region.hpp index 0f048860b3ca2b954bf68c0d63504e3b2a80fcb2..0439e23db09a47c873c8517b932b1dcda847f101 100644 --- a/arbor/include/arbor/morph/region.hpp +++ b/arbor/include/arbor/morph/region.hpp @@ -8,6 +8,7 @@ #include <utility> #include <vector> +#include <arbor/export.hpp> #include <arbor/morph/primitives.hpp> #include <arbor/morph/morphology.hpp> @@ -16,7 +17,7 @@ namespace arb { struct mprovider; struct region_tag {}; -class region { +class ARB_SYMBOL_VISIBLE region { public: template <typename Impl, typename = std::enable_if_t<std::is_base_of<region_tag, std::decay_t<Impl>>::value>> @@ -120,64 +121,64 @@ class locset; namespace reg { // An empty region. -region nil(); +ARB_ARBOR_API region nil(); // An explicit cable section. -region cable(msize_t, double, double); +ARB_ARBOR_API region cable(msize_t, double, double); // An explicit branch. -region branch(msize_t); +ARB_ARBOR_API region branch(msize_t); // Region with all segments with segment tag id. -region tagged(int id); +ARB_ARBOR_API region tagged(int id); // Region corresponding to a single segment. -region segment(int id); +ARB_ARBOR_API region segment(int id); // Region up to `distance` distal from points in `start`. -region distal_interval(locset start, double distance); +ARB_ARBOR_API region distal_interval(locset start, double distance); // Region up to `distance` proximal from points in `start`. -region proximal_interval(locset end, double distance); +ARB_ARBOR_API region proximal_interval(locset end, double distance); // Region with all segments with radius less than/less than or equal to r -region radius_lt(region reg, double r); -region radius_le(region reg, double r); +ARB_ARBOR_API region radius_lt(region reg, double r); +ARB_ARBOR_API region radius_le(region reg, double r); // Region with all segments with radius greater than/greater than or equal to r -region radius_gt(region reg, double r); -region radius_ge(region reg, double r); +ARB_ARBOR_API region radius_gt(region reg, double r); +ARB_ARBOR_API region radius_ge(region reg, double r); // Region with all segments with projection less than/less than or equal to r -region z_dist_from_root_lt(double r); -region z_dist_from_root_le(double r); +ARB_ARBOR_API region z_dist_from_root_lt(double r); +ARB_ARBOR_API region z_dist_from_root_le(double r); // Region with all segments with projection greater than/greater than or equal to r -region z_dist_from_root_gt(double r); -region z_dist_from_root_ge(double r); +ARB_ARBOR_API region z_dist_from_root_gt(double r); +ARB_ARBOR_API region z_dist_from_root_ge(double r); // Region with all segments in a cell. -region all(); +ARB_ARBOR_API region all(); // Region including all covers of included fork points. // (Pre-image of projection onto the topological tree.) -region complete(region); +ARB_ARBOR_API region complete(region); // Region associated with a name. -region named(std::string); +ARB_ARBOR_API region named(std::string); } // namespace reg // Union of two regions. -region join(region, region); +ARB_ARBOR_API region join(region, region); // Intersection of two regions. -region intersect(region, region); +ARB_ARBOR_API region intersect(region, region); // Closed complement of a region. -region complement(region); +ARB_ARBOR_API region complement(region); // (Closure of) set difference of two regions. -region difference(region a, region b); +ARB_ARBOR_API region difference(region a, region b); } // namespace arb diff --git a/arbor/include/arbor/morph/segment_tree.hpp b/arbor/include/arbor/morph/segment_tree.hpp index 4ce5a19ce2f92e946cc42f2dfb6e18b10c56399d..e934f102eb1d709e3fbb3c20136e0658e55fba29 100644 --- a/arbor/include/arbor/morph/segment_tree.hpp +++ b/arbor/include/arbor/morph/segment_tree.hpp @@ -5,12 +5,13 @@ #include <vector> #include <string> +#include <arbor/export.hpp> #include <arbor/morph/primitives.hpp> namespace arb { /// Morphology composed of segments. -class segment_tree { +class ARB_ARBOR_API segment_tree { struct child_prop { int count; bool is_fork() const { return count>1; } diff --git a/arbor/include/arbor/morph/stitch.hpp b/arbor/include/arbor/morph/stitch.hpp index d5086642a10dce1fc8a9ccfc31d7df2cc05cb532..c64b46e1de3eb61b7e398c591cf319a19c775120 100644 --- a/arbor/include/arbor/morph/stitch.hpp +++ b/arbor/include/arbor/morph/stitch.hpp @@ -6,6 +6,7 @@ #include <string> #include <vector> +#include <arbor/export.hpp> #include <arbor/morph/morphology.hpp> #include <arbor/morph/primitives.hpp> #include <arbor/morph/label_dict.hpp> @@ -42,7 +43,7 @@ struct mstitch { struct stitch_builder_impl; struct stitched_morphology; -struct stitch_builder { +struct ARB_ARBOR_API stitch_builder { stitch_builder(); stitch_builder(const stitch_builder&) = delete; @@ -71,7 +72,7 @@ private: struct stitched_morphology_impl; -struct stitched_morphology { +struct ARB_ARBOR_API stitched_morphology { stitched_morphology() = delete; stitched_morphology(const stitch_builder&); // implicit stitched_morphology(stitch_builder&&); // implicit diff --git a/arbor/include/arbor/profile/clock.hpp b/arbor/include/arbor/profile/clock.hpp index c4e9c5c9ca8a3e32dc27ac7303f74a65557db3ef..f7183673ac342ad9233678998a137dcd797e5a6b 100644 --- a/arbor/include/arbor/profile/clock.hpp +++ b/arbor/include/arbor/profile/clock.hpp @@ -1,5 +1,7 @@ #pragma once +#include <arbor/export.hpp> + typedef unsigned long long tick_type; // Assuming POSIX monotonic clock is available; add @@ -9,7 +11,7 @@ typedef unsigned long long tick_type; namespace arb { namespace profile { -tick_type posix_clock_gettime_monotonic_ns(); +ARB_ARBOR_API tick_type posix_clock_gettime_monotonic_ns(); struct posix_clock_monotonic { static constexpr double seconds_per_tick() { return 1.e-9; } diff --git a/arbor/include/arbor/profile/meter_manager.hpp b/arbor/include/arbor/profile/meter_manager.hpp index 9459023f2ae492567bba256f83a5eb5a6428f2d4..985e43c6e80c831fdfeacd99f3162a3a7aee200a 100644 --- a/arbor/include/arbor/profile/meter_manager.hpp +++ b/arbor/include/arbor/profile/meter_manager.hpp @@ -4,6 +4,7 @@ #include <string> #include <vector> +#include <arbor/export.hpp> #include <arbor/context.hpp> #include <arbor/profile/meter.hpp> #include <arbor/profile/timer.hpp> @@ -28,7 +29,7 @@ struct measurement { measurement(std::string, std::string, const std::vector<double>&, const context&); }; -class meter_manager { +class ARB_ARBOR_API meter_manager { private: bool started_ = false; @@ -58,8 +59,8 @@ struct meter_report { std::vector<std::string> hosts; }; -meter_report make_meter_report(const meter_manager& manager, const context& ctx); -std::ostream& operator<<(std::ostream& o, const meter_report& report); +ARB_ARBOR_API meter_report make_meter_report(const meter_manager& manager, const context& ctx); +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const meter_report& report); } // namespace profile } // namespace arb diff --git a/arbor/include/arbor/profile/profiler.hpp b/arbor/include/arbor/profile/profiler.hpp index f812d13d82895d3303348ffa0107a5adcde536d9..8d7d02c7b59cde44ed2a350d8231e4c3cf029f2d 100644 --- a/arbor/include/arbor/profile/profiler.hpp +++ b/arbor/include/arbor/profile/profiler.hpp @@ -5,6 +5,7 @@ #include <unordered_map> #include <vector> +#include <arbor/export.hpp> #include <arbor/context.hpp> #include <arbor/profile/timer.hpp> @@ -33,15 +34,16 @@ struct profile { double wall_time; }; +// TODO: remove declaration and update the docs void profiler_clear(); -void profiler_initialize(context& ctx); -void profiler_enter(std::size_t region_id); -void profiler_leave(); +ARB_ARBOR_API void profiler_initialize(context& ctx); +ARB_ARBOR_API void profiler_enter(std::size_t region_id); +ARB_ARBOR_API void profiler_leave(); -profile profiler_summary(); -std::size_t profiler_region_id(const std::string& name); +ARB_ARBOR_API profile profiler_summary(); +ARB_ARBOR_API std::size_t profiler_region_id(const std::string& name); -std::ostream& operator<<(std::ostream&, const profile&); +ARB_ARBOR_API std::ostream& operator<<(std::ostream&, const profile&); } // namespace profile } // namespace arb diff --git a/arbor/include/arbor/recipe.hpp b/arbor/include/arbor/recipe.hpp index 2853d4d0b81b788c96b1185cb23f9b9c298e2d66..ed5e621850c9f9de547056278568741db21db822 100644 --- a/arbor/include/arbor/recipe.hpp +++ b/arbor/include/arbor/recipe.hpp @@ -4,6 +4,7 @@ #include <utility> #include <vector> +#include <arbor/export.hpp> #include <arbor/common_types.hpp> #include <arbor/event_generator.hpp> #include <arbor/util/unique_any.hpp> @@ -60,7 +61,7 @@ struct gap_junction_connection { peer(std::move(peer)), local(std::move(local)), weight(g) {} }; -class recipe { +class ARB_ARBOR_API recipe { public: virtual cell_size_type num_cells() const = 0; diff --git a/arbor/include/arbor/s_expr.hpp b/arbor/include/arbor/s_expr.hpp index e6ac0d5156f279605dc833e4265ca602b47afc37..e8ddb218eb9c96136fcc1412247e748ab4a585f9 100644 --- a/arbor/include/arbor/s_expr.hpp +++ b/arbor/include/arbor/s_expr.hpp @@ -11,6 +11,8 @@ #include <variant> #include <vector> +#include <arbor/export.hpp> + namespace arb { struct src_location { @@ -24,7 +26,7 @@ struct src_location { {} }; -std::ostream& operator<<(std::ostream& o, const src_location& l); +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const src_location& l); enum class tok { nil, @@ -38,7 +40,7 @@ enum class tok { error // special error state marker }; -std::ostream& operator<<(std::ostream&, const tok&); +ARB_ARBOR_API std::ostream& operator<<(std::ostream&, const tok&); struct token { src_location loc; @@ -46,7 +48,7 @@ struct token { std::string spelling; }; -std::ostream& operator<<(std::ostream&, const token&); +ARB_ARBOR_API std::ostream& operator<<(std::ostream&, const token&); struct symbol { std::string str; @@ -57,7 +59,7 @@ inline symbol operator"" _symbol(const char* chars, size_t size) { return {chars}; } -struct s_expr { +struct ARB_ARBOR_API s_expr { template <typename U> struct s_pair { U head = U(); @@ -242,16 +244,16 @@ struct s_expr { const_iterator cbegin() const { return {*this}; } const_iterator cend() const { return const_iterator::sentinel{}; } - friend std::ostream& operator<<(std::ostream& o, const s_expr& x); + ARB_ARBOR_API friend std::ostream& operator<<(std::ostream& o, const s_expr& x); }; // Build s-expr from string -s_expr parse_s_expr(const std::string& line); +ARB_ARBOR_API s_expr parse_s_expr(const std::string& line); // Length of the s-expr -std::size_t length(const s_expr& l); +ARB_ARBOR_API std::size_t length(const s_expr& l); // Location of the head of the s-expr -src_location location(const s_expr& l); +ARB_ARBOR_API src_location location(const s_expr& l); } // namespace arb diff --git a/arbor/include/arbor/schedule.hpp b/arbor/include/arbor/schedule.hpp index e75903afe268595f2458ed43caf54a706f1a3282..253efa7bf7bcc308452216248e9a3831f3da8c48 100644 --- a/arbor/include/arbor/schedule.hpp +++ b/arbor/include/arbor/schedule.hpp @@ -11,6 +11,7 @@ #include <arbor/assert.hpp> #include <arbor/common_types.hpp> #include <arbor/util/extra_traits.hpp> +#include <arbor/export.hpp> // Time schedules for probe–sampler associations. @@ -103,7 +104,7 @@ inline schedule::schedule(): schedule(empty_schedule{}) {} // Common schedules // Schedule at k·dt for integral k≥0 within the interval [t0, t1). -class regular_schedule_impl { +class ARB_ARBOR_API regular_schedule_impl { public: explicit regular_schedule_impl(time_type t0, time_type dt, time_type t1): t0_(t0), t1_(t1), dt_(dt), oodt_(1./dt) @@ -135,7 +136,7 @@ inline schedule regular_schedule(time_type dt) { // Schedule at times given explicitly via a provided sorted sequence. -class explicit_schedule_impl { +class ARB_ARBOR_API explicit_schedule_impl { public: explicit_schedule_impl(const explicit_schedule_impl&) = default; explicit_schedule_impl(explicit_schedule_impl&&) = default; diff --git a/arbor/include/arbor/simulation.hpp b/arbor/include/arbor/simulation.hpp index 1f4afc6926803bb516e54f1af564854096dd74cb..0559f40f257cd3032e67ea17996e00f98c55e01d 100644 --- a/arbor/include/arbor/simulation.hpp +++ b/arbor/include/arbor/simulation.hpp @@ -5,6 +5,7 @@ #include <unordered_map> #include <vector> +#include <arbor/export.hpp> #include <arbor/common_types.hpp> #include <arbor/context.hpp> #include <arbor/domain_decomposition.hpp> @@ -21,7 +22,7 @@ using spike_export_function = std::function<void(const std::vector<spike>&)>; // simulation_state comprises private implementation for simulation class. class simulation_state; -class simulation { +class ARB_ARBOR_API simulation { public: simulation(const recipe& rec, const domain_decomposition& decomp, const context& ctx); diff --git a/arbor/include/arbor/spike_event.hpp b/arbor/include/arbor/spike_event.hpp index 102f3c42403dc1402f5b1cfda2e0a2b399219c30..405a357ba4e5bdcbf0f5bf0de1777232ba60fd66 100644 --- a/arbor/include/arbor/spike_event.hpp +++ b/arbor/include/arbor/spike_event.hpp @@ -4,6 +4,7 @@ #include <tuple> #include <vector> +#include <arbor/export.hpp> #include <arbor/common_types.hpp> namespace arb { @@ -33,6 +34,6 @@ struct cell_spike_events { using cse_vector = std::vector<cell_spike_events>; -std::ostream& operator<<(std::ostream&, const spike_event&); +ARB_ARBOR_API std::ostream& operator<<(std::ostream&, const spike_event&); } // namespace arb diff --git a/arbor/include/arbor/spike_source_cell.hpp b/arbor/include/arbor/spike_source_cell.hpp index 9d04282730a1b3c888ce5b2a986c383d7c6f8f7e..5688b9949dd76016cbac40a6f25716efe680add7 100644 --- a/arbor/include/arbor/spike_source_cell.hpp +++ b/arbor/include/arbor/spike_source_cell.hpp @@ -1,6 +1,7 @@ #pragma once #include <arbor/common_types.hpp> +#include <arbor/export.hpp> #include <arbor/schedule.hpp> namespace arb { @@ -8,7 +9,7 @@ namespace arb { // Cell description returned by recipe::cell_description(gid) for cells with // recipe::cell_kind(gid) returning cell_kind::spike_source -struct spike_source_cell { +struct ARB_SYMBOL_VISIBLE spike_source_cell { cell_tag_type source; // Label of source. schedule seq; diff --git a/arbor/include/arbor/symmetric_recipe.hpp b/arbor/include/arbor/symmetric_recipe.hpp index 7fdf873221a1e2bf9af162b210ad18e44a416395..57012d063ca18d6f25fbc6bb9e78196e0488687a 100644 --- a/arbor/include/arbor/symmetric_recipe.hpp +++ b/arbor/include/arbor/symmetric_recipe.hpp @@ -2,6 +2,7 @@ #include <any> +#include <arbor/export.hpp> #include <arbor/recipe.hpp> #include <arbor/util/unique_any.hpp> @@ -21,7 +22,7 @@ public: // as many ranks as tile indicates. Its functions call the // underlying functions of tile and perform transformations // on the results when needed. -class symmetric_recipe: public recipe { +class ARB_ARBOR_API symmetric_recipe: public recipe { public: symmetric_recipe(std::unique_ptr<tile> rec): tiled_recipe_(std::move(rec)) {} diff --git a/arbor/include/arbor/util/any_ptr.hpp b/arbor/include/arbor/util/any_ptr.hpp index f148c566bbd5455d32dd5158c3a6a7942060d09b..c6e11b823c95ea622bd3bae5e858641175cc700a 100644 --- a/arbor/include/arbor/util/any_ptr.hpp +++ b/arbor/include/arbor/util/any_ptr.hpp @@ -29,13 +29,14 @@ #include <cstddef> #include <type_traits> +#include <arbor/export.hpp> #include <arbor/util/any_cast.hpp> #include <arbor/util/lexcmp_def.hpp> namespace arb { namespace util { -struct any_ptr { +struct ARB_SYMBOL_VISIBLE any_ptr { any_ptr() {} any_ptr(std::nullptr_t) {} diff --git a/arbor/include/arbor/util/unique_any.hpp b/arbor/include/arbor/util/unique_any.hpp index 3b4ebffce308929d152ffcbb2df59bf387a6735e..9cbcf67d14077f9dfb3fac0a56052de2afd5a75f 100644 --- a/arbor/include/arbor/util/unique_any.hpp +++ b/arbor/include/arbor/util/unique_any.hpp @@ -5,6 +5,7 @@ #include <typeinfo> #include <type_traits> +#include <arbor/export.hpp> #include <arbor/util/any_cast.hpp> #include <arbor/util/extra_traits.hpp> @@ -44,7 +45,7 @@ namespace arb { namespace util { -class unique_any { +class ARB_SYMBOL_VISIBLE unique_any { public: constexpr unique_any() = default; diff --git a/arbor/include/arbor/util/visibility.hpp b/arbor/include/arbor/util/visibility.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b818091cb41783b5a22af9b5907e3470136c1210 --- /dev/null +++ b/arbor/include/arbor/util/visibility.hpp @@ -0,0 +1,51 @@ +#pragma once + +#if defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC) +// Intel +# if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__) +# define ARB_SYMBOL_IMPORT __attribute__((__dllimport__)) +# define ARB_SYMBOL_EXPORT __attribute__((__dllexport__)) +# elif defined(__GNUC__) && (__GNUC__ >= 4) +# define ARB_SYMBOL_EXPORT __attribute__((visibility("default"))) +# define ARB_SYMBOL_VISIBLE __attribute__((__visibility__("default"))) +# endif + +#elif defined(__clang__) +// Clang C++ +# if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__) +# define ARB_SYMBOL_IMPORT __attribute__((__dllimport__)) +# define ARB_SYMBOL_EXPORT __attribute__((__dllexport__)) +# else +# define ARB_SYMBOL_EXPORT __attribute__((__visibility__("default"))) +# define ARB_SYMBOL_VISIBLE __attribute__((__visibility__("default"))) +# endif + +# elif defined(__GNUC__) +// GNU C++: +# if __GNUC__ >= 4 +# if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__) +# define ARB_SYMBOL_IMPORT __attribute__((__dllimport__)) +# define ARB_SYMBOL_EXPORT __attribute__((__dllexport__)) +# else +# define ARB_SYMBOL_EXPORT __attribute__((__visibility__("default"))) +# define ARB_SYMBOL_VISIBLE __attribute__((__visibility__("default"))) +# endif +# endif + +#endif + +#if defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) +// MacOS +# define ARB_ON_MACOS +#endif + +#ifndef ARB_SYMBOL_IMPORT +# define ARB_SYMBOL_IMPORT +#endif +#ifndef ARB_SYMBOL_EXPORT +# define ARB_SYMBOL_EXPORT +#endif +#ifndef ARB_SYMBOL_VISIBLE +# define ARB_SYMBOL_VISIBLE +#endif + diff --git a/arbor/include/git-source-id b/arbor/include/git-source-id index c3fc3ec9e4e793f3b42775f89be2da8c17f948c1..f2cc49cbe4c1b61c1fd9b382a3a0aaae15bac31c 100755 --- a/arbor/include/git-source-id +++ b/arbor/include/git-source-id @@ -44,16 +44,18 @@ done cat << __end__ #pragma once +#include <arbor/export.hpp> + namespace arb { -extern const char* source_id; -extern const char* arch; -extern const char* build_config; -extern const char* version; -extern const char* full_build_id; +ARB_ARBOR_API extern const char* source_id; +ARB_ARBOR_API extern const char* arch; +ARB_ARBOR_API extern const char* build_config; +ARB_ARBOR_API extern const char* version; +ARB_ARBOR_API extern const char* full_build_id; constexpr int version_major = ${version_major}; constexpr int version_minor = ${version_minor}; constexpr int version_patch = ${version_patch}; -extern const char* version_dev; +ARB_ARBOR_API extern const char* version_dev; } #define ARB_SOURCE_ID "${gitlog}" diff --git a/arbor/label_resolution.hpp b/arbor/label_resolution.hpp index 5912672e13e2642c98693cdf7fe73978df3cb89c..7cd69a5bd8cbc8908cb9293fb3bf6d9b2ad17ea4 100644 --- a/arbor/label_resolution.hpp +++ b/arbor/label_resolution.hpp @@ -3,6 +3,7 @@ #include <unordered_map> #include <vector> +#include <arbor/export.hpp> #include <arbor/arbexcept.hpp> #include <arbor/common_types.hpp> #include <arbor/util/expected.hpp> @@ -17,7 +18,7 @@ using lid_hopefully = arb::util::expected<cell_lid_type, std::string>; // `sizes` is a partitioning vector for associating a cell with a set of // (label, range) pairs in `labels`, `ranges`. // gids of the cells are unknown. -class cell_label_range { +class ARB_ARBOR_API cell_label_range { public: cell_label_range() = default; cell_label_range(cell_label_range&&) = default; @@ -52,7 +53,7 @@ private: }; // Struct for associating each cell of `cell_label_range` with a gid. -struct cell_labels_and_gids { +struct ARB_ARBOR_API cell_labels_and_gids { cell_labels_and_gids() = default; cell_labels_and_gids(cell_label_range lr, std::vector<cell_gid_type> gids); @@ -67,7 +68,7 @@ struct cell_labels_and_gids { // Class constructed from `cell_labels_and_ranges`: // Represents the information in the object in a more // structured manner for lid resolution in `resolver` -class label_resolution_map { +class ARB_ARBOR_API label_resolution_map { public: struct range_set { std::vector<lid_range> ranges; @@ -86,20 +87,20 @@ private: std::unordered_map<cell_gid_type, std::unordered_map<cell_tag_type, range_set>> map; }; -struct round_robin_state { +struct ARB_ARBOR_API round_robin_state { cell_size_type state = 0; round_robin_state() : state(0) {}; round_robin_state(cell_lid_type state) : state(state) {}; lid_hopefully update(const label_resolution_map::range_set& range); }; -struct assert_univalent_state { +struct ARB_ARBOR_API assert_univalent_state { lid_hopefully update(const label_resolution_map::range_set& range); }; // Struct used for resolving the lid of a (gid, label, lid_selection_policy) input. // Requires a `label_resolution_map` which stores the constant mapping of (gid, label) pairs to lid sets. -struct resolver { +struct ARB_ARBOR_API resolver { resolver(const label_resolution_map* label_map): label_map_(label_map) {} cell_lid_type resolve(const cell_global_label_type& iden); diff --git a/arbor/lif_cell_group.hpp b/arbor/lif_cell_group.hpp index feda74c97808f5fcbb90eca20b959bf30406da7e..b89e442f863206f13f5b5b1c25e2b293f8044be8 100644 --- a/arbor/lif_cell_group.hpp +++ b/arbor/lif_cell_group.hpp @@ -2,6 +2,7 @@ #include <vector> +#include <arbor/export.hpp> #include <arbor/common_types.hpp> #include <arbor/lif_cell.hpp> #include <arbor/recipe.hpp> @@ -13,7 +14,7 @@ namespace arb { -class lif_cell_group: public cell_group { +class ARB_ARBOR_API lif_cell_group: public cell_group { public: using value_type = double; diff --git a/arbor/mc_cell_group.hpp b/arbor/mc_cell_group.hpp index 173aae9ae6681cfd4d08b90979d52de88a51595b..3640c8cf248a66e1e43f790665f1b11bd9ddbe77 100644 --- a/arbor/mc_cell_group.hpp +++ b/arbor/mc_cell_group.hpp @@ -7,6 +7,7 @@ #include <unordered_map> #include <vector> +#include <arbor/export.hpp> #include <arbor/common_types.hpp> #include <arbor/recipe.hpp> #include <arbor/sampling.hpp> @@ -23,7 +24,7 @@ namespace arb { -class mc_cell_group: public cell_group { +class ARB_ARBOR_API mc_cell_group: public cell_group { public: mc_cell_group() = default; diff --git a/arbor/mechcat.cpp b/arbor/mechcat.cpp index 3dc187742e5c5a5c1e04ef63ef90a7e07528f573..161c5f9a58253d770e65f8db721d08ac66de02eb 100644 --- a/arbor/mechcat.cpp +++ b/arbor/mechcat.cpp @@ -592,7 +592,7 @@ std::pair<mechanism_ptr, mechanism_overrides> mechanism_catalogue::instance_impl mechanism_catalogue::~mechanism_catalogue() = default; -const mechanism_catalogue& load_catalogue(const std::string& fn) { +ARB_ARBOR_API const mechanism_catalogue& load_catalogue(const std::string& fn) { typedef const void* global_catalogue_t(); global_catalogue_t* get_catalogue = nullptr; try { diff --git a/arbor/merge_events.hpp b/arbor/merge_events.hpp index 9a8581f62e4d766fb9a222773fbbb8f7d951bdea..9ce69241eac9a9559af69df9ab6ff8359c86f440 100644 --- a/arbor/merge_events.hpp +++ b/arbor/merge_events.hpp @@ -3,6 +3,7 @@ #include <iosfwd> #include <vector> +#include <arbor/export.hpp> #include <arbor/event_generator.hpp> #include <arbor/spike_event.hpp> @@ -21,7 +22,7 @@ namespace impl { // The tournament tree is used internally by the merge_events method, and // it is not intended for use elsewhere. It is exposed here for unit testing // of its functionality. - class tourney_tree { + class ARB_ARBOR_API tourney_tree { using key_val = std::pair<unsigned, spike_event>; public: diff --git a/arbor/morph/cv_data.cpp b/arbor/morph/cv_data.cpp index 410bac0cc4bc1d1db0f2b6936f4ea3d9563b1925..719d609ab44566bed0c6e6b16d8bd304ba71afbc 100644 --- a/arbor/morph/cv_data.cpp +++ b/arbor/morph/cv_data.cpp @@ -137,7 +137,7 @@ fvm_size_type cell_cv_data::size() const { return impl_->cv_parent.size(); } -std::optional<cell_cv_data> cv_data(const cable_cell& cell) { +ARB_ARBOR_API std::optional<cell_cv_data> cv_data(const cable_cell& cell) { if (auto policy = cell.decorations().defaults().discretization) { return cell_cv_data(cell, policy->cv_boundary_points(cell)); } @@ -154,7 +154,7 @@ cell_cv_data::cell_cv_data(const cable_cell& cell, const locset& lset): provider_(cell.provider()) {} -std::vector<cv_proportion> intersect_region(const region& reg, const cell_cv_data& geom, bool by_length) { +ARB_ARBOR_API std::vector<cv_proportion> intersect_region(const region& reg, const cell_cv_data& geom, bool by_length) { const auto& mp = geom.provider(); const auto& embedding = mp.embedding(); diff --git a/arbor/morph/locset.cpp b/arbor/morph/locset.cpp index 0cb46fe2d95ffe8a088d53f57bb9ea14e6e3a5b5..3502caa0086ac8567511e1711a9d8cef6a47fe8f 100644 --- a/arbor/morph/locset.cpp +++ b/arbor/morph/locset.cpp @@ -33,7 +33,7 @@ void assert_valid(mlocation x) { struct nil_: locset_tag {}; -locset nil() { +ARB_ARBOR_API locset nil() { return locset{nil_{}}; } @@ -52,7 +52,7 @@ struct location_: locset_tag { mlocation loc; }; -locset location(msize_t branch, double pos) { +ARB_ARBOR_API locset location(msize_t branch, double pos) { mlocation loc{branch, pos}; assert_valid(loc); return locset{location_{loc}}; @@ -101,7 +101,7 @@ std::ostream& operator<<(std::ostream& o, const location_list_& x) { struct terminal_: locset_tag {}; -locset terminal() { +ARB_ARBOR_API locset terminal() { return locset{terminal_{}}; } @@ -162,7 +162,7 @@ mlocation_list thingify_(const proximal_translate_& dt, const mprovider& p) { return L; } -locset proximal_translate(locset ls, double distance) { +ARB_ARBOR_API locset proximal_translate(locset ls, double distance) { return locset(proximal_translate_{ls, distance}); } @@ -177,7 +177,7 @@ struct distal_translate_: locset_tag { double distance; }; -locset distal_translate(locset ls, double distance) { +ARB_ARBOR_API locset distal_translate(locset ls, double distance) { return locset(distal_translate_{ls, distance}); } @@ -253,7 +253,7 @@ std::ostream& operator<<(std::ostream& o, const distal_translate_& l) { struct root_: locset_tag {}; -locset root() { +ARB_ARBOR_API locset root() { return locset{root_{}}; } @@ -269,7 +269,7 @@ std::ostream& operator<<(std::ostream& o, const root_& x) { struct segments_: locset_tag {}; -locset segment_boundaries() { +ARB_ARBOR_API locset segment_boundaries() { return locset{segments_{}}; } @@ -289,7 +289,7 @@ struct on_branches_: locset_tag { double pos; }; -locset on_branches(double pos) { +ARB_ARBOR_API locset on_branches(double pos) { return locset{on_branches_{pos}}; } @@ -315,7 +315,7 @@ struct named_: locset_tag { std::string name; }; -locset named(std::string name) { +ARB_ARBOR_API locset named(std::string name) { return locset(named_{std::move(name)}); } @@ -334,7 +334,7 @@ struct most_distal_: locset_tag { region reg; }; -locset most_distal(region reg) { +ARB_ARBOR_API locset most_distal(region reg) { return locset(most_distal_{std::move(reg)}); } @@ -358,7 +358,7 @@ struct most_proximal_: locset_tag { region reg; }; -locset most_proximal(region reg) { +ARB_ARBOR_API locset most_proximal(region reg) { return locset(most_proximal_{std::move(reg)}); } @@ -386,7 +386,7 @@ struct boundary_: locset_tag { region reg; }; -locset boundary(region reg) { +ARB_ARBOR_API locset boundary(region reg) { return locset(boundary_(std::move(reg))); }; @@ -422,7 +422,7 @@ struct cboundary_: locset_tag { region reg; }; -locset cboundary(region reg) { +ARB_ARBOR_API locset cboundary(region reg) { return locset(cboundary_(std::move(reg))); }; @@ -462,7 +462,7 @@ struct on_components_: locset_tag { region reg; }; -locset on_components(double relpos, region reg) { +ARB_ARBOR_API locset on_components(double relpos, region reg) { return locset(on_components_(relpos, std::move(reg))); } @@ -541,7 +541,7 @@ struct uniform_: locset_tag { uint64_t seed; }; -locset uniform(arb::region reg, unsigned left, unsigned right, uint64_t seed) { +ARB_ARBOR_API locset uniform(arb::region reg, unsigned left, unsigned right, uint64_t seed) { return locset(uniform_{reg, left, right, seed}); } @@ -647,7 +647,7 @@ struct lsup_: locset_tag { lsup_(locset arg): arg(std::move(arg)) {} }; -locset support(locset arg) { +ARB_ARBOR_API locset support(locset arg) { return locset{lsup_{std::move(arg)}}; } @@ -686,7 +686,7 @@ mlocation_list thingify_(const lrestrict_& P, const mprovider& p) { return L; } -locset restrict(locset ls, region reg) { +ARB_ARBOR_API locset restrict(locset ls, region reg) { return locset{lrestrict_{std::move(ls), std::move(reg)}}; } @@ -704,11 +704,11 @@ locset intersect(locset lhs, locset rhs) { return locset(ls::land(std::move(lhs), std::move(rhs))); } -locset join(locset lhs, locset rhs) { +ARB_ARBOR_API locset join(locset lhs, locset rhs) { return locset(ls::lor(std::move(lhs), std::move(rhs))); } -locset sum(locset lhs, locset rhs) { +ARB_ARBOR_API locset sum(locset lhs, locset rhs) { return locset(ls::lsum(std::move(lhs), std::move(rhs))); } diff --git a/arbor/morph/morphology.cpp b/arbor/morph/morphology.cpp index ff126d7372fa91c771a6412041979722c7f3f6a9..34159271493ec2920ca64c836694b2a18cbcf447 100644 --- a/arbor/morph/morphology.cpp +++ b/arbor/morph/morphology.cpp @@ -173,13 +173,13 @@ msize_t morphology::num_branches() const { return impl_->branches_.size(); } -std::ostream& operator<<(std::ostream& o, const morphology& m) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const morphology& m) { return o << *m.impl_; } // Utilities. -mlocation_list minset(const morphology& m, const mlocation_list& in) { +ARB_ARBOR_API mlocation_list minset(const morphology& m, const mlocation_list& in) { mlocation_list L; std::stack<msize_t> stack; @@ -213,7 +213,7 @@ mlocation_list minset(const morphology& m, const mlocation_list& in) { return L; } -mlocation_list maxset(const morphology& m, const mlocation_list& in_) { +ARB_ARBOR_API mlocation_list maxset(const morphology& m, const mlocation_list& in_) { mlocation_list L; // Sort the input in reverse order, so that more distal locations @@ -244,7 +244,7 @@ mlocation_list maxset(const morphology& m, const mlocation_list& in_) { return L; } -mlocation canonical(const morphology& m, mlocation loc) { +ARB_ARBOR_API mlocation canonical(const morphology& m, mlocation loc) { if (loc.pos==0) { msize_t parent = m.branch_parent(loc.branch); return parent==mnpos? mlocation{0, 0.}: mlocation{parent, 1.}; @@ -337,7 +337,7 @@ bool mextent::intersects(const mcable_list& a) const { return false; } -mextent intersect(const mextent& a, const mextent& b) { +ARB_ARBOR_API mextent intersect(const mextent& a, const mextent& b) { auto precedes = [](mcable x, mcable y) { return x.branch<y.branch || (x.branch==y.branch && x.dist_pos<y.prox_pos); }; @@ -387,7 +387,7 @@ mextent join(const mextent& a, const mextent& b) { return m; } -std::vector<mextent> components(const morphology& m, const mextent& ex) { +ARB_ARBOR_API std::vector<mextent> components(const morphology& m, const mextent& ex) { std::unordered_map<mlocation, unsigned> component_index; std::vector<mcable_list> component_cables; diff --git a/arbor/morph/primitives.cpp b/arbor/morph/primitives.cpp index d4b780feccbb4b15165015e8f8c3871fe1a435f4..be9444b7e07d33d1ca0d5c3c31a611d0ffd0cc24 100644 --- a/arbor/morph/primitives.cpp +++ b/arbor/morph/primitives.cpp @@ -36,7 +36,7 @@ int multiplicity(T& it, T end) { // interpolate between two points. -mpoint lerp(const mpoint& a, const mpoint& b, double u) { +ARB_ARBOR_API mpoint lerp(const mpoint& a, const mpoint& b, double u) { return { math::lerp(a.x, b.x, u), math::lerp(a.y, b.y, u), math::lerp(a.z, b.z, u), @@ -44,12 +44,12 @@ mpoint lerp(const mpoint& a, const mpoint& b, double u) { } // test if two morphology sample points share the same location. -bool is_collocated(const mpoint& a, const mpoint& b) { +ARB_ARBOR_API bool is_collocated(const mpoint& a, const mpoint& b) { return a.x==b.x && a.y==b.y && a.z==b.z; } // calculate the distance between two morphology sample points. -double distance(const mpoint& a, const mpoint& b) { +ARB_ARBOR_API double distance(const mpoint& a, const mpoint& b) { double dx = a.x - b.x; double dy = a.y - b.y; double dz = a.z - b.z; @@ -57,18 +57,18 @@ double distance(const mpoint& a, const mpoint& b) { return std::sqrt(dx*dx + dy*dy + dz*dz); } -bool test_invariants(const mlocation& l) { +ARB_ARBOR_API bool test_invariants(const mlocation& l) { return (0.<=l.pos && l.pos<=1.) && l.branch!=mnpos; } -mlocation_list sum(const mlocation_list& lhs, const mlocation_list& rhs) { +ARB_ARBOR_API mlocation_list sum(const mlocation_list& lhs, const mlocation_list& rhs) { mlocation_list v; v.resize(lhs.size() + rhs.size()); std::merge(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), v.begin()); return v; } -mlocation_list join(const mlocation_list& lhs, const mlocation_list& rhs) { +ARB_ARBOR_API mlocation_list join(const mlocation_list& lhs, const mlocation_list& rhs) { mlocation_list L; L.reserve(lhs.size()+rhs.size()); @@ -91,7 +91,7 @@ mlocation_list join(const mlocation_list& lhs, const mlocation_list& rhs) { return L; } -mlocation_list intersection(const mlocation_list& lhs, const mlocation_list& rhs) { +ARB_ARBOR_API mlocation_list intersection(const mlocation_list& lhs, const mlocation_list& rhs) { mlocation_list L; L.reserve(lhs.size()+rhs.size()); @@ -118,41 +118,41 @@ mlocation_list intersection(const mlocation_list& lhs, const mlocation_list& rhs return L; } -mlocation_list support(mlocation_list L) { +ARB_ARBOR_API mlocation_list support(mlocation_list L) { util::unique_in_place(L); return L; } -bool test_invariants(const mcable& c) { +ARB_ARBOR_API bool test_invariants(const mcable& c) { return (0.<=c.prox_pos && c.prox_pos<=c.dist_pos && c.dist_pos<=1.) && c.branch!=mnpos; } -bool test_invariants(const mcable_list& l) { +ARB_ARBOR_API bool test_invariants(const mcable_list& l) { return std::is_sorted(l.begin(), l.end()) && l.end()==std::find_if(l.begin(), l.end(), [](const mcable& c) {return !test_invariants(c);}); } -std::ostream& operator<<(std::ostream& o, const mpoint& p) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const mpoint& p) { return o << "(point " << p.x << " " << p.y << " " << p.z << " " << p.radius << ")"; } -std::ostream& operator<<(std::ostream& o, const msegment& s) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const msegment& s) { return o << "(segment " << s.id << " " << s.prox << " " << s.dist << " " << s.tag << ")"; } -std::ostream& operator<<(std::ostream& o, const mlocation& l) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const mlocation& l) { return o << "(location " << l.branch << " " << l.pos << ")"; } -std::ostream& operator<<(std::ostream& o, const mlocation_list& l) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const mlocation_list& l) { return o << "(list " << io::sepval(l, ' ') << ")"; } -std::ostream& operator<<(std::ostream& o, const mcable& c) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const mcable& c) { return o << "(cable " << c.branch << " " << c.prox_pos << " " << c.dist_pos << ")"; } -std::ostream& operator<<(std::ostream& o, const mcable_list& c) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const mcable_list& c) { return o << "(list " << io::sepval(c, ' ') << ")"; } diff --git a/arbor/morph/region.cpp b/arbor/morph/region.cpp index 038b1364a3cdc2a395ae42597c78eebceaa28d6e..cf59e6ea255c7441a02cb6cd5f708fee1917d0a4 100644 --- a/arbor/morph/region.cpp +++ b/arbor/morph/region.cpp @@ -32,7 +32,7 @@ std::optional<mcable> intersect(const mcable& a, const mcable& b) { struct nil_: region_tag {}; -region nil() { +ARB_ARBOR_API region nil() { return region{nil_{}}; } @@ -52,7 +52,7 @@ struct cable_: region_tag { mcable cable; }; -region cable(msize_t id, double prox, double dist) { +ARB_ARBOR_API region cable(msize_t id, double prox, double dist) { mcable c{id, prox, dist}; if (!test_invariants(c)) { throw invalid_mcable(c); @@ -60,7 +60,7 @@ region cable(msize_t id, double prox, double dist) { return region(cable_{c}); } -region branch(msize_t bid) { +ARB_ARBOR_API region branch(msize_t bid) { return cable(bid, 0, 1); } @@ -137,7 +137,7 @@ struct tagged_: region_tag { int tag; }; -region tagged(int id) { +ARB_ARBOR_API region tagged(int id) { return region(tagged_{id}); } @@ -170,7 +170,7 @@ struct segment_: region_tag { int id; }; -region segment(int id) { +ARB_ARBOR_API region segment(int id) { return region(segment_{id}); } @@ -194,7 +194,7 @@ std::ostream& operator<<(std::ostream& o, const segment_& reg) { struct all_: region_tag {}; -region all() { +ARB_ARBOR_API region all() { return region(all_{}); } @@ -220,7 +220,7 @@ struct distal_interval_: region_tag { double distance; //um }; -region distal_interval(locset start, double distance) { +ARB_ARBOR_API region distal_interval(locset start, double distance) { return region(distal_interval_{start, distance}); } @@ -295,7 +295,7 @@ struct proximal_interval_: region_tag { double distance; //um }; -region proximal_interval(locset end, double distance) { +ARB_ARBOR_API region proximal_interval(locset end, double distance) { return region(proximal_interval_{end, distance}); } @@ -368,7 +368,7 @@ struct radius_lt_: region_tag { double val; //um }; -region radius_lt(region reg, double val) { +ARB_ARBOR_API region radius_lt(region reg, double val) { return region(radius_lt_{reg, val}); } @@ -387,7 +387,7 @@ struct radius_le_: region_tag { double val; //um }; -region radius_le(region reg, double val) { +ARB_ARBOR_API region radius_le(region reg, double val) { return region(radius_le_{reg, val}); } @@ -406,7 +406,7 @@ struct radius_gt_: region_tag { double val; //um }; -region radius_gt(region reg, double val) { +ARB_ARBOR_API region radius_gt(region reg, double val) { return region(radius_gt_{reg, val}); } @@ -425,7 +425,7 @@ struct radius_ge_: region_tag { double val; //um }; -region radius_ge(region reg, double val) { +ARB_ARBOR_API region radius_ge(region reg, double val) { return region(radius_ge_{reg, val}); } @@ -521,7 +521,7 @@ std::ostream& operator<<(std::ostream& o, const projection_ge_& r) { return o << "(projection-ge " << r.val << ")"; } -region z_dist_from_root_lt(double r0) { +ARB_ARBOR_API region z_dist_from_root_lt(double r0) { if (r0 == 0) { return {}; } @@ -530,19 +530,19 @@ region z_dist_from_root_lt(double r0) { return intersect(std::move(lt), std::move(gt)); } -region z_dist_from_root_le(double r0) { +ARB_ARBOR_API region z_dist_from_root_le(double r0) { region le = reg::projection_le(r0); region ge = reg::projection_ge(-r0); return intersect(std::move(le), std::move(ge)); } -region z_dist_from_root_gt(double r0) { +ARB_ARBOR_API region z_dist_from_root_gt(double r0) { region lt = reg::projection_lt(-r0); region gt = reg::projection_gt(r0); return region{join(std::move(lt), std::move(gt))}; } -region z_dist_from_root_ge(double r0) { +ARB_ARBOR_API region z_dist_from_root_ge(double r0) { region lt = reg::projection_le(-r0); region gt = reg::projection_ge(r0); return region{join(std::move(lt), std::move(gt))}; @@ -554,7 +554,7 @@ struct named_: region_tag { std::string name; }; -region named(std::string name) { +ARB_ARBOR_API region named(std::string name) { return region(named_{std::move(name)}); } @@ -573,7 +573,7 @@ struct super_: region_tag { region reg; }; -region complete(region r) { +ARB_ARBOR_API region complete(region r) { return region(super_{std::move(r)}); } @@ -733,19 +733,19 @@ std::ostream& operator<<(std::ostream& o, const reg_minus& x) { // namespace with region so that ADL allows for construction of expressions // with regions without having to namespace qualify these operations. -region intersect(region l, region r) { +ARB_ARBOR_API region intersect(region l, region r) { return region{reg::reg_and(std::move(l), std::move(r))}; } -region join(region l, region r) { +ARB_ARBOR_API region join(region l, region r) { return region{reg::reg_or(std::move(l), std::move(r))}; } -region complement(region r) { +ARB_ARBOR_API region complement(region r) { return region{reg::reg_not(std::move(r))}; } -region difference(region l, region r) { +ARB_ARBOR_API region difference(region l, region r) { return region{reg::reg_minus(std::move(l), std::move(r))}; } diff --git a/arbor/morph/segment_tree.cpp b/arbor/morph/segment_tree.cpp index 955307cb10c793de62371847cae8f80da84fac0f..70498e47095995c6cea8166758fc5b12a4488c13 100644 --- a/arbor/morph/segment_tree.cpp +++ b/arbor/morph/segment_tree.cpp @@ -76,7 +76,7 @@ bool segment_tree::is_root(msize_t i) const { return parents_[i]==mnpos; } -std::ostream& operator<<(std::ostream& o, const segment_tree& m) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const segment_tree& m) { auto tstr = util::transform_view(m.parents_, [](msize_t i) -> std::string { return i==mnpos? "npos": std::to_string(i); diff --git a/arbor/partition_load_balance.cpp b/arbor/partition_load_balance.cpp index 40b145b003bb04e5bfc7e5c3117eb622f8984a4d..254bd53a6f808d2f39b0ba2b1b98fe6f4fa6d9cc 100644 --- a/arbor/partition_load_balance.cpp +++ b/arbor/partition_load_balance.cpp @@ -20,7 +20,7 @@ namespace arb { -domain_decomposition partition_load_balance( +ARB_ARBOR_API domain_decomposition partition_load_balance( const recipe& rec, const context& ctx, partition_hint_map hint_map) diff --git a/arbor/profile/clock.cpp b/arbor/profile/clock.cpp index bd73d4aae733f46ef0a54c13a946b6928596b792..2362b2461e59fe9dafedf51b83f8884e423c4bc5 100644 --- a/arbor/profile/clock.cpp +++ b/arbor/profile/clock.cpp @@ -23,7 +23,7 @@ inline tick_type posix_clock_gettime_ns(clockid_t clock) { return nanoseconds; }; -tick_type posix_clock_gettime_monotonic_ns() { +ARB_ARBOR_API tick_type posix_clock_gettime_monotonic_ns() { return posix_clock_gettime_ns(CLOCK_MONOTONIC); } diff --git a/arbor/profile/meter_manager.cpp b/arbor/profile/meter_manager.cpp index dc2e12804cd8fa44078dfdec04422b052164e278..c2540c84267c9e08154113a515cf8638649091e6 100644 --- a/arbor/profile/meter_manager.cpp +++ b/arbor/profile/meter_manager.cpp @@ -101,7 +101,7 @@ const std::vector<double>& meter_manager::times() const { // Build a report of meters, for use at the end of a simulation // for output to file or analysis. -meter_report make_meter_report(const meter_manager& manager, const context& ctx) { +ARB_ARBOR_API meter_report make_meter_report(const meter_manager& manager, const context& ctx) { meter_report report; // Add the times to the meter outputs @@ -131,7 +131,7 @@ meter_report make_meter_report(const meter_manager& manager, const context& ctx) } // Print easy to read report of meters to a stream. -std::ostream& operator<<(std::ostream& o, const meter_report& report) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const meter_report& report) { o << "\n---- meters -------------------------------------------------------------------------------\n"; o << strprintf("meter%16s", ""); for (auto const& m: report.meters) { diff --git a/arbor/profile/profiler.cpp b/arbor/profile/profiler.cpp index 03bfc75070706a37a8c6a4b0f4623e8d97240623..c5e0b641dfcb59ad2a9fe6896ff6e156d613b15e 100644 --- a/arbor/profile/profiler.cpp +++ b/arbor/profile/profiler.cpp @@ -342,27 +342,27 @@ void print(std::ostream& o, // convenience functions for instrumenting code. // -void profiler_leave() { +ARB_ARBOR_API void profiler_leave() { profiler::get_global_profiler().leave(); } -region_id_type profiler_region_id(const std::string& name) { +ARB_ARBOR_API region_id_type profiler_region_id(const std::string& name) { if (!is_valid_region_string(name)) { throw std::runtime_error(std::string("'")+name+"' is not a valid profiler region name."); } return profiler::get_global_profiler().region_index(name); } -void profiler_enter(region_id_type region_id) { +ARB_ARBOR_API void profiler_enter(region_id_type region_id) { profiler::get_global_profiler().enter(region_id); } -void profiler_initialize(context& ctx) { +ARB_ARBOR_API void profiler_initialize(context& ctx) { profiler::get_global_profiler().initialize(ctx->thread_pool); } // Print profiler statistics to an ostream -std::ostream& operator<<(std::ostream& o, const profile& prof) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const profile& prof) { char buf[80]; auto tree = make_profile_tree(prof); @@ -373,19 +373,18 @@ std::ostream& operator<<(std::ostream& o, const profile& prof) { return o; } -profile profiler_summary() { +ARB_ARBOR_API profile profiler_summary() { return profiler::get_global_profiler().results(); } #else -void profiler_leave() {} -void profiler_enter(region_id_type) {} -profile profiler_summary(); -void profiler_print(const profile& prof, float threshold) {}; -profile profiler_summary() {return profile();} -region_id_type profiler_region_id(const std::string&) {return 0;} -std::ostream& operator<<(std::ostream& o, const profile&) {return o;} +ARB_ARBOR_API void profiler_leave() {} +ARB_ARBOR_API void profiler_enter(region_id_type) {} +ARB_ARBOR_API profile profiler_summary(); +ARB_ARBOR_API profile profiler_summary() {return profile();} +ARB_ARBOR_API region_id_type profiler_region_id(const std::string&) {return 0;} +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const profile&) {return o;} #endif // ARB_HAVE_PROFILING diff --git a/arbor/s_expr.cpp b/arbor/s_expr.cpp index fed7878a8173a0d3f28dbbf29faea409906c5348..01e626c3da89663fe90a764fd95d5fb244ffbb63 100644 --- a/arbor/s_expr.cpp +++ b/arbor/s_expr.cpp @@ -43,11 +43,11 @@ inline bool is_valid_symbol_char(char c) { } } -std::ostream& operator<<(std::ostream& o, const src_location& l) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const src_location& l) { return o << l.line << ":" << l.column; } -std::ostream& operator<<(std::ostream& o, const tok& t) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const tok& t) { switch (t) { case tok::nil: return o << "nil"; case tok::lparen: return o << "lparen"; @@ -62,7 +62,7 @@ std::ostream& operator<<(std::ostream& o, const tok& t) { return o << "<unknown>"; } -std::ostream& operator<<(std::ostream& o, const token& t) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const token& t) { if (t.kind==tok::string) { return o << util::pprintf("\"{}\"", t.spelling); } @@ -432,11 +432,11 @@ std::ostream& print(std::ostream& o, const s_expr& x, int indent) { return o << ")"; } -std::ostream& operator<<(std::ostream& o, const s_expr& x) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const s_expr& x) { return print(o, x, 1); } -std::size_t length(const s_expr& l) { +ARB_ARBOR_API std::size_t length(const s_expr& l) { // The length of an atom is 1. if (l.is_atom() && l) { return 1; @@ -448,7 +448,7 @@ std::size_t length(const s_expr& l) { return 1+length(l.tail()); } -src_location location(const s_expr& l) { +ARB_ARBOR_API src_location location(const s_expr& l) { if (l.is_atom()) return l.atom().loc; return location(l.head()); } @@ -514,7 +514,7 @@ s_expr parse(lexer& L) { } -s_expr parse_s_expr(const std::string& line) { +ARB_ARBOR_API s_expr parse_s_expr(const std::string& line) { lexer l(line.c_str()); s_expr result = impl::parse(l); const bool err = result.is_atom()? result.atom().kind==tok::error: false; diff --git a/arbor/simulation.cpp b/arbor/simulation.cpp index 300b9947da1111faaeebfbc558a1a504be263f19..f0a6cccaa303304dbd83d567c1522a2e9ca50bdb 100644 --- a/arbor/simulation.cpp +++ b/arbor/simulation.cpp @@ -2,6 +2,7 @@ #include <set> #include <vector> +#include <arbor/export.hpp> #include <arbor/arbexcept.hpp> #include <arbor/context.hpp> #include <arbor/domain_decomposition.hpp> @@ -36,7 +37,7 @@ auto split_sorted_range(Seq&& seq, const Value& v, Less cmp = Less{}) { // Create a new cell event_lane vector from sorted pending events, previous event_lane events, // and events from event generators for the given interval. -void merge_cell_events( +ARB_ARBOR_API void merge_cell_events( time_type t_from, time_type t_to, event_span old_events, diff --git a/arbor/spike_event_io.cpp b/arbor/spike_event_io.cpp index f035ae860d9a5d759097825df299282f929f6a8d..639f55c8895294b91ae782a3791673e0b34db9ad 100644 --- a/arbor/spike_event_io.cpp +++ b/arbor/spike_event_io.cpp @@ -4,7 +4,7 @@ namespace arb { -std::ostream& operator<<(std::ostream& o, const spike_event& ev) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const spike_event& ev) { return o << "E[tgt " << ev.target << ", t " << ev.time << ", w " << ev.weight << "]"; } diff --git a/arbor/spike_source_cell_group.hpp b/arbor/spike_source_cell_group.hpp index a20772258c25f4138d321ecef2981a4c0cb0c1e2..4a54237e6c87b147e6988bbe3f1e7db94b0df34a 100644 --- a/arbor/spike_source_cell_group.hpp +++ b/arbor/spike_source_cell_group.hpp @@ -2,6 +2,7 @@ #include <vector> +#include <arbor/export.hpp> #include <arbor/common_types.hpp> #include <arbor/recipe.hpp> #include <arbor/sampling.hpp> @@ -14,7 +15,7 @@ namespace arb { -class spike_source_cell_group: public cell_group { +class ARB_ARBOR_API spike_source_cell_group: public cell_group { public: spike_source_cell_group(const std::vector<cell_gid_type>& gids, const recipe& rec, cell_label_range& cg_sources, cell_label_range& cg_targets); diff --git a/arbor/thread_private_spike_store.hpp b/arbor/thread_private_spike_store.hpp index 1293de5b26521311d741785190dee0a8e2e66fcb..ff31f2072847a43ab54006984c6b096d0e7a4e7d 100644 --- a/arbor/thread_private_spike_store.hpp +++ b/arbor/thread_private_spike_store.hpp @@ -3,6 +3,7 @@ #include <memory> #include <vector> +#include <arbor/export.hpp> #include <arbor/common_types.hpp> #include <arbor/spike.hpp> @@ -18,7 +19,7 @@ struct local_spike_store_type; /// The thread private buffer of the calling thread. /// The insert() and gather() methods add a vector of spikes to the buffer, /// and collate all of the buffers into a single vector respectively. -class thread_private_spike_store { +class ARB_ARBOR_API thread_private_spike_store { public : thread_private_spike_store(); ~thread_private_spike_store(); diff --git a/arbor/threading/threading.hpp b/arbor/threading/threading.hpp index ad2b1d74a6d5e395319656e7e466d4e45ac1ab7f..06b7e1c99b53fa754198b18278684c2f1b54c8c2 100644 --- a/arbor/threading/threading.hpp +++ b/arbor/threading/threading.hpp @@ -14,6 +14,8 @@ #include <unordered_map> #include <utility> +#include <arbor/export.hpp> + namespace arb { namespace threading { @@ -68,7 +70,7 @@ struct priority_task { namespace impl { -class notification_queue { +class ARB_ARBOR_API notification_queue { // Number of priority levels in notification queues. static constexpr int n_priority = max_async_task_priority+1; @@ -120,7 +122,7 @@ private: }// namespace impl -class task_system { +class ARB_ARBOR_API task_system { private: // Number of notification queues. unsigned count_; diff --git a/arbor/tree.cpp b/arbor/tree.cpp index a46718699176774fa3ee5af1a921928d8e72208b..a22501e831ea8cdf94d72549c08650db82d2d381 100644 --- a/arbor/tree.cpp +++ b/arbor/tree.cpp @@ -372,7 +372,7 @@ void depth_from_root(const tree& t, tree::iarray& depth, tree::int_type segment) } } -tree::iarray depth_from_root(const tree& t) { +ARB_ARBOR_API tree::iarray depth_from_root(const tree& t) { tree::iarray depth(t.num_segments()); depth[0] = 0; for (auto c: t.children(0)) { diff --git a/arbor/tree.hpp b/arbor/tree.hpp index 23f44fbdab084166b5dd3a7ef7158a09ff1cddd3..137598318a595349dc01cd98dc04bb394f06f15a 100644 --- a/arbor/tree.hpp +++ b/arbor/tree.hpp @@ -6,6 +6,7 @@ #include <numeric> #include <vector> +#include <arbor/export.hpp> #include <arbor/common_types.hpp> #include "memory/memory.hpp" @@ -14,7 +15,7 @@ namespace arb { -class tree { +class ARB_ARBOR_API tree { public: using int_type = cell_lid_type; using size_type = cell_local_size_type; @@ -113,7 +114,7 @@ private: // Calculates the depth of each branch from the root of a cell segment tree. // The root has depth 0, it's children have depth 1, and so on. -tree::iarray depth_from_root(const tree& t); +ARB_ARBOR_API tree::iarray depth_from_root(const tree& t); // Check if c[0] == 0 and c[i] < 0 holds for i != 0 // Also handle the valid case of c[0]==value_type(-1) diff --git a/arbor/version.cpp b/arbor/version.cpp index 0b2233a29c6a17df73b48920cd1f55f673d6831b..88b693891f53ae9cf31b4f03edc2a8dd959c5ba2 100644 --- a/arbor/version.cpp +++ b/arbor/version.cpp @@ -1,14 +1,14 @@ #include <arbor/version.hpp> namespace arb { -const char* source_id = ARB_SOURCE_ID; -const char* arch = ARB_ARCH; -const char* build_config = ARB_BUILD_CONFIG; -const char* version = ARB_VERSION; +ARB_ARBOR_API const char* source_id = ARB_SOURCE_ID; +ARB_ARBOR_API const char* arch = ARB_ARCH; +ARB_ARBOR_API const char* build_config = ARB_BUILD_CONFIG; +ARB_ARBOR_API const char* version = ARB_VERSION; #ifdef ARB_VERSION_DEV -const char* version_dev = ARB_VERSION_DEV; +ARB_ARBOR_API const char* version_dev = ARB_VERSION_DEV; #else -const char* version_dev = ""; +ARB_ARBOR_API const char* version_dev = ""; #endif -const char* full_build_id = ARB_FULL_BUILD_ID; +ARB_ARBOR_API const char* full_build_id = ARB_FULL_BUILD_ID; } diff --git a/arborenv/CMakeLists.txt b/arborenv/CMakeLists.txt index 16128499391839a27eff81acecd6e1e93eee9af0..6651f0108c349486512ff2255d00f49cda052813 100644 --- a/arborenv/CMakeLists.txt +++ b/arborenv/CMakeLists.txt @@ -16,6 +16,7 @@ add_library(arborenv ${arborenv-sources}) add_library(arborenv-public-headers INTERFACE) target_include_directories(arborenv-public-headers INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> + $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include> $<INSTALL_INTERFACE:include> ) @@ -26,6 +27,11 @@ target_include_directories(arborenv-public-headers INTERFACE target_link_libraries(arborenv PUBLIC arbor arborenv-public-headers) target_link_libraries(arborenv PRIVATE arbor-config-defs arborenv-private-deps) +export_visibility(arborenv) + +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/arborenv/export.hpp + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/arborenv) + install(DIRECTORY include/arborenv DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "*.hpp") diff --git a/arborenv/affinity.cpp b/arborenv/affinity.cpp index 61502cc621d89f3f129f450eab53dea358f37070..469a304ec190b974ee47df2ae78cad7be34ce7e5 100644 --- a/arborenv/affinity.cpp +++ b/arborenv/affinity.cpp @@ -2,6 +2,8 @@ #include <system_error> #include <vector> +#include <arborenv/concurrency.hpp> + #ifdef __linux__ #ifndef _GNU_SOURCE @@ -14,7 +16,7 @@ extern "C" { namespace arbenv { -std::vector<int> get_affinity() { +ARB_ARBORENV_API std::vector<int> get_affinity() { std::vector<int> cores; cpu_set_t cpu_set_mask; @@ -39,7 +41,7 @@ std::vector<int> get_affinity() { // No support for non-linux systems. namespace arbenv { -std::vector<int> get_affinity() { +ARB_ARBORENV_API std::vector<int> get_affinity() { return {}; } diff --git a/arborenv/concurrency.cpp b/arborenv/concurrency.cpp index 208acee4590bda4543138242ba957817c5c9b505..35bafe68b612748c0bdc4ce11ec9f738c3c1cd3f 100644 --- a/arborenv/concurrency.cpp +++ b/arborenv/concurrency.cpp @@ -14,7 +14,7 @@ namespace arbenv { // Take a best guess at the number of threads that can be run concurrently. // Will return at least 1. -unsigned long thread_concurrency() { +ARB_ARBORENV_API unsigned long thread_concurrency() { // Attempt to get count first from affinity information if available. unsigned long n = get_affinity().size(); diff --git a/arborenv/cuda_api.hpp b/arborenv/cuda_api.hpp index 14b3a363960a59e2ad92d387343d9b4cc675b268..f3395a5d83ab5f87535385791de1340aa47169d6 100644 --- a/arborenv/cuda_api.hpp +++ b/arborenv/cuda_api.hpp @@ -4,10 +4,11 @@ #include <cuda.h> #include <cuda_runtime.h> #include <cuda_runtime_api.h> +#include <arborenv/export.hpp> using DeviceProp = cudaDeviceProp; -struct api_error_type { +struct ARB_SYMBOL_VISIBLE api_error_type { cudaError_t value; api_error_type(cudaError_t e): value(e) {} @@ -42,4 +43,4 @@ inline api_error_type get_device_count(ARGS&&... args) { template <typename... ARGS> inline api_error_type get_device_properties(ARGS&&... args) { return cudaGetDeviceProperties(std::forward<ARGS>(args)...); -} \ No newline at end of file +} diff --git a/arborenv/default_env.cpp b/arborenv/default_env.cpp index 1f55acfe45ac45eb0abb869def371639214548a7..ddeff5fe82b6b6db388d9cc621037bd69130f644 100644 --- a/arborenv/default_env.cpp +++ b/arborenv/default_env.cpp @@ -13,12 +13,12 @@ namespace arbenv { -unsigned long default_concurrency() { +ARB_ARBORENV_API unsigned long default_concurrency() { unsigned long env_thread = get_env_num_threads(); return env_thread? env_thread: thread_concurrency(); } -unsigned long get_env_num_threads() { +ARB_ARBORENV_API unsigned long get_env_num_threads() { constexpr const char* env_var = "ARBENV_NUM_THREADS"; std::optional<long long> env_val = read_env_integer(env_var, throw_on_invalid); if (!env_val) return 0; @@ -31,7 +31,7 @@ unsigned long get_env_num_threads() { #ifdef ARB_HAVE_GPU -int default_gpu() { +ARB_ARBORENV_API int default_gpu() { constexpr const char* env_var = "ARBENV_GPU_ID"; int n_device = -1; get_device_count(&n_device); // error => leave n_device == -1 @@ -56,7 +56,7 @@ int default_gpu() { #else -int default_gpu() { +ARB_ARBORENV_API int default_gpu() { return -1; } diff --git a/arborenv/hip_api.hpp b/arborenv/hip_api.hpp index 8a4fe45e267a28f06fa3333dd59d385d58aed2a2..b5417d3a5bfb9727e2dabcd65c7a1b0bfa7b7bd8 100644 --- a/arborenv/hip_api.hpp +++ b/arborenv/hip_api.hpp @@ -3,10 +3,11 @@ #include<hip/hip_runtime.h> #include<hip/hip_runtime_api.h> +#include <arborenv/export.hpp> using DeviceProp = hipDeviceProp_t; -struct api_error_type { +struct ARB_SYMBOL_VISIBLE api_error_type { hipError_t value; api_error_type(hipError_t e): value(e) {} diff --git a/arborenv/include/arborenv/arbenvexcept.hpp b/arborenv/include/arborenv/arbenvexcept.hpp index 7b140ccfec61a2a2095642dd502a7a1e484c0996..49fba2c4dd6a685e84ee569bb8d4764a5c3eb521 100644 --- a/arborenv/include/arborenv/arbenvexcept.hpp +++ b/arborenv/include/arborenv/arbenvexcept.hpp @@ -3,13 +3,15 @@ #include <stdexcept> #include <string> +#include <arborenv/export.hpp> + // Arborenv-specific exception hierarchy. namespace arbenv { // Common base-class for arborenv run-time errors. -struct arborenv_exception: std::runtime_error { +struct ARB_SYMBOL_VISIBLE arborenv_exception: std::runtime_error { arborenv_exception(const std::string& what_arg): std::runtime_error(what_arg) {} @@ -17,7 +19,7 @@ struct arborenv_exception: std::runtime_error { // Environment variable parsing errors. -struct invalid_env_value: arborenv_exception { +struct ARB_SYMBOL_VISIBLE invalid_env_value: arborenv_exception { invalid_env_value(const std::string& variable, const std::string& value); std::string env_variable; std::string env_value; @@ -25,12 +27,12 @@ struct invalid_env_value: arborenv_exception { // GPU enumeration, selection. -struct no_such_gpu: arborenv_exception { +struct ARB_SYMBOL_VISIBLE no_such_gpu: arborenv_exception { no_such_gpu(int gpu_id); int gpu_id; }; -struct gpu_uuid_error: arborenv_exception { +struct ARB_SYMBOL_VISIBLE gpu_uuid_error: arborenv_exception { gpu_uuid_error(std::string what); }; diff --git a/arborenv/include/arborenv/concurrency.hpp b/arborenv/include/arborenv/concurrency.hpp index 25b0f7ac2ad1c1eeea11f32291e9097d62ec9d09..0d7d91f760a706ed5986aa8fae61beb7be7ba5b9 100644 --- a/arborenv/include/arborenv/concurrency.hpp +++ b/arborenv/include/arborenv/concurrency.hpp @@ -2,12 +2,14 @@ #include <vector> +#include <arborenv/export.hpp> + namespace arbenv { // Attempt to determine number of available threads that can be run concurrently. // Will return at least 1. -unsigned long thread_concurrency(); +ARB_ARBORENV_API unsigned long thread_concurrency(); // The list of logical processors for which the calling thread has affinity. // If calling from the main thread at application start up, before @@ -19,6 +21,6 @@ unsigned long thread_concurrency(); // Returns an empty vector if unable to determine the number of // available cores. -std::vector<int> get_affinity(); +ARB_ARBORENV_API std::vector<int> get_affinity(); } // namespace arbenv diff --git a/arborenv/include/arborenv/default_env.hpp b/arborenv/include/arborenv/default_env.hpp index 843503b678ef1b6a0e87bdd9547f319c428a897a..136df0509d776de2a5a2f252a577d217dd250a00 100644 --- a/arborenv/include/arborenv/default_env.hpp +++ b/arborenv/include/arborenv/default_env.hpp @@ -8,6 +8,7 @@ #include <arborenv/arbenvexcept.hpp> #include <arborenv/concurrency.hpp> #include <arborenv/gpu_env.hpp> +#include <arborenv/export.hpp> namespace arbenv { @@ -15,7 +16,7 @@ namespace arbenv { // if set and non-zero, throwing arbev::invalid_env_value if it has an invalid // value, or else return the value determined by arbenv::thread_concurrency(). -unsigned long default_concurrency(); +ARB_ARBORENV_API unsigned long default_concurrency(); // If Arbor is built without GPU support, return -1. // @@ -29,7 +30,7 @@ unsigned long default_concurrency(); // Throws arbenv::invalid_env_value if ARBENV_GPU_ID is not an int value, or // arbenv::no_such_gpu if it doesn't correspond to a valid GPU id. -int default_gpu(); +ARB_ARBORENV_API int default_gpu(); // Construct default proc_allocation from `default_concurrency()` and // `default_gpu()`. @@ -44,6 +45,6 @@ inline arb::proc_allocation default_allocation() { // non-numeric, non-positive, or out of range value. // * Returns zero if ARBENV_NUM_THREADS is unset, or set and empty. -unsigned long get_env_num_threads(); +ARB_ARBORENV_API unsigned long get_env_num_threads(); } // namespace arbenv diff --git a/arborenv/include/arborenv/gpu_env.hpp b/arborenv/include/arborenv/gpu_env.hpp index 2aefde7bae60862997405ce1595de5521ad14028..069e44c2713e0b8adde4dc9b44b0ce758f113f39 100644 --- a/arborenv/include/arborenv/gpu_env.hpp +++ b/arborenv/include/arborenv/gpu_env.hpp @@ -1,9 +1,11 @@ #pragma once +#include <arborenv/export.hpp> + namespace arbenv { template <typename Comm> -int find_private_gpu(Comm comm); +ARB_ARBORENV_API int find_private_gpu(Comm comm); } // namespace arbenv diff --git a/arborenv/private_gpu.cpp b/arborenv/private_gpu.cpp index 23376454506a215669638bb6866d0e84bade1b54..ee5cd531d294f70e9914075d67c6f1acc6c83425 100644 --- a/arborenv/private_gpu.cpp +++ b/arborenv/private_gpu.cpp @@ -14,7 +14,7 @@ namespace arbenv { #ifdef ARB_HAVE_GPU template <> -int find_private_gpu(MPI_Comm comm) { +ARB_ARBORENV_API int find_private_gpu(MPI_Comm comm) { int nranks; int rank; MPI_Comm_rank(comm, &rank); @@ -96,7 +96,7 @@ int find_private_gpu(MPI_Comm comm) { // return -1 -> "no gpu" when compiled without GPU support. template <> -int find_private_gpu(MPI_Comm comm) { +ARB_ARBORENV_API int find_private_gpu(MPI_Comm comm) { return -1; } diff --git a/arborio/CMakeLists.txt b/arborio/CMakeLists.txt index 4c1eff4abcc8d7ba00ed414cdaf8e8fc9817f9e1..6db6b46fc27f2a8930dd95387a67b2854c9b5482 100644 --- a/arborio/CMakeLists.txt +++ b/arborio/CMakeLists.txt @@ -23,6 +23,7 @@ add_library(arborio-private-headers INTERFACE) target_include_directories(arborio-public-headers INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> + $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include> $<INSTALL_INTERFACE:include> ) target_include_directories(arborio-private-headers INTERFACE @@ -40,6 +41,11 @@ endif() target_link_libraries(arborio PRIVATE arbor-config-defs arborio-private-deps) +export_visibility(arborio) + +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/arborio/export.hpp + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/arborio) + install(DIRECTORY include/arborio DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "*.hpp") diff --git a/arborio/cableio.cpp b/arborio/cableio.cpp index 25f6d6e2631d0dc1ad6e0b64b297228d433a287a..88eefd723e2e0d06bad91d62a8ecc025758b597a 100644 --- a/arborio/cableio.cpp +++ b/arborio/cableio.cpp @@ -17,7 +17,7 @@ namespace arborio { using namespace arb; -std::string acc_version() {return "0.1-dev";} +ARB_ARBORIO_API std::string acc_version() {return "0.1-dev";} cableio_parse_error::cableio_parse_error(const std::string& msg, const arb::src_location& loc): arb::arbor_exception(msg+" at :"+ @@ -153,32 +153,32 @@ s_expr mksexp(const meta_data& meta) { } // Implement public facing s-expr writers -std::ostream& write_component(std::ostream& o, const decor& x, const meta_data& m) { +ARB_ARBORIO_API std::ostream& write_component(std::ostream& o, const decor& x, const meta_data& m) { if (m.version != acc_version()) { throw cableio_version_error(m.version); } return o << s_expr{"arbor-component"_symbol, slist(mksexp(m), mksexp(x))}; } -std::ostream& write_component(std::ostream& o, const label_dict& x, const meta_data& m) { +ARB_ARBORIO_API std::ostream& write_component(std::ostream& o, const label_dict& x, const meta_data& m) { if (m.version != acc_version()) { throw cableio_version_error(m.version); } return o << s_expr{"arbor-component"_symbol, slist(mksexp(m), mksexp(x))}; } -std::ostream& write_component(std::ostream& o, const morphology& x, const meta_data& m) { +ARB_ARBORIO_API std::ostream& write_component(std::ostream& o, const morphology& x, const meta_data& m) { if (m.version != acc_version()) { throw cableio_version_error(m.version); } return o << s_expr{"arbor-component"_symbol, slist(mksexp(m), mksexp(x))}; } -std::ostream& write_component(std::ostream& o, const cable_cell& x, const meta_data& m) { +ARB_ARBORIO_API std::ostream& write_component(std::ostream& o, const cable_cell& x, const meta_data& m) { if (m.version != acc_version()) { throw cableio_version_error(m.version); } auto cell = s_expr{"cable-cell"_symbol, slist(mksexp(x.morphology()), mksexp(x.labels()), mksexp(x.decorations()))}; return o << s_expr{"arbor-component"_symbol, slist(mksexp(m), cell)}; } -std::ostream& write_component(std::ostream& o, const cable_cell_component& x) { +ARB_ARBORIO_API std::ostream& write_component(std::ostream& o, const cable_cell_component& x) { if (x.meta.version != acc_version()) { throw cableio_version_error(x.meta.version); } @@ -665,12 +665,12 @@ inline parse_hopefully<std::any> parse(const arb::s_expr& s) { return eval(std::move(s), named_evals, unnamed_evals); } -parse_hopefully<std::any> parse_expression(const std::string& s) { +ARB_ARBORIO_API parse_hopefully<std::any> parse_expression(const std::string& s) { return parse(parse_s_expr(s)); } // Read s-expr -parse_hopefully<cable_cell_component> parse_component(const std::string& s) { +ARB_ARBORIO_API parse_hopefully<cable_cell_component> parse_component(const std::string& s) { auto sexp = parse_s_expr(s); auto try_parse = parse(sexp); if (!try_parse) { @@ -686,7 +686,7 @@ parse_hopefully<cable_cell_component> parse_component(const std::string& s) { return comp; }; -parse_hopefully<cable_cell_component> parse_component(std::istream& s) { +ARB_ARBORIO_API parse_hopefully<cable_cell_component> parse_component(std::istream& s) { return parse_component(std::string(std::istreambuf_iterator<char>(s), {})); } } // namespace arborio diff --git a/arborio/cv_policy_parse.cpp b/arborio/cv_policy_parse.cpp index 16ad8160861eae2b714f860e5a415052398c07d0..7e5bc2fe4200f9a531743a7fc6d064dd5494f3a6 100644 --- a/arborio/cv_policy_parse.cpp +++ b/arborio/cv_policy_parse.cpp @@ -188,7 +188,7 @@ parse_hopefully<std::any> eval(const s_expr& e) { } } -parse_cv_policy_hopefully parse_cv_policy_expression(const arb::s_expr& s) { +ARB_ARBORIO_API parse_cv_policy_hopefully parse_cv_policy_expression(const arb::s_expr& s) { if (auto e = eval(s)) { if (e->type() == typeid(cv_policy)) { return {std::move(std::any_cast<cv_policy&>(*e))}; @@ -200,7 +200,7 @@ parse_cv_policy_hopefully parse_cv_policy_expression(const arb::s_expr& s) { return util::unexpected(cv_policy_parse_error(std::string() + e.error().what())); } } -parse_cv_policy_hopefully parse_cv_policy_expression(const std::string& s) { +ARB_ARBORIO_API parse_cv_policy_hopefully parse_cv_policy_expression(const std::string& s) { return parse_cv_policy_expression(parse_s_expr(s)); } } // namespace arb diff --git a/arborio/include/arborio/cableio.hpp b/arborio/include/arborio/cableio.hpp index 7502e7510bf9b114a35ed92c3fd41af235a1adb3..cbdeb146d41a0a3a476465381d6480771e1d42c2 100644 --- a/arborio/include/arborio/cableio.hpp +++ b/arborio/include/arborio/cableio.hpp @@ -2,19 +2,20 @@ #include <arbor/cable_cell.hpp> #include <arbor/s_expr.hpp> +#include <arborio/export.hpp> namespace arborio { -std::string acc_version(); +ARB_ARBORIO_API std::string acc_version(); -struct cableio_parse_error: arb::arbor_exception { +struct ARB_SYMBOL_VISIBLE cableio_parse_error: arb::arbor_exception { explicit cableio_parse_error(const std::string& msg, const arb::src_location& loc); }; -struct cableio_morphology_error: arb::arbor_exception { +struct ARB_SYMBOL_VISIBLE cableio_morphology_error: arb::arbor_exception { explicit cableio_morphology_error(const unsigned bid); }; -struct cableio_version_error: arb::arbor_exception { +struct ARB_SYMBOL_VISIBLE cableio_version_error: arb::arbor_exception { explicit cableio_version_error(const std::string& version); }; @@ -30,13 +31,13 @@ struct cable_cell_component { cable_cell_variant component; }; -std::ostream& write_component(std::ostream&, const cable_cell_component&); -std::ostream& write_component(std::ostream&, const arb::decor& x, const meta_data& m = {}); -std::ostream& write_component(std::ostream&, const arb::label_dict& x, const meta_data& m = {}); -std::ostream& write_component(std::ostream&, const arb::morphology& x, const meta_data& m = {}); -std::ostream& write_component(std::ostream&, const arb::cable_cell& x, const meta_data& m = {}); +ARB_ARBORIO_API std::ostream& write_component(std::ostream&, const cable_cell_component&); +ARB_ARBORIO_API std::ostream& write_component(std::ostream&, const arb::decor& x, const meta_data& m = {}); +ARB_ARBORIO_API std::ostream& write_component(std::ostream&, const arb::label_dict& x, const meta_data& m = {}); +ARB_ARBORIO_API std::ostream& write_component(std::ostream&, const arb::morphology& x, const meta_data& m = {}); +ARB_ARBORIO_API std::ostream& write_component(std::ostream&, const arb::cable_cell& x, const meta_data& m = {}); -parse_hopefully<cable_cell_component> parse_component(const std::string&); -parse_hopefully<cable_cell_component> parse_component(std::istream&); +ARB_ARBORIO_API parse_hopefully<cable_cell_component> parse_component(const std::string&); +ARB_ARBORIO_API parse_hopefully<cable_cell_component> parse_component(std::istream&); -} // namespace arborio \ No newline at end of file +} // namespace arborio diff --git a/arborio/include/arborio/cv_policy_parse.hpp b/arborio/include/arborio/cv_policy_parse.hpp index 6069740a9f509097356682ac5cd478642b1368d8..70836105c7326e8ea7bbe1149f24feee3d51b7b7 100644 --- a/arborio/include/arborio/cv_policy_parse.hpp +++ b/arborio/include/arborio/cv_policy_parse.hpp @@ -7,18 +7,19 @@ #include <arbor/arbexcept.hpp> #include <arbor/util/expected.hpp> #include <arbor/s_expr.hpp> +#include <arborio/export.hpp> namespace arborio { -struct cv_policy_parse_error: arb::arbor_exception { +struct ARB_SYMBOL_VISIBLE cv_policy_parse_error: arb::arbor_exception { explicit cv_policy_parse_error(const std::string& msg, const arb::src_location& loc); explicit cv_policy_parse_error(const std::string& msg); }; using parse_cv_policy_hopefully = arb::util::expected<arb::cv_policy, cv_policy_parse_error>; -parse_cv_policy_hopefully parse_cv_policy_expression(const std::string& s); -parse_cv_policy_hopefully parse_cv_policy_expression(const arb::s_expr& s); +ARB_ARBORIO_API parse_cv_policy_hopefully parse_cv_policy_expression(const std::string& s); +ARB_ARBORIO_API parse_cv_policy_hopefully parse_cv_policy_expression(const arb::s_expr& s); namespace literals { diff --git a/arborio/include/arborio/label_parse.hpp b/arborio/include/arborio/label_parse.hpp index b51f9361e67e3c87cc9b8ff46b57fd102f30fa2f..5f96ede80817da7c505f8fb05ebfc7f3c2254eca 100644 --- a/arborio/include/arborio/label_parse.hpp +++ b/arborio/include/arborio/label_parse.hpp @@ -9,10 +9,11 @@ #include <arbor/util/expected.hpp> #include <arbor/s_expr.hpp> +#include <arborio/export.hpp> namespace arborio { -struct label_parse_error: arb::arbor_exception { +struct ARB_SYMBOL_VISIBLE label_parse_error: arb::arbor_exception { explicit label_parse_error(const std::string& msg, const arb::src_location& loc); explicit label_parse_error(const std::string& msg): arb::arbor_exception(msg) {} }; @@ -20,11 +21,11 @@ struct label_parse_error: arb::arbor_exception { template <typename T> using parse_label_hopefully = arb::util::expected<T, label_parse_error>; -parse_label_hopefully<std::any> parse_label_expression(const std::string&); -parse_label_hopefully<std::any> parse_label_expression(const arb::s_expr&); +ARB_ARBORIO_API parse_label_hopefully<std::any> parse_label_expression(const std::string&); +ARB_ARBORIO_API parse_label_hopefully<std::any> parse_label_expression(const arb::s_expr&); -parse_label_hopefully<arb::region> parse_region_expression(const std::string& s); -parse_label_hopefully<arb::locset> parse_locset_expression(const std::string& s); +ARB_ARBORIO_API parse_label_hopefully<arb::region> parse_region_expression(const std::string& s); +ARB_ARBORIO_API parse_label_hopefully<arb::locset> parse_locset_expression(const std::string& s); namespace literals { diff --git a/arborio/include/arborio/neurolucida.hpp b/arborio/include/arborio/neurolucida.hpp index 4021329d5e5cab8c9bc01dc0a157904b45e9a436..cf82961380c093048e314d67513c9899138649eb 100644 --- a/arborio/include/arborio/neurolucida.hpp +++ b/arborio/include/arborio/neurolucida.hpp @@ -7,18 +7,19 @@ #include <arbor/arbexcept.hpp> #include <arbor/morph/label_dict.hpp> #include <arbor/morph/morphology.hpp> +#include <arborio/export.hpp> namespace arborio { // Common base-class for arborio run-time errors. -struct asc_exception: public arb::arbor_exception { +struct ARB_SYMBOL_VISIBLE asc_exception: public arb::arbor_exception { asc_exception(const std::string& what_arg): arb::arbor_exception(what_arg) {} }; // Generic error parsing asc data. -struct asc_parse_error: asc_exception { +struct ARB_SYMBOL_VISIBLE asc_parse_error: asc_exception { asc_parse_error(const std::string& error_msg, unsigned line, unsigned column); std::string message; unsigned line; @@ -26,7 +27,7 @@ struct asc_parse_error: asc_exception { }; // An unsupported ASC description feature was encountered. -struct asc_unsupported: asc_exception { +struct ARB_SYMBOL_VISIBLE asc_unsupported: asc_exception { asc_unsupported(const std::string& error_msg); std::string message; }; @@ -39,7 +40,10 @@ struct asc_morphology { arb::label_dict labels; }; +// Perform the parsing of the input as a string. +ARB_ARBORIO_API asc_morphology parse_asc_string(const char* input); + // Load asc morphology from file with name filename. -asc_morphology load_asc(std::string filename); +ARB_ARBORIO_API asc_morphology load_asc(std::string filename); } // namespace arborio diff --git a/arborio/include/arborio/neuroml.hpp b/arborio/include/arborio/neuroml.hpp index eead3b6c054659d547060b2d906c06e798cb4640..27c2663b2e95bccc6049f3199c9ec5ce45ed5896 100644 --- a/arborio/include/arborio/neuroml.hpp +++ b/arborio/include/arborio/neuroml.hpp @@ -10,23 +10,24 @@ #include <arbor/morph/label_dict.hpp> #include <arbor/morph/morphology.hpp> +#include <arborio/export.hpp> namespace arborio { // Common base-class for neuroml run-time errors. -struct neuroml_exception: std::runtime_error { +struct ARB_SYMBOL_VISIBLE neuroml_exception: std::runtime_error { neuroml_exception(const std::string& what_arg): std::runtime_error(what_arg) {} }; // Can't parse NeuroML if we don't have a document. -struct nml_no_document: neuroml_exception { +struct ARB_SYMBOL_VISIBLE nml_no_document: neuroml_exception { nml_no_document(); }; // Generic error parsing NeuroML data. -struct nml_parse_error: neuroml_exception { +struct ARB_SYMBOL_VISIBLE nml_parse_error: neuroml_exception { nml_parse_error(const std::string& error_msg, unsigned line = 0); std::string error_msg; unsigned line; @@ -35,7 +36,7 @@ struct nml_parse_error: neuroml_exception { // NeuroML morphology error: improper segment data, e.g. bad id specification, // segment parent does not exist, fractionAlong is out of bounds, missing // required <proximal> data. -struct nml_bad_segment: neuroml_exception { +struct ARB_SYMBOL_VISIBLE nml_bad_segment: neuroml_exception { nml_bad_segment(unsigned long long segment_id, unsigned line = 0); unsigned long long segment_id; unsigned line; @@ -43,7 +44,7 @@ struct nml_bad_segment: neuroml_exception { // NeuroML morphology error: improper segmentGroup data, e.g. malformed // element data, missing referenced segments or groups, etc. -struct nml_bad_segment_group: neuroml_exception { +struct ARB_SYMBOL_VISIBLE nml_bad_segment_group: neuroml_exception { nml_bad_segment_group(const std::string& group_id, unsigned line = 0); std::string group_id; unsigned line; @@ -51,7 +52,7 @@ struct nml_bad_segment_group: neuroml_exception { // A segment or segmentGroup ultimately refers to itself via `parent` // or `include` elements respectively. -struct nml_cyclic_dependency: neuroml_exception { +struct ARB_SYMBOL_VISIBLE nml_cyclic_dependency: neuroml_exception { nml_cyclic_dependency(const std::string& id, unsigned line = 0); std::string id; unsigned line; @@ -88,7 +89,7 @@ struct nml_morphology_data { // Represent NeuroML data determined by provided string. -struct neuroml_impl; +struct ARB_ARBORIO_API neuroml_impl; // TODO: C++20, replace with enum class and deploy using enum as appropriate. namespace neuroml_options { @@ -98,7 +99,7 @@ namespace neuroml_options { }; } -struct neuroml { +struct ARB_ARBORIO_API neuroml { // Correct interpretation of zero-length segments is currently a bit unclear // in NeuroML 2.0, hence these options. For further options, use flags in powers of two // so that we can bitwise combine and test them. diff --git a/arborio/include/arborio/swcio.hpp b/arborio/include/arborio/swcio.hpp index 2cb76b28693707562dea08013c48d1fb89a4d3ac..26189571ba91a9c7cb21e81ce44fca2a80c339f3 100644 --- a/arborio/include/arborio/swcio.hpp +++ b/arborio/include/arborio/swcio.hpp @@ -6,49 +6,50 @@ #include <arbor/arbexcept.hpp> #include <arbor/morph/morphology.hpp> +#include <arborio/export.hpp> namespace arborio { // SWC exceptions are thrown by `parse_swc`, and correspond // to inconsistent, or in `strict` mode, dubious SWC data. -struct swc_error: public arb::arbor_exception { +struct ARB_SYMBOL_VISIBLE swc_error: public arb::arbor_exception { swc_error(const std::string& msg, int record_id); int record_id; }; // Parent id in record has no corresponding SWC record, // nor is the record the root record with parent id -1. -struct swc_no_such_parent: swc_error { +struct ARB_SYMBOL_VISIBLE swc_no_such_parent: swc_error { explicit swc_no_such_parent(int record_id); }; // Parent id is greater than or equal to record id. -struct swc_record_precedes_parent: swc_error { +struct ARB_SYMBOL_VISIBLE swc_record_precedes_parent: swc_error { explicit swc_record_precedes_parent(int record_id); }; // Multiple records cannot have the same id. -struct swc_duplicate_record_id: swc_error { +struct ARB_SYMBOL_VISIBLE swc_duplicate_record_id: swc_error { explicit swc_duplicate_record_id(int record_id); }; // Smells like a spherical soma. -struct swc_spherical_soma: swc_error { +struct ARB_SYMBOL_VISIBLE swc_spherical_soma: swc_error { explicit swc_spherical_soma(int record_id); }; // Segment cannot have samples with different tags -struct swc_mismatched_tags: swc_error { +struct ARB_SYMBOL_VISIBLE swc_mismatched_tags: swc_error { explicit swc_mismatched_tags(int record_id); }; // Only tags 1, 2, 3, 4 supported -struct swc_unsupported_tag: swc_error { +struct ARB_SYMBOL_VISIBLE swc_unsupported_tag: swc_error { explicit swc_unsupported_tag(int record_id); }; -struct swc_record { +struct ARB_ARBORIO_API swc_record { int id = 0; // sample number int tag = 0; // structure identifier (tag) double x = 0; // sample coordinates @@ -79,7 +80,7 @@ struct swc_record { friend std::istream& operator>>(std::istream&, swc_record&); }; -struct swc_data { +struct ARB_ARBORIO_API swc_data { private: std::string metadata_; std::vector<swc_record> records_; @@ -114,8 +115,8 @@ public: // // SWC records are returned in id order. -swc_data parse_swc(std::istream&); -swc_data parse_swc(const std::string&); +ARB_ARBORIO_API swc_data parse_swc(std::istream&); +ARB_ARBORIO_API swc_data parse_swc(const std::string&); // Convert a valid, ordered sequence of SWC records into a morphology. // @@ -126,7 +127,7 @@ swc_data parse_swc(const std::string&); // and distal point of the segment, while the proximal point is taken from the // parent record. -arb::morphology load_swc_arbor(const swc_data& data); +ARB_ARBORIO_API arb::morphology load_swc_arbor(const swc_data& data); // As above, will convert a valid, ordered sequence of SWC records into a morphology // @@ -134,6 +135,6 @@ arb::morphology load_swc_arbor(const swc_data& data); // // Complies inferred SWC rules from NEURON, explicitly listed in the docs. -arb::morphology load_swc_neuron(const swc_data& data); +ARB_ARBORIO_API arb::morphology load_swc_neuron(const swc_data& data); } // namespace arborio diff --git a/arborio/include/arborio/xml.hpp b/arborio/include/arborio/xml.hpp index 702827c3c9cdd57b48389ac7400f091ace91130c..bedc54fdf2ee5ca8f084f38fcf578a4eaeed1566 100644 --- a/arborio/include/arborio/xml.hpp +++ b/arborio/include/arborio/xml.hpp @@ -3,12 +3,14 @@ #include <stdexcept> #include <string> +#include <arborio/export.hpp> + // XML related interfaces deriving from the underlying XML implementation library. namespace arborio { // Generic XML error (as reported by libxml2). -struct xml_error: std::runtime_error { +struct ARB_SYMBOL_VISIBLE xml_error: std::runtime_error { xml_error(const std::string& xml_error_msg, unsigned line = 0); std::string xml_error_msg; unsigned line; @@ -20,7 +22,7 @@ struct xml_error: std::runtime_error { // used in a multithreaded context and the client code is // not managing libxml2 initialization and cleanup. -struct with_xml { +struct ARB_ARBORIO_API with_xml { with_xml(); ~with_xml(); diff --git a/arborio/label_parse.cpp b/arborio/label_parse.cpp index 4a2a3ce229ff8cc77b863525fe5855da89813d48..961754cc3cf8b0862ed721e94ba743f6e1bb42b3 100644 --- a/arborio/label_parse.cpp +++ b/arborio/label_parse.cpp @@ -213,14 +213,14 @@ parse_label_hopefully<std::any> eval(const s_expr& e) { } // namespace -parse_label_hopefully<std::any> parse_label_expression(const std::string& e) { +ARB_ARBORIO_API parse_label_hopefully<std::any> parse_label_expression(const std::string& e) { return eval(parse_s_expr(e)); } -parse_label_hopefully<std::any> parse_label_expression(const s_expr& s) { +ARB_ARBORIO_API parse_label_hopefully<std::any> parse_label_expression(const s_expr& s) { return eval(s); } -parse_label_hopefully<arb::region> parse_region_expression(const std::string& s) { +ARB_ARBORIO_API parse_label_hopefully<arb::region> parse_region_expression(const std::string& s) { if (auto e = eval(parse_s_expr(s))) { if (e->type() == typeid(region)) { return {std::move(std::any_cast<region&>(*e))}; @@ -237,7 +237,7 @@ parse_label_hopefully<arb::region> parse_region_expression(const std::string& s) } } -parse_label_hopefully<arb::locset> parse_locset_expression(const std::string& s) { +ARB_ARBORIO_API parse_label_hopefully<arb::locset> parse_locset_expression(const std::string& s) { if (auto e = eval(parse_s_expr(s))) { if (e->type() == typeid(locset)) { return {std::move(std::any_cast<locset&>(*e))}; diff --git a/arborio/neurolucida.cpp b/arborio/neurolucida.cpp index fb05007ea832295e52bb3a0c77b736180429c4c7..a2a353e4b682adab75164d3c793399557e0e31e0 100644 --- a/arborio/neurolucida.cpp +++ b/arborio/neurolucida.cpp @@ -696,7 +696,7 @@ asc_morphology parse_asc_string(const char* input) { return {std::move(morphology), std::move(labels)}; } -asc_morphology load_asc(std::string filename) { +ARB_ARBORIO_API asc_morphology load_asc(std::string filename) { std::ifstream fid(filename); if (!fid.good()) { diff --git a/arborio/neuroml.cpp b/arborio/neuroml.cpp index 05d594c0132514f4322d79ab61f61f0f14624b87..31dcc80777c40ffaa1ae42dffe5aeb96493f32ea 100644 --- a/arborio/neuroml.cpp +++ b/arborio/neuroml.cpp @@ -59,7 +59,7 @@ nml_cyclic_dependency::nml_cyclic_dependency(const std::string& id, unsigned lin line(line) {} -struct neuroml_impl { +struct ARB_ARBORIO_API neuroml_impl { xml_doc doc; neuroml_impl() {} diff --git a/arborio/parse_s_expr.hpp b/arborio/parse_s_expr.hpp index b240897dd65490bf5b9c852f5dbb9d01eb289bbd..0e6362b794d677a6f575cd32e4257e3029158fed 100644 --- a/arborio/parse_s_expr.hpp +++ b/arborio/parse_s_expr.hpp @@ -1,6 +1,7 @@ #pragma once #include <arbor/s_expr.hpp> +#include <arborio/export.hpp> #include <arborio/cableio.hpp> namespace arborio { @@ -40,6 +41,6 @@ s_expr slist_range(const Range& range) { return slist_range(std::begin(range), std::end(range)); } -parse_hopefully<std::any> parse_expression(const std::string&); +ARB_ARBORIO_API parse_hopefully<std::any> parse_expression(const std::string&); } // namespace arborio diff --git a/arborio/swcio.cpp b/arborio/swcio.cpp index 1b6bec16f8f648d59abda2f78162e01ebb253d8a..9fc2f2613d5bf8a268a8e6ffd390f0b0ca10d1e1 100644 --- a/arborio/swcio.cpp +++ b/arborio/swcio.cpp @@ -51,7 +51,7 @@ swc_unsupported_tag::swc_unsupported_tag(int record_id): // Record I/O: -std::ostream& operator<<(std::ostream& out, const swc_record& record) { +ARB_ARBORIO_API std::ostream& operator<<(std::ostream& out, const swc_record& record) { std::ios_base::fmtflags flags(out.flags()); out.precision(std::numeric_limits<double>::digits10+2); @@ -64,7 +64,7 @@ std::ostream& operator<<(std::ostream& out, const swc_record& record) { return out; } -std::istream& operator>>(std::istream& in, swc_record& record) { +ARB_ARBORIO_API std::istream& operator>>(std::istream& in, swc_record& record) { std::string line; if (!getline(in, line, '\n')) return in; @@ -124,7 +124,7 @@ swc_data::swc_data(std::string meta, std::vector<arborio::swc_record> recs) : // Parse and validate swc data -swc_data parse_swc(std::istream& in) { +ARB_ARBORIO_API swc_data parse_swc(std::istream& in) { // Collect any initial comments (lines beginning with '#'). std::string metadata; @@ -155,12 +155,12 @@ swc_data parse_swc(std::istream& in) { return swc_data(metadata, std::move(records)); } -swc_data parse_swc(const std::string& text) { +ARB_ARBORIO_API swc_data parse_swc(const std::string& text) { std::istringstream is(text); return parse_swc(is); } -arb::morphology load_swc_arbor(const swc_data& data) { +ARB_ARBORIO_API arb::morphology load_swc_arbor(const swc_data& data) { const auto& records = data.records(); if (records.empty()) return {}; @@ -205,7 +205,7 @@ arb::morphology load_swc_arbor(const swc_data& data) { return arb::morphology(tree); } -arb::morphology load_swc_neuron(const swc_data& data) { +ARB_ARBORIO_API arb::morphology load_swc_neuron(const swc_data& data) { constexpr int soma_tag = 1; const auto n_samples = data.records().size(); diff --git a/cmake/CompilerOptions.cmake b/cmake/CompilerOptions.cmake index 086726857dc5cd015e4bd825e73c7bba8a47973c..6c1b8eb559c5d7e4680a8dec478210ccbdb54754 100644 --- a/cmake/CompilerOptions.cmake +++ b/cmake/CompilerOptions.cmake @@ -136,3 +136,31 @@ function(set_arch_target optvar arch) endif() endfunction() + +function(export_visibility target) + # mangle target name to correspond to cmake naming + string(REPLACE "-" "_" target_name ${target}) + # extract compact library name + string(REPLACE "arbor-" "" target_short_name ${target}) + # make upper case + string(TOUPPER ${target_short_name} target_short_NAME) + + # conditional on build type + get_target_property(target_type ${target} TYPE) + if (${target_type} STREQUAL STATIC_LIBRARY) + # building static library + string(CONCAT target_export_def ${target_name} "_EXPORTS_STATIC") + target_compile_definitions(${target} PRIVATE ${target_export_def}) + else() + # building shared library + string(CONCAT target_export_def ${target_name} "_EXPORTS") + # the above compile definition is added by cmake automatically + endif() + + # generate config file + get_target_property(target_binary_dir ${target} BINARY_DIR) + configure_file( + ${CMAKE_SOURCE_DIR}/cmake/export.hpp.in + ${target_binary_dir}/include/${target_short_name}/export.hpp + @ONLY) +endfunction() diff --git a/cmake/export.hpp.in b/cmake/export.hpp.in new file mode 100644 index 0000000000000000000000000000000000000000..655cb4bb2dbdec24f2ef4b7329aab99cd97f0137 --- /dev/null +++ b/cmake/export.hpp.in @@ -0,0 +1,41 @@ +#pragma once + +//#ifndef ARB_EXPORT_DEBUG +//# define ARB_EXPORT_DEBUG +//#endif + +#include <arbor/util/visibility.hpp> + +/* library build type (ARB_@target_short_NAME@_STATIC_LIBRARY/ARB_@target_short_NAME@_SHARED_LIBRARY) */ +#define ARB_@target_short_NAME@_@target_type@ + +#ifndef ARB_@target_short_NAME@_EXPORTS +# if defined(@target_name@_EXPORTS) + /* we are building @target@ dynamically */ +# ifdef ARB_EXPORT_DEBUG +# pragma message "we are building @target@ dynamically" +# endif +# define ARB_@target_short_NAME@_API ARB_SYMBOL_EXPORT +# elif defined(@target_name@_EXPORTS_STATIC) + /* we are building @target@ statically */ +# ifdef ARB_EXPORT_DEBUG +# pragma message "we are building @target@ statically" +# endif +# define ARB_@target_short_NAME@_API +# else + /* we are using the library @target@ */ +# if defined(ARB_@target_short_NAME@_SHARED_LIBRARY) + /* we are importing @target@ dynamically */ +# ifdef ARB_EXPORT_DEBUG +# pragma message "we are importing @target@ dynamically" +# endif +# define ARB_@target_short_NAME@_API ARB_SYMBOL_IMPORT +# else + /* we are importing @target@ statically */ +# ifdef ARB_EXPORT_DEBUG +# pragma message "we are importing @target@ statically" +# endif +# define ARB_@target_short_NAME@_API +# endif +# endif +#endif diff --git a/example/drybench/drybench.cpp b/example/drybench/drybench.cpp index 59b30fa6d17718f24ba6362cf1136ea2c2f0a2f0..ac891cdd551de85540c202b0f41d2d0fdf248c2a 100644 --- a/example/drybench/drybench.cpp +++ b/example/drybench/drybench.cpp @@ -143,7 +143,7 @@ int main(int argc, char** argv) { auto ctx = arb::make_context(resources); ctx = arb::make_context(resources, arb::dry_run_info(params.num_ranks, params.num_cells)); - arb_assert(arb::num_ranks(ctx)==params.num_ranks); + arb_assert(arb::num_ranks(ctx)==(unsigned int)params.num_ranks); #ifdef ARB_PROFILE_ENABLED arb::profile::profiler_initialize(ctx); diff --git a/mechanisms/generate_catalogue b/mechanisms/generate_catalogue index b0491e5ebfd1dbd3cedb0c828b0008ace2e49397..53eec3af393cb2a93e7d3eb43d28bc245c68416e 100755 --- a/mechanisms/generate_catalogue +++ b/mechanisms/generate_catalogue @@ -112,7 +112,7 @@ mechanism_catalogue build_${catalogue}_catalogue() { return cat; } -const mechanism_catalogue& global_${catalogue}_catalogue() { +ARB_ARBOR_API const mechanism_catalogue& global_${catalogue}_catalogue() { static mechanism_catalogue cat = build_${catalogue}_catalogue(); return cat; } diff --git a/modcc/CMakeLists.txt b/modcc/CMakeLists.txt index 32af1a737953610f436b61dfdd717139633dbc02..51857c36103312e8deae7204bc6d98bda391eca8 100644 --- a/modcc/CMakeLists.txt +++ b/modcc/CMakeLists.txt @@ -30,17 +30,32 @@ set(libmodcc_sources set(modcc_sources modcc.cpp) add_library(libmodcc STATIC ${libmodcc_sources}) -target_include_directories(libmodcc PUBLIC .) +target_link_libraries(libmodcc PUBLIC arbor-public-headers) + if (ARB_USE_BUNDLED_FMT) - target_include_directories(libmodcc PRIVATE ../ext/fmt/include) + target_include_directories(libmodcc + PUBLIC + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> + $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include> + PRIVATE + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../ext/fmt/include>) + target_compile_definitions(libmodcc PRIVATE FMT_HEADER_ONLY) -else () + +else() + target_include_directories(libmodcc + PUBLIC + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> + $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>) find_package(fmt REQUIRED) target_link_libraries(libmodcc PRIVATE fmt::fmt-header-only) -endif () +endif() set_target_properties(libmodcc PROPERTIES OUTPUT_NAME modcc) +export_visibility(libmodcc) + + add_executable(modcc ${modcc_sources}) target_link_libraries(modcc PRIVATE libmodcc ext-tinyopt) set_target_properties(modcc libmodcc PROPERTIES EXCLUDE_FROM_ALL ${ARB_WITH_EXTERNAL_MODCC}) diff --git a/modcc/astmanip.cpp b/modcc/astmanip.cpp index 4d58b09226bc9f75c4930d95f28ceeab73b8e5db..040e340ab8e89698b38f868c205f7c4aad540094 100644 --- a/modcc/astmanip.cpp +++ b/modcc/astmanip.cpp @@ -12,7 +12,7 @@ static std::string unique_local_name(scope_ptr scope, std::string const& prefix) } } -local_assignment make_unique_local_assign(scope_ptr scope, Expression* e, std::string const& prefix) { +ARB_LIBMODCC_API local_assignment make_unique_local_assign(scope_ptr scope, Expression* e, std::string const& prefix) { Location loc = e->location(); std::string name = unique_local_name(scope, prefix); @@ -28,7 +28,7 @@ local_assignment make_unique_local_assign(scope_ptr scope, Expression* e, std::s return { std::move(local), std::move(ass), std::move(id), scope }; } -local_declaration make_unique_local_decl(scope_ptr scope, Location loc, std::string const& prefix) { +ARB_LIBMODCC_API local_declaration make_unique_local_decl(scope_ptr scope, Location loc, std::string const& prefix) { std::string name = unique_local_name(scope, prefix); auto local = make_expression<LocalDeclaration>(loc, name); diff --git a/modcc/astmanip.hpp b/modcc/astmanip.hpp index e42586ff9b4197e633b7702801a3f133c58ad67f..0e961b8bb7e7e68185e6441e663d421fe38b5359 100644 --- a/modcc/astmanip.hpp +++ b/modcc/astmanip.hpp @@ -7,6 +7,7 @@ #include "expression.hpp" #include "location.hpp" #include "scope.hpp" +#include <libmodcc/export.hpp> // Create new local variable symbol and local declaration expression in current scope. // Returns the local declaration expression. @@ -17,7 +18,7 @@ struct local_declaration { scope_ptr scope; }; -local_declaration make_unique_local_decl( +ARB_LIBMODCC_API local_declaration make_unique_local_decl( scope_ptr scope, Location loc, std::string const& prefix="ll"); @@ -34,7 +35,7 @@ struct local_assignment { scope_ptr scope; }; -local_assignment make_unique_local_assign( +ARB_LIBMODCC_API local_assignment make_unique_local_assign( scope_ptr scope, Expression* e, std::string const& prefix="ll"); diff --git a/modcc/blocks.cpp b/modcc/blocks.cpp index bc9d57ec25e6d5a3512ac7451051c92bb27b6aae..8e979ca596252feb962e1f4cfa9c9c314bb41709 100644 --- a/modcc/blocks.cpp +++ b/modcc/blocks.cpp @@ -18,7 +18,7 @@ std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) { return os; } -std::ostream& operator<<(std::ostream& os, Id const& V) { +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, Id const& V) { if(V.units.size()) os << "(" << V.token << "," << V.value << "," << V.units << ")"; else @@ -27,19 +27,19 @@ std::ostream& operator<<(std::ostream& os, Id const& V) { return os; } -std::ostream& operator<<(std::ostream& os, UnitsBlock::units_pair const& p) { +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, UnitsBlock::units_pair const& p) { return os << "(" << p.first << ", " << p.second << ")"; } -std::ostream& operator<<(std::ostream& os, IonDep const& I) { +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, IonDep const& I) { return os << "(" << I.name << ": read " << I.read << " write " << I.write << ")"; } -std::ostream& operator<<(std::ostream& os, moduleKind const& k) { +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, moduleKind const& k) { return os << (k==moduleKind::density ? "density" : "point process"); } -std::ostream& operator<<(std::ostream& os, NeuronBlock const& N) { +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, NeuronBlock const& N) { os << blue("NeuronBlock") << std::endl; os << " kind : " << N.kind << std::endl; os << " name : " << N.name << std::endl; @@ -51,27 +51,27 @@ std::ostream& operator<<(std::ostream& os, NeuronBlock const& N) { return os; } -std::ostream& operator<<(std::ostream& os, StateBlock const& B) { +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, StateBlock const& B) { os << blue("StateBlock") << std::endl; return os << " variables : " << B.state_variables << std::endl; } -std::ostream& operator<<(std::ostream& os, UnitsBlock const& U) { +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, UnitsBlock const& U) { os << blue("UnitsBlock") << std::endl; os << " aliases : " << U.unit_aliases << std::endl; return os; } -std::ostream& operator<<(std::ostream& os, ParameterBlock const& P) { +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, ParameterBlock const& P) { os << blue("ParameterBlock") << std::endl; os << " parameters : " << P.parameters << std::endl; return os; } -std::ostream& operator<<(std::ostream& os, AssignedBlock const& A) { +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, AssignedBlock const& A) { os << blue("AssignedBlock") << std::endl; os << " parameters : " << A.parameters << std::endl; diff --git a/modcc/blocks.hpp b/modcc/blocks.hpp index df77a04939160b2a8dbbb4bb7186e376195abdc5..495a47ac0337b02a2b3f38b748bf8ccca7f66758 100644 --- a/modcc/blocks.hpp +++ b/modcc/blocks.hpp @@ -8,6 +8,7 @@ #include "identifier.hpp" #include "location.hpp" #include "token.hpp" +#include <libmodcc/export.hpp> // describes a relationship with an ion channel struct IonDep { @@ -161,20 +162,20 @@ struct AssignedBlock { // helpers for pretty printing block information //////////////////////////////////////////////// -std::ostream& operator<<(std::ostream& os, Id const& V); +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, Id const& V); -std::ostream& operator<<(std::ostream& os, UnitsBlock::units_pair const& p); +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, UnitsBlock::units_pair const& p); -std::ostream& operator<<(std::ostream& os, IonDep const& I); +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, IonDep const& I); -std::ostream& operator<<(std::ostream& os, moduleKind const& k); +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, moduleKind const& k); -std::ostream& operator<<(std::ostream& os, NeuronBlock const& N); +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, NeuronBlock const& N); -std::ostream& operator<<(std::ostream& os, StateBlock const& B); +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, StateBlock const& B); -std::ostream& operator<<(std::ostream& os, UnitsBlock const& U); +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, UnitsBlock const& U); -std::ostream& operator<<(std::ostream& os, ParameterBlock const& P); +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, ParameterBlock const& P); -std::ostream& operator<<(std::ostream& os, AssignedBlock const& A); +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, AssignedBlock const& A); diff --git a/modcc/errorvisitor.hpp b/modcc/errorvisitor.hpp index c9b633857bd0e9c8ca44db8e6f0fd44ae97da07e..c12cfe6617dc35f8fefe4a1b69c61f264783e1ee 100644 --- a/modcc/errorvisitor.hpp +++ b/modcc/errorvisitor.hpp @@ -3,8 +3,9 @@ #include <iostream> #include "visitor.hpp" #include "expression.hpp" +#include <libmodcc/export.hpp> -class ErrorVisitor : public Visitor { +class ARB_LIBMODCC_API ErrorVisitor : public Visitor { public: ErrorVisitor(std::string const& m) : module_name_(m) diff --git a/modcc/expression.cpp b/modcc/expression.cpp index 8cb81f7106e592d85570e8964260a305b8ddb36d..8eb9fab2bf0d9de6b33e3e5c168ef8f80bb8ad9c 100644 --- a/modcc/expression.cpp +++ b/modcc/expression.cpp @@ -1147,7 +1147,7 @@ void CompartmentExpression::accept(Visitor *v) { v->visit(this); } -expression_ptr unary_expression( Location loc, +ARB_LIBMODCC_API expression_ptr unary_expression( Location loc, tok op, expression_ptr&& e ) @@ -1178,7 +1178,7 @@ expression_ptr unary_expression( Location loc, return nullptr; } -expression_ptr binary_expression( tok op, +ARB_LIBMODCC_API expression_ptr binary_expression( tok op, expression_ptr&& lhs, expression_ptr&& rhs ) @@ -1186,7 +1186,7 @@ expression_ptr binary_expression( tok op, return binary_expression(Location(), op, std::move(lhs), std::move(rhs)); } -expression_ptr binary_expression(Location loc, +ARB_LIBMODCC_API expression_ptr binary_expression(Location loc, tok op, expression_ptr&& lhs, expression_ptr&& rhs diff --git a/modcc/expression.hpp b/modcc/expression.hpp index 280791a7d51cb6f09ba64f533b5d6bade288d0b6..da885630f2080290de61ca1b8c209f14282b0126 100644 --- a/modcc/expression.hpp +++ b/modcc/expression.hpp @@ -11,45 +11,46 @@ #include "identifier.hpp" #include "scope.hpp" #include "token.hpp" +#include <libmodcc/export.hpp> #include "io/pprintf.hpp" class Visitor; -class Expression; -class CallExpression; -class BlockExpression; -class IfExpression; -class LocalDeclaration; -class ArgumentExpression; -class FunctionExpression; -class DerivativeExpression; -class PrototypeExpression; -class ProcedureExpression; -class IdentifierExpression; -class NumberExpression; -class IntegerExpression; -class BinaryExpression; -class UnaryExpression; -class AssignmentExpression; -class ConserveExpression; -class LinearExpression; -class ReactionExpression; -class StoichExpression; -class StoichTermExpression; -class CompartmentExpression; -class ConditionalExpression; -class InitialBlock; -class SolveExpression; -class Symbol; -class ConductanceExpression; -class PDiffExpression; -class VariableExpression; -class NetReceiveExpression; -class PostEventExpression; -class APIMethod; -class IndexedVariable; -class LocalVariable; +class ARB_LIBMODCC_API Expression; +class ARB_LIBMODCC_API CallExpression; +class ARB_LIBMODCC_API BlockExpression; +class ARB_LIBMODCC_API IfExpression; +class ARB_LIBMODCC_API LocalDeclaration; +class ARB_LIBMODCC_API ArgumentExpression; +class ARB_LIBMODCC_API FunctionExpression; +class ARB_LIBMODCC_API DerivativeExpression; +class ARB_LIBMODCC_API PrototypeExpression; +class ARB_LIBMODCC_API ProcedureExpression; +class ARB_LIBMODCC_API IdentifierExpression; +class ARB_LIBMODCC_API NumberExpression; +class ARB_LIBMODCC_API IntegerExpression; +class ARB_LIBMODCC_API BinaryExpression; +class ARB_LIBMODCC_API UnaryExpression; +class ARB_LIBMODCC_API AssignmentExpression; +class ARB_LIBMODCC_API ConserveExpression; +class ARB_LIBMODCC_API LinearExpression; +class ARB_LIBMODCC_API ReactionExpression; +class ARB_LIBMODCC_API StoichExpression; +class ARB_LIBMODCC_API StoichTermExpression; +class ARB_LIBMODCC_API CompartmentExpression; +class ARB_LIBMODCC_API ConditionalExpression; +class ARB_LIBMODCC_API InitialBlock; +class ARB_LIBMODCC_API SolveExpression; +class ARB_LIBMODCC_API Symbol; +class ARB_LIBMODCC_API ConductanceExpression; +class ARB_LIBMODCC_API PDiffExpression; +class ARB_LIBMODCC_API VariableExpression; +class ARB_LIBMODCC_API NetReceiveExpression; +class ARB_LIBMODCC_API PostEventExpression; +class ARB_LIBMODCC_API APIMethod; +class ARB_LIBMODCC_API IndexedVariable; +class ARB_LIBMODCC_API LocalVariable; using expression_ptr = std::unique_ptr<Expression>; using symbol_ptr = std::unique_ptr<Symbol>; @@ -68,10 +69,9 @@ symbol_ptr make_symbol(Args&&... args) { } // helper functions for generating unary and binary expressions -expression_ptr unary_expression(Location, tok, expression_ptr&&); -expression_ptr unary_expression(tok, expression_ptr&&); -expression_ptr binary_expression(Location, tok, expression_ptr&&, expression_ptr&&); -expression_ptr binary_expression(tok, expression_ptr&&, expression_ptr&&); +ARB_LIBMODCC_API expression_ptr unary_expression(Location, tok, expression_ptr&&); +ARB_LIBMODCC_API expression_ptr binary_expression(Location, tok, expression_ptr&&, expression_ptr&&); +ARB_LIBMODCC_API expression_ptr binary_expression(tok, expression_ptr&&, expression_ptr&&); /// specifies special properties of a ProcedureExpression enum class procedureKind { @@ -118,7 +118,7 @@ static std::string to_string(solverMethod m) { return std::string("<error : undefined solverMethod>"); } -class Expression { +class ARB_LIBMODCC_API Expression { public: explicit Expression(Location location) : location_(location) @@ -209,7 +209,7 @@ protected: scope_ptr scope_; }; -class Symbol : public Expression { +class ARB_LIBMODCC_API Symbol : public Expression { public : Symbol(Location loc, std::string name, symbolKind kind) : Expression(std::move(loc)), @@ -251,7 +251,7 @@ enum class localVariableKind { }; // an identifier -class IdentifierExpression : public Expression { +class ARB_LIBMODCC_API IdentifierExpression : public Expression { public: IdentifierExpression(Location loc, std::string const& spelling) : Expression(loc), spelling_(spelling) @@ -304,7 +304,7 @@ protected: }; // an identifier for a derivative -class DerivativeExpression : public IdentifierExpression { +class ARB_LIBMODCC_API DerivativeExpression : public IdentifierExpression { public: DerivativeExpression(Location loc, std::string const& name) : IdentifierExpression(loc, name) @@ -326,7 +326,7 @@ public: }; // a number -class NumberExpression : public Expression { +class ARB_LIBMODCC_API NumberExpression : public Expression { public: NumberExpression(Location loc, std::string const& value) : Expression(loc), value_(std::stold(value)) @@ -356,7 +356,7 @@ private: }; // an integral number -class IntegerExpression : public NumberExpression { +class ARB_LIBMODCC_API IntegerExpression : public NumberExpression { public: IntegerExpression(Location loc, std::string const& value) : NumberExpression(loc, value), integer_(std::stoll(value)) @@ -388,7 +388,7 @@ private: // declaration of a LOCAL variable -class LocalDeclaration : public Expression { +class ARB_LIBMODCC_API LocalDeclaration : public Expression { public: LocalDeclaration(Location loc) : Expression(loc) @@ -417,7 +417,7 @@ private: }; // declaration of an argument -class ArgumentExpression : public Expression { +class ARB_LIBMODCC_API ArgumentExpression : public Expression { public: ArgumentExpression(Location loc, Token const& tok) : Expression(loc), @@ -447,7 +447,7 @@ private: }; // variable definition -class VariableExpression : public Symbol { +class ARB_LIBMODCC_API VariableExpression : public Symbol { public: VariableExpression(Location loc, std::string name) : Symbol(loc, std::move(name), symbolKind::variable) @@ -528,7 +528,7 @@ protected: // Printers will rewrite reads from or assignments from indexed variables // according to its data source and ion channel. -class IndexedVariable : public Symbol { +class ARB_LIBMODCC_API IndexedVariable : public Symbol { public: IndexedVariable(Location loc, std::string lookup_name, @@ -569,7 +569,7 @@ protected: sourceKind data_source_; }; -class LocalVariable : public Symbol { +class ARB_LIBMODCC_API LocalVariable : public Symbol { public : LocalVariable(Location loc, std::string name, @@ -630,7 +630,7 @@ private : // a SOLVE statement -class SolveExpression : public Expression { +class ARB_LIBMODCC_API SolveExpression : public Expression { public: SolveExpression( Location loc, @@ -685,7 +685,7 @@ private: }; // a CONDUCTANCE statement -class ConductanceExpression : public Expression { +class ARB_LIBMODCC_API ConductanceExpression : public Expression { public: ConductanceExpression( Location loc, @@ -729,7 +729,7 @@ private: // of Expressions surrounded by {} //////////////////////////////////////////////////////////////////////////////// -class BlockExpression : public Expression { +class ARB_LIBMODCC_API BlockExpression : public Expression { protected: expr_list_type statements_; bool is_nested_ = false; @@ -777,7 +777,7 @@ public: std::string to_string() const override; }; -class IfExpression : public Expression { +class ARB_LIBMODCC_API IfExpression : public Expression { public: IfExpression(Location loc, expression_ptr&& con, expression_ptr&& tb, expression_ptr&& fb) : Expression(loc), condition_(std::move(con)), true_branch_(std::move(tb)), false_branch_(std::move(fb)) @@ -811,7 +811,7 @@ private: }; // a proceduce prototype -class PrototypeExpression : public Expression { +class ARB_LIBMODCC_API PrototypeExpression : public Expression { public: PrototypeExpression( Location loc, @@ -877,7 +877,7 @@ private: expression_ptr rev_rate_; }; -class CompartmentExpression : public Expression { +class ARB_LIBMODCC_API CompartmentExpression : public Expression { public: CompartmentExpression(Location loc, expression_ptr&& scale_factor, @@ -904,7 +904,7 @@ private: std::vector<expression_ptr> state_vars_; }; -class StoichTermExpression : public Expression { +class ARB_LIBMODCC_API StoichTermExpression : public Expression { public: StoichTermExpression(Location loc, expression_ptr&& coeff, @@ -938,7 +938,7 @@ private: expression_ptr ident_; }; -class StoichExpression : public Expression { +class ARB_LIBMODCC_API StoichExpression : public Expression { public: StoichExpression(Location loc, std::vector<expression_ptr>&& terms) : Expression(loc), terms_(std::move(terms)) @@ -964,7 +964,7 @@ private: // marks a call site in the AST // is used to mark both function and procedure calls -class CallExpression : public Expression { +class ARB_LIBMODCC_API CallExpression : public Expression { public: CallExpression(Location loc, std::string spelling, std::vector<expression_ptr>&& args) : Expression(loc), spelling_(std::move(spelling)), args_(std::move(args)) @@ -1010,7 +1010,7 @@ private: std::vector<expression_ptr> args_; }; -class ProcedureExpression : public Symbol { +class ARB_LIBMODCC_API ProcedureExpression : public Symbol { public: ProcedureExpression( Location loc, std::string name, @@ -1063,7 +1063,7 @@ protected: procedureKind kind_ = procedureKind::normal; }; -class APIMethod : public ProcedureExpression { +class ARB_LIBMODCC_API APIMethod : public ProcedureExpression { public: APIMethod( Location loc, std::string name, @@ -1082,7 +1082,7 @@ public: /// stores the INITIAL block in a NET_RECEIVE block, if there is one /// should not be used anywhere but NET_RECEIVE -class InitialBlock : public BlockExpression { +class ARB_LIBMODCC_API InitialBlock : public BlockExpression { public: InitialBlock( Location loc, @@ -1102,7 +1102,7 @@ public: }; /// handle NetReceiveExpressions as a special case of ProcedureExpression -class NetReceiveExpression : public ProcedureExpression { +class ARB_LIBMODCC_API NetReceiveExpression : public ProcedureExpression { public: NetReceiveExpression( Location loc, std::string name, @@ -1123,7 +1123,7 @@ protected: }; /// handle PostEventExpression as a special case of ProcedureExpression -class PostEventExpression : public ProcedureExpression { +class ARB_LIBMODCC_API PostEventExpression : public ProcedureExpression { public: PostEventExpression( Location loc, std::string name, @@ -1140,7 +1140,7 @@ public: void accept(Visitor *v) override; }; -class FunctionExpression : public Symbol { +class ARB_LIBMODCC_API FunctionExpression : public Symbol { public: FunctionExpression( Location loc, std::string name, @@ -1192,7 +1192,7 @@ private: //////////////////////////////////////////////////////////// /// Unary expression -class UnaryExpression : public Expression { +class ARB_LIBMODCC_API UnaryExpression : public Expression { protected: expression_ptr expression_; tok op_; @@ -1219,7 +1219,7 @@ public: }; /// negation unary expression, i.e. -x -class NegUnaryExpression : public UnaryExpression { +class ARB_LIBMODCC_API NegUnaryExpression : public UnaryExpression { public: NegUnaryExpression(Location loc, expression_ptr e) : UnaryExpression(loc, tok::minus, std::move(e)) @@ -1229,7 +1229,7 @@ public: }; /// exponential unary expression, i.e. e^x or exp(x) -class ExpUnaryExpression : public UnaryExpression { +class ARB_LIBMODCC_API ExpUnaryExpression : public UnaryExpression { public: ExpUnaryExpression(Location loc, expression_ptr e) : UnaryExpression(loc, tok::exp, std::move(e)) @@ -1239,7 +1239,7 @@ public: }; // logarithm unary expression, i.e. log_10(x) -class LogUnaryExpression : public UnaryExpression { +class ARB_LIBMODCC_API LogUnaryExpression : public UnaryExpression { public: LogUnaryExpression(Location loc, expression_ptr e) : UnaryExpression(loc, tok::log, std::move(e)) @@ -1249,7 +1249,7 @@ public: }; // absolute value unary expression, i.e. abs(x) -class AbsUnaryExpression : public UnaryExpression { +class ARB_LIBMODCC_API AbsUnaryExpression : public UnaryExpression { public: AbsUnaryExpression(Location loc, expression_ptr e) : UnaryExpression(loc, tok::abs, std::move(e)) @@ -1258,7 +1258,7 @@ public: void accept(Visitor *v) override; }; -class SafeInvUnaryExpression : public UnaryExpression { +class ARB_LIBMODCC_API SafeInvUnaryExpression : public UnaryExpression { public: SafeInvUnaryExpression(Location loc, expression_ptr e) : UnaryExpression(loc, tok::safeinv, std::move(e)) @@ -1269,7 +1269,7 @@ public: // exprel reciprocal unary expression, // i.e. x/(exp(x)-1)=x/expm1(x) with exprelr(0)=1 -class ExprelrUnaryExpression : public UnaryExpression { +class ARB_LIBMODCC_API ExprelrUnaryExpression : public UnaryExpression { public: ExprelrUnaryExpression(Location loc, expression_ptr e) : UnaryExpression(loc, tok::exprelr, std::move(e)) @@ -1279,7 +1279,7 @@ public: }; // cosine unary expression, i.e. cos(x) -class CosUnaryExpression : public UnaryExpression { +class ARB_LIBMODCC_API CosUnaryExpression : public UnaryExpression { public: CosUnaryExpression(Location loc, expression_ptr e) : UnaryExpression(loc, tok::cos, std::move(e)) @@ -1289,7 +1289,7 @@ public: }; // sin unary expression, i.e. sin(x) -class SinUnaryExpression : public UnaryExpression { +class ARB_LIBMODCC_API SinUnaryExpression : public UnaryExpression { public: SinUnaryExpression(Location loc, expression_ptr e) : UnaryExpression(loc, tok::sin, std::move(e)) @@ -1306,7 +1306,7 @@ public: /// binary expression base class /// never used directly in the AST, instead the specializations that derive from /// it are inserted into the AST. -class BinaryExpression : public Expression { +class ARB_LIBMODCC_API BinaryExpression : public Expression { protected: expression_ptr lhs_; expression_ptr rhs_; @@ -1334,7 +1334,7 @@ public: void accept(Visitor *v) override; }; -class AssignmentExpression : public BinaryExpression { +class ARB_LIBMODCC_API AssignmentExpression : public BinaryExpression { public: AssignmentExpression(Location loc, expression_ptr&& lhs, expression_ptr&& rhs) : BinaryExpression(loc, tok::eq, std::move(lhs), std::move(rhs)) @@ -1347,7 +1347,7 @@ public: void accept(Visitor *v) override; }; -class ConserveExpression : public BinaryExpression { +class ARB_LIBMODCC_API ConserveExpression : public BinaryExpression { public: ConserveExpression(Location loc, expression_ptr&& lhs, expression_ptr&& rhs) : BinaryExpression(loc, tok::eq, std::move(lhs), std::move(rhs)) @@ -1361,7 +1361,7 @@ public: void accept(Visitor *v) override; }; -class LinearExpression : public BinaryExpression { +class ARB_LIBMODCC_API LinearExpression : public BinaryExpression { public: LinearExpression(Location loc, expression_ptr&& lhs, expression_ptr&& rhs) : BinaryExpression(loc, tok::eq, std::move(lhs), std::move(rhs)) @@ -1375,7 +1375,7 @@ public: void accept(Visitor *v) override; }; -class AddBinaryExpression : public BinaryExpression { +class ARB_LIBMODCC_API AddBinaryExpression : public BinaryExpression { public: AddBinaryExpression(Location loc, expression_ptr&& lhs, expression_ptr&& rhs) : BinaryExpression(loc, tok::plus, std::move(lhs), std::move(rhs)) @@ -1384,7 +1384,7 @@ public: void accept(Visitor *v) override; }; -class SubBinaryExpression : public BinaryExpression { +class ARB_LIBMODCC_API SubBinaryExpression : public BinaryExpression { public: SubBinaryExpression(Location loc, expression_ptr&& lhs, expression_ptr&& rhs) : BinaryExpression(loc, tok::minus, std::move(lhs), std::move(rhs)) @@ -1393,7 +1393,7 @@ public: void accept(Visitor *v) override; }; -class MulBinaryExpression : public BinaryExpression { +class ARB_LIBMODCC_API MulBinaryExpression : public BinaryExpression { public: MulBinaryExpression(Location loc, expression_ptr&& lhs, expression_ptr&& rhs) : BinaryExpression(loc, tok::times, std::move(lhs), std::move(rhs)) @@ -1402,7 +1402,7 @@ public: void accept(Visitor *v) override; }; -class DivBinaryExpression : public BinaryExpression { +class ARB_LIBMODCC_API DivBinaryExpression : public BinaryExpression { public: DivBinaryExpression(Location loc, expression_ptr&& lhs, expression_ptr&& rhs) : BinaryExpression(loc, tok::divide, std::move(lhs), std::move(rhs)) @@ -1411,7 +1411,7 @@ public: void accept(Visitor *v) override; }; -class MinBinaryExpression : public BinaryExpression { +class ARB_LIBMODCC_API MinBinaryExpression : public BinaryExpression { public: MinBinaryExpression(Location loc, expression_ptr&& lhs, expression_ptr&& rhs) : BinaryExpression(loc, tok::min, std::move(lhs), std::move(rhs)) @@ -1423,7 +1423,7 @@ public: void accept(Visitor *v) override; }; -class MaxBinaryExpression : public BinaryExpression { +class ARB_LIBMODCC_API MaxBinaryExpression : public BinaryExpression { public: MaxBinaryExpression(Location loc, expression_ptr&& lhs, expression_ptr&& rhs) : BinaryExpression(loc, tok::max, std::move(lhs), std::move(rhs)) @@ -1435,7 +1435,7 @@ public: void accept(Visitor *v) override; }; -class PowBinaryExpression : public BinaryExpression { +class ARB_LIBMODCC_API PowBinaryExpression : public BinaryExpression { public: PowBinaryExpression(Location loc, expression_ptr&& lhs, expression_ptr&& rhs) : BinaryExpression(loc, tok::pow, std::move(lhs), std::move(rhs)) @@ -1447,7 +1447,7 @@ public: void accept(Visitor *v) override; }; -class ConditionalExpression : public BinaryExpression { +class ARB_LIBMODCC_API ConditionalExpression : public BinaryExpression { public: ConditionalExpression(Location loc, tok op, expression_ptr&& lhs, expression_ptr&& rhs) : BinaryExpression(loc, op, std::move(lhs), std::move(rhs)) @@ -1458,7 +1458,7 @@ public: void accept(Visitor *v) override; }; -class PDiffExpression : public Expression { +class ARB_LIBMODCC_API PDiffExpression : public Expression { public: PDiffExpression(Location loc, expression_ptr&& var, expression_ptr&& arg) : Expression(loc), var_(std::move(var)), arg_(std::move(arg)) diff --git a/modcc/functionexpander.cpp b/modcc/functionexpander.cpp index d53e83965897e4fc21ff2040e9f2c7c76b7210b4..e4dde3f0ca9f077141e9e7e547dce70d57a1e607 100644 --- a/modcc/functionexpander.cpp +++ b/modcc/functionexpander.cpp @@ -5,7 +5,7 @@ #include "error.hpp" #include "functionexpander.hpp" -expression_ptr insert_unique_local_assignment(expr_list_type& stmts, Expression* e) { +ARB_LIBMODCC_API expression_ptr insert_unique_local_assignment(expr_list_type& stmts, Expression* e) { auto zero = make_expression<NumberExpression>(e->location(), 0.); auto exprs = make_unique_local_assign(e->scope(), zero); @@ -34,7 +34,7 @@ expression_ptr insert_unique_local_assignment(expr_list_type& stmts, Expression* // ll0_ = foo(ll1_, y, 1) // a = 2 + ll0_ ///////////////////////////////////////////////////////////////////// -expression_ptr lower_functions(BlockExpression* block) { +ARB_LIBMODCC_API expression_ptr lower_functions(BlockExpression* block) { auto v = std::make_unique<FunctionCallLowerer>(); block->accept(v.get()); return v->as_block(false); diff --git a/modcc/functionexpander.hpp b/modcc/functionexpander.hpp index cfb04b7f4f47866af0072aac6a58a0ea446c8eda..7c5671c37df761882628d02a2a8337dbcb24fb97 100644 --- a/modcc/functionexpander.hpp +++ b/modcc/functionexpander.hpp @@ -5,16 +5,17 @@ #include "expression.hpp" #include "scope.hpp" #include "visitor.hpp" +#include <libmodcc/export.hpp> // Make a local declaration and assignment for the given expression, // and insert at the front and back respectively of the statement list. // Return the new unique local identifier. -expression_ptr insert_unique_local_assignment(expr_list_type& stmts, Expression* e); +ARB_LIBMODCC_API expression_ptr insert_unique_local_assignment(expr_list_type& stmts, Expression* e); // prototype for lowering function calls and arguments -expression_ptr lower_functions(BlockExpression* block); +ARB_LIBMODCC_API expression_ptr lower_functions(BlockExpression* block); -class FunctionCallLowerer : public BlockRewriterBase { +class ARB_LIBMODCC_API FunctionCallLowerer : public BlockRewriterBase { public: using BlockRewriterBase::visit; diff --git a/modcc/functioninliner.cpp b/modcc/functioninliner.cpp index ddfcbf6283258826dbff91248ad7a2e21148c9c0..6d727e7f29d5cc6f47508cad5a10b82d49fa6a6f 100644 --- a/modcc/functioninliner.cpp +++ b/modcc/functioninliner.cpp @@ -17,7 +17,7 @@ // argument renaming. This means that if a local variable shadows a function // argument, the local variable takes precedence. -expression_ptr inline_function_calls(std::string calling_func, BlockExpression* block) { +ARB_LIBMODCC_API expression_ptr inline_function_calls(std::string calling_func, BlockExpression* block) { auto inline_block = block->clone(); // The function inliner will inline one function at a time diff --git a/modcc/functioninliner.hpp b/modcc/functioninliner.hpp index ba4bada981e5ad43def73fe3d699391ec271b9db..2fac9a72cb9844adb4a8b91d53c2324610230262 100644 --- a/modcc/functioninliner.hpp +++ b/modcc/functioninliner.hpp @@ -4,10 +4,11 @@ #include "scope.hpp" #include "visitor.hpp" +#include <libmodcc/export.hpp> -expression_ptr inline_function_calls(std::string calling_func, BlockExpression* block); +ARB_LIBMODCC_API expression_ptr inline_function_calls(std::string calling_func, BlockExpression* block); -class FunctionInliner : public BlockRewriterBase { +class ARB_LIBMODCC_API FunctionInliner : public BlockRewriterBase { public: using BlockRewriterBase::visit; FunctionInliner(std::string calling_func) : BlockRewriterBase(), calling_func_(calling_func) {}; @@ -61,4 +62,4 @@ protected: inlining_executed_ = false; BlockRewriterBase::reset(); } -}; \ No newline at end of file +}; diff --git a/modcc/io/prefixbuf.cpp b/modcc/io/prefixbuf.cpp index 916e795070a221cc1a61379d9a05fae3631ea1d5..6b85f907dfcbae882c7af7728fa616eabf5a31ac 100644 --- a/modcc/io/prefixbuf.cpp +++ b/modcc/io/prefixbuf.cpp @@ -56,7 +56,7 @@ prefixbuf::int_type prefixbuf::overflow(int_type ch) { // setprefix implementation: -std::ostream& operator<<(std::ostream& os, const setprefix& sp) { +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, const setprefix& sp) { if (auto pbuf = dynamic_cast<prefixbuf*>(os.rdbuf())) { pbuf->prefix = sp.prefix_; } @@ -111,7 +111,7 @@ static void indent_stack_callback(std::ios_base::event ev, std::ios_base& ios, i } } -std::ostream& operator<<(std::ostream& os, indent_manip in) { +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, indent_manip in) { int xindex = indent_manip::xindex(); void*& pword = os.pword(xindex); long& iword = os.iword(xindex); diff --git a/modcc/io/prefixbuf.hpp b/modcc/io/prefixbuf.hpp index 107637073cc848e34b2bc72848c8a6f7ad489000..34e044ce611c100a9bf4539be294143a42b6e833 100644 --- a/modcc/io/prefixbuf.hpp +++ b/modcc/io/prefixbuf.hpp @@ -8,6 +8,8 @@ #include <sstream> #include <string> +#include <libmodcc/export.hpp> + namespace io { // `prefixbuf` acts an output-only filter for another streambuf, inserting @@ -28,7 +30,7 @@ namespace io { // A flag determines if the prefixbuf should or should not emit the prefix // for empty lines. -class prefixbuf: public std::streambuf { +class ARB_LIBMODCC_API prefixbuf: public std::streambuf { public: explicit prefixbuf(std::streambuf* inner, bool prefix_empty_lines=false): inner_(inner), prefix_empty_lines_(prefix_empty_lines) {} @@ -75,7 +77,7 @@ protected: // The manipulator `indent(0)` can be used to reset the prefix of the underlying // stream to match the current indentation level. -class setprefix { +class ARB_LIBMODCC_API setprefix { public: explicit setprefix(std::string prefix): prefix_(std::move(prefix)) {} @@ -85,7 +87,7 @@ private: std::string prefix_; }; -struct indent_manip { +struct ARB_LIBMODCC_API indent_manip { enum action_enum {push, pop, settab}; explicit constexpr indent_manip(action_enum action, unsigned value=0): @@ -119,7 +121,7 @@ inline indent_manip settab(unsigned w) { // Acts very much like a `std::ostringstream`, but with prefix // and indent functionality. -class pfxstringstream: public std::ostream { +class ARB_LIBMODCC_API pfxstringstream: public std::ostream { public: pfxstringstream(): std::ostream(nullptr), diff --git a/modcc/kineticrewriter.cpp b/modcc/kineticrewriter.cpp index bb6ef0b77f3a6857d95521f4b91bed6bdfb21538..b3aef7ab9f6131da52d5f21cb1720066b080f2c8 100644 --- a/modcc/kineticrewriter.cpp +++ b/modcc/kineticrewriter.cpp @@ -30,7 +30,7 @@ private: std::map<std::string, expression_ptr> dterms; }; -expression_ptr kinetic_rewrite(BlockExpression* block) { +ARB_LIBMODCC_API expression_ptr kinetic_rewrite(BlockExpression* block) { KineticRewriter visitor; block->accept(&visitor); return visitor.as_block(false); diff --git a/modcc/kineticrewriter.hpp b/modcc/kineticrewriter.hpp index 3dfb2648a1006bc6432e9bd7d082e988b49a0795..3d640eff951dba0ccfcf07e9b98f4d6dd40ab4f4 100644 --- a/modcc/kineticrewriter.hpp +++ b/modcc/kineticrewriter.hpp @@ -1,6 +1,7 @@ #pragma once #include "expression.hpp" +#include <libmodcc/export.hpp> // Translate a supplied KINETIC block to equivalent DERIVATIVE block. -expression_ptr kinetic_rewrite(BlockExpression*); +ARB_LIBMODCC_API expression_ptr kinetic_rewrite(BlockExpression*); diff --git a/modcc/lexer.hpp b/modcc/lexer.hpp index f897db5856e0df368e1a840aadb3367f35544d39..82690dfa518835e0266f01d0bac31b3ba20828fe 100644 --- a/modcc/lexer.hpp +++ b/modcc/lexer.hpp @@ -11,6 +11,7 @@ #include "location.hpp" #include "error.hpp" #include "token.hpp" +#include <libmodcc/export.hpp> // status of the lexer enum class lexerStatus { @@ -29,7 +30,7 @@ bool is_keyword(Token const& t); // class that implements the lexer // takes a range of characters as input parameters -class Lexer { +class ARB_LIBMODCC_API Lexer { public: Lexer(const char* begin, const char* end) : begin_(begin), diff --git a/modcc/linearrewriter.cpp b/modcc/linearrewriter.cpp index e3513694fc5cffda7847e3aa3bdb0a813542f4ff..ea055c5e21ee91e63764b858461152744a3b55b6 100644 --- a/modcc/linearrewriter.cpp +++ b/modcc/linearrewriter.cpp @@ -25,7 +25,7 @@ private: std::vector<std::string> state_vars; }; -expression_ptr linear_rewrite(BlockExpression* block, std::vector<std::string> state_vars) { +ARB_LIBMODCC_API expression_ptr linear_rewrite(BlockExpression* block, std::vector<std::string> state_vars) { LinearRewriter visitor(state_vars); block->accept(&visitor); return visitor.as_block(false); diff --git a/modcc/linearrewriter.hpp b/modcc/linearrewriter.hpp index 32b3386334b87c4799dd86034bb0f747772cf892..a517981c0d38e2e4e72510bb8d76f98d41bc31b1 100644 --- a/modcc/linearrewriter.hpp +++ b/modcc/linearrewriter.hpp @@ -1,6 +1,7 @@ #pragma once #include "expression.hpp" +#include <libmodcc/export.hpp> // Translate a supplied LINEAR block. -expression_ptr linear_rewrite(BlockExpression*, std::vector<std::string>); +ARB_LIBMODCC_API expression_ptr linear_rewrite(BlockExpression*, std::vector<std::string>); diff --git a/modcc/module.hpp b/modcc/module.hpp index 1854bd55c86e82c98d99df5844638665c9110f39..8411328fb9458a5d3be03a38a376e56ca33aab61 100644 --- a/modcc/module.hpp +++ b/modcc/module.hpp @@ -8,9 +8,10 @@ #include "blocks.hpp" #include "error.hpp" #include "expression.hpp" +#include <libmodcc/export.hpp> // wrapper around a .mod file -class Module: public error_stack { +class ARB_LIBMODCC_API Module: public error_stack { public: using symbol_map = scope_type::symbol_map; using symbol_ptr = scope_type::symbol_ptr; diff --git a/modcc/parser.hpp b/modcc/parser.hpp index 0bdf0ea84b5dfaa779f768575dd2fd5c2572f6a9..84e56316c0acb4dc001c6bf42756912e38d60092 100644 --- a/modcc/parser.hpp +++ b/modcc/parser.hpp @@ -7,8 +7,9 @@ #include "expression.hpp" #include "lexer.hpp" #include "module.hpp" +#include <libmodcc/export.hpp> -class Parser: public Lexer { +class ARB_LIBMODCC_API Parser: public Lexer { public: explicit Parser(Module& m, bool advance = true); Parser(std::string const&); diff --git a/modcc/printer/cexpr_emit.cpp b/modcc/printer/cexpr_emit.cpp index e9c23e4d229221d853ac116ad947de6f8935cb2a..6e93c1d0c15b194ea7cac5436f4282dfa5f95149 100644 --- a/modcc/printer/cexpr_emit.cpp +++ b/modcc/printer/cexpr_emit.cpp @@ -11,7 +11,7 @@ #include "astmanip.hpp" #include "io/prefixbuf.hpp" -std::ostream& operator<<(std::ostream& out, as_c_double wrap) { +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& out, as_c_double wrap) { bool neg = std::signbit(wrap.value); switch (std::fpclassify(wrap.value)) { diff --git a/modcc/printer/cexpr_emit.hpp b/modcc/printer/cexpr_emit.hpp index 4b278ec85be11e6ad61369b6abbef9aaaf5c708d..86b5f957e80812e088a8c04bec2109ef781e76a6 100644 --- a/modcc/printer/cexpr_emit.hpp +++ b/modcc/printer/cexpr_emit.hpp @@ -6,11 +6,12 @@ #include "expression.hpp" #include "visitor.hpp" #include "marks.hpp" +#include <libmodcc/export.hpp> // Common functionality for generating source from binary expressions // and conditional structures with C syntax. -class CExprEmitter: public Visitor { +class ARB_LIBMODCC_API CExprEmitter: public Visitor { public: CExprEmitter(std::ostream& out, Visitor* fallback): out_(out), fallback_(fallback) @@ -37,7 +38,7 @@ inline void cexpr_emit(Expression* e, std::ostream& out, Visitor* fallback) { e->accept(&emitter); } -class SimdExprEmitter: public CExprEmitter { +class ARB_LIBMODCC_API SimdExprEmitter: public CExprEmitter { using CExprEmitter::visit; public: SimdExprEmitter( @@ -95,4 +96,4 @@ struct as_c_double { as_c_double(double value): value(value) {} }; -std::ostream& operator<<(std::ostream&, as_c_double); +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream&, as_c_double); diff --git a/modcc/printer/cprinter.cpp b/modcc/printer/cprinter.cpp index 872f3d4344ffe1affbc2e56ac1e2d3cbcd34e10f..ee417bea075edcde5688ced694534a6471a36d0b 100644 --- a/modcc/printer/cprinter.cpp +++ b/modcc/printer/cprinter.cpp @@ -117,7 +117,7 @@ struct simdprint { } }; -std::string emit_cpp_source(const Module& module_, const printer_options& opt) { +ARB_LIBMODCC_API std::string emit_cpp_source(const Module& module_, const printer_options& opt) { auto name = module_.module_name(); auto namespace_name = "kernel_" + name; auto ppack_name = "arb_mechanism_ppack"; diff --git a/modcc/printer/cprinter.hpp b/modcc/printer/cprinter.hpp index b07b7f1b550abeda1b0553010c70ea7cbaa273c3..57f94d5957bd3f1d334fc83da6efe6b90c9574b9 100644 --- a/modcc/printer/cprinter.hpp +++ b/modcc/printer/cprinter.hpp @@ -5,15 +5,16 @@ #include "module.hpp" #include "visitor.hpp" +#include <libmodcc/export.hpp> #include "printer/cexpr_emit.hpp" #include "printer/printeropt.hpp" -std::string emit_cpp_source(const Module& m, const printer_options& opt); +ARB_LIBMODCC_API std::string emit_cpp_source(const Module& m, const printer_options& opt); // CPrinter and SimdPrinter visitors exposed in header for testing purposes only. -class CPrinter: public Visitor { +class ARB_LIBMODCC_API CPrinter: public Visitor { public: CPrinter(std::ostream& out): out_(out) {} @@ -44,7 +45,7 @@ enum class simd_expr_constraint{ other }; -class SimdPrinter: public Visitor { +class ARB_LIBMODCC_API SimdPrinter: public Visitor { public: SimdPrinter(std::ostream& out): out_(out) {} diff --git a/modcc/printer/gpuprinter.cpp b/modcc/printer/gpuprinter.cpp index 21a24d9c3011a6deb1168d04afd4bbda75745c9a..d0a69873c1cec738436c52dd10a809064a6041a5 100644 --- a/modcc/printer/gpuprinter.cpp +++ b/modcc/printer/gpuprinter.cpp @@ -42,7 +42,7 @@ static std::string ion_field(const IonDep& ion) { return fmt::format("ion_{}", static std::string ion_index(const IonDep& ion) { return fmt::format("ion_{}_index", ion.name); } -std::string emit_gpu_cpp_source(const Module& module_, const printer_options& opt) { +ARB_LIBMODCC_API std::string emit_gpu_cpp_source(const Module& module_, const printer_options& opt) { std::string name = module_.module_name(); std::string class_name = make_class_name(name); std::string ppack_name = make_ppack_name(name); @@ -92,7 +92,7 @@ std::string emit_gpu_cpp_source(const Module& module_, const printer_options& op return out.str(); } -std::string emit_gpu_cu_source(const Module& module_, const printer_options& opt) { +ARB_LIBMODCC_API std::string emit_gpu_cu_source(const Module& module_, const printer_options& opt) { std::string name = module_.module_name(); std::string class_name = make_class_name(name); diff --git a/modcc/printer/gpuprinter.hpp b/modcc/printer/gpuprinter.hpp index 9d3a0b7ddc799e4a23762711c01d5b433c2da5da..58f4ecdadb02b053cf5a026b44b622ce45e18ea8 100644 --- a/modcc/printer/gpuprinter.hpp +++ b/modcc/printer/gpuprinter.hpp @@ -5,11 +5,12 @@ #include "cprinter.hpp" #include "module.hpp" #include "cexpr_emit.hpp" +#include <libmodcc/export.hpp> -std::string emit_gpu_cpp_source(const Module& m, const printer_options& opt); -std::string emit_gpu_cu_source(const Module& m, const printer_options& opt); +ARB_LIBMODCC_API std::string emit_gpu_cpp_source(const Module& m, const printer_options& opt); +ARB_LIBMODCC_API std::string emit_gpu_cu_source(const Module& m, const printer_options& opt); -class GpuPrinter: public CPrinter { +class ARB_LIBMODCC_API GpuPrinter: public CPrinter { public: GpuPrinter(std::ostream& out): CPrinter(out) {} diff --git a/modcc/printer/infoprinter.cpp b/modcc/printer/infoprinter.cpp index d0b207d63e1b7ac704b54932489ee8858d26a80d..0db24b4990e3a18919dc3ee19945031d57769844 100644 --- a/modcc/printer/infoprinter.cpp +++ b/modcc/printer/infoprinter.cpp @@ -17,7 +17,7 @@ using io::quote; -std::string build_info_header(const Module& m, const printer_options& opt, bool cpu, bool gpu) { +ARB_LIBMODCC_API std::string build_info_header(const Module& m, const printer_options& opt, bool cpu, bool gpu) { using io::indent; using io::popindent; diff --git a/modcc/printer/infoprinter.hpp b/modcc/printer/infoprinter.hpp index ae43c8994dd93f659af23c780fd7afa7700f7c1d..41f81a0c4b5fe760586d28d4c64cb249397a2eaf 100644 --- a/modcc/printer/infoprinter.hpp +++ b/modcc/printer/infoprinter.hpp @@ -3,9 +3,11 @@ #include <string> #include "module.hpp" +#include <libmodcc/export.hpp> + #include "printer/printeropt.hpp" // Build header file comprising mechanism metadata // and declarations of backend-specific mechanism implementations. -std::string build_info_header(const Module& m, const printer_options& opt, bool cpu=false, bool gpu=false); +ARB_LIBMODCC_API std::string build_info_header(const Module& m, const printer_options& opt, bool cpu=false, bool gpu=false); diff --git a/modcc/printer/printerutil.cpp b/modcc/printer/printerutil.cpp index 7e7b7c31a8b9e8326c7fdaf037531bddbed68811..72f208e99899d79d1de0ee6b489f36f8ebd4c62f 100644 --- a/modcc/printer/printerutil.cpp +++ b/modcc/printer/printerutil.cpp @@ -6,7 +6,7 @@ #include "module.hpp" #include "printerutil.hpp" -std::vector<std::string> namespace_components(const std::string& ns) { +ARB_LIBMODCC_API std::vector<std::string> namespace_components(const std::string& ns) { static std::regex ns_regex("([^:]+)(?:::|$)"); std::vector<std::string> components; @@ -18,7 +18,7 @@ std::vector<std::string> namespace_components(const std::string& ns) { return components; } -std::vector<LocalVariable*> indexed_locals(scope_ptr scope) { +ARB_LIBMODCC_API std::vector<LocalVariable*> indexed_locals(scope_ptr scope) { std::vector<LocalVariable*> vars; for (auto& entry: scope->locals()) { LocalVariable* local = entry.second->is_local_variable(); @@ -29,7 +29,7 @@ std::vector<LocalVariable*> indexed_locals(scope_ptr scope) { return vars; } -std::vector<LocalVariable*> pure_locals(scope_ptr scope) { +ARB_LIBMODCC_API std::vector<LocalVariable*> pure_locals(scope_ptr scope) { std::vector<LocalVariable*> vars; for (auto& entry: scope->locals()) { LocalVariable* local = entry.second->is_local_variable(); @@ -40,7 +40,7 @@ std::vector<LocalVariable*> pure_locals(scope_ptr scope) { return vars; } -std::vector<ProcedureExpression*> normal_procedures(const Module& m) { +ARB_LIBMODCC_API std::vector<ProcedureExpression*> normal_procedures(const Module& m) { std::vector<ProcedureExpression*> procs; for (auto& sym: m.symbols()) { @@ -54,7 +54,7 @@ std::vector<ProcedureExpression*> normal_procedures(const Module& m) { return procs; } -public_variable_ids_t public_variable_ids(const Module& m) { +ARB_LIBMODCC_API public_variable_ids_t public_variable_ids(const Module& m) { public_variable_ids_t ids; ids.state_ids = m.state_block().state_variables; @@ -79,7 +79,7 @@ public_variable_ids_t public_variable_ids(const Module& m) { return ids; } -module_variables_t local_module_variables(const Module& m) { +ARB_LIBMODCC_API module_variables_t local_module_variables(const Module& m) { module_variables_t mv; for (auto& sym: m.symbols()) { @@ -92,7 +92,7 @@ module_variables_t local_module_variables(const Module& m) { return mv; } -std::vector<ProcedureExpression*> module_normal_procedures(const Module& m) { +ARB_LIBMODCC_API std::vector<ProcedureExpression*> module_normal_procedures(const Module& m) { std::vector<ProcedureExpression*> procs; for (auto& sym: m.symbols()) { auto p = sym.second->is_procedure(); @@ -104,17 +104,17 @@ std::vector<ProcedureExpression*> module_normal_procedures(const Module& m) { return procs; } -APIMethod* find_api_method(const Module& m, const char* which) { +ARB_LIBMODCC_API APIMethod* find_api_method(const Module& m, const char* which) { auto it = m.symbols().find(which); return it==m.symbols().end()? nullptr: it->second->is_api_method(); } -NetReceiveExpression* find_net_receive(const Module& m) { +ARB_LIBMODCC_API NetReceiveExpression* find_net_receive(const Module& m) { auto it = m.symbols().find("net_receive"); return it==m.symbols().end()? nullptr: it->second->is_net_receive(); } -PostEventExpression* find_post_event(const Module& m) { +ARB_LIBMODCC_API PostEventExpression* find_post_event(const Module& m) { auto it = m.symbols().find("post_event"); return it==m.symbols().end()? nullptr: it->second->is_post_event(); } @@ -135,7 +135,7 @@ std::string indexed_variable_info::outer_index_var() const { } } -indexed_variable_info decode_indexed_variable(IndexedVariable* sym) { +ARB_LIBMODCC_API indexed_variable_info decode_indexed_variable(IndexedVariable* sym) { indexed_variable_info v; v.node_index_var = "node_index"; v.index_var_kind = index_kind::node; diff --git a/modcc/printer/printerutil.hpp b/modcc/printer/printerutil.hpp index 77daace53832fe08bdfba2dfc8aca8f24fd83012..608a231ad8afd5027bb9de8334868c64806da2be 100644 --- a/modcc/printer/printerutil.hpp +++ b/modcc/printer/printerutil.hpp @@ -11,8 +11,9 @@ #include "error.hpp" #include "expression.hpp" #include "module.hpp" +#include <libmodcc/export.hpp> -std::vector<std::string> namespace_components(const std::string& qualified_namespace); +ARB_LIBMODCC_API std::vector<std::string> namespace_components(const std::string& qualified_namespace); // Can use this in a namespace. No __ allowed anywhere, neither _[A-Z], and in _global namespace_ _ followed by anything is verboten. const static std::string pp_var_pfx = "_pp_var_"; @@ -79,17 +80,17 @@ inline void assert_has_scope(Expression* expr, const std::string& context) { // Scope query functions: // All local variables in scope with `is_indexed()` true. -std::vector<LocalVariable*> indexed_locals(scope_ptr scope); +ARB_LIBMODCC_API std::vector<LocalVariable*> indexed_locals(scope_ptr scope); // All local variables in scope with `is_arg()` and `is_indexed()` false. -std::vector<LocalVariable*> pure_locals(scope_ptr scope); +ARB_LIBMODCC_API std::vector<LocalVariable*> pure_locals(scope_ptr scope); // Module state query functions: // Normal (not API, net_receive) procedures in module: -std::vector<ProcedureExpression*> normal_procedures(const Module&); +ARB_LIBMODCC_API std::vector<ProcedureExpression*> normal_procedures(const Module&); struct public_variable_ids_t { std::vector<Id> state_ids; @@ -99,7 +100,7 @@ struct public_variable_ids_t { // Public module variables by role. -public_variable_ids_t public_variable_ids(const Module&); +ARB_LIBMODCC_API public_variable_ids_t public_variable_ids(const Module&); struct module_variables_t { std::vector<VariableExpression*> scalars; @@ -108,21 +109,21 @@ struct module_variables_t { // Scalar and array variables with local linkage. -module_variables_t local_module_variables(const Module&); +ARB_LIBMODCC_API module_variables_t local_module_variables(const Module&); // "normal" procedures in a module. // A normal procedure is one that has been declared with the // PROCEDURE keyword in NMODL. -std::vector<ProcedureExpression*> module_normal_procedures(const Module& m); +ARB_LIBMODCC_API std::vector<ProcedureExpression*> module_normal_procedures(const Module& m); // Extract key procedures from module. -APIMethod* find_api_method(const Module& m, const char* which); +ARB_LIBMODCC_API APIMethod* find_api_method(const Module& m, const char* which); -NetReceiveExpression* find_net_receive(const Module& m); +ARB_LIBMODCC_API NetReceiveExpression* find_net_receive(const Module& m); -PostEventExpression* find_post_event(const Module& m); +ARB_LIBMODCC_API PostEventExpression* find_post_event(const Module& m); // For generating vectorized code for reading and writing data sources. // node: The data source uses the CV index which is categorized into @@ -139,7 +140,7 @@ enum class index_kind { none }; -struct indexed_variable_info { +struct ARB_LIBMODCC_API indexed_variable_info { std::string data_var; std::string node_index_var; std::string cell_index_var; @@ -157,7 +158,7 @@ struct indexed_variable_info { std::string outer_index_var() const; }; -indexed_variable_info decode_indexed_variable(IndexedVariable* sym); +ARB_LIBMODCC_API indexed_variable_info decode_indexed_variable(IndexedVariable* sym); template<typename C> size_t emit_array(std::ostream& out, const C& vars) { diff --git a/modcc/solvers.cpp b/modcc/solvers.cpp index 4e49ded06562b73ca100e431fdb6f004cd2ef83a..1d31e55d8fe70e4573efed3390b0b389ebf477d0 100644 --- a/modcc/solvers.cpp +++ b/modcc/solvers.cpp @@ -964,7 +964,7 @@ public: } }; -expression_ptr remove_unused_locals(BlockExpression* block) { +ARB_LIBMODCC_API expression_ptr remove_unused_locals(BlockExpression* block) { UnusedVisitor unused_visitor; block->accept(&unused_visitor); diff --git a/modcc/solvers.hpp b/modcc/solvers.hpp index 718c0900ffcf3f4f51a6ad972c4b5337ceddcf7e..719ad0c0e3b12db12a2db2460f84dc0418d29064 100644 --- a/modcc/solvers.hpp +++ b/modcc/solvers.hpp @@ -12,8 +12,9 @@ #include "symdiff.hpp" #include "symge.hpp" #include "visitor.hpp" +#include <libmodcc/export.hpp> -expression_ptr remove_unused_locals(BlockExpression* block); +ARB_LIBMODCC_API expression_ptr remove_unused_locals(BlockExpression* block); class SolverVisitorBase: public BlockRewriterBase { protected: @@ -56,7 +57,7 @@ public: } }; -class CnexpSolverVisitor : public SolverVisitorBase { +class ARB_LIBMODCC_API CnexpSolverVisitor : public SolverVisitorBase { public: using SolverVisitorBase::visit; @@ -67,7 +68,7 @@ public: virtual void visit(AssignmentExpression *e) override; }; -class SystemSolver { +class ARB_LIBMODCC_API SystemSolver { protected: // Symbolic matrix for backwards Euler step. symge::sym_matrix A_; @@ -132,7 +133,7 @@ public: }; -class SparseSolverVisitor : public SolverVisitorBase { +class ARB_LIBMODCC_API SparseSolverVisitor : public SolverVisitorBase { protected: solverVariant solve_variant_; @@ -185,7 +186,7 @@ public: } }; -class SparseNonlinearSolverVisitor : public SolverVisitorBase { +class ARB_LIBMODCC_API SparseNonlinearSolverVisitor : public SolverVisitorBase { protected: // 'Current' differential equation is for variable with this // index in `dvars`. @@ -231,7 +232,7 @@ public: } }; -class LinearSolverVisitor : public SolverVisitorBase { +class ARB_LIBMODCC_API LinearSolverVisitor : public SolverVisitorBase { protected: // 'Current' differential equation is for variable with this // index in `dvars`. diff --git a/modcc/symdiff.cpp b/modcc/symdiff.cpp index db32ac3aeb96ffeedfc4fbfaff1996e26229f813..4946a1b8108c4ce3f33a405a712be82269019c8e 100644 --- a/modcc/symdiff.cpp +++ b/modcc/symdiff.cpp @@ -87,13 +87,13 @@ private: bool found_ = false; }; -bool involves_identifier(Expression* e, const identifier_set& ids) { +ARB_LIBMODCC_API bool involves_identifier(Expression* e, const identifier_set& ids) { FindIdentifierVisitor v(ids); e->accept(&v); return v.found(); } -bool involves_identifier(Expression* e, const std::string& id) { +ARB_LIBMODCC_API bool involves_identifier(Expression* e, const std::string& id) { identifier_set ids = {id}; FindIdentifierVisitor v(ids); e->accept(&v); @@ -262,7 +262,7 @@ private: std::string id_; }; -double expr_value(Expression* e) { +ARB_LIBMODCC_API double expr_value(Expression* e) { return e && e->is_number()? e->is_number()->value(): NAN; } @@ -547,14 +547,14 @@ public: } }; -expression_ptr constant_simplify(Expression* e) { +ARB_LIBMODCC_API expression_ptr constant_simplify(Expression* e) { ConstantSimplifyVisitor csimp_visitor; e->accept(&csimp_visitor); return csimp_visitor.result(); } -expression_ptr symbolic_pdiff(Expression* e, const std::string& id) { +ARB_LIBMODCC_API expression_ptr symbolic_pdiff(Expression* e, const std::string& id) { if (!involves_identifier(e, id)) { return make_expression<NumberExpression>(e->location(), 0); } @@ -644,7 +644,7 @@ private: const substitute_map& sub_; }; -expression_ptr substitute(Expression* e, const std::string& id, Expression* sub) { +ARB_LIBMODCC_API expression_ptr substitute(Expression* e, const std::string& id, Expression* sub) { substitute_map subs; subs[id] = sub->clone(); SubstituteVisitor sub_visitor(subs); @@ -652,13 +652,13 @@ expression_ptr substitute(Expression* e, const std::string& id, Expression* sub) return sub_visitor.result(); } -expression_ptr substitute(Expression* e, const substitute_map& sub) { +ARB_LIBMODCC_API expression_ptr substitute(Expression* e, const substitute_map& sub) { SubstituteVisitor sub_visitor(sub); e->accept(&sub_visitor); return sub_visitor.result(); } -linear_test_result linear_test(Expression* e, const std::vector<std::string>& vars) { +ARB_LIBMODCC_API linear_test_result linear_test(Expression* e, const std::vector<std::string>& vars) { linear_test_result result; auto loc = e->location(); auto zero = [loc]() { return make_expression<IntegerExpression>(loc, 0); }; diff --git a/modcc/symdiff.hpp b/modcc/symdiff.hpp index 9e8192150d88e670f0d321b49949755ac534c7ba..cb58ffae803c36d37a4bef86e2b6974b9424badf 100644 --- a/modcc/symdiff.hpp +++ b/modcc/symdiff.hpp @@ -13,19 +13,20 @@ #include <utility> #include "expression.hpp" +#include <libmodcc/export.hpp> // True if `id` matches the spelling of any identifier in the expression. -bool involves_identifier(Expression* e, const std::string& id); +ARB_LIBMODCC_API bool involves_identifier(Expression* e, const std::string& id); using identifier_set = std::vector<std::string>; -bool involves_identifier(Expression* e, const identifier_set& ids); +ARB_LIBMODCC_API bool involves_identifier(Expression* e, const identifier_set& ids); // Return new expression formed by folding constants and removing trivial terms. -expression_ptr constant_simplify(Expression* e); +ARB_LIBMODCC_API expression_ptr constant_simplify(Expression* e); // Extract value of expression that is a NumberExpression, or else return NAN. -double expr_value(Expression* e); +ARB_LIBMODCC_API double expr_value(Expression* e); // Test if expression is a NumberExpression with value zero. inline bool is_zero(Expression* e) { @@ -33,14 +34,14 @@ inline bool is_zero(Expression* e) { } // Return new expression of symbolic partial differentiation of argument wrt `id`. -expression_ptr symbolic_pdiff(Expression* e, const std::string& id); +ARB_LIBMODCC_API expression_ptr symbolic_pdiff(Expression* e, const std::string& id); // Substitute all occurances of identifier `id` within expression by a clone of `sub`. // (Only applicable to unary, binary, call and number expressions.) -expression_ptr substitute(Expression* e, const std::string& id, Expression* sub); +ARB_LIBMODCC_API expression_ptr substitute(Expression* e, const std::string& id, Expression* sub); using substitute_map = std::map<std::string, expression_ptr>; -expression_ptr substitute(Expression* e, const substitute_map& sub); +ARB_LIBMODCC_API expression_ptr substitute(Expression* e, const substitute_map& sub); // Convenience interfaces for the above functions work with `expression_ptr` as // well as with `Expression*` values. @@ -112,7 +113,7 @@ struct linear_test_result { } }; -linear_test_result linear_test(Expression* e, const std::vector<std::string>& vars); +ARB_LIBMODCC_API linear_test_result linear_test(Expression* e, const std::vector<std::string>& vars); inline linear_test_result linear_test(const expression_ptr& e, const std::vector<std::string>& vars) { return linear_test(e.get(), vars); diff --git a/modcc/symge.cpp b/modcc/symge.cpp index 0968b0406f9ce171e50b8fa18f315771596cb214..ccc2afade9201c53b5aed57153b5a4f2661a9a51 100644 --- a/modcc/symge.cpp +++ b/modcc/symge.cpp @@ -81,7 +81,7 @@ double estimate_cost(const sym_matrix& A, pivot p) { // that are symbols that are either primitive, or defined (in the symbol // table) as products or differences of products of other symbols. // Returns a vector of vectors of symbols, partitioned by row of the matrix -std::vector<std::vector<symge::symbol>> gj_reduce(sym_matrix& A, symbol_table& table) { +ARB_LIBMODCC_API std::vector<std::vector<symge::symbol>> gj_reduce(sym_matrix& A, symbol_table& table) { std::vector<std::vector<symge::symbol>> row_symbols; if (A.nrow()>A.ncol()) throw std::runtime_error("improper matrix for reduction"); diff --git a/modcc/symge.hpp b/modcc/symge.hpp index 9343609255a8e4a6371345d312f1d4f68760b4da..3a3cbc1ecd10aa129db66411d901abad3bdb00b5 100644 --- a/modcc/symge.hpp +++ b/modcc/symge.hpp @@ -3,13 +3,14 @@ #include <stdexcept> #include "msparse.hpp" +#include <libmodcc/export.hpp> // Symbolic sparse matrix manipulation for symbolic Gauss-Jordan elimination // (used in `sparse` solver). namespace symge { -struct symbol_error: public std::runtime_error { +struct ARB_LIBMODCC_API symbol_error: public std::runtime_error { symbol_error(const std::string& what): std::runtime_error(what) {} }; @@ -154,6 +155,6 @@ using sym_matrix = msparse::matrix<symbol>; // pivots taken from the diagonal elements. New symbol definitions due to fill-in // will be added via the provided symbol table. // Returns a vector of vectors of symbols, partitioned by row of the matrix -std::vector<std::vector<symge::symbol>> gj_reduce(sym_matrix& A, symbol_table& table); +ARB_LIBMODCC_API std::vector<std::vector<symge::symbol>> gj_reduce(sym_matrix& A, symbol_table& table); } // namespace symge diff --git a/modcc/token.cpp b/modcc/token.cpp index e884bc0d062f899fbe0664f689722ff7686f4d28..7ba2f71b9ba508c55e9e5b5dc73416e1d22e5227 100644 --- a/modcc/token.cpp +++ b/modcc/token.cpp @@ -157,7 +157,7 @@ static TokenString token_strings[] = { /// set up lookup tables for converting between tokens and their /// string representations -void initialize_token_maps() { +ARB_LIBMODCC_API void initialize_token_maps() { // ensure that tables are initialized only once std::lock_guard<std::mutex> g(mutex); @@ -181,18 +181,18 @@ void initialize_token_maps() { } } -std::string token_string(tok token) { +ARB_LIBMODCC_API std::string token_string(tok token) { auto pos = token_map.find(token); return pos==token_map.end() ? std::string("<unknown token>") : pos->second; } -bool is_keyword(Token const& t) { +ARB_LIBMODCC_API bool is_keyword(Token const& t) { for(Keyword *k=keywords; k->name!=nullptr; ++k) if(t.type == k->type) return true; return false; } -std::ostream& operator<< (std::ostream& os, Token const& t) { +ARB_LIBMODCC_API std::ostream& operator<< (std::ostream& os, Token const& t) { return os << "<<" << token_string(t.type) << ", " << t.spelling << ", " << t.location << ">>"; } diff --git a/modcc/token.hpp b/modcc/token.hpp index 5e6466fe55853510a27fa9df685c31f67416f1b0..0e09c385b3b323d4e3d2df6c9de225dd5621ea98 100644 --- a/modcc/token.hpp +++ b/modcc/token.hpp @@ -5,6 +5,7 @@ #include <unordered_map> #include "location.hpp" +#include <libmodcc/export.hpp> enum class tok { eof, // end of file @@ -118,8 +119,8 @@ extern std::unordered_map<std::string, tok> keyword_map; // for stringifying a token type extern std::map<tok, std::string> token_map; -void initialize_token_maps(); -std::string token_string(tok token); -bool is_keyword(Token const& t); -std::ostream& operator<< (std::ostream& os, Token const& t); +ARB_LIBMODCC_API void initialize_token_maps(); +ARB_LIBMODCC_API std::string token_string(tok token); +ARB_LIBMODCC_API bool is_keyword(Token const& t); +ARB_LIBMODCC_API std::ostream& operator<< (std::ostream& os, Token const& t); diff --git a/python/test/cpp/CMakeLists.txt b/python/test/cpp/CMakeLists.txt index fc460292f5aa08c6c8d07250b3f8f8bce277cef3..823a2d816984c0d1a972b3f78cbd124fa74ec706 100644 --- a/python/test/cpp/CMakeLists.txt +++ b/python/test/cpp/CMakeLists.txt @@ -9,7 +9,7 @@ set(py_unit_sources add_executable(py_unit EXCLUDE_FROM_ALL ${py_unit_sources}) add_dependencies(tests py_unit) -add_library(py_unit_lib $<TARGET_OBJECTS:pyarb_obj>) +add_library(py_unit_lib STATIC $<TARGET_OBJECTS:pyarb_obj>) target_link_libraries(py_unit_lib PRIVATE arbor pybind11::module) target_compile_options(py_unit PRIVATE ${ARB_CXX_FLAGS_TARGET_FULL}) diff --git a/sup/CMakeLists.txt b/sup/CMakeLists.txt index 596888bbc6b9e9a4a8a2fa1369255b0288eaaccb..831b3c544ef1c3aad7fe999695e0c84a3dcb6fd1 100644 --- a/sup/CMakeLists.txt +++ b/sup/CMakeLists.txt @@ -12,7 +12,12 @@ target_compile_options(arbor-sup PRIVATE ${ARB_CXX_FLAGS_TARGET_FULL}) # The sup library uses both the json library and libarbor target_link_libraries(arbor-sup PUBLIC ${json_library_name} arbor) -target_include_directories(arbor-sup PUBLIC include) +#target_include_directories(arbor-sup PUBLIC include) +target_include_directories(arbor-sup + PUBLIC + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/include + $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>) set_target_properties(arbor-sup PROPERTIES OUTPUT_NAME arborsup) +export_visibility(arbor-sup) diff --git a/sup/include/sup/ioutil.hpp b/sup/include/sup/ioutil.hpp index cf516dc0eaed61f33129c70154b67a7a4c87f2db..c1be394b6b02862657b151f2421dad6727ee3fa4 100644 --- a/sup/include/sup/ioutil.hpp +++ b/sup/include/sup/ioutil.hpp @@ -14,10 +14,12 @@ #include <iostream> #include <fstream> +#include <sup/export.hpp> #include <sup/path.hpp> namespace sup { + template <typename charT, typename traitsT = std::char_traits<charT> > class basic_null_streambuf: public std::basic_streambuf<charT, traitsT> { private: @@ -42,7 +44,7 @@ protected: } }; -class mask_stream { +class ARB_SUP_API mask_stream { public: explicit mask_stream(bool mask): mask_(mask) {} @@ -87,7 +89,7 @@ private: bool mask_; }; -std::fstream open_or_throw(const sup::path& p, std::ios_base::openmode, bool exclusive); +ARB_SUP_API std::fstream open_or_throw(const sup::path& p, std::ios_base::openmode, bool exclusive); inline std::fstream open_or_throw(const sup::path& p, bool exclusive) { using std::ios_base; diff --git a/sup/include/sup/json_meter.hpp b/sup/include/sup/json_meter.hpp index 76c94ae83436d5b2f750bf309ad226b0d472da9b..a017c2643009cef235c5d711bba0f9ea770f8e92 100644 --- a/sup/include/sup/json_meter.hpp +++ b/sup/include/sup/json_meter.hpp @@ -1,8 +1,9 @@ #include <arbor/profile/meter_manager.hpp> +#include <sup/export.hpp> #include <nlohmann/json.hpp> namespace sup { -nlohmann::json to_json(const arb::profile::meter_report&); +ARB_SUP_API nlohmann::json to_json(const arb::profile::meter_report&); } // namespace sup diff --git a/sup/include/sup/path.hpp b/sup/include/sup/path.hpp index 3c13aa2d440fdb0d47e02106278c86aae3362018..4ffd7861f2ccc7570f97f83c32f526c670ad8644 100644 --- a/sup/include/sup/path.hpp +++ b/sup/include/sup/path.hpp @@ -26,6 +26,8 @@ #include <utility> #include <vector> +#include <sup/export.hpp> + namespace sup { class posix_path { @@ -363,8 +365,8 @@ private: // POSIX implementations of path queries (see path.cpp for implementations). -file_status posix_status(const path&, std::error_code&) noexcept; -file_status posix_symlink_status(const path&, std::error_code&) noexcept; +ARB_SUP_API file_status posix_status(const path&, std::error_code&) noexcept; +ARB_SUP_API file_status posix_symlink_status(const path&, std::error_code&) noexcept; inline file_status status(const path& p, std::error_code& ec) noexcept { return posix_status(p, ec); @@ -599,7 +601,7 @@ inline constexpr bool operator!=(directory_options a, unsigned x) { struct posix_directory_state; -struct posix_directory_iterator { +struct ARB_SUP_API posix_directory_iterator { using value_type = directory_entry; using difference_type = std::ptrdiff_t; using pointer = const directory_entry*; diff --git a/sup/ioutil.cpp b/sup/ioutil.cpp index 4725cc1a98be251d978266b783e7f91ee2545775..e8d7ce0e21dfa1fb5fa4dd5da43245bb28116e15 100644 --- a/sup/ioutil.cpp +++ b/sup/ioutil.cpp @@ -7,7 +7,7 @@ namespace sup { -std::fstream open_or_throw(const path& p, std::ios_base::openmode mode, bool exclusive) { +ARB_SUP_API std::fstream open_or_throw(const path& p, std::ios_base::openmode mode, bool exclusive) { if (exclusive && exists(p)) { throw std::runtime_error(strsub("file % already exists", p)); } diff --git a/sup/json_meter.cpp b/sup/json_meter.cpp index c587d4dfe32b5eebb5a6d1d3522e03fe97be3948..bb40bd48bd1e9fd5dac83f5e579a24d17c4e29a8 100644 --- a/sup/json_meter.cpp +++ b/sup/json_meter.cpp @@ -1,4 +1,5 @@ #include <arbor/profile/meter_manager.hpp> +#include <sup/json_meter.hpp> #include <nlohmann/json.hpp> namespace sup { @@ -16,7 +17,7 @@ static nlohmann::json to_json(const arb::profile::measurement& mnt) { }; } -nlohmann::json to_json(const arb::profile::meter_report& report) { +ARB_SUP_API nlohmann::json to_json(const arb::profile::meter_report& report) { nlohmann::json json_meters; for (const auto& mnt: report.meters) { json_meters.push_back(to_json(mnt)); diff --git a/sup/path.cpp b/sup/path.cpp index 5622f687b3b7b0cca53387ef1da2f6a809331f2d..d12946ee3b76c069a1a6f6f2e746c9e22ec5c6fa 100644 --- a/sup/path.cpp +++ b/sup/path.cpp @@ -52,13 +52,13 @@ namespace impl { } // namespace impl -file_status posix_status(const path& p, std::error_code& ec) noexcept { +ARB_SUP_API file_status posix_status(const path& p, std::error_code& ec) noexcept { struct stat st; int r = stat(p.c_str(), &st); return impl::status(p.c_str(), r, st, ec); } -file_status posix_symlink_status(const path& p, std::error_code& ec) noexcept { +ARB_SUP_API file_status posix_symlink_status(const path& p, std::error_code& ec) noexcept { struct stat st; int r = lstat(p.c_str(), &st); return impl::status(p.c_str(), r, st, ec); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index db3e8e7e92833b809a182a2a3c42257770097c58..5b398e61cb66ac39d1954bf4c7fc0a4e3d4c2769 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,6 +1,7 @@ find_package(Threads REQUIRED) -add_library(gtest EXCLUDE_FROM_ALL STATIC gtest-all.cpp) +add_library(gtest EXCLUDE_FROM_ALL gtest-all.cpp) +set_target_properties(gtest PROPERTIES CXX_VISIBILITY_PRESET hidden) target_include_directories(gtest PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(gtest PUBLIC Threads::Threads) diff --git a/test/unit/test_fvm_layout.cpp b/test/unit/test_fvm_layout.cpp index e7836e77e5787375b829cfaed90b159779e8b7b3..e26c8db8a8f765ff0ea8f9774ab89f7f4a445c49 100644 --- a/test/unit/test_fvm_layout.cpp +++ b/test/unit/test_fvm_layout.cpp @@ -40,6 +40,9 @@ using util::value_by_key; using backend = arb::multicore::backend; using fvm_cell = arb::fvm_lowered_cell_impl<backend>; +// instantiate template class +template class arb::fvm_lowered_cell_impl<arb::multicore::backend>; + namespace { struct system { std::vector<soma_cell_builder> builders; diff --git a/test/unit/test_mechcat.cpp b/test/unit/test_mechcat.cpp index 431dffb08d339dc74f3fbb866f5a9d1043b08f55..181c203476bf73868add8ee28d8b3ecabe59ee89 100644 --- a/test/unit/test_mechcat.cpp +++ b/test/unit/test_mechcat.cpp @@ -281,7 +281,15 @@ TEST(mechcat, names) { #ifdef USE_DYNAMIC_CATALOGUES TEST(mechcat, loading) { EXPECT_THROW(load_catalogue(LIBDIR "/does-not-exist-catalogue.so"), file_not_found_error); +#if defined(ARB_ARBOR_SHARED_LIBRARY) +#if defined(ARB_ON_MACOS) + EXPECT_THROW(load_catalogue(LIBDIR "/libarbor.dylib"), bad_catalogue_error); +#else + EXPECT_THROW(load_catalogue(LIBDIR "/libarbor.so"), bad_catalogue_error); +#endif +#else EXPECT_THROW(load_catalogue(LIBDIR "/libarbor.a"), bad_catalogue_error); +#endif const mechanism_catalogue* cat = nullptr; EXPECT_NO_THROW(cat = &load_catalogue(LIBDIR "/dummy-catalogue.so")); ASSERT_NE(cat, nullptr);