Files
caa20dd196 Adsk contrib - Add support for neon intrinsic integration (#1828)
* Merging the previous ARM Neon branch

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>

* Testing each SIMD variants using a small code snippet and first pass on unifying the way related cmake variables

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>

* Removing the usage of USE_SSE in favor of the new OCIO_USE_SSE2 as they serve the same purpose

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>

* Using try_compile instead of check_cxx_source_compiles as it was given false positive.  Stubbing cpuinfo for Apple ARM plateform. Handling Apple M1 correctly and adding support for SSE2NEON.

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>

* Comments clean up and refactor some comments and documentations

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>

* Added something in the documentation for Rosetta and small change in cmake

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>

* Fixing the build under Rosetta and fixing issue in the MacOS CI.

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>

* Using try_compile for CheckSupportSSEUsingSSE2NEON to standardize the code and fixed CheckSupport compiler flags.

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>

* use emmintrin.h for only sse2 features

Signed-off-by: Mark Reid <mindmark@gmail.com>
Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>

* Allow F16C to be completely turned off

Signed-off-by: Mark Reid <mindmark@gmail.com>
Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>

* Seperate SIMD test code from code that adds unit tests.

This isolates the compulation units and
avoids executing illegal hardware instructions

Signed-off-by: Mark Reid <mindmark@gmail.com>
Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>

* remove uneeded checks

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>

* use software implementations of f16c intrinsics for SSE2

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>

* Added preprocessor checks for ARM as it is needed for universal build on APPLE platform

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>

* Adding missing checks for "not arm64"

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>

* Ease the future maintainability a the new OCIO_USE_xyz be moving the logic into CPUInfoConfig.h.in as well as fixing issue on ARM when building with OCIO_USE_SSE2NEON=OFF.

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>

* Fixing some spacing, documentations and making some cmake conditions clearer.

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>

* Adding a build in ci_workflow for macos USE_OCIO_SSE2NEON=OFF

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>

* typo

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>

* Changing back all the macOS (except one) builds to x86_64 only as it takes double the time to do the universal build.
OCIO no longuer build a universal binary by default

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>

* Update the CMakeLists.txt logic to accomodate all scenario and fixing documentations.

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>

* Update documentation and remove ocio_use_sse2neon from the CI matrix

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>

---------

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
Signed-off-by: Mark Reid <mindmark@gmail.com>
Signed-off-by: Cédrik Fuoco <105517825+cedrik-fuoco-adsk@users.noreply.github.com>
Co-authored-by: Mark Reid <mindmark@gmail.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
2023-08-31 21:10:29 -04:00

354 lines
9.8 KiB
C++

// SPDX-License-Identifier: BSD-3-Clause
// Copyright Contributors to the OpenColorIO Project.
#include <OpenColorIO/OpenColorIO.h>
#include <math.h>
#include "GPUUnitTest.h"
namespace OCIO = OCIO_NAMESPACE;
#if OCIO_USE_SSE2
const float g_epsilon = 1e-4f;
const float g_epsilon_inverse = 1e-3f;
#else
const float g_epsilon = 1e-5f;
const float g_epsilon_inverse = 1e-4f;
#endif
const float base10 = 10.0f;
const float eulerConstant = expf(1.0f);
// Helper method to build unit tests
void AddLogTest(OCIOGPUTest & test,
OCIO::TransformDirection direction,
float base,
float epsilon)
{
OCIO::LogTransformRcPtr log = OCIO::LogTransform::Create();
log->setDirection(direction);
log->setBase(base);
test.setProcessor(log);
test.setErrorThreshold(epsilon);
// TODO: Would like to be able to remove the setTestNaN(false) and
// setTestInfinity(false) from all of these tests.
test.setTestInfinity(false);
}
OCIO_ADD_GPU_TEST(LogTransform, LogBase_10_legacy)
{
AddLogTest(test, OCIO::TRANSFORM_DIR_FORWARD, base10, g_epsilon);
test.setLegacyShader(true);
// TODO: Would like to be able to remove the setTestNaN(false) from all of these tests.
test.setTestNaN(false);
}
OCIO_ADD_GPU_TEST(LogTransform, LogBase_10_legacy_inverse)
{
AddLogTest(test, OCIO::TRANSFORM_DIR_INVERSE, base10, g_epsilon_inverse);
test.setLegacyShader(true);
test.setTestNaN(false);
}
OCIO_ADD_GPU_TEST(LogTransform, LogBase_10_generic_shader)
{
AddLogTest(test, OCIO::TRANSFORM_DIR_FORWARD, base10, g_epsilon);
test.setTestNaN(false);
}
OCIO_ADD_GPU_TEST(LogTransform, LogBase_10_inverse_generic_shader)
{
AddLogTest(test, OCIO::TRANSFORM_DIR_INVERSE, base10, g_epsilon_inverse);
test.setTestNaN(false);
}
OCIO_ADD_GPU_TEST(LogTransform, LogBase_euler_legacy)
{
AddLogTest(test, OCIO::TRANSFORM_DIR_FORWARD, eulerConstant, g_epsilon);
test.setLegacyShader(true);
test.setTestNaN(false);
}
OCIO_ADD_GPU_TEST(LogTransform, LogBase_euler_legacy_inverse)
{
AddLogTest(test, OCIO::TRANSFORM_DIR_INVERSE, eulerConstant, g_epsilon_inverse);
test.setLegacyShader(true);
test.setTestNaN(false);
}
OCIO_ADD_GPU_TEST(LogTransform, LogBase_euler_generic_shader)
{
AddLogTest(test, OCIO::TRANSFORM_DIR_FORWARD, eulerConstant, g_epsilon);
test.setTestNaN(false);
}
OCIO_ADD_GPU_TEST(LogTransform, LogBase_euler_inverse_generic_shader)
{
AddLogTest(test, OCIO::TRANSFORM_DIR_INVERSE, eulerConstant, g_epsilon_inverse);
test.setTestNaN(false);
}
OCIO_ADD_GPU_TEST(LogAffineTransform, base)
{
OCIO::LogAffineTransformRcPtr log = OCIO::LogAffineTransform::Create();
log->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
log->setBase(base10);
test.setProcessor(log);
test.setErrorThreshold(g_epsilon);
test.setTestInfinity(false);
}
OCIO_ADD_GPU_TEST(LogAffineTransform, base_inverse)
{
OCIO::LogAffineTransformRcPtr log = OCIO::LogAffineTransform::Create();
log->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
log->setBase(base10);
test.setProcessor(log);
test.setErrorThreshold(g_epsilon); // Use the tighter tolerance than g_epsilon_inverse
test.setRelativeComparison(true);
test.setTestNaN(false);
test.setTestInfinity(false);
}
OCIO_ADD_GPU_TEST(LogAffineTransform, linSideSlope)
{
OCIO::LogAffineTransformRcPtr log = OCIO::LogAffineTransform::Create();
log->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
const double linSideSlope[3] = {2.0, 0.5, 3.0};
log->setLinSideSlopeValue(linSideSlope);
test.setProcessor(log);
test.setErrorThreshold(g_epsilon);
test.setTestInfinity(false);
}
OCIO_ADD_GPU_TEST(LogAffineTransform, linSideSlope_inverse)
{
OCIO::LogAffineTransformRcPtr log = OCIO::LogAffineTransform::Create();
log->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
const double linSideSlope[3] = { 2.0, 0.5, 3.0 };
log->setLinSideSlopeValue(linSideSlope);
test.setProcessor(log);
test.setErrorThreshold(g_epsilon); // Use the tighter tolerance than g_epsilon_inverse
test.setTestNaN(false);
test.setTestInfinity(false);
}
OCIO_ADD_GPU_TEST(LogAffineTransform, linSideOffset)
{
OCIO::LogAffineTransformRcPtr log = OCIO::LogAffineTransform::Create();
log->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
const double linSideOffset[3] = { 0.1, 0.2, 0.3 };
log->setLinSideOffsetValue(linSideOffset);
test.setProcessor(log);
test.setErrorThreshold(g_epsilon);
test.setTestInfinity(false);
}
OCIO_ADD_GPU_TEST(LogAffineTransform, linSideOffset_inverse)
{
OCIO::LogAffineTransformRcPtr log = OCIO::LogAffineTransform::Create();
log->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
const double linSideOffset[3] = { 0.1, 0.2, 0.3 };
log->setLinSideOffsetValue(linSideOffset);
test.setProcessor(log);
test.setErrorThreshold(g_epsilon); // Use the tighter tolerance than g_epsilon_inverse
test.setTestNaN(false);
test.setTestInfinity(false);
}
OCIO_ADD_GPU_TEST(LogAffineTransform, logSideSlope)
{
OCIO::LogAffineTransformRcPtr log = OCIO::LogAffineTransform::Create();
log->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
const double logSideSlope[3] = { 2.0, 0.5, 3.0 };
log->setLogSideSlopeValue(logSideSlope);
test.setProcessor(log);
test.setErrorThreshold(g_epsilon * 5.0f);
test.setTestInfinity(false);
}
OCIO_ADD_GPU_TEST(LogAffineTransform, logSideSlope_inverse)
{
OCIO::LogAffineTransformRcPtr log = OCIO::LogAffineTransform::Create();
log->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
const double logSideSlope[3] = { 2.0, 0.5, 3.0 };
log->setLogSideSlopeValue(logSideSlope);
test.setProcessor(log);
test.setErrorThreshold(g_epsilon); // Use the tighter tolerance than g_epsilon_inverse
test.setTestNaN(false);
test.setTestInfinity(false);
}
OCIO_ADD_GPU_TEST(LogAffineTransform, logSideOffset)
{
OCIO::LogAffineTransformRcPtr log = OCIO::LogAffineTransform::Create();
log->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
const double logSideOffset[3] = { 0.1, 0.2, 0.3 };
log->setLogSideOffsetValue(logSideOffset);
test.setProcessor(log);
test.setErrorThreshold(g_epsilon);
test.setTestInfinity(false);
}
OCIO_ADD_GPU_TEST(LogAffineTransform, logSideOffset_inverse)
{
OCIO::LogAffineTransformRcPtr log = OCIO::LogAffineTransform::Create();
log->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
const double logSideOffset[3] = { 0.1, 0.2, 0.3 };
log->setLogSideOffsetValue(logSideOffset);
test.setProcessor(log);
test.setErrorThreshold(g_epsilon); // Use the tighter tolerance than g_epsilon_inverse
test.setTestNaN(false);
test.setTestInfinity(false);
}
OCIO_ADD_GPU_TEST(LogAffineTransform, lin2log)
{
OCIO::LogAffineTransformRcPtr log = OCIO::LogAffineTransform::Create();
log->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
const double logSideSlope[3] = { 0.2, 0.4, 0.25 };
log->setLogSideSlopeValue(logSideSlope);
const double logSideOffset[3] = { 0.14, 0.13, 0.12 };
log->setLogSideOffsetValue(logSideOffset);
const double linSideSlope[3] = { 1.5, 1.8, 1.2 };
log->setLinSideSlopeValue(linSideSlope);
const double linSideOffset[3] = { 0.05, 0.1, 0.15 };
log->setLinSideOffsetValue(linSideOffset);
test.setProcessor(log);
test.setErrorThreshold(g_epsilon * 5.0f);
test.setTestInfinity(false);
}
OCIO_ADD_GPU_TEST(LogAffineTransform, log2lin)
{
OCIO::LogAffineTransformRcPtr log = OCIO::LogAffineTransform::Create();
log->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
const double logSideSlope[3] = { 0.21, 0.2, 0.19 };
log->setLogSideSlopeValue(logSideSlope);
const double logSideOffset[3] = { 0.61, 0.6, 0.59 };
log->setLogSideOffsetValue(logSideOffset);
const double linSideSlope[3] = { 1.11, 1.1, 1.12 };
log->setLinSideSlopeValue(linSideSlope);
const double linSideOffset[3] = { 0.051, 0.05, 0.052 };
log->setLinSideOffsetValue(linSideOffset);
test.setProcessor(log);
test.setErrorThreshold(g_epsilon_inverse);
test.setTestInfinity(false);
}
OCIO_ADD_GPU_TEST(LogCameraTransform, camera_lin2log)
{
const double linSideBreak[3] = { 0.12, 0.13, 0.15 };
OCIO::LogCameraTransformRcPtr log = OCIO::LogCameraTransform::Create(linSideBreak);
log->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
const double logSideSlope[3] = { 0.2, 0.3, 0.4 };
log->setLogSideSlopeValue(logSideSlope);
const double logSideOffset[3] = { 0.7, 0.6, 0.5 };
log->setLogSideOffsetValue(logSideOffset);
const double linSideSlope[3] = { 1.4, 1.1, 1.2 };
log->setLinSideSlopeValue(linSideSlope);
const double linSideOffset[3] = { 0.15, 0.16, 0.25 };
log->setLinSideOffsetValue(linSideOffset);
const double linearSlope[3] = { 1.22, 1.33, 1.44 };
log->setLinearSlopeValue(linearSlope);
test.setProcessor(log);
test.setErrorThreshold(g_epsilon);
#ifdef __APPLE__
test.setTestNaN(false);
test.setTestInfinity(false);
#endif
}
OCIO_ADD_GPU_TEST(LogCameraTransform, camera_log2lin)
{
const double linSideBreak[3] = { 0.12, 0.13, 0.14 };
OCIO::LogCameraTransformRcPtr log = OCIO::LogCameraTransform::Create(linSideBreak);
log->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
const double logSideSlope[3] = { 0.21, 0.22, 0.23 };
log->setLogSideSlopeValue(logSideSlope);
const double logSideOffset[3] = { 0.6, 0.7, 0.8 };
log->setLogSideOffsetValue(logSideOffset);
const double linSideSlope[3] = { 1.1, 1.2, 1.3 };
log->setLinSideSlopeValue(linSideSlope);
const double linSideOffset[3] = { 0.051, 0.052, 0.053 };
log->setLinSideOffsetValue(linSideOffset);
const double linearSlope[3] = { 1.25, 1.23, 1.22 };
log->setLinearSlopeValue(linearSlope);
test.setProcessor(log);
test.setErrorThreshold(g_epsilon_inverse);
#ifdef __APPLE__
test.setTestNaN(false);
test.setTestInfinity(false);
#endif
}