//===----------------------------------------------------------------------===// // // Part of CUDA Experimental in CUDA C++ Core Libraries, // under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. // //===----------------------------------------------------------------------===// #ifndef __COMMON_UTILITY_H__ #define __COMMON_UTILITY_H__ #include // cuda_runtime_api needs to come first #include #include #include #include #include #include // IWYU pragma: keep (needed for placement new) #include "testing.cuh" namespace { namespace test { constexpr auto one_thread_dims = cuda::make_config(cuda::block_dims<1>(), cuda::grid_dims<1>()); struct _malloc_pinned { private: void* pv = nullptr; public: explicit _malloc_pinned(std::size_t size) { cuda::__ensure_current_context guard(cuda::device_ref{0}); _CCCL_TRY_CUDA_API(::cudaMallocHost, "failed to allocate pinned memory", &pv, size); } ~_malloc_pinned() { cuda::__ensure_current_context guard(cuda::device_ref{0}); [[maybe_unused]] auto status = ::cudaFreeHost(pv); } template T* get_as() const noexcept { return static_cast(pv); } }; template struct pinned { private: _malloc_pinned _mem; public: explicit pinned(T t) : _mem(sizeof(T)) { ::new (_mem.get_as()) T(std::move(t)); } ~pinned() { get()->~T(); } T* get() noexcept { return _mem.get_as(); } const T* get() const noexcept { return _mem.get_as(); } T& operator*() noexcept { return *get(); } const T& operator*() const noexcept { return *get(); } }; template struct assign_n { __device__ constexpr void operator()(int* pi) const noexcept { *pi = N; } }; template struct verify_n { __device__ void operator()(int* pi) const noexcept { REQUIRE_DEVICE(*pi == N); } }; using assign_42 = assign_n<42>; using verify_42 = verify_n<42>; struct atomic_add_one { __device__ void operator()(int* pi) const noexcept { cuda::atomic_ref atomic_pi(*pi); atomic_pi.fetch_add(1); } }; struct atomic_sub_one { __device__ void operator()(int* pi) const noexcept { cuda::atomic_ref atomic_pi(*pi); atomic_pi.fetch_sub(1); } }; struct spin_until_80 { __device__ void operator()(int* pi) const noexcept { cuda::atomic_ref atomic_pi(*pi); while (atomic_pi.load() != 80) ; } }; struct empty_kernel { __device__ void operator()() const noexcept {} }; } // namespace test } // namespace #endif // __COMMON_UTILITY_H__