From 19df5df68d6d50dc81563e2a532f0586578061a9 Mon Sep 17 00:00:00 2001 From: Andrew Cassidy Date: Sat, 18 Jun 2022 17:06:17 -0700 Subject: [PATCH] Rework project layout and tests --- CMakeLists.txt | 73 +---------------- quicktex/CMakeLists.txt | 60 ++++++++++++++ quicktex/_bindings.cpp | 6 -- tests/CMakeLists.txt | 23 ++++++ .../TestVec.cpp => tests/ctest/TestMatrix.cpp | 80 ++++++++----------- {quicktex/ctests => tests/ctest}/TestSIMD.cpp | 27 +++---- tests/test_ctest.py | 5 -- 7 files changed, 135 insertions(+), 139 deletions(-) create mode 100644 quicktex/CMakeLists.txt create mode 100644 tests/CMakeLists.txt rename quicktex/ctests/TestVec.cpp => tests/ctest/TestMatrix.cpp (60%) rename {quicktex/ctests => tests/ctest}/TestSIMD.cpp (84%) delete mode 100644 tests/test_ctest.py diff --git a/CMakeLists.txt b/CMakeLists.txt index 57cbfda..1874ed8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,75 +5,10 @@ set(CMAKE_VERBOSE_MAKEFILE ON) project(quicktex) -# Find dependencies -find_package(Python COMPONENTS Interpreter Development.Module) -find_package(pybind11 CONFIG REQUIRED) -find_package(OpenMP) - add_subdirectory(external/xsimd) -include_directories(external/utest) -include_directories(quicktex) # include source root for project-relative includes - -# Collect source files -file(GLOB SOURCE_FILES - "quicktex/*.cpp" - "quicktex/util/*.cpp" - "quicktex/ctests/*.cpp" - "quicktex/texture/*.cpp" - "quicktex/s3tc/*.cpp" - "quicktex/s3tc/bc1/*.cpp" - "quicktex/s3tc/bc3/*.cpp" - "quicktex/s3tc/bc4/*.cpp" - "quicktex/s3tc/bc5/*.cpp" - "quicktex/s3tc/interpolator/*.cpp" - ) - -file(GLOB HEADER_FILES - "quicktex/*.h" - "quicktex/util/*.h" - "quicktex/ctests/*.h" - "quicktex/texture/*.h" - "quicktex/s3tc/*.h" - "quicktex/s3tc/bc1/*.h" - "quicktex/s3tc/bc3/*.h" - "quicktex/s3tc/bc4/*.h" - "quicktex/s3tc/bc5/*.h" - "quicktex/s3tc/interpolator/*.h" - ) - -file(GLOB_RECURSE PYTHON_FILES "src/**/*.py") - -# Organize source files together for some IDEs -source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCE_FILES} ${HEADER_FILES} ${PYTHON_FILES}) - -# Add python module -pybind11_add_module(_quicktex - ${SOURCE_FILES} - ${HEADER_FILES}) - -# Set Quicktex version info -target_compile_definitions(_quicktex PRIVATE VERSION_INFO=${QUICKTEX_VERSION_INFO}) - -# enable openMP if available -if (OpenMP_CXX_FOUND) - target_link_libraries(_quicktex PUBLIC OpenMP::OpenMP_CXX) -endif () - -target_link_libraries(_quicktex PUBLIC xsimd) - -# Set module features, like C/C++ standards -target_compile_features(_quicktex PUBLIC cxx_std_20 c_std_11) - -# Set compiler warnings -set_project_warnings(_quicktex) -set_simd_flags(_quicktex) - -if (MSVC) - target_compile_options(_quicktex PUBLIC /DWIN32_LEAN_AND_MEAN=1 /DNOMINMAX=1) # prevent windows macros from stepping on everything -endif () - -message("RELEASE FLAGS=${CMAKE_CXX_FLAGS}") - -message("DEBUG FLAGS=${CMAKE_CXX_FLAGS_DEBUG}") +add_subdirectory(quicktex) +add_subdirectory(tests) +enable_testing () +add_test (NAME MyTest COMMAND Test) \ No newline at end of file diff --git a/quicktex/CMakeLists.txt b/quicktex/CMakeLists.txt new file mode 100644 index 0000000..f3837ce --- /dev/null +++ b/quicktex/CMakeLists.txt @@ -0,0 +1,60 @@ + +# Find dependencies +find_package(Python COMPONENTS Interpreter Development.Module) +find_package(pybind11 CONFIG REQUIRED) +find_package(OpenMP) + +#Collect source files +set(SOURCE_FILES + Matrix4x4.cpp OldColor.cpp + s3tc/bc1/BC1Block.cpp s3tc/bc1/BC1Decoder.cpp + s3tc/bc1/BC1Encoder.cpp s3tc/bc1/OrderTable.cpp s3tc/bc1/OrderTable4.cpp + s3tc/bc3/BC3Decoder.cpp s3tc/bc3/BC3Encoder.cpp + s3tc/bc4/BC4Block.cpp s3tc/bc4/BC4Decoder.cpp s3tc/bc4/BC4Encoder.cpp + s3tc/bc5/BC5Decoder.cpp s3tc/bc5/BC5Encoder.cpp + s3tc/interpolator/Interpolator.cpp + texture/RawTexture.cpp texture/Window.cpp) + +set(BINDING_FILES + _bindings.cpp + s3tc/_bindings.cpp + s3tc/bc1/_bindings.cpp + s3tc/bc3/_bindings.cpp + s3tc/bc4/_bindings.cpp + s3tc/bc5/_bindings.cpp + s3tc/interpolator/_bindings.cpp) + +file(GLOB_RECURSE HEADER_FILES "**.h") +file(GLOB_RECURSE PYTHON_FILES "**.py") + +# Organize source files together for some IDEs +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCE_FILES} ${BINDING_FILES} ${HEADER_FILES} ${PYTHON_FILES}) + +# Declare implementation module +add_library(quicktex STATIC ${SOURCE_FILES} ${HEADER_FILES}) + +# Link openMP if available +if (OpenMP_CXX_FOUND) + target_link_libraries(quicktex PUBLIC OpenMP::OpenMP_CXX) +endif () + +# Link XSimd +target_link_libraries(quicktex PUBLIC xsimd) + +# Set library features, like C/C++ standards +target_compile_features(quicktex PUBLIC cxx_std_20 c_std_11) +set_property(TARGET quicktex PROPERTY CXX_VISIBILITY_PRESET hidden) + +# Include source root for project-relative includes +target_include_directories(quicktex PUBLIC .) + +# Set compiler warnings and SIMD flags +set_project_warnings(quicktex) +set_simd_flags(quicktex) + +# Declare python module +pybind11_add_module(_quicktex ${BINDING_FILES} ${HEADER_FILES}) +target_compile_definitions(_quicktex PRIVATE VERSION_INFO=${QUICKTEX_VERSION_INFO}) + +# Link python module with implementation +target_link_libraries(_quicktex PUBLIC quicktex) diff --git a/quicktex/_bindings.cpp b/quicktex/_bindings.cpp index 8081966..f6449bb 100644 --- a/quicktex/_bindings.cpp +++ b/quicktex/_bindings.cpp @@ -20,7 +20,6 @@ #include "_bindings.h" #include -#include #include "Decoder.h" #include "Encoder.h" @@ -32,8 +31,6 @@ #define STRINGIFY(x) #x #define MACRO_STRINGIFY(x) STRINGIFY(x) -UTEST_STATE(); - namespace py = pybind11; namespace quicktex::bindings { @@ -82,9 +79,6 @@ PYBIND11_MODULE(_quicktex, m) { [](RawTexture &self, int x, int y, Color val) { self.pixel(x, y) = val; }, &RawTexture::Size); InitS3TC(m); - - // CTests - m.def("_run_ctests", []() { return utest_main(0, NULL); }); } } // namespace quicktex::bindings \ No newline at end of file diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..a90697b --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,23 @@ +include(FetchContent) +FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/e2239ee6043f73722e7aa812a459f54a28552929.zip +) +# For Windows: Prevent overriding the parent project's compiler/linker settings +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) +FetchContent_MakeAvailable(googletest) + +file(GLOB_RECURSE TEST_HEADER_FILES "**.h") +file(GLOB_RECURSE TEST_SOURCE_FILES "**.cpp") +file(GLOB_RECURSE TEST_PYTHON_FILES "**.py") + +# Organize source files together for some IDEs +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${TEST_SOURCE_FILES} ${TEST_HEADER_FILES} ${TEST_PYTHON_FILES}) + +add_executable(Test ${TEST_SOURCE_FILES} ${TEST_HEADER_FILES}) + +target_link_libraries(Test PUBLIC quicktex gtest_main) + +include(GoogleTest) +gtest_discover_tests(Test) + diff --git a/quicktex/ctests/TestVec.cpp b/tests/ctest/TestMatrix.cpp similarity index 60% rename from quicktex/ctests/TestVec.cpp rename to tests/ctest/TestMatrix.cpp index ba1c2e8..90883c3 100644 --- a/quicktex/ctests/TestVec.cpp +++ b/tests/ctest/TestMatrix.cpp @@ -17,120 +17,110 @@ along with this program. If not, see . */ -#include // for abs -#include // for UTEST +#include +#include +#include -#include // for operator== - -#include "../Matrix.h" // for Vec, ope... -#include "util/math.h" // for abs +#include +#include namespace quicktex::tests { +template inline void expect_vec_eq(V value, V expected) { + EXPECT_FLOAT_EQ((value - expected).sqr_mag(), 0); +} + // region Vec_float unit tests -UTEST(Vec_float, add) { +TEST(Vec_float, add) { auto a = Vec{1.0f, 1.5f, 2.0f}; auto b = Vec{2.0f, -2.5f, 3.0f}; - auto expected = Vec{3.0f, -1.0f, 5.0f}; - float diff = ((a + b) - expected).sqr_mag(); - ASSERT_LT(diff, 0.01f); + expect_vec_eq(a + b, {3.0f, -1.0f, 5.0f}); } -UTEST(Vec_float, sub) { +TEST(Vec_float, sub) { auto a = Vec{1.0f, 1.5f, 2.0f}; auto b = Vec{3.0f, 1.5f, 1.0f}; - auto expected = Vec{-2.0f, 0.0f, 1.0f}; - float diff = ((a - b) - expected).sqr_mag(); - ASSERT_LT(diff, 0.01f); + expect_vec_eq(a - b, {-2.0f, 0.0f, 1.0f}); } -UTEST(Vec_float, mul) { +TEST(Vec_float, mul) { auto a = Vec{1.0f, 1.5f, 2.0f}; auto b = Vec{3.0f, 1.5f, 0.0f}; - auto expected = Vec{3.0f, 2.25f, 0.0f}; - float diff = ((a * b) - expected).sqr_mag(); - ASSERT_LT(diff, 0.01f); + expect_vec_eq(a * b, {3.0f, 2.25f, 0.0f}); } -UTEST(Vec_float, div) { +TEST(Vec_float, div) { auto a = Vec{1.0f, 1.5f, 2.0f}; auto b = Vec{2.0f, 1.5f, 1.0f}; - auto expected = Vec{0.5f, 1.0f, 2.0f}; - float diff = ((a / b) - expected).sqr_mag(); - ASSERT_LT(diff, 0.01f); + expect_vec_eq(a / b, {0.5f, 1.0f, 2.0f}); } -UTEST(Vec_float, vsum) { +TEST(Vec_float, vsum) { auto a = Vec{1.0f, 2.0f, 3.5f, 4.0f, -4.0f}; - auto diff = abs(a.vsum() - 6.5f); - ASSERT_LT(diff, 0.01f); + EXPECT_FLOAT_EQ(a.vsum(), 6.5f); } -UTEST(Vec_float, dot) { +TEST(Vec_float, dot) { auto a = Vec{1.0f, 1.5f, 2.0f}; auto b = Vec{2.0f, 1.5f, 2.0f}; - auto diff = abs(a.dot(b) - 8.25f); - ASSERT_LT(diff, 0.01f); + EXPECT_FLOAT_EQ(a.dot(b), 8.25f); } -UTEST(Vec_float, abs) { +TEST(Vec_float, abs) { auto a = Vec{1.0f, -5.0f, -1.0f}; auto expected = Vec{1.0f, 5.0f, 1.0f}; - auto diff = (a.abs() - expected).sqr_mag(); - ASSERT_LT(diff, 0.01f); + expect_vec_eq(a.abs(), expected); } -UTEST(Vec_float, clamp) { +TEST(Vec_float, clamp) { auto a = Vec{-1, -1, -1, 1, 1, 1}; auto low1 = Vec{-2, -0.5, -2, 0, 2, 0.5}; auto high1 = Vec{-1.5, 0, 0, 0.5, 3, 2}; auto result1 = a.clamp(low1, high1); auto expected1 = Vec{-1.5, -0.5, -1, 0.5, 2, 1}; - auto diff1 = (result1 - expected1).sqr_mag(); - ASSERT_LT(diff1, 0.01f); + expect_vec_eq(result1, expected1); auto b = Vec{-1, -0.5, 0, 0.2, 0.5, 1}; auto result2 = b.clamp(-0.8, 0.3); auto expected2 = Vec{-0.8, -0.5, 0, 0.2, 0.3, 0.3}; - auto diff2 = (result2 - expected2).sqr_mag(); - ASSERT_LT(diff2, 0.01f); + expect_vec_eq(result2, expected2); } // endregion // region Vec_int unit tests -UTEST(Vec_int, subscript) { +TEST(Vec_int, subscript) { auto a = Vec{1, 3, 1, 2}; - ASSERT_EQ(a[0], 1); - ASSERT_EQ(a[1], 3); - ASSERT_EQ(a[2], 1); - ASSERT_EQ(a[3], 2); + EXPECT_EQ(a[0], 1); + EXPECT_EQ(a[1], 3); + EXPECT_EQ(a[2], 1); + EXPECT_EQ(a[3], 2); a[2] = 4; - ASSERT_EQ(a[2], 4); + EXPECT_EQ(a[2], 4); } -UTEST(Vec_int, copy) { +TEST(Vec_int, copy) { std::array arr{1, 3, 1, 2}; Vec a(arr); Vec expected{1, 3, 1, 2}; - ASSERT_TRUE(a == expected); + EXPECT_EQ(a, expected); std::array out{-1, -3, -1, -2}; std::copy(a.begin(), a.end(), out.begin()); - ASSERT_TRUE(out == arr); + EXPECT_EQ(out, arr); } // endregion } // namespace quicktex::tests \ No newline at end of file diff --git a/quicktex/ctests/TestSIMD.cpp b/tests/ctest/TestSIMD.cpp similarity index 84% rename from quicktex/ctests/TestSIMD.cpp rename to tests/ctest/TestSIMD.cpp index cf41118..0d57173 100644 --- a/quicktex/ctests/TestSIMD.cpp +++ b/tests/ctest/TestSIMD.cpp @@ -17,7 +17,10 @@ along with this program. If not, see . */ -#include +#include +#include +#include +#include #include #include @@ -26,10 +29,6 @@ #include #include -#include "util/math.h" -#include "util/simd.h" -#include "util/types.h" - namespace quicktex::tests { template constexpr auto make_arrays() { @@ -62,21 +61,21 @@ template constexpr auto make_arrays() { return arrays; } -#define UTEST_WHADD(TYPE) \ - UTEST(simd, whadd_##TYPE) { \ +#define TEST_WHADD(TYPE) \ + TEST(simd, whadd_##TYPE) { \ for (auto arr : make_arrays()) { \ auto v = xsimd::load_unaligned(&arr[0]); \ auto vsum = simd::whadd(v); \ auto ssum = std::accumulate(arr.begin(), arr.end(), static_cast>(0)); \ - ASSERT_EQ(vsum, ssum); \ + EXPECT_EQ(vsum, ssum); \ } \ } -UTEST_WHADD(int8_t) -UTEST_WHADD(uint8_t) -UTEST_WHADD(int16_t) -UTEST_WHADD(uint16_t) -UTEST_WHADD(int32_t) -UTEST_WHADD(uint32_t) +TEST_WHADD(int8_t) +TEST_WHADD(uint8_t) +TEST_WHADD(int16_t) +TEST_WHADD(uint16_t) +TEST_WHADD(int32_t) +TEST_WHADD(uint32_t) } // namespace quicktex::tests \ No newline at end of file diff --git a/tests/test_ctest.py b/tests/test_ctest.py deleted file mode 100644 index 64e6b21..0000000 --- a/tests/test_ctest.py +++ /dev/null @@ -1,5 +0,0 @@ -from _quicktex import _run_ctests - - -def test_ctests(): - _run_ctests()