CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
309 lines
11 KiB
C++
309 lines
11 KiB
C++
// Copyright (c) 2023-2024 Advanced Micro Devices, Inc. All rights reserved.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to deal
|
|
// in the Software without restriction, including without limitation the rights
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
// copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in
|
|
// all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
// THE SOFTWARE.
|
|
|
|
#include "rng/common.hpp"
|
|
#include "rng/config_types.hpp"
|
|
#include "test_common.hpp"
|
|
#include <gtest/gtest.h>
|
|
|
|
__global__
|
|
void write_target_arch([[maybe_unused]] rocrand_impl::host::target_arch host_arch,
|
|
int* __restrict__ result)
|
|
{
|
|
#if !defined(__SPIRV__)
|
|
constexpr auto arch = rocrand_impl::host::get_device_arch();
|
|
|
|
*result = arch == host_arch;
|
|
#else
|
|
*result = -1;
|
|
#endif
|
|
}
|
|
|
|
static constexpr rocrand_rng_type dummy_rng_type = rocrand_rng_type(0);
|
|
|
|
namespace rocrand_impl::host
|
|
{
|
|
|
|
template<class T>
|
|
struct generator_config_defaults<dummy_rng_type, T>
|
|
{
|
|
static constexpr inline unsigned int threads = 256;
|
|
static constexpr inline unsigned int blocks = 1;
|
|
};
|
|
|
|
template<>
|
|
struct generator_config_defaults<dummy_rng_type, double>
|
|
{
|
|
static constexpr inline unsigned int threads = 512;
|
|
static constexpr inline unsigned int blocks = 2;
|
|
};
|
|
|
|
template<>
|
|
struct generator_config_defaults<dummy_rng_type, half>
|
|
{
|
|
static constexpr inline unsigned int threads = 512;
|
|
static constexpr inline unsigned int blocks = 7;
|
|
};
|
|
|
|
} // namespace rocrand_impl::host
|
|
|
|
template<class T,
|
|
unsigned int BlockSize = rocrand_impl::host::default_config_provider<
|
|
dummy_rng_type>::template device_config<T>(true)
|
|
.threads>
|
|
__global__ __launch_bounds__(BlockSize)
|
|
void write_config(unsigned int* block_size, unsigned int* grid_size)
|
|
{
|
|
if(blockIdx.x == 0 && threadIdx.x == 0 && BlockSize == blockDim.x)
|
|
{
|
|
*block_size = blockDim.x;
|
|
*grid_size = gridDim.x;
|
|
}
|
|
}
|
|
|
|
TEST(rocrand_config_dispatch_tests, host_matches_device)
|
|
{
|
|
const hipStream_t stream = 0;
|
|
|
|
rocrand_impl::host::target_arch host_arch;
|
|
HIP_CHECK(rocrand_impl::host::get_device_arch(stream, host_arch));
|
|
|
|
int* result_ptr = nullptr;
|
|
HIP_CHECK(hipMallocHelper(&result_ptr, sizeof(result_ptr)));
|
|
|
|
hipLaunchKernelGGL(write_target_arch, dim3(1), dim3(1), 0, stream, host_arch, result_ptr);
|
|
HIP_CHECK(hipGetLastError());
|
|
|
|
int result = -1;
|
|
HIP_CHECK(hipMemcpy(&result, result_ptr, sizeof(result), hipMemcpyDeviceToHost));
|
|
|
|
if(result != -1)
|
|
{
|
|
ASSERT_NE(host_arch, rocrand_impl::host::target_arch::invalid);
|
|
ASSERT_EQ(result, 1);
|
|
}
|
|
else
|
|
{
|
|
GTEST_SKIP() << "SPIR-V build: result is null; skipping arch match assertion.";
|
|
}
|
|
|
|
HIP_CHECK(hipFree(result_ptr));
|
|
}
|
|
|
|
TEST(rocrand_config_dispatch_tests, parse_common_architectures)
|
|
{
|
|
using rocrand_impl::host::parse_gcn_arch;
|
|
using rocrand_impl::host::target_arch;
|
|
|
|
ASSERT_EQ(parse_gcn_arch(""), target_arch::unknown);
|
|
ASSERT_EQ(parse_gcn_arch("not a gfx arch"), target_arch::unknown);
|
|
ASSERT_EQ(parse_gcn_arch(":"), target_arch::unknown);
|
|
ASSERT_EQ(parse_gcn_arch("g:"), target_arch::unknown);
|
|
|
|
ASSERT_EQ(parse_gcn_arch("gfx900:sramecc+"), target_arch::gfx900);
|
|
ASSERT_EQ(parse_gcn_arch("gfx906:::"), target_arch::gfx906);
|
|
ASSERT_EQ(parse_gcn_arch("gfx908:"), target_arch::gfx908);
|
|
ASSERT_EQ(parse_gcn_arch("gfx90a:sramecc+:xnack-"), target_arch::gfx90a);
|
|
}
|
|
|
|
TEST(rocrand_config_dispatch_tests, get_config_on_host_and_device)
|
|
{
|
|
using T = unsigned int;
|
|
|
|
const hipStream_t stream = 0;
|
|
|
|
unsigned int *d_block_size{}, *d_grid_size{};
|
|
HIP_CHECK(hipMallocHelper(&d_block_size, sizeof(*d_block_size)));
|
|
HIP_CHECK(hipMallocHelper(&d_grid_size, sizeof(*d_grid_size)));
|
|
|
|
rocrand_impl::host::generator_config config{};
|
|
const hipError_t err = rocrand_impl::host::get_generator_config<dummy_rng_type, T>(
|
|
stream,
|
|
ROCRAND_ORDERING_PSEUDO_DEFAULT,
|
|
config);
|
|
HIP_CHECK(err);
|
|
|
|
hipLaunchKernelGGL(write_config<T>,
|
|
dim3(config.blocks),
|
|
dim3(config.threads),
|
|
0,
|
|
stream,
|
|
d_block_size,
|
|
d_grid_size);
|
|
HIP_CHECK(hipGetLastError());
|
|
|
|
unsigned int block_size{}, grid_size{};
|
|
HIP_CHECK(hipMemcpy(&block_size, d_block_size, sizeof(block_size), hipMemcpyDeviceToHost));
|
|
HIP_CHECK(hipMemcpy(&grid_size, d_grid_size, sizeof(grid_size), hipMemcpyDeviceToHost));
|
|
|
|
HIP_CHECK(hipFree(d_block_size));
|
|
HIP_CHECK(hipFree(d_grid_size));
|
|
|
|
ASSERT_EQ(block_size, config.threads);
|
|
ASSERT_EQ(grid_size, config.blocks);
|
|
}
|
|
|
|
#if USE_DEVICE_DISPATCH
|
|
TEST(rocrand_config_dispatch_tests, device_id_from_stream)
|
|
{
|
|
using rocrand_impl::host::get_device_from_stream;
|
|
hipDevice_t device_id;
|
|
HIP_CHECK(hipGetDevice(&device_id));
|
|
|
|
int result;
|
|
static constexpr hipStream_t default_stream = 0;
|
|
HIP_CHECK(get_device_from_stream(default_stream, result));
|
|
ASSERT_EQ(result, device_id);
|
|
|
|
HIP_CHECK(get_device_from_stream(hipStreamPerThread, result));
|
|
ASSERT_EQ(result, device_id);
|
|
|
|
hipStream_t stream;
|
|
HIP_CHECK(hipStreamCreate(&stream));
|
|
HIP_CHECK(get_device_from_stream(stream, result));
|
|
HIP_CHECK(hipStreamDestroy(stream));
|
|
ASSERT_EQ(result, device_id);
|
|
|
|
HIP_CHECK(hipStreamCreateWithFlags(&stream, hipStreamNonBlocking));
|
|
HIP_CHECK(get_device_from_stream(stream, result));
|
|
HIP_CHECK(hipStreamDestroy(stream));
|
|
ASSERT_EQ(result, device_id);
|
|
}
|
|
|
|
template<class ConfigProvider>
|
|
__global__
|
|
void least_common_grid_size_kernel(unsigned int* least_common_grid_size, rocrand_ordering order)
|
|
{
|
|
*least_common_grid_size
|
|
= rocrand_impl::host::get_least_common_grid_size<ConfigProvider,
|
|
rocrand_impl::host::target_arch{}>(
|
|
rocrand_impl::host::is_ordering_dynamic(order));
|
|
}
|
|
|
|
TEST(rocrand_config_dispatch_tests, default_config_provider)
|
|
{
|
|
using config_provider = rocrand_impl::host::default_config_provider<dummy_rng_type>;
|
|
static constexpr hipStream_t default_stream = 0;
|
|
static constexpr rocrand_ordering ordering = ROCRAND_ORDERING_PSEUDO_DEFAULT;
|
|
|
|
rocrand_impl::host::generator_config config{};
|
|
ASSERT_EQ(config_provider::host_config<unsigned int>(default_stream, ordering, config),
|
|
hipSuccess);
|
|
ASSERT_EQ(config.blocks, 1);
|
|
ASSERT_EQ(config.threads, 256);
|
|
|
|
config = {};
|
|
ASSERT_EQ(config_provider::host_config<double>(default_stream, ordering, config), hipSuccess);
|
|
ASSERT_EQ(config.blocks, 2);
|
|
ASSERT_EQ(config.threads, 512);
|
|
|
|
unsigned int least_common_grid_size{};
|
|
ASSERT_EQ(
|
|
rocrand_impl::host::get_least_common_grid_size<config_provider>(default_stream,
|
|
ordering,
|
|
least_common_grid_size),
|
|
hipSuccess);
|
|
ASSERT_EQ(least_common_grid_size, 512 * 2 * 7);
|
|
|
|
unsigned int* d_least_common_grid_size{};
|
|
HIP_CHECK(hipMalloc(&d_least_common_grid_size, sizeof(*d_least_common_grid_size)));
|
|
hipLaunchKernelGGL(HIP_KERNEL_NAME(least_common_grid_size_kernel<config_provider>),
|
|
1,
|
|
1,
|
|
0,
|
|
default_stream,
|
|
d_least_common_grid_size,
|
|
ordering);
|
|
unsigned int h_least_common_grid_size{};
|
|
HIP_CHECK(hipMemcpy(&h_least_common_grid_size,
|
|
d_least_common_grid_size,
|
|
sizeof(h_least_common_grid_size),
|
|
hipMemcpyDeviceToHost));
|
|
HIP_CHECK(hipFree(d_least_common_grid_size));
|
|
|
|
ASSERT_EQ(least_common_grid_size, h_least_common_grid_size);
|
|
}
|
|
|
|
template<class ConfigProvider>
|
|
__global__
|
|
void config_selector_kernel(unsigned int* output)
|
|
{
|
|
if(threadIdx.x == 0 && blockIdx.x == 0)
|
|
{
|
|
output[0] = ConfigProvider::template device_config<unsigned short>(true).blocks;
|
|
output[1] = ConfigProvider::template device_config<unsigned short>(true).threads;
|
|
}
|
|
}
|
|
|
|
namespace rocrand_impl::host
|
|
{
|
|
|
|
template<>
|
|
struct generator_config_selector<dummy_rng_type, unsigned short>
|
|
{
|
|
__host__ __device__
|
|
static constexpr unsigned int get_threads(const target_arch arch)
|
|
{
|
|
if(arch == target_arch::gfx906)
|
|
return 64;
|
|
return generator_config_defaults<dummy_rng_type, unsigned short>::threads;
|
|
}
|
|
|
|
__host__ __device__
|
|
static constexpr unsigned int get_blocks(const target_arch /*arch*/)
|
|
{
|
|
return generator_config_defaults<dummy_rng_type, unsigned short>::blocks;
|
|
}
|
|
};
|
|
|
|
} // namespace rocrand_impl::host
|
|
|
|
TEST(rocrand_config_dispatch_tests, config_selection)
|
|
{
|
|
unsigned int* d_output{};
|
|
constexpr std::size_t size = 2;
|
|
HIP_CHECK(hipMallocHelper(&d_output, size * sizeof(*d_output)));
|
|
|
|
using config_provider_t = rocrand_impl::host::default_config_provider<dummy_rng_type>;
|
|
config_provider_t config_provider{};
|
|
rocrand_impl::host::generator_config config{};
|
|
|
|
static constexpr hipStream_t default_stream = 0;
|
|
static constexpr rocrand_ordering ordering = ROCRAND_ORDERING_PSEUDO_DYNAMIC;
|
|
HIP_CHECK(config_provider.host_config<unsigned short>(default_stream, ordering, config));
|
|
|
|
hipLaunchKernelGGL(HIP_KERNEL_NAME(config_selector_kernel<config_provider_t>),
|
|
config.blocks,
|
|
config.threads,
|
|
0,
|
|
default_stream,
|
|
d_output);
|
|
HIP_CHECK(hipGetLastError());
|
|
|
|
std::array<unsigned int, 2> h_output{};
|
|
HIP_CHECK(
|
|
hipMemcpy(h_output.data(), d_output, size * sizeof(*d_output), hipMemcpyDeviceToHost));
|
|
HIP_CHECK(hipFree(d_output));
|
|
|
|
ASSERT_EQ(config.blocks, h_output[0]);
|
|
ASSERT_EQ(config.threads, h_output[1]);
|
|
}
|
|
#endif // USE_DEVICE_DISPATCH
|