From 46d426a0a7765855e882e1c993542ace54ce1bdc Mon Sep 17 00:00:00 2001 From: Larry Gritz Date: Thu, 9 Apr 2026 17:24:46 -0700 Subject: [PATCH] testing: hwy testing strategies 1. Some tests are repeated, run once with hwy off and once with hwy on. The "on" version append ".hwy" to the test name and set the OPENIMAGEIO_ENABLE_HWY=1 environment variable to force it on while running the test. The advantage to this approach is that the test itself doesn't need to change at all, we just run it separately in each mode. In this PR, I do this with oiiotool, oiiotool-xform, and docs-examples-cpp. For now, while hwy is not enabled by default, it's doing these extra things to enable hwy. Eventually, if/when hwy is enabled by default, we'll flip the sense and use the env variable to turn it off. 2. Some tests do certain operations both ways when hwy support was enabled at build time. This is more convenient for certain unit test executables, where perhaps we want to benchmark both ways and have those show up right next to each other within the run. In this PR, I do this with the imagebufalgo_test unit test. Signed-off-by: Larry Gritz --- CMakeLists.txt | 2 +- src/cmake/testing.cmake | 39 ++++++++++++++++++++++-- src/libOpenImageIO/CMakeLists.txt | 1 + src/libOpenImageIO/imagebufalgo_test.cpp | 31 ++++++++++++++----- 4 files changed, 62 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 46527cbca0..dd24534c94 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -112,7 +112,7 @@ else () endif () option (${PROJ_NAME}_BUILD_TOOLS "Build the command-line tools" ON) option (${PROJ_NAME}_BUILD_TESTS "Build the unit tests" ON) -set_option (OIIO_USE_HWY "Enable experimental Google Highway SIMD optimizations (if Highway is available)" OFF) +set_option (OIIO_USE_HWY "Enable experimental Google Highway SIMD optimizations (if Highway is available)" OFF VERBOSE) set (OIIO_LIBNAME_SUFFIX "" CACHE STRING "Optional name appended to ${PROJECT_NAME} libraries that are built") option (BUILD_OIIOUTIL_ONLY "If ON, will build *only* libOpenImageIO_Util" OFF) diff --git a/src/cmake/testing.cmake b/src/cmake/testing.cmake index a954a83d21..a209c50524 100644 --- a/src/cmake/testing.cmake +++ b/src/cmake/testing.cmake @@ -30,6 +30,7 @@ set(OIIO_TESTSUITE_IMAGEDIR "${PROJECT_BINARY_DIR}/testsuite" CACHE PATH # [ URL http://find.reference.cases.here.com ] # [ FOUNDVAR variable_name ... ] # [ ENABLEVAR variable_name ... ] +# [ DISABLEVAR variable_name ... ] # [ SUFFIX suffix ] # [ ENVIRONMENT "VAR=value" ... ] # ) @@ -43,7 +44,11 @@ set(OIIO_TESTSUITE_IMAGEDIR "${PROJECT_BINARY_DIR}/testsuite" CACHE PATH # not existing and true, will skip the test. # # The optional ENABLEVAR introduces variables (typically ENABLE_Foo) that -# if existing and yet false, will skip the test. +# if existing and yet false/off/zero, will skip the test. (Not existing +# does NOT disable the test.) +# +# The optional DISABLEVAR introduces variables that, if existing and +# true/on/nonzero, will skip the test. # # The optional SUFFIX is appended to the test name. # @@ -51,7 +56,7 @@ set(OIIO_TESTSUITE_IMAGEDIR "${PROJECT_BINARY_DIR}/testsuite" CACHE PATH # test. # macro (oiio_add_tests) - cmake_parse_arguments (_ats "" "SUFFIX;TESTNAME" "URL;IMAGEDIR;LABEL;FOUNDVAR;ENABLEVAR;ENVIRONMENT" ${ARGN}) + cmake_parse_arguments (_ats "" "SUFFIX;TESTNAME" "URL;IMAGEDIR;LABEL;FOUNDVAR;ENABLEVAR;DISABLEVAR;ENVIRONMENT" ${ARGN}) # Arguments: args... set (_ats_testdir "${OIIO_TESTSUITE_IMAGEDIR}/${_ats_IMAGEDIR}") # If there was a FOUNDVAR param specified and that variable name is @@ -59,6 +64,7 @@ macro (oiio_add_tests) set (_test_disabled FALSE) set (_test_notfound FALSE) foreach (_var ${_ats_FOUNDVAR}) + # FOUNDVAR entires had better exist and be true if (NOT ${_var}) set (_ats_LABEL "broken") set (_test_notfound TRUE) @@ -66,12 +72,20 @@ macro (oiio_add_tests) endforeach () set (_test_disabled 0) foreach (_var ${_ats_ENABLEVAR}) + # ENABLEVAR, *if* it exists, must be true. But not existing is fine. if ((NOT "${${_var}}" STREQUAL "" AND NOT "${${_var}}") OR (NOT "$ENV{${_var}}" STREQUAL "" AND NOT "$ENV{${_var}}")) set (_ats_LABEL "broken") set (_test_disabled TRUE) endif () endforeach () + foreach (_var ${_ats_DISABLEVAR}) + # DISABLEVAR, if true, disable the test. Not existing is fine. + if (${_var}) + set (_ats_LABEL "broken") + set (_test_disabled TRUE) + endif () + endforeach () # For OCIO 2.2+, have the testsuite use the default built-in config list (APPEND _ats_ENVIRONMENT "OCIO=ocio://default" "OIIO_TESTSUITE_OCIOCONFIG=ocio://default") @@ -238,6 +252,27 @@ macro (oiio_add_all_tests) oiio_add_tests (oiiotool-color FOUNDVAR OpenColorIO_FOUND) + # Tests to run with HWY enabled. + # Remember to add tests here as hwy enabled IBA functions are added + oiio_add_tests ( oiiotool + oiiotool-composite + oiiotool-xform + docs-examples-cpp + FOUNDVAR hwy_FOUND + ENABLEVAR OIIO_USE_HWY + SUFFIX ".hwy" + ENVIRONMENT "OPENIMAGEIO_ENABLE_HWY=1" + ) + + oiio_add_tests ( python-imagebufalgo + FOUNDVAR hwy_FOUND + ENABLEVAR OIIO_USE_HWY USE_PYTHON + DISABLEVAR BUILD_OIIOUTIL_ONLY SANITIZE + SUFFIX ".hwy" + ENVIRONMENT "OPENIMAGEIO_ENABLE_HWY=1" + IMAGEDIR oiio-images + ) + # List testsuites for specific formats or features which might be not found # or be intentionally disabled, or which need special external reference # images from the web that if not found, should skip the tests: diff --git a/src/libOpenImageIO/CMakeLists.txt b/src/libOpenImageIO/CMakeLists.txt index 262c85f4dd..04fcf58f2f 100644 --- a/src/libOpenImageIO/CMakeLists.txt +++ b/src/libOpenImageIO/CMakeLists.txt @@ -282,6 +282,7 @@ if (OIIO_BUILD_TESTS AND BUILD_TESTING) ${OpenCV_LIBRARIES} ${OPENIMAGEIO_IMATH_TARGETS} FOLDER "Unit Tests" NO_INSTALL) + target_compile_definitions (imagebufalgo_test PRIVATE OIIO_USE_HWY=${_oiio_use_hwy}) add_test (unit_imagebufalgo ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/imagebufalgo_test) fancy_add_executable (NAME imagespec_test SRC imagespec_test.cpp diff --git a/src/libOpenImageIO/imagebufalgo_test.cpp b/src/libOpenImageIO/imagebufalgo_test.cpp index cf9c0de7bf..763ece2577 100644 --- a/src/libOpenImageIO/imagebufalgo_test.cpp +++ b/src/libOpenImageIO/imagebufalgo_test.cpp @@ -43,6 +43,10 @@ static bool wedge = false; static int threadcounts[] = { 1, 2, 4, 8, 12, 16, 20, 24, 28, 32, 64, 128, 1024, 1 << 30 }; +static const int hwy_build = OIIO_USE_HWY; +static int hwy_on = hwy_build; + + static void getargs(int argc, char* argv[]) @@ -403,7 +407,7 @@ test_channel_append() void test_add() { - std::cout << "test add\n"; + print("test add{}\n", hwy_on ? " (HWY)" : ""); // Create buffers const float Aval[] = { 0.1f, 0.2f, 0.3f, 0.4f }; @@ -429,7 +433,7 @@ test_add() void test_sub() { - std::cout << "test sub\n"; + print("test sub{}\n", hwy_on ? " (HWY)" : ""); // Create buffers const float Aval[] = { 0.1f, 0.2f, 0.3f, 0.4f }; @@ -455,7 +459,7 @@ test_sub() void test_mul() { - std::cout << "test mul\n"; + print("test mul{}\n", hwy_on ? " (HWY)" : ""); // Create buffers // Create buffers @@ -482,7 +486,7 @@ test_mul() void test_mad() { - std::cout << "test mad\n"; + print("test mad{}\n", hwy_on ? " (HWY)" : ""); const int WIDTH = 4, HEIGHT = 4, CHANNELS = 4; ImageSpec spec(WIDTH, HEIGHT, CHANNELS, TypeDesc::FLOAT); @@ -1678,6 +1682,17 @@ test_demosaic() } + +// clang-format off +// Neat trick macro to prefix in front of the calls where we want to +// run it in both hwy and non-hwy modes. It will loop over both settings. +#define HWY_TEST \ + for (hwy_on = 0; hwy_on <= hwy_build; ++hwy_on) \ + OIIO::attribute("enable_hwy", hwy_on), /* next command */ +// clang-format on + + + int main(int argc, char** argv) { @@ -1702,10 +1717,10 @@ main(int argc, char** argv) test_crop(); test_paste(); test_channel_append(); - test_add(); - test_sub(); - test_mul(); - test_mad(); + HWY_TEST test_add(); + HWY_TEST test_sub(); + HWY_TEST test_mul(); + HWY_TEST test_mad(); test_hwy_strided_roi_fallback(); test_min(); test_max();