diff --git a/CMakeLists.txt b/CMakeLists.txt index 2496c559d..823899c26 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -296,6 +296,7 @@ if (CLAD_INCLUDE_DOCS) endif() if (NOT CLAD_BUILD_STATIC_ONLY) + add_subdirectory(unittests) add_subdirectory(test) add_subdirectory(demos/ErrorEstimation/CustomModel) add_subdirectory(demos/ErrorEstimation/PrintModel) diff --git a/cmake/modules/AddCladBenchmark.cmake b/cmake/modules/AddCladBenchmark.cmake index 17983d0aa..ef0e66eb0 100644 --- a/cmake/modules/AddCladBenchmark.cmake +++ b/cmake/modules/AddCladBenchmark.cmake @@ -10,31 +10,87 @@ string(REPLACE "/" "" CURRENT_REPO_COMMIT ${CURRENT_REPO_COMMIT}) set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/.git/HEAD") - # Change the default compiler to the clang which we run clad upon. set(CMAKE_CXX_COMPILER ${LLVM_TOOLS_BINARY_DIR}/clang) -#---------------------------------------------------------------------------- -# function CB_ADD_GBENCHMARK( source1 source2... LIBRARIES libs) -#---------------------------------------------------------------------------- -function(CB_ADD_GBENCHMARK benchmark) - cmake_parse_arguments(ARG "" "LABEL" "DEPENDS;LIBRARIES" ${ARGN}) - set(source_files ${ARG_UNPARSED_ARGUMENTS}) - - add_executable(${benchmark} ${source_files}) +#------------------------------------------------------------------------------- +# function ENABLE_CLAD_FOR_EXECUTABLE( +# DEPENDS dependencies... +# A list of targets that the executable depends on. +# LIBRARIES libraries... +# A list of libraries to be linked in. Defaults to stdc++ pthread m. +# ) +#------------------------------------------------------------------------------- +function(ENABLE_CLAD_FOR_EXECUTABLE executable) + if (NOT TARGET ${executable}) + message(FATAL_ERROR "'${executable}' is not a valid target.") + endif() # Add the clad plugin - target_compile_options(${benchmark} PUBLIC -fplugin=$) + target_compile_options(${executable} PUBLIC -fplugin=$) # Debugging. Emitting the derivatives' source code. - #target_compile_options(${benchmark} PUBLIC "SHELL:-Xclang -plugin-arg-clad" + #target_compile_options(${executable} PUBLIC "SHELL:-Xclang -plugin-arg-clad" # "SHELL: -Xclang -fdump-derived-fn") # Debugging. Emit llvm IR. - #target_compile_options(${benchmark} PUBLIC -S -emit-llvm) + #target_compile_options(${executable} PUBLIC -S -emit-llvm) # Debugging. Optimization misses. - #target_compile_options(${benchmark} PUBLIC "SHELL:-Xclang -Rpass-missed=.*inline.*") + #target_compile_options(${executable} PUBLIC "SHELL:-Xclang -Rpass-missed=.*inline.*") + + # Clad requires us to link against these libraries. + target_link_libraries(${executable} PUBLIC stdc++ pthread m) + + target_include_directories(${executable} PUBLIC ${CMAKE_CURRENT_BINARY_DIR}) + set_property(TARGET ${executable} PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + + add_dependencies(${executable} clad) + # If clad.so changes we don't need to relink but to rebuild the source files. + # $ does not work for OBJECT_DEPENDS. + set (CLAD_SO_PATH "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/clad${CMAKE_SHARED_LIBRARY_SUFFIX}") + set_source_files_properties(${source_files} PROPERTY OBJECT_DEPENDS ${CLAD_SO_PATH}) + + # Add dependencies to executable + if(ARG_DEPENDS) + add_dependencies(${executable} ${ARG_DEPENDS}) + endif(ARG_DEPENDS) + +endfunction(ENABLE_CLAD_FOR_EXECUTABLE) + +#------------------------------------------------------------------------------- +# function ADD_CLAD_EXECUTABLE( sources... +# DEPENDS dependencies... +# A list of targets that the executable depends on. +# LIBRARIES libraries... +# A list of libraries to be linked in. Defaults to stdc++ pthread m. +# ) +#------------------------------------------------------------------------------- +function(ADD_CLAD_EXECUTABLE executable) + cmake_parse_arguments(ARG "" "DEPENDS;LIBRARIES" "" ${ARGN}) + + set(source_files ${ARG_UNPARSED_ARGUMENTS}) + + add_executable(${executable} ${source_files}) + + ENABLE_CLAD_FOR_EXECUTABLE(${executable} ${ARGN}) + +endfunction(ADD_CLAD_EXECUTABLE) + +#------------------------------------------------------------------------------- +# function CB_ADD_GBENCHMARK( sources +# LABEL +# A label that classifies how much time a benchmark is expected to take. +# Short benchmarks time out at 1200 seconds, long at 2400. +# DEPENDS dependencies... +# A list of targets that the executable depends on. +# LIBRARIES libraries... +# A list of libraries to be linked in. Defaults to stdc++ pthread m. +# ) +#------------------------------------------------------------------------------- +function(CB_ADD_GBENCHMARK benchmark) + cmake_parse_arguments(ARG "" "LABEL" "" ${ARGN}) + ADD_CLAD_EXECUTABLE(${benchmark} ${ARG_UNPARSED_ARGUMENTS}) # Optimize the produced code. target_compile_options(${benchmark} PUBLIC -O3) @@ -42,23 +98,11 @@ function(CB_ADD_GBENCHMARK benchmark) # Turn off numerical diff fallback. target_compile_definitions(${benchmark} PUBLIC CLAD_NO_NUM_DIFF) - # Clad requires us to link against these libraries. - target_link_libraries(${benchmark} PUBLIC stdc++ pthread m) - - target_include_directories(${benchmark} PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ${GBENCHMARK_INCLUDE_DIR}) - set_property(TARGET ${benchmark} PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - target_link_libraries(${benchmark} PUBLIC ${ARG_LIBRARIES} gbenchmark) if (NOT APPLE) target_link_libraries(${benchmark} PUBLIC rt) endif() - add_dependencies(${benchmark} clad) - # If clad.so changes we don't need to relink but to rebuild the source files. - # $ does not work for OBJECT_DEPENDS. - set (CLAD_SO_PATH "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/clad${CMAKE_SHARED_LIBRARY_SUFFIX}") - set_source_files_properties(${source_files} PROPERTY OBJECT_DEPENDS ${CLAD_SO_PATH}) - set (TIMEOUT_VALUE 1200) set (LABEL "short") if (ARG_LABEL AND "${ARG_LABEL}" STREQUAL "long") @@ -66,11 +110,6 @@ function(CB_ADD_GBENCHMARK benchmark) set (LABEL "long") endif() - # Add dependencies to benchmark - if(ARG_DEPENDS) - add_dependencies(${benchmark} ${ARG_DEPENDS}) - endif() - # Add benchmark as a CTest add_test(NAME clad-${benchmark} COMMAND ${benchmark} --benchmark_out_format=json diff --git a/cmake/modules/CladGoogleTest.cmake b/cmake/modules/CladGoogleTest.cmake new file mode 100644 index 000000000..381158a44 --- /dev/null +++ b/cmake/modules/CladGoogleTest.cmake @@ -0,0 +1,85 @@ +set(_gtest_byproduct_binary_dir + ${CMAKE_BINARY_DIR}/downloads/googletest-prefix/src/googletest-build) +set(_gtest_byproducts + ${_gtest_byproduct_binary_dir}/lib/libgtest.a + ${_gtest_byproduct_binary_dir}/lib/libgtest_main.a + ${_gtest_byproduct_binary_dir}/lib/libgmock.a + ${_gtest_byproduct_binary_dir}/lib/libgmock_main.a + ) + +if(MSVC) + set(EXTRA_GTEST_OPTS + -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG:PATH=${_gtest_byproduct_binary_dir}/lib/ + -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_MINSIZEREL:PATH=${_gtest_byproduct_binary_dir}/lib/ + -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE:PATH=${_gtest_byproduct_binary_dir}/lib/ + -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO:PATH=${_gtest_byproduct_binary_dir}/lib/ + -Dgtest_force_shared_crt=ON + BUILD_COMMAND ${CMAKE_COMMAND} --build --config Release) +elseif(APPLE) + set(EXTRA_GTEST_OPTS -DCMAKE_OSX_SYSROOT=${CMAKE_OSX_SYSROOT}) +endif() + +include(ExternalProject) +ExternalProject_Add( + googletest + GIT_REPOSITORY https://github.com/google/googletest.git + EXCLUDE_FROM_ALL 1 + GIT_SHALLOW 1 + GIT_TAG release-1.12.1 + UPDATE_COMMAND "" + # # Force separate output paths for debug and release builds to allow easy + # # identification of correct lib in subsequent TARGET_LINK_LIBRARIES commands + # CMAKE_ARGS -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG:PATH=DebugLibs + # -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE:PATH=ReleaseLibs + # -Dgtest_force_shared_crt=ON + CMAKE_ARGS -G ${CMAKE_GENERATOR} + -DCMAKE_BUILD_TYPE=Release + -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} + -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} + -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} + -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} + -DCMAKE_AR=${CMAKE_AR} + -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} + ${EXTRA_GTEST_OPTS} + # Disable install step + INSTALL_COMMAND "" + BUILD_BYPRODUCTS ${_gtest_byproducts} + # Wrap download, configure and build steps in a script to log output + LOG_DOWNLOAD ON + LOG_CONFIGURE ON + LOG_BUILD ON + TIMEOUT 600 + ) + +# Specify include dirs for gtest and gmock +ExternalProject_Get_Property(googletest source_dir) +set(GTEST_INCLUDE_DIR ${source_dir}/googletest/include) +set(GMOCK_INCLUDE_DIR ${source_dir}/googlemock/include) +# Create the directories. Prevents bug https://gitlab.kitware.com/cmake/cmake/issues/15052 +file(MAKE_DIRECTORY ${GTEST_INCLUDE_DIR} ${GMOCK_INCLUDE_DIR}) + +# Libraries +ExternalProject_Get_Property(googletest binary_dir) +set(_G_LIBRARY_PATH ${binary_dir}/lib/) + +# Use gmock_main instead of gtest_main because it initializes gtest as well. +# Note: The libraries are listed in reverse order of their dependancies. +foreach(lib gtest gtest_main gmock gmock_main) + add_library(${lib} IMPORTED STATIC GLOBAL) + set_target_properties(${lib} PROPERTIES + IMPORTED_LOCATION "${_G_LIBRARY_PATH}${CMAKE_STATIC_LIBRARY_PREFIX}${lib}${CMAKE_STATIC_LIBRARY_SUFFIX}" + INTERFACE_INCLUDE_DIRECTORIES "${GTEST_INCLUDE_DIR}" + ) + add_dependencies(${lib} googletest) + if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND + ${CMAKE_CXX_COMPILER_VERSION} VERSION_GREATER_EQUAL 9) + target_compile_options(${lib} INTERFACE -Wno-deprecated-copy) + endif() +endforeach() +target_include_directories(gtest INTERFACE ${GTEST_INCLUDE_DIR}) +target_include_directories(gmock INTERFACE ${GMOCK_INCLUDE_DIR}) + +set_property(TARGET gtest PROPERTY IMPORTED_LOCATION ${_G_LIBRARY_PATH}/${CMAKE_STATIC_LIBRARY_PREFIX}gtest${CMAKE_STATIC_LIBRARY_SUFFIX}) +set_property(TARGET gtest_main PROPERTY IMPORTED_LOCATION ${_G_LIBRARY_PATH}/${CMAKE_STATIC_LIBRARY_PREFIX}gtest_main${CMAKE_STATIC_LIBRARY_SUFFIX}) +set_property(TARGET gmock PROPERTY IMPORTED_LOCATION ${_G_LIBRARY_PATH}/${CMAKE_STATIC_LIBRARY_PREFIX}gmock${CMAKE_STATIC_LIBRARY_SUFFIX}) +set_property(TARGET gmock_main PROPERTY IMPORTED_LOCATION ${_G_LIBRARY_PATH}/${CMAKE_STATIC_LIBRARY_PREFIX}gmock_main${CMAKE_STATIC_LIBRARY_SUFFIX}) diff --git a/cmake/modules/GoogleBenchmark.cmake b/cmake/modules/GoogleBenchmark.cmake index 6b87c705c..d01017d30 100644 --- a/cmake/modules/GoogleBenchmark.cmake +++ b/cmake/modules/GoogleBenchmark.cmake @@ -8,6 +8,7 @@ ExternalProject_Add( googlebenchmark GIT_REPOSITORY https://github.com/google/benchmark.git EXCLUDE_FROM_ALL 1 + GIT_SHALLOW 1 GIT_TAG v1.6.0 UPDATE_COMMAND "" # TIMEOUT 10 @@ -35,6 +36,8 @@ ExternalProject_Add( # Specify include dirs for googlebenchmark ExternalProject_Get_Property(googlebenchmark source_dir) set(GBENCHMARK_INCLUDE_DIR ${source_dir}/include) +# Create the directories. Prevents bug https://gitlab.kitware.com/cmake/cmake/issues/15052 +file(MAKE_DIRECTORY ${GBENCHMARK_INCLUDE_DIR}) # Libraries ExternalProject_Get_Property(googlebenchmark binary_dir) @@ -42,5 +45,9 @@ set(_GBENCH_LIBRARY_PATH ${binary_dir}/) # Register googlebenchmark add_library(gbenchmark IMPORTED STATIC GLOBAL) -set_property(TARGET gbenchmark PROPERTY IMPORTED_LOCATION ${_GBENCH_LIBRARY_PATH}/src/libbenchmark.a) +set_target_properties(gbenchmark PROPERTIES + IMPORTED_LOCATION ${_GBENCH_LIBRARY_PATH}/src/${CMAKE_STATIC_LIBRARY_PREFIX}benchmark${CMAKE_STATIC_LIBRARY_SUFFIX} + INTERFACE_INCLUDE_DIRECTORIES "${GBENCHMARK_INCLUDE_DIR}" + ) +target_include_directories(gbenchmark INTERFACE ${GBENCHMARK_INCLUDE_DIR}) add_dependencies(gbenchmark googlebenchmark) diff --git a/include/clad/Differentiator/CladConfig.h b/include/clad/Differentiator/CladConfig.h index 8ed22421b..4ad838a31 100644 --- a/include/clad/Differentiator/CladConfig.h +++ b/include/clad/Differentiator/CladConfig.h @@ -54,16 +54,10 @@ constexpr unsigned GetBitmaskedOpts(unsigned const first, Opts... opts) { // Define trap function that is a CUDA compatible replacement for // exit(int code) function #ifdef __CUDACC__ -__device__ void trap(int code) { - asm("trap;"); -} -__host__ void trap(int code) { - exit(code); -} +inline __device__ void trap(int code) { asm("trap;"); } +inline __host__ void trap(int code) { exit(code); } #else -void trap(int code) { - exit(code); -} +inline void trap(int code) { exit(code); } #endif #ifdef __CUDACC__ diff --git a/include/clad/Differentiator/Differentiator.h b/include/clad/Differentiator/Differentiator.h index 49797a7ba..b6f4e8474 100644 --- a/include/clad/Differentiator/Differentiator.h +++ b/include/clad/Differentiator/Differentiator.h @@ -27,20 +27,20 @@ template struct ValueAndAdjoint { }; /// \returns the size of a c-style string - CUDA_HOST_DEVICE unsigned int GetLength(const char* code) { - unsigned int count; - const char* code_copy = code; - #ifdef __CUDACC__ - count = 0; - while (*code_copy != '\0') { - count++; - code_copy++; - } - #else - count = strlen(code_copy); - #endif - return count; +inline CUDA_HOST_DEVICE unsigned int GetLength(const char* code) { + unsigned int count; + const char* code_copy = code; +#ifdef __CUDACC__ + count = 0; + while (*code_copy != '\0') { + count++; + code_copy++; } +#else + count = strlen(code_copy); +#endif + return count; +} /// Tape type used for storing values in reverse-mode AD inside loops. template diff --git a/include/clad/Differentiator/NumericalDiff.h b/include/clad/Differentiator/NumericalDiff.h index 5f090d793..e8ae560c0 100644 --- a/include/clad/Differentiator/NumericalDiff.h +++ b/include/clad/Differentiator/NumericalDiff.h @@ -73,7 +73,10 @@ namespace numerical_diff { /// A buffer manager to request for buffer space /// while forwarding reference/pointer args to the target function. - ManageBufferSpace bufferManager; + inline ManageBufferSpace& getBufferManager() { + static ManageBufferSpace bufMan; + return bufMan; + } /// The precision to do the numerical differentiation calculations in. using precision = double; @@ -87,7 +90,7 @@ namespace numerical_diff { /// \param[in] \c h The h to make representable. /// /// \returns A value of h that does not result in catastrohic cancellation. - precision make_h_representable(precision x, precision h) { + inline precision make_h_representable(precision x, precision h) { precision xph = x + h; precision dx = xph - x; @@ -104,7 +107,7 @@ namespace numerical_diff { /// \param[in] \c arg The input argument to adjust and get h for. /// /// \returns A calculated and adjusted h value. - precision get_h(precision arg) { + inline precision get_h(precision arg) { // First get a suitable h value, we do all of this in elevated precision // (default double). Maximum error in h = eps^4/5 precision h = std::pow(11.25 * std::numeric_limits::epsilon(), @@ -126,8 +129,8 @@ namespace numerical_diff { /// belongs. /// \param[in] \c arrPos The position of the array element /// (-1 if parameter is scalar) to which the error belongs. - void printError(precision derivError, precision evalError, unsigned paramPos, - int arrPos = -1) { + inline void printError(precision derivError, precision evalError, + unsigned paramPos, int arrPos = -1) { if (arrPos != -1) printf("\nError Report for parameter at position %d and index %d:\n", paramPos, arrPos); @@ -227,7 +230,7 @@ namespace numerical_diff { // this is required to make sure that we are retuning a deep copy // that is valid throughout the scope of the central_diff function. // Temp is system owned. - T* temp = bufferManager.make_buffer_space(n); + T* temp = getBufferManager().make_buffer_space(n); // deepcopy for (std::size_t j = 0; j < n; j++) { temp[j] = arg[j]; @@ -318,7 +321,7 @@ namespace numerical_diff { // five-point stencil formula = (4f[x+h, x-h] - f[x+2h, x-2h])/3 _grad[i][j] = 4.0 * xf1 / 3.0 - xf2 / 3.0; - bufferManager.free_buffer(); + getBufferManager().free_buffer(); } } } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 823109517..a37a418ad 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -29,6 +29,13 @@ configure_lit_site_cfg( ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg ) +configure_lit_site_cfg( + ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.py.in + ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg.py + MAIN_CONFIG + ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.cfg.py + ) + option(CLANG_TEST_USE_VG "Run Clang tests under Valgrind" OFF) if(CLANG_TEST_USE_VG) set(CLANG_TEST_EXTRA_ARGS ${CLANG_TEST_EXTRA_ARGS} "--vg") @@ -44,6 +51,12 @@ set(CLAD_TEST_PARAMS clad_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg ) +# Unit tests +list(APPEND CLAD_TEST_DEPS CladUnitTests) +list(APPEND CLAD_TEST_PARAMS + clad_site_config=${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg + ) + add_custom_target(clad-test-depends DEPENDS ${CLAD_TEST_DEPS}) set_target_properties(clad-test-depends PROPERTIES FOLDER "Clad tests") diff --git a/test/NumericalDiff/UserDefinedPointers.C b/test/NumericalDiff/UserDefinedPointers.C index d1f6dc13b..be4320aae 100644 --- a/test/NumericalDiff/UserDefinedPointers.C +++ b/test/NumericalDiff/UserDefinedPointers.C @@ -39,7 +39,7 @@ myStruct* updateIndexParamValue(myStruct* arg, std::size_t idx, std::size_t currIdx, int multiplier, numerical_diff::precision &h_val, std::size_t n = 0, std::size_t i = 0) { - myStruct* temp = numerical_diff::bufferManager + myStruct* temp = numerical_diff::getBufferManager() .make_buffer_space(1, true, arg->data, arg->effect); if (idx == currIdx) { diff --git a/test/Unit/lit.cfg.py b/test/Unit/lit.cfg.py new file mode 100644 index 000000000..3741bbc07 --- /dev/null +++ b/test/Unit/lit.cfg.py @@ -0,0 +1,42 @@ +# -*- Python -*- + +import platform + +import lit.formats + +config.name = "Clad Unit Tests" +config.suffixes = [] # Seems not to matter for google tests? + +# Test Source and Exec root dirs both point to the same directory where google +# test binaries are built. +config.test_exec_root = os.path.join(config.clad_obj_root, "unittests") +config.test_source_root = config.test_exec_root +print(config.test_exec_root) +# All GoogleTests are named to have 'Tests' as their suffix. The '.' coming from +# llvm_build_mode option is a special value for GoogleTest indicating that it +# should look through the entire testsuite recursively for tests (alternatively, +# one could provide a ;-separated list of subdirectories). +config.test_format = lit.formats.GoogleTest(config.llvm_build_mode, "Tests") + +if platform.system() == "Darwin": + shlibpath_var = "DYLD_LIBRARY_PATH" +elif platform.system() == "Windows": + shlibpath_var = "PATH" +else: + shlibpath_var = "LD_LIBRARY_PATH" + +# Point the dynamic loader at dynamic libraries in 'lib'. +shlibpath = os.path.pathsep.join( + (config.shlibdir, config.llvm_libs_dir, config.environment.get(shlibpath_var, "")) +) + +# Win32 seeks DLLs along %PATH%. +if sys.platform in ["win32", "cygwin"] and os.path.isdir(config.shlibdir): + shlibpath = os.path.pathsep.join((config.shlibdir, shlibpath)) + +config.environment[shlibpath_var] = shlibpath + +# It is not realistically possible to account for all options that could +# possibly be present in system and user configuration files, so disable +# default configs for the test runs. +config.environment["CLANG_NO_DEFAULT_CONFIG"] = "1" diff --git a/test/Unit/lit.site.cfg.py.in b/test/Unit/lit.site.cfg.py.in new file mode 100644 index 000000000..281a9fbcd --- /dev/null +++ b/test/Unit/lit.site.cfg.py.in @@ -0,0 +1,8 @@ +@LIT_SITE_CFG_IN_HEADER@ + +config.llvm_libs_dir = "@LLVM_LIBS_DIR@" +config.shlibdir = "@SHLIBDIR@" +config.clad_obj_root = "@CLAD_BINARY_DIR@" +config.llvm_build_mode = lit_config.substitute("@LLVM_BUILD_MODE@") + +lit_config.load_config(config, "@CLAD_SOURCE_DIR@/test/Unit/lit.cfg.py") diff --git a/unittests/Basic/CMakeLists.txt b/unittests/Basic/CMakeLists.txt new file mode 100644 index 000000000..48da2fd0b --- /dev/null +++ b/unittests/Basic/CMakeLists.txt @@ -0,0 +1,4 @@ +add_clad_unittest(DifferentiatorHTests + DifferentiatorH.cpp + MultiIncludeDifferentiatorH.cpp + ) diff --git a/unittests/Basic/DifferentiatorH.cpp b/unittests/Basic/DifferentiatorH.cpp new file mode 100644 index 000000000..34157c910 --- /dev/null +++ b/unittests/Basic/DifferentiatorH.cpp @@ -0,0 +1,8 @@ +#include "clad/Differentiator/Differentiator.h" + +#include "gtest/gtest.h" + +TEST(DifferentiatorH, GetLength) { + EXPECT_TRUE(clad::GetLength("") == 0); + EXPECT_TRUE(clad::GetLength("abc") == 3); +} diff --git a/unittests/Basic/MultiIncludeDifferentiatorH.cpp b/unittests/Basic/MultiIncludeDifferentiatorH.cpp new file mode 100644 index 000000000..d6e5c5179 --- /dev/null +++ b/unittests/Basic/MultiIncludeDifferentiatorH.cpp @@ -0,0 +1 @@ +#include "clad/Differentiator/Differentiator.h" diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt new file mode 100644 index 000000000..68f24fdd5 --- /dev/null +++ b/unittests/CMakeLists.txt @@ -0,0 +1,36 @@ +add_custom_target(CladUnitTests) +set_target_properties(CladUnitTests PROPERTIES FOLDER "Clang tests") + +# LLVM builds (not installed llvm) provides gtest. +if (NOT TARGET gtest) + include(CladGoogleTest) + include(AddCladBenchmark) +endif() + +# add_clad_unittest(test_dirname file1.cpp file2.cpp) +# +# Will compile the list of files together and link against clad. +# Produces a binary named 'basename(test_dirname)'. +function(add_clad_unittest test_dirname) + add_unittest(CladUnitTests ${test_dirname} ${ARGN}) + + # Remove the llvm_gtest_* coming from add_unittest. + get_target_property(GTEST_LINKED_LIBS ${test_dirname} LINK_LIBRARIES) + list(REMOVE_ITEM GTEST_LINKED_LIBS llvm_gtest_main llvm_gtest) + set_property(TARGET ${test_dirname} PROPERTY LINK_LIBRARIES ${GTEST_LINKED_LIBS}) + + enable_clad_for_executable(${test_dirname}) + + # Add gtest dependencies. + set(gtest_libs gtest gtest_main) + # Clang prior than clang13 (I think) merges both gmock into gtest. + if (TARGET gmock) + list(APPEND gtest_libs gmock gmock_main) + endif() + + target_link_libraries(${test_dirname} PUBLIC ${gtest_libs}) + +endfunction() + +add_subdirectory(Basic) +