| | #pragma once |
| |
|
| | #include <string> |
| |
|
| | #include <thrust/detail/static_assert.h> |
| | #undef THRUST_STATIC_ASSERT |
| | #undef THRUST_STATIC_ASSERT_MSG |
| |
|
| | #define THRUST_STATIC_ASSERT(B) unittest::assert_static((B), __FILE__, __LINE__); |
| | #define THRUST_STATIC_ASSERT_MSG(B, msg) unittest::assert_static((B), __FILE__, __LINE__); |
| |
|
| | namespace unittest |
| | { |
| | __host__ __device__ |
| | void assert_static(bool condition, const char * filename, int lineno); |
| | } |
| |
|
| | #include <thrust/device_new.h> |
| | #include <thrust/device_delete.h> |
| |
|
| | #if THRUST_DEVICE_SYSTEM == THRUST_DEVICE_SYSTEM_CUDA |
| |
|
| | #define ASSERT_STATIC_ASSERT(X) \ |
| | { \ |
| | bool triggered = false; \ |
| | typedef unittest::static_assert_exception ex_t; \ |
| | thrust::device_ptr<ex_t> device_ptr = thrust::device_new<ex_t>(); \ |
| | ex_t* raw_ptr = thrust::raw_pointer_cast(device_ptr); \ |
| | ::cudaMemcpyToSymbol(unittest::detail::device_exception, &raw_ptr, sizeof(ex_t*)); \ |
| | try { X; } catch (ex_t) { triggered = true; } \ |
| | if (!triggered) { \ |
| | triggered = static_cast<ex_t>(*device_ptr).triggered; \ |
| | } \ |
| | thrust::device_free(device_ptr); \ |
| | raw_ptr = NULL; \ |
| | ::cudaMemcpyToSymbol(unittest::detail::device_exception, &raw_ptr, sizeof(ex_t*)); \ |
| | if (!triggered) { unittest::UnitTestFailure f; f << "[" << __FILE__ << ":" << __LINE__ << "] did not trigger a THRUST_STATIC_ASSERT"; throw f; } \ |
| | } |
| |
|
| | #else |
| |
|
| | #define ASSERT_STATIC_ASSERT(X) \ |
| | { \ |
| | bool triggered = false; \ |
| | typedef unittest::static_assert_exception ex_t; \ |
| | try { X; } catch (ex_t) { triggered = true; } \ |
| | if (!triggered) { unittest::UnitTestFailure f; f << "[" << __FILE__ << ":" << __LINE__ << "] did not trigger a THRUST_STATIC_ASSERT"; throw f; } \ |
| | } |
| |
|
| | #endif |
| |
|
| | namespace unittest |
| | { |
| | class static_assert_exception |
| | { |
| | public: |
| | __host__ __device__ |
| | static_assert_exception() : triggered(false) |
| | { |
| | } |
| |
|
| | __host__ __device__ |
| | static_assert_exception(const char * filename, int lineno) |
| | : triggered(true), filename(filename), lineno(lineno) |
| | { |
| | } |
| |
|
| | bool triggered; |
| | const char * filename; |
| | int lineno; |
| | }; |
| |
|
| | namespace detail |
| | { |
| | #ifdef __clang__ |
| | __attribute__((used)) |
| | #endif |
| | __device__ static static_assert_exception* device_exception = NULL; |
| | } |
| |
|
| | __host__ __device__ |
| | void assert_static(bool condition, const char * filename, int lineno) |
| | { |
| | if (!condition) |
| | { |
| | static_assert_exception ex(filename, lineno); |
| |
|
| | #ifdef __CUDA_ARCH__ |
| | *detail::device_exception = ex; |
| | #else |
| | throw ex; |
| | #endif |
| | } |
| | } |
| | } |
| |
|
| |
|