Commit cbb335a8 authored by David Frank's avatar David Frank Committed by Tobias Lasser

add elsa:all convenience target and matching elsa.h convenience header for...

add elsa:all convenience target and matching elsa.h convenience header for linking/including all of elsa. In addition: tests are no longer part of the default target, but have their own tests target. (#25)
parent 15d1fbb1
Pipeline #188789 failed with stages
in 9 minutes and 3 seconds
......@@ -36,8 +36,7 @@ stages:
script:
- cd build
- cmake -DELSA_CREATE_JUNIT_REPORTS=ON ..
- make
- ctest
- make -j4 tests
artifacts:
reports:
junit: "build/test_reports/test_*.xml"
......@@ -180,7 +179,7 @@ test-coverage:
- mkdir -p build
- cd build
- cmake -DCMAKE_BUILD_TYPE=Debug -DELSA_COVERAGE=ON ../
- make all -j4
- make tests -j4
- make test_coverage
artifacts:
name: "$CI_JOB_NAME-$CI_COMMIT_REF_NAME-coverage"
......
......@@ -84,6 +84,11 @@ if(ELSA_TESTING)
enable_testing()
add_subdirectory(thirdparty/Catch2)
add_custom_target(tests
COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Build and run all the tests.")
# add the CMake modules for automatic test discovery
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/thirdparty/Catch2/contrib" ${CMAKE_MODULE_PATH})
......
......@@ -23,7 +23,7 @@ Current testing includes gcc7, gcc9, and clang8.
The main third party dependencies (Eigen3, spdlog, Catch2) are integrated via git submodules.
For CUDA support, you need a CUDA capable graphics card as well as an installation of the CUDA toolkit.
Current testing includes CUDA 9.1 and 9.2 combined with gcc7.
Current testing includes CUDA 9.2 combined with gcc7.
Compiling
---------
......@@ -41,17 +41,21 @@ make install
You can provide `-DCMAKE_INSTALL_PREFIX=folder` during the cmake step to select an installation destination other than the default (`/usr/local` on Unix).
You can run the elsa unit tests by running (in the build folder):
You can build and run the elsa unit tests by running (in the build folder):
```
ctest
make tests
```
Building against the elsa library
---------------------------------
When using the elsa library in your project, we advise using CMake as the build system. You can then include elsa via the `find_package(elsa)` statement and linking your target against the corresponding elsa modules, e.g. `target_link_libraries(myTarget elsa::core)`.
When using the elsa library in your project, we suggest using CMake as the build system.
Then you can configure elsa via the `find_package(elsa)` statement and link your target against elsa with `target_link_libraries(myTarget elsa::all)`.
Alternatively, you can link more specifically only against the required elsa modules, such as `target_link_libraries(myTarget elsa::core)`.
In your source code, `#include "elsa.h"` to include all of elsa; alternatively, include only the header files you are actually using to minimize compilation times.
As elsa depends on Eigen3 and spdlog, you will need to have these packages installed on your system, and you have to point CMake to those installations.
As elsa depends on Eigen3 (version 3.3 or newer) and spdlog (version 1.0 or newer), you will need to have these packages installed on your system, and you have to point CMake to those installations.
When using CUDA, your CMake should be version 3.14 or newer.
Contributing
------------
......
......@@ -2,7 +2,8 @@
include(CMakeFindDependencyMacro)
find_dependency(Eigen3 3.3 NO_MODULE REQUIRED)
find_dependency(Spdlog REQUIRED)
find_dependency(spdlog REQUIRED)
find_dependency(OpenMP QUIET)
set(_supported_components @ELSA_REGISTERED_COMPONENTS@)
......
cmake_minimum_required(VERSION 3.9)
# setup macro for component registration
# so you can use find_package(elsa COMPONENT name)
# setup macro for component registration, so you can use find_package(elsa COMPONENT name)
# also sets all target names
macro(registerComponent name)
set(ELSA_REGISTERED_COMPONENTS "${ELSA_REGISTERED_COMPONENTS};${name}" PARENT_SCOPE)
set(ELSA_REGISTERED_TARGETS "${ELSA_REGISTERED_TARGETS};elsa_${name}" PARENT_SCOPE)
endmacro()
# macro for the unit tests
macro(ELSA_TEST NAME)
# create the test executable
add_executable(test_${NAME} test_${NAME}.cpp test_main.cpp)
add_executable(test_${NAME} EXCLUDE_FROM_ALL test_${NAME}.cpp test_main.cpp)
# add catch and the corresponding elsa library
target_link_libraries(test_${NAME} PRIVATE Catch2::Catch2 ${ELSA_MODULE_TARGET_NAME})
# enable C++17
......@@ -20,18 +22,18 @@ macro(ELSA_TEST NAME)
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/test_reports)
set(ELSA_JUNIT_ARGUMENTS "-r junit" "-o ${PROJECT_BINARY_DIR}/test_reports/test_${NAME}.xml")
endif(${ELSA_CREATE_JUNIT_REPORTS})
add_dependencies(tests test_${NAME})
# let Catch discover and register all the test cases
catch_discover_tests(test_${NAME} TEST_SPEC ${ELSA_JUNIT_ARGUMENTS})
endmacro(ELSA_TEST)
# add sanitizers if in debug mode
if(${CMAKE_BUILD_TYPE} MATCHES "Debug")
include(${PROJECT_SOURCE_DIR}/cmake/Sanitizers.cmake)
endif()
# add a general custom target "elsa" that includes everything
add_custom_target(elsa)
# add the elsa modules
add_subdirectory(core)
......@@ -48,8 +50,29 @@ endif(ELSA_BUILD_CUDA_PROJECTORS)
add_subdirectory(generators)
# library to build and add all registered components of the library
add_library(elsa_all INTERFACE)
add_library(elsa::all ALIAS elsa_all)
# link against all modules
target_link_libraries(elsa_all INTERFACE ${ELSA_REGISTERED_TARGETS})
target_include_directories(elsa_all INTERFACE
$<INSTALL_INTERFACE:include/elsa/>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
)
# register the all "module"
registerComponent(all)
# install the all module and the elsa.h file
InstallElsaModule(all elsa_all elsa_allTargets)
install(FILES elsa.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/elsa/)
# if stand-alone and option set, turn on all warnings for all components
if(${ELSA_MASTER_PROJECT} AND ${ELSA_BUILD_WITH_MORE_WARNINGS})
list(REMOVE_ITEM ELSA_REGISTERED_COMPONENTS "")
foreach(_component ${ELSA_REGISTERED_COMPONENTS})
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang")
target_compile_options(elsa_${_component} PUBLIC -Wall -Wextra -Wconversion -pedantic -Wfatal-errors)
......@@ -60,5 +83,6 @@ if(${ELSA_MASTER_PROJECT} AND ${ELSA_BUILD_WITH_MORE_WARNINGS})
endforeach(_component ELSA_REGISTERED_COMPONENTS)
endif()
# propogate the variable to the parent scope
set(ELSA_REGISTERED_COMPONENTS "${ELSA_REGISTERED_COMPONENTS};" PARENT_SCOPE)
# propagate the variable to the parent scope
set(ELSA_REGISTERED_COMPONENTS "${ELSA_REGISTERED_COMPONENTS};all;" PARENT_SCOPE)
#pragma once
#include "elsa.h"
#include "elsaDefines.h"
#include "Cloneable.h"
#include "DataDescriptor.h"
......
......@@ -8,7 +8,7 @@ set(ELSA_MODULE_EXPORT_TARGET elsa_${ELSA_MODULE_NAME}Targets)
# list all the headers of the module
set(MODULE_HEADERS
elsa.h
elsaDefines.h
Cloneable.h
DataDescriptor.h
BlockDescriptor.h
......@@ -32,7 +32,6 @@ set(MODULE_SOURCES
# build the module library
add_library(${ELSA_MODULE_TARGET_NAME} ${MODULE_HEADERS} ${MODULE_SOURCES})
add_library(elsa::${ELSA_MODULE_NAME} ALIAS ${ELSA_MODULE_TARGET_NAME})
add_dependencies(elsa ${ELSA_MODULE_TARGET_NAME})
target_link_libraries(${ELSA_MODULE_TARGET_NAME} PUBLIC Eigen3::Eigen)
......
#pragma once
#include "elsa.h"
#include "elsaDefines.h"
#include "DataDescriptor.h"
#include "DataHandler.h"
#include "DataContainerIterator.h"
......
#pragma once
#include "elsa.h"
#include "elsaDefines.h"
#include "Cloneable.h"
namespace elsa
......
#pragma once
#include "elsa.h"
#include "elsaDefines.h"
#include "Cloneable.h"
namespace elsa
......
#pragma once
#include "elsa.h"
#include "elsaDefines.h"
#include "DataHandler.h"
#include <Eigen/Core>
......
#pragma once
#include "elsa.h"
#include "elsaDefines.h"
#include "DataHandler.h"
#include <Eigen/Core>
......@@ -173,4 +173,5 @@ namespace elsa
*/
DataHandlerMapCPU(DataHandlerCPU<data_t>* dataOwner, data_t* data, index_t n);
};
} // namespace elsa
\ No newline at end of file
} // namespace elsa
#pragma once
#include "elsa.h"
#include "elsaDefines.h"
#include "Cloneable.h"
#include "DataDescriptor.h"
#include "DataContainer.h"
......
#pragma once
// Core headers
#include "core/elsaDefines.h"
#include "core/DataContainer.h"
#include "core/DataDescriptor.h"
#include "core/LinearOperator.h"
// Functional headers
#include "functionals/Functional.h"
#include "functionals/Residual.h"
#include "functionals/LinearResidual.h"
#include "functionals/Huber.h"
#include "functionals/L1Norm.h"
#include "functionals/L2NormPow2.h"
#include "functionals/WeightedL2NormPow2.h"
#include "functionals/LInfNorm.h"
#include "functionals/PseudoHuber.h"
#include "functionals/Quadric.h"
#include "functionals/EmissionLogLikelihood.h"
#include "functionals/TransmissionLogLikelihood.h"
// Generators headers
#include "generators/PhantomGenerator.h"
#include "generators/CircleTrajectoryGenerator.h"
// IO headers
#include "io/EDFHandler.h"
#include "io/MHDHandler.h"
// Logging headers
#include "logging/Logger.h"
#include "logging/LogGuard.h"
#include "logging/Timer.h"
// Operator headers
#include "operators/Identity.h"
#include "operators/Scaling.h"
#include "operators/FiniteDifferences.h"
// Problem headers
#include "problems/Problem.h"
#include "problems/RegularizationTerm.h"
#include "problems/QuadricProblem.h"
#include "problems/WLSProblem.h"
// Projector headers
#include "projectors/Geometry.h"
#include "projectors/BinaryMethod.h"
#include "projectors/JosephsMethod.h"
#include "projectors/SiddonsMethod.h"
// CUDA projectors
#ifdef ELSA_CUDA_PROJECTORS
#include "projectors_cuda/SiddonsMethodCUDA.h"
#include "projectors_cuda/JosephsMethodCUDA.h"
#endif
// Solver headers
#include "solvers/Solver.h"
#include "solvers/GradientDescent.h"
#include "solvers/CG.h"
......@@ -40,7 +40,6 @@ set(MODULE_SOURCES
# build the module library
add_library(${ELSA_MODULE_TARGET_NAME} ${MODULE_HEADERS} ${MODULE_SOURCES})
add_library(elsa::${ELSA_MODULE_NAME} ALIAS ${ELSA_MODULE_TARGET_NAME})
add_dependencies(elsa ${ELSA_MODULE_TARGET_NAME})
target_link_libraries(${ELSA_MODULE_TARGET_NAME} PUBLIC elsa_core elsa_logging elsa_operators)
......
......@@ -22,7 +22,6 @@ set(MODULE_SOURCES
# build the module library
add_library(${ELSA_MODULE_TARGET_NAME} ${MODULE_HEADERS} ${MODULE_SOURCES})
add_library(elsa::${ELSA_MODULE_NAME} ALIAS ${ELSA_MODULE_TARGET_NAME})
add_dependencies(elsa ${ELSA_MODULE_TARGET_NAME})
target_link_libraries(${ELSA_MODULE_TARGET_NAME} PUBLIC elsa_core elsa_logging elsa_projectors)
......
#pragma once
#include "elsa.h"
#include "elsaDefines.h"
#include "DataContainer.h"
namespace elsa
......
#pragma once
#include "elsa.h"
#include "elsaDefines.h"
#include "DataContainer.h"
namespace elsa
......
......@@ -22,7 +22,6 @@ set(MODULE_SOURCES
# build the module library
add_library(${ELSA_MODULE_TARGET_NAME} ${MODULE_HEADERS} ${MODULE_SOURCES})
add_library(elsa::${ELSA_MODULE_NAME} ALIAS ${ELSA_MODULE_TARGET_NAME})
add_dependencies(elsa ${ELSA_MODULE_TARGET_NAME})
target_link_libraries(${ELSA_MODULE_TARGET_NAME} PUBLIC elsa_core elsa_logging)
......
#pragma once
#include "elsa.h"
#include "elsaDefines.h"
#include "DataContainer.h"
#include "DataDescriptor.h"
#include "ioUtils.h"
......
#pragma once
#include "elsa.h"
#include "elsaDefines.h"
#include "DataContainer.h"
#include "DataDescriptor.h"
#include "ioUtils.h"
......
#include "ioUtils.h"
#include "elsa.h"
#include "elsaDefines.h"
#include <algorithm>
#include <cctype>
......
#pragma once
#include "elsa.h"
#include "elsaDefines.h"
#include "DataContainer.h"
#include <fstream>
......
......@@ -8,7 +8,7 @@
#include <catch2/catch.hpp>
#include "ioUtils.h"
#include "elsa.h"
#include "elsaDefines.h"
using namespace elsa;
......
......@@ -22,7 +22,6 @@ set(MODULE_SOURCES
# build the module library
add_library(${ELSA_MODULE_TARGET_NAME} ${MODULE_HEADERS} ${MODULE_SOURCES})
add_library(elsa::${ELSA_MODULE_NAME} ALIAS ${ELSA_MODULE_TARGET_NAME})
add_dependencies(elsa ${ELSA_MODULE_TARGET_NAME})
target_include_directories(${ELSA_MODULE_TARGET_NAME}
PUBLIC
......
......@@ -22,7 +22,6 @@ set(MODULE_SOURCES
# build the module library
add_library(${ELSA_MODULE_TARGET_NAME} ${MODULE_HEADERS} ${MODULE_SOURCES})
add_library(elsa::${ELSA_MODULE_NAME} ALIAS ${ELSA_MODULE_TARGET_NAME})
add_dependencies(elsa ${ELSA_MODULE_TARGET_NAME})
target_link_libraries(${ELSA_MODULE_TARGET_NAME} PUBLIC elsa_core elsa_logging)
......
......@@ -24,7 +24,6 @@ set(MODULE_SOURCES
# build the module library
add_library(${ELSA_MODULE_TARGET_NAME} ${MODULE_HEADERS} ${MODULE_SOURCES})
add_library(elsa::${ELSA_MODULE_NAME} ALIAS ${ELSA_MODULE_TARGET_NAME})
add_dependencies(elsa ${ELSA_MODULE_TARGET_NAME})
target_link_libraries(${ELSA_MODULE_TARGET_NAME} PUBLIC elsa_core elsa_logging elsa_operators elsa_functionals)
......
......@@ -80,4 +80,4 @@ namespace elsa
template class RegularizationTerm<std::complex<float>>;
template class RegularizationTerm<std::complex<double>>;
} // namespace elsa
\ No newline at end of file
} // namespace elsa
#pragma once
#include "elsa.h"
#include "elsaDefines.h"
namespace elsa
{
......
......@@ -32,7 +32,6 @@ set(MODULE_SOURCES
# build the module library
add_library(${ELSA_MODULE_TARGET_NAME} ${MODULE_HEADERS} ${MODULE_SOURCES})
add_library(elsa::${ELSA_MODULE_NAME} ALIAS ${ELSA_MODULE_TARGET_NAME})
add_dependencies(elsa ${ELSA_MODULE_TARGET_NAME})
target_link_libraries(${ELSA_MODULE_TARGET_NAME} PUBLIC elsa_core elsa_logging)
......
#pragma once
#include "elsa.h"
#include "elsaDefines.h"
#include "DataDescriptor.h"
#include <utility>
......
#pragma once
#include "elsa.h"
#include "elsaDefines.h"
#include "BoundingBox.h"
#include <Eigen/Geometry>
......
#pragma once
#include "elsa.h"
#include "elsaDefines.h"
#include "BoundingBox.h"
#include <Eigen/Geometry>
......
......@@ -2,7 +2,7 @@
// core
#include <utility>
#include "elsa.h"
#include "elsaDefines.h"
// geometry
#include "Intersection.h"
......
......@@ -32,7 +32,6 @@ if (CMAKE_CUDA_COMPILER)
# build the module library
add_library(${ELSA_MODULE_TARGET_NAME} ${MODULE_HEADERS} ${MODULE_SOURCES})
add_library(elsa::${ELSA_MODULE_NAME} ALIAS ${ELSA_MODULE_TARGET_NAME})
add_dependencies(elsa ${ELSA_MODULE_TARGET_NAME})
target_link_libraries(${ELSA_MODULE_TARGET_NAME} PUBLIC elsa_core elsa_logging elsa_projectors elsa_projector_kernels)
......@@ -48,7 +47,8 @@ if (CMAKE_CUDA_COMPILER)
target_compile_features(${ELSA_MODULE_TARGET_NAME} PUBLIC cxx_std_17)
# set -fPIC
set_target_properties(${ELSA_MODULE_TARGET_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON)
# set define to check cuda projectors in projects
target_compile_definitions(${ELSA_MODULE_TARGET_NAME} PUBLIC ELSA_CUDA_PROJECTORS)
# build the tests (if enabled)
if(ELSA_TESTING)
......
......@@ -4,7 +4,7 @@
#include <cuda_runtime.h>
#include "elsa.h"
#include "elsaDefines.h"
#include "LinearOperator.h"
#include "Geometry.h"
#include "BoundingBox.h"
......
......@@ -2,7 +2,7 @@
#include <cuda_runtime.h>
#include "elsa.h"
#include "elsaDefines.h"
#include "LinearOperator.h"
#include "Geometry.h"
#include "BoundingBox.h"
......
......@@ -102,7 +102,7 @@ set_target_properties(${ELSA_MODULE_TARGET_NAME} PROPERTIES CUDA_STANDARD 14 POS
#we only need the elsa.h header -> manually specify include directories
target_include_directories(${ELSA_MODULE_TARGET_NAME} PUBLIC
$<TARGET_PROPERTY:elsa_core,INTERFACE_INCLUDE_DIRECTORIES>
$<INSTALL_INTERFACE:include/${ELSA_MODULE_NAME}>
$<INSTALL_INTERFACE:include/elsa/${ELSA_MODULE_NAME}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
# register the module
......
......@@ -11,7 +11,7 @@
#include <cuda_runtime.h>
#include "elsa.h"
#include "elsaDefines.h"
namespace elsa
{
......
......@@ -9,7 +9,7 @@
#include "cuda_runtime.h"
#include "stdint.h"
#include "elsa.h"
#include "elsaDefines.h"
namespace elsa {
......
......@@ -22,7 +22,6 @@ set(MODULE_SOURCES
# build the module library
add_library(${ELSA_MODULE_TARGET_NAME} ${MODULE_HEADERS} ${MODULE_SOURCES})
add_library(elsa::${ELSA_MODULE_NAME} ALIAS ${ELSA_MODULE_TARGET_NAME})
add_dependencies(elsa ${ELSA_MODULE_TARGET_NAME})
target_link_libraries(${ELSA_MODULE_TARGET_NAME} PUBLIC elsa_core elsa_logging elsa_problems)
......
#pragma once
#include "elsa.h"
#include "elsaDefines.h"
#include "Cloneable.h"
#include "Problem.h"
......
......@@ -5,7 +5,7 @@ add_custom_target(examples)
# build the 2d example program
add_executable(example2d example2d.cpp)
target_link_libraries(example2d elsa_core elsa_projectors elsa_generators elsa_io elsa_solvers)
target_link_libraries(example2d elsa::all)
target_compile_features(example2d PUBLIC cxx_std_17)
add_dependencies(examples example2d)
......@@ -17,7 +17,7 @@ if(ELSA_BUILD_CUDA_PROJECTORS)
# build the 3d example program
add_executable(example3d example3d.cpp)
target_link_libraries(example3d elsa_core elsa_projectors_cuda elsa_generators elsa_io elsa_solvers)
target_link_libraries(example3d elsa::all)
target_compile_features(example3d PUBLIC cxx_std_17)
add_dependencies(examples example3d)
......
/// Elsa example program: basic 2d X-ray CT simulation and reconstruction
#include "elsa.h"
#include "PhantomGenerator.h"
#include "CircleTrajectoryGenerator.h"
#include "SiddonsMethod.h"
#include "EDFHandler.h"
#include "GradientDescent.h"
#include "WLSProblem.h"
#include "Logger.h"
#include <iostream>
......@@ -61,4 +54,4 @@ int main()
catch (std::exception& e) {
std::cerr << "An exception occurred: " << e.what() << "\n";
}
}
\ No newline at end of file
}
/// Elsa example program: basic 3d X-ray CT simulation and reconstruction using CUDA projectors
#include "elsa.h"
#include "PhantomGenerator.h"
#include "CircleTrajectoryGenerator.h"
#include "JosephsMethodCUDA.h"
#include "EDFHandler.h"
#include "GradientDescent.h"
#include "WLSProblem.h"
#include "Logger.h"
#include <iostream>
......@@ -61,4 +54,4 @@ int main()
catch (std::exception& e) {
std::cerr << "An exception occurred: " << e.what() << "\n";
}
}
\ No newline at end of file