371 lines
9.3 KiB
C++
371 lines
9.3 KiB
C++
// Copyright 2009 Intel Corporation
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
#pragma once
|
|
|
|
#include "../include/OpenImageDenoise/config.h"
|
|
|
|
// -------------------------------------------------------------------------------------------------
|
|
// Macros
|
|
// -------------------------------------------------------------------------------------------------
|
|
|
|
#if defined(__x86_64__) || defined(_M_X64)
|
|
#define OIDN_ARCH_X64
|
|
#elif defined(__aarch64__) || defined(_M_ARM64)
|
|
#define OIDN_ARCH_ARM64
|
|
#endif
|
|
|
|
#if defined(SYCL_LANGUAGE_VERSION)
|
|
#define OIDN_COMPILE_SYCL
|
|
#endif
|
|
#if defined(__SYCL_DEVICE_ONLY__)
|
|
#define OIDN_COMPILE_SYCL_DEVICE
|
|
#endif
|
|
|
|
#if defined(__CUDACC__)
|
|
#define OIDN_COMPILE_CUDA
|
|
#endif
|
|
#if defined(__CUDA_ARCH__)
|
|
#define OIDN_COMPILE_CUDA_DEVICE
|
|
#endif
|
|
|
|
#if defined(__HIPCC__)
|
|
#define OIDN_COMPILE_HIP
|
|
#endif
|
|
#if defined(__HIP_DEVICE_COMPILE__)
|
|
#define OIDN_COMPILE_HIP_DEVICE
|
|
#endif
|
|
|
|
#if defined(__METAL_VERSION__)
|
|
#define OIDN_COMPILE_METAL_DEVICE
|
|
#endif
|
|
#if defined(OIDN_COMPILE_METAL_HOST) || defined(OIDN_COMPILE_METAL_DEVICE)
|
|
#define OIDN_COMPILE_METAL
|
|
#endif
|
|
|
|
#if defined(OIDN_COMPILE_SYCL_DEVICE) || defined(OIDN_COMPILE_CUDA_DEVICE) || \
|
|
defined(OIDN_COMPILE_HIP_DEVICE) || defined(OIDN_COMPILE_METAL_DEVICE)
|
|
#define OIDN_COMPILE_DEVICE
|
|
#endif
|
|
|
|
#if defined(_WIN32)
|
|
// Windows
|
|
#define oidn_inline __forceinline
|
|
#define oidn_noinline __declspec(noinline)
|
|
#else
|
|
// Unix
|
|
#define oidn_inline inline __attribute__((always_inline))
|
|
#define oidn_noinline __attribute__((noinline))
|
|
#endif
|
|
|
|
#ifndef UNUSED
|
|
#define UNUSED(x) ((void)x)
|
|
#endif
|
|
#ifndef MAYBE_UNUSED
|
|
#define MAYBE_UNUSED(x) UNUSED(x)
|
|
#endif
|
|
|
|
#if defined(OIDN_COMPILE_CUDA) || defined(OIDN_COMPILE_HIP)
|
|
#define oidn_device __device__
|
|
#define oidn_device_inline __device__ oidn_inline
|
|
#define oidn_host_device __host__ __device__
|
|
#define oidn_host_device_inline __host__ __device__ oidn_inline
|
|
#define oidn_constant
|
|
#define oidn_global
|
|
#define oidn_local
|
|
#define oidn_private
|
|
#else
|
|
#define oidn_device
|
|
#define oidn_device_inline oidn_inline
|
|
#define oidn_host_device
|
|
#define oidn_host_device_inline oidn_inline
|
|
#if defined(OIDN_COMPILE_METAL_DEVICE)
|
|
#define oidn_constant constant
|
|
#define oidn_global device
|
|
#define oidn_local threadgroup
|
|
#define oidn_private thread
|
|
#else
|
|
#define oidn_constant
|
|
#define oidn_global
|
|
#define oidn_local
|
|
#define oidn_private
|
|
#endif
|
|
#endif
|
|
|
|
// Helper string macros
|
|
#define _OIDN_TO_STRING(a) #a
|
|
#define OIDN_TO_STRING(a) _OIDN_TO_STRING(a)
|
|
|
|
#define _OIDN_CONCAT(a, b) a##b
|
|
#define OIDN_CONCAT(a, b) _OIDN_CONCAT(a, b)
|
|
|
|
// -------------------------------------------------------------------------------------------------
|
|
// Includes
|
|
// -------------------------------------------------------------------------------------------------
|
|
|
|
#if defined(OIDN_COMPILE_METAL_DEVICE)
|
|
#include <metal_stdlib>
|
|
#else
|
|
#if defined(_WIN32)
|
|
#if !defined(WIN32_LEAN_AND_MEAN)
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#endif
|
|
#if !defined(NOMINMAX)
|
|
#define NOMINMAX
|
|
#endif
|
|
#include <Windows.h>
|
|
#elif defined(__APPLE__)
|
|
#include <sys/sysctl.h>
|
|
#include <TargetConditionals.h>
|
|
#endif
|
|
|
|
#if defined(OIDN_ARCH_X64)
|
|
#include <xmmintrin.h>
|
|
#include <pmmintrin.h>
|
|
#endif
|
|
|
|
#include <cstdint>
|
|
#include <cstddef>
|
|
#include <cstdlib>
|
|
#include <climits>
|
|
#include <cstring>
|
|
#include <limits>
|
|
#include <atomic>
|
|
#include <algorithm>
|
|
#include <memory>
|
|
#include <array>
|
|
#include <type_traits>
|
|
#include <cmath>
|
|
#include <cfloat>
|
|
#include <string>
|
|
#include <sstream>
|
|
#include <iostream>
|
|
#include <cassert>
|
|
#include <stdexcept>
|
|
|
|
#if defined(OIDN_COMPILE_SYCL)
|
|
#include <sycl/sycl.hpp>
|
|
#include <sycl/ext/intel/esimd.hpp>
|
|
#elif defined(OIDN_COMPILE_CUDA)
|
|
#include <cuda_fp16.h>
|
|
#elif defined(OIDN_COMPILE_HIP)
|
|
#include <hip/hip_runtime.h>
|
|
#include <hip/hip_fp16.h>
|
|
#else
|
|
#include "half.h"
|
|
#endif
|
|
#endif
|
|
|
|
OIDN_NAMESPACE_BEGIN
|
|
|
|
#if defined(OIDN_COMPILE_SYCL)
|
|
namespace syclx = sycl::ext::intel::experimental;
|
|
namespace esimd = sycl::ext::intel::esimd;
|
|
namespace esimdx = sycl::ext::intel::experimental::esimd;
|
|
|
|
using sycl::half;
|
|
using namespace esimd;
|
|
using namespace esimdx;
|
|
#endif
|
|
|
|
#if !defined(OIDN_COMPILE_METAL_DEVICE)
|
|
template<bool B, class T = void>
|
|
using enable_if_t = typename std::enable_if<B, T>::type;
|
|
#endif
|
|
|
|
// -----------------------------------------------------------------------------------------------
|
|
// Common functions
|
|
// -----------------------------------------------------------------------------------------------
|
|
|
|
template<typename T>
|
|
oidn_host_device_inline constexpr T min(T a, T b) { return (b < a) ? b : a; }
|
|
|
|
template<typename T>
|
|
oidn_host_device_inline constexpr T max(T a, T b) { return (a < b) ? b : a; }
|
|
|
|
template<typename T>
|
|
oidn_host_device_inline constexpr T clamp(T x, T minVal, T maxVal)
|
|
{
|
|
return min(max(x, minVal), maxVal);
|
|
}
|
|
|
|
// Returns ceil(a / b) for non-negative integers
|
|
template<typename Int, typename IntB>
|
|
oidn_host_device_inline constexpr Int ceil_div(Int a, IntB b)
|
|
{
|
|
//assert(a >= 0);
|
|
//assert(b > 0);
|
|
return (a + b - 1) / b;
|
|
}
|
|
|
|
// Returns a rounded up to multiple of b
|
|
template<typename Int, typename IntB>
|
|
oidn_host_device_inline constexpr Int round_up(Int a, IntB b)
|
|
{
|
|
return ceil_div(a, b) * b;
|
|
}
|
|
|
|
// Returns the smallest integer larger than or equal to a which has remainder c when divided by b
|
|
template<typename Int, typename IntB>
|
|
oidn_host_device_inline constexpr Int round_up(Int a, IntB b, IntB c)
|
|
{
|
|
//assert(a >= 0);
|
|
//assert(b > 0);
|
|
//assert(c >= 0 && c < b);
|
|
return (a + b - c - 1) / b * b + c;
|
|
}
|
|
|
|
// Returns the greatest common divisor of a and b
|
|
template<typename Int>
|
|
oidn_host_device_inline Int gcd(Int a, Int b)
|
|
{
|
|
while (b != 0)
|
|
{
|
|
const Int t = b;
|
|
b = a % b;
|
|
a = t;
|
|
}
|
|
return a;
|
|
}
|
|
|
|
// Returns the least common multiple of a and b
|
|
template<typename Int>
|
|
oidn_host_device_inline Int lcm(Int a, Int b)
|
|
{
|
|
return (a * b) / gcd(a, b);
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------------------------
|
|
// Data type
|
|
// -----------------------------------------------------------------------------------------------
|
|
|
|
// Data types sorted by precision in ascending order
|
|
enum class DataType
|
|
{
|
|
Undefined,
|
|
UInt8,
|
|
Float16,
|
|
Float32,
|
|
};
|
|
|
|
#if !defined(OIDN_COMPILE_METAL_DEVICE)
|
|
|
|
std::ostream& operator <<(std::ostream& sm, DataType dataType);
|
|
|
|
// -----------------------------------------------------------------------------------------------
|
|
// Memory allocation
|
|
// -----------------------------------------------------------------------------------------------
|
|
|
|
struct SizeAndAlignment
|
|
{
|
|
size_t size;
|
|
size_t alignment;
|
|
};
|
|
|
|
constexpr size_t memoryAlignment = 256;
|
|
|
|
void* alignedMalloc(size_t size, size_t alignment = memoryAlignment);
|
|
void alignedFree(void* ptr);
|
|
|
|
static_assert(sizeof(size_t) == 8, "size_t is not 64-bit!");
|
|
|
|
// -----------------------------------------------------------------------------------------------
|
|
// String functions
|
|
// -----------------------------------------------------------------------------------------------
|
|
|
|
template<typename T>
|
|
inline std::string toString(const T& a)
|
|
{
|
|
std::stringstream sm;
|
|
sm << a;
|
|
return sm.str();
|
|
}
|
|
|
|
template<typename T>
|
|
inline T fromString(const std::string& str)
|
|
{
|
|
std::stringstream sm(str);
|
|
T a{};
|
|
sm >> a;
|
|
return a;
|
|
}
|
|
|
|
template<>
|
|
inline std::string fromString(const std::string& str)
|
|
{
|
|
return str;
|
|
}
|
|
|
|
inline std::string toLower(const std::string& str)
|
|
{
|
|
std::string result = str;
|
|
std::transform(str.begin(), str.end(), result.begin(), ::tolower);
|
|
return result;
|
|
}
|
|
|
|
#if defined(__APPLE__)
|
|
template<typename T>
|
|
inline bool getSysctl(const char* name, T& value)
|
|
{
|
|
int64_t result = 0;
|
|
size_t size = sizeof(result);
|
|
|
|
if (sysctlbyname(name, &result, &size, nullptr, 0) != 0)
|
|
return false;
|
|
|
|
value = T(result);
|
|
return true;
|
|
}
|
|
#endif
|
|
|
|
inline bool isEnvVar(const std::string& name)
|
|
{
|
|
auto* str = getenv(name.c_str());
|
|
return (str != nullptr);
|
|
}
|
|
|
|
template<typename T>
|
|
inline bool getEnvVar(const std::string& name, T& value)
|
|
{
|
|
auto* str = getenv(name.c_str());
|
|
bool found = (str != nullptr);
|
|
if (found)
|
|
value = fromString<T>(str);
|
|
return found;
|
|
}
|
|
|
|
template<typename T>
|
|
inline T getEnvVarOrDefault(const std::string& name, const T& defaultValue)
|
|
{
|
|
T value = defaultValue;
|
|
getEnvVar(name, value);
|
|
return value;
|
|
}
|
|
|
|
template<typename T>
|
|
inline bool setEnvVar(const std::string& name, const T& value, bool overwrite)
|
|
{
|
|
const std::string valueStr = toString(value);
|
|
#if defined(_WIN32)
|
|
if (overwrite || !isEnvVar(name))
|
|
return _putenv_s(name.c_str(), valueStr.c_str()) == 0;
|
|
else
|
|
return true;
|
|
#else
|
|
return setenv(name.c_str(), valueStr.c_str(), overwrite) == 0;
|
|
#endif
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------------------------
|
|
// System information
|
|
// -----------------------------------------------------------------------------------------------
|
|
|
|
std::string getOSName();
|
|
std::string getCompilerName();
|
|
std::string getBuildName();
|
|
|
|
#endif // !defined(OIDN_COMPILE_METAL_DEVICE)
|
|
|
|
OIDN_NAMESPACE_END
|
|
|