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
465 lines
15 KiB
C++
465 lines
15 KiB
C++
/*
|
|
* Copyright (c) Advanced Micro Devices, Inc., or its affiliates.
|
|
*
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
|
|
#include <hip_test_common.hh>
|
|
#include <hip_test_kernels.hh>
|
|
|
|
// Simple DAXPY kernel: out[i] = A[i] + alpha * B[i]
|
|
__global__ void daxpyKernel(const float* A, const float* B, float* out,
|
|
float alpha, int N) {
|
|
int tid = blockIdx.x * blockDim.x + threadIdx.x;
|
|
if (tid < N) {
|
|
out[tid] = A[tid] + alpha * B[tid];
|
|
}
|
|
}
|
|
|
|
static hipLaunchAttribute makeDynDataPrefetchAttr(
|
|
const hipExtDynDataPrefetchConfig* prefetchConfig) {
|
|
hipLaunchAttribute attr;
|
|
memset(&attr, 0, sizeof(attr));
|
|
attr.id = hipLaunchAttributeExtDynDataPrefetch;
|
|
attr.val.dynDataPrefetch = prefetchConfig;
|
|
return attr;
|
|
}
|
|
|
|
/**
|
|
* @addtogroup hipExtDynDataPrefetch hipExtDynDataPrefetch
|
|
* @{
|
|
* @ingroup KernelTest
|
|
* Test the hipLaunchAttributeExtDynDataPrefetch launch attribute.
|
|
*/
|
|
|
|
/**
|
|
* Test Description
|
|
* ------------------------
|
|
* Negative tests for hipLaunchAttributeExtDynDataPrefetch validation.
|
|
*
|
|
* Test source
|
|
* ------------------------
|
|
* - catch/unit/kernel/hipExtDynDataPrefetch.cc
|
|
* Test requirements
|
|
* ------------------------
|
|
* - HIP_VERSION >= 6.5
|
|
*/
|
|
HIP_TEST_CASE(Unit_hipExtDynDataPrefetch_NegativeTests) {
|
|
constexpr int N = 1024;
|
|
float* d_A = nullptr;
|
|
HIP_CHECK(hipMalloc(&d_A, N * sizeof(float)));
|
|
|
|
int maxRegions = 0;
|
|
HIP_CHECK(hipDeviceGetAttribute(&maxRegions, hipDeviceAttributeMaxDynDataPrefetchRegions, 0));
|
|
|
|
auto makeConfig = [](hipLaunchAttribute* attr, int numAttrs) {
|
|
hipLaunchConfig_t cfg = {};
|
|
cfg.gridDim = dim3{4, 1, 1};
|
|
cfg.blockDim = dim3{256, 1, 1};
|
|
cfg.dynamicSmemBytes = 0;
|
|
cfg.stream = 0;
|
|
cfg.attrs = attr;
|
|
cfg.numAttrs = numAttrs;
|
|
return cfg;
|
|
};
|
|
|
|
// On devices without prefetch support (maxRegions == 0), all attempts to use
|
|
// the attribute return hipErrorNotSupported regardless of other parameters.
|
|
hipError_t unsupportedOrInvalid =
|
|
(maxRegions == 0) ? hipErrorNotSupported : hipErrorInvalidValue;
|
|
|
|
SECTION("device query returns non-negative max regions") {
|
|
REQUIRE(maxRegions >= 0);
|
|
}
|
|
|
|
SECTION("numRegions == 0 returns error") {
|
|
hipExtDynDataPrefetchRegion region = {};
|
|
region.address = d_A;
|
|
region.width = 256;
|
|
region.height = 1;
|
|
region.stride = 256;
|
|
|
|
hipExtDynDataPrefetchConfig prefetchConfig = {};
|
|
prefetchConfig.numRegions = 0;
|
|
prefetchConfig.temporal = hipExtDynDataPrefetchTemporalRegular;
|
|
prefetchConfig.regions[0] = region;
|
|
hipLaunchAttribute attr = makeDynDataPrefetchAttr(&prefetchConfig);
|
|
|
|
auto cfg = makeConfig(&attr, 1);
|
|
void* args[] = {&d_A, &d_A, &d_A, nullptr, nullptr};
|
|
HIP_CHECK_ERROR(hipLaunchKernelExC(&cfg, reinterpret_cast<void*>(daxpyKernel), args),
|
|
unsupportedOrInvalid);
|
|
}
|
|
|
|
SECTION("numRegions > device max returns error") {
|
|
hipExtDynDataPrefetchRegion region = {};
|
|
region.address = d_A;
|
|
region.width = 256;
|
|
region.height = 1;
|
|
region.stride = 256;
|
|
|
|
hipExtDynDataPrefetchConfig prefetchConfig = {};
|
|
prefetchConfig.numRegions = static_cast<unsigned int>(maxRegions) + 1;
|
|
prefetchConfig.temporal = hipExtDynDataPrefetchTemporalRegular;
|
|
prefetchConfig.regions[0] = region;
|
|
hipLaunchAttribute attr = makeDynDataPrefetchAttr(&prefetchConfig);
|
|
|
|
auto cfg = makeConfig(&attr, 1);
|
|
void* args[] = {&d_A, &d_A, &d_A, nullptr, nullptr};
|
|
HIP_CHECK_ERROR(hipLaunchKernelExC(&cfg, reinterpret_cast<void*>(daxpyKernel), args),
|
|
unsupportedOrInvalid);
|
|
}
|
|
|
|
SECTION("null address in first region returns error") {
|
|
hipExtDynDataPrefetchConfig prefetchConfig = {};
|
|
prefetchConfig.numRegions = 1;
|
|
prefetchConfig.temporal = hipExtDynDataPrefetchTemporalRegular;
|
|
// regions[0].address is 0 (null) from memset
|
|
hipLaunchAttribute attr = makeDynDataPrefetchAttr(&prefetchConfig);
|
|
|
|
auto cfg = makeConfig(&attr, 1);
|
|
void* args[] = {&d_A, &d_A, &d_A, nullptr, nullptr};
|
|
HIP_CHECK_ERROR(hipLaunchKernelExC(&cfg, reinterpret_cast<void*>(daxpyKernel), args),
|
|
unsupportedOrInvalid);
|
|
}
|
|
|
|
SECTION("null address in region returns error") {
|
|
hipExtDynDataPrefetchRegion region = {};
|
|
region.address = nullptr;
|
|
region.width = 256;
|
|
region.height = 1;
|
|
region.stride = 256;
|
|
|
|
hipExtDynDataPrefetchConfig prefetchConfig = {};
|
|
prefetchConfig.numRegions = 1;
|
|
prefetchConfig.temporal = hipExtDynDataPrefetchTemporalRegular;
|
|
prefetchConfig.regions[0] = region;
|
|
hipLaunchAttribute attr = makeDynDataPrefetchAttr(&prefetchConfig);
|
|
|
|
auto cfg = makeConfig(&attr, 1);
|
|
void* args[] = {&d_A, &d_A, &d_A, nullptr, nullptr};
|
|
HIP_CHECK_ERROR(hipLaunchKernelExC(&cfg, reinterpret_cast<void*>(daxpyKernel), args),
|
|
unsupportedOrInvalid);
|
|
}
|
|
|
|
SECTION("unaligned address returns error") {
|
|
hipExtDynDataPrefetchRegion region = {};
|
|
region.address = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(d_A) + 1);
|
|
region.width = 256;
|
|
region.height = 1;
|
|
region.stride = 256;
|
|
|
|
hipExtDynDataPrefetchConfig prefetchConfig = {};
|
|
prefetchConfig.numRegions = 1;
|
|
prefetchConfig.temporal = hipExtDynDataPrefetchTemporalRegular;
|
|
prefetchConfig.regions[0] = region;
|
|
hipLaunchAttribute attr = makeDynDataPrefetchAttr(&prefetchConfig);
|
|
|
|
auto cfg = makeConfig(&attr, 1);
|
|
void* args[] = {&d_A, &d_A, &d_A, nullptr, nullptr};
|
|
HIP_CHECK_ERROR(hipLaunchKernelExC(&cfg, reinterpret_cast<void*>(daxpyKernel), args),
|
|
unsupportedOrInvalid);
|
|
}
|
|
|
|
SECTION("width == 0 returns error") {
|
|
hipExtDynDataPrefetchRegion region = {};
|
|
region.address = d_A;
|
|
region.width = 0;
|
|
region.height = 1;
|
|
region.stride = 256;
|
|
|
|
hipExtDynDataPrefetchConfig prefetchConfig = {};
|
|
prefetchConfig.numRegions = 1;
|
|
prefetchConfig.temporal = hipExtDynDataPrefetchTemporalRegular;
|
|
prefetchConfig.regions[0] = region;
|
|
hipLaunchAttribute attr = makeDynDataPrefetchAttr(&prefetchConfig);
|
|
|
|
auto cfg = makeConfig(&attr, 1);
|
|
void* args[] = {&d_A, &d_A, &d_A, nullptr, nullptr};
|
|
HIP_CHECK_ERROR(hipLaunchKernelExC(&cfg, reinterpret_cast<void*>(daxpyKernel), args),
|
|
unsupportedOrInvalid);
|
|
}
|
|
|
|
SECTION("width not a multiple of 256 returns error") {
|
|
hipExtDynDataPrefetchRegion region = {};
|
|
region.address = d_A;
|
|
region.width = 300;
|
|
region.height = 1;
|
|
region.stride = 300;
|
|
|
|
hipExtDynDataPrefetchConfig prefetchConfig = {};
|
|
prefetchConfig.numRegions = 1;
|
|
prefetchConfig.temporal = hipExtDynDataPrefetchTemporalRegular;
|
|
prefetchConfig.regions[0] = region;
|
|
hipLaunchAttribute attr = makeDynDataPrefetchAttr(&prefetchConfig);
|
|
|
|
auto cfg = makeConfig(&attr, 1);
|
|
void* args[] = {&d_A, &d_A, &d_A, nullptr, nullptr};
|
|
HIP_CHECK_ERROR(hipLaunchKernelExC(&cfg, reinterpret_cast<void*>(daxpyKernel), args),
|
|
unsupportedOrInvalid);
|
|
}
|
|
|
|
SECTION("height == 0 returns error") {
|
|
hipExtDynDataPrefetchRegion region = {};
|
|
region.address = d_A;
|
|
region.width = 256;
|
|
region.height = 0;
|
|
region.stride = 256;
|
|
|
|
hipExtDynDataPrefetchConfig prefetchConfig = {};
|
|
prefetchConfig.numRegions = 1;
|
|
prefetchConfig.temporal = hipExtDynDataPrefetchTemporalRegular;
|
|
prefetchConfig.regions[0] = region;
|
|
hipLaunchAttribute attr = makeDynDataPrefetchAttr(&prefetchConfig);
|
|
|
|
auto cfg = makeConfig(&attr, 1);
|
|
void* args[] = {&d_A, &d_A, &d_A, nullptr, nullptr};
|
|
HIP_CHECK_ERROR(hipLaunchKernelExC(&cfg, reinterpret_cast<void*>(daxpyKernel), args),
|
|
unsupportedOrInvalid);
|
|
}
|
|
|
|
HIP_CHECK(hipFree(d_A));
|
|
}
|
|
|
|
/**
|
|
* Test Description
|
|
* ------------------------
|
|
* Functional test: launch a DAXPY kernel with L2 prefetch of both input
|
|
* buffers via hipLaunchAttributeExtDynDataPrefetch and verify correctness.
|
|
* Devices without dynamic data prefetch support skip this test.
|
|
*
|
|
* Test source
|
|
* ------------------------
|
|
* - catch/unit/kernel/hipExtDynDataPrefetch.cc
|
|
* Test requirements
|
|
* ------------------------
|
|
* - HIP_VERSION >= 6.5
|
|
*/
|
|
HIP_TEST_CASE(Unit_hipExtDynDataPrefetch_FunctionalDaxpy) {
|
|
int maxRegions = 0;
|
|
HIP_CHECK(hipDeviceGetAttribute(&maxRegions, hipDeviceAttributeMaxDynDataPrefetchRegions, 0));
|
|
if (maxRegions < 2) {
|
|
HIP_SKIP_TEST("Device does not support >= 2 prefetch regions");
|
|
return;
|
|
}
|
|
|
|
constexpr int N = 4096;
|
|
constexpr float alpha = 2.0f;
|
|
|
|
size_t bytes = N * sizeof(float);
|
|
float* d_A = nullptr;
|
|
float* d_B = nullptr;
|
|
float* d_C = nullptr;
|
|
HIP_CHECK(hipMalloc(&d_A, bytes));
|
|
HIP_CHECK(hipMalloc(&d_B, bytes));
|
|
HIP_CHECK(hipMalloc(&d_C, bytes));
|
|
|
|
std::vector<float> h_A(N), h_B(N), h_C(N);
|
|
for (int i = 0; i < N; ++i) {
|
|
h_A[i] = static_cast<float>(i);
|
|
h_B[i] = static_cast<float>(i * 0.5f);
|
|
}
|
|
HIP_CHECK(hipMemcpy(d_A, h_A.data(), bytes, hipMemcpyHostToDevice));
|
|
HIP_CHECK(hipMemcpy(d_B, h_B.data(), bytes, hipMemcpyHostToDevice));
|
|
|
|
size_t width = (bytes / 256) * 256;
|
|
|
|
hipExtDynDataPrefetchRegion regions[2] = {};
|
|
regions[0].address = d_A;
|
|
regions[0].width = width;
|
|
regions[0].height = 1;
|
|
regions[0].stride = width;
|
|
|
|
regions[1].address = d_B;
|
|
regions[1].width = width;
|
|
regions[1].height = 1;
|
|
regions[1].stride = width;
|
|
|
|
hipExtDynDataPrefetchConfig prefetchConfig = {};
|
|
prefetchConfig.numRegions = 2;
|
|
prefetchConfig.temporal = hipExtDynDataPrefetchTemporalRegular;
|
|
prefetchConfig.regions[0] = regions[0];
|
|
prefetchConfig.regions[1] = regions[1];
|
|
hipLaunchAttribute attr = makeDynDataPrefetchAttr(&prefetchConfig);
|
|
|
|
hipLaunchConfig_t config = {};
|
|
constexpr int blockSize = 256;
|
|
config.gridDim = dim3{(N + blockSize - 1) / blockSize, 1, 1};
|
|
config.blockDim = dim3{blockSize, 1, 1};
|
|
config.dynamicSmemBytes = 0;
|
|
config.stream = 0;
|
|
config.attrs = &attr;
|
|
config.numAttrs = 1;
|
|
|
|
int n = N;
|
|
void* args[] = {&d_A, &d_B, &d_C, const_cast<float*>(&alpha), &n};
|
|
HIP_CHECK(hipLaunchKernelExC(&config, reinterpret_cast<void*>(daxpyKernel), args));
|
|
HIP_CHECK(hipDeviceSynchronize());
|
|
|
|
HIP_CHECK(hipMemcpy(h_C.data(), d_C, bytes, hipMemcpyDeviceToHost));
|
|
|
|
for (int i = 0; i < N; ++i) {
|
|
float expected = h_A[i] + alpha * h_B[i];
|
|
REQUIRE(h_C[i] == Catch::Approx(expected).epsilon(1e-5f));
|
|
}
|
|
|
|
HIP_CHECK(hipFree(d_A));
|
|
HIP_CHECK(hipFree(d_B));
|
|
HIP_CHECK(hipFree(d_C));
|
|
}
|
|
|
|
/**
|
|
* Test Description
|
|
* ------------------------
|
|
* Functional test: launch a kernel with a single prefetch region.
|
|
*
|
|
* Test source
|
|
* ------------------------
|
|
* - catch/unit/kernel/hipExtDynDataPrefetch.cc
|
|
* Test requirements
|
|
* ------------------------
|
|
* - HIP_VERSION >= 6.5
|
|
*/
|
|
HIP_TEST_CASE(Unit_hipExtDynDataPrefetch_SingleRegion) {
|
|
int maxRegions = 0;
|
|
HIP_CHECK(hipDeviceGetAttribute(&maxRegions, hipDeviceAttributeMaxDynDataPrefetchRegions, 0));
|
|
if (maxRegions < 1) {
|
|
HIP_SKIP_TEST("Device does not support prefetch regions");
|
|
return;
|
|
}
|
|
|
|
constexpr int N = 1024;
|
|
constexpr float alpha = 1.0f;
|
|
size_t bytes = N * sizeof(float);
|
|
|
|
float* d_A = nullptr;
|
|
float* d_B = nullptr;
|
|
float* d_C = nullptr;
|
|
HIP_CHECK(hipMalloc(&d_A, bytes));
|
|
HIP_CHECK(hipMalloc(&d_B, bytes));
|
|
HIP_CHECK(hipMalloc(&d_C, bytes));
|
|
|
|
std::vector<float> h_A(N, 1.0f), h_B(N, 2.0f), h_C(N);
|
|
HIP_CHECK(hipMemcpy(d_A, h_A.data(), bytes, hipMemcpyHostToDevice));
|
|
HIP_CHECK(hipMemcpy(d_B, h_B.data(), bytes, hipMemcpyHostToDevice));
|
|
|
|
size_t width = (bytes / 256) * 256;
|
|
|
|
hipExtDynDataPrefetchRegion region = {};
|
|
region.address = d_A;
|
|
region.width = width;
|
|
region.height = 1;
|
|
region.stride = width;
|
|
|
|
hipExtDynDataPrefetchConfig prefetchConfig = {};
|
|
prefetchConfig.numRegions = 1;
|
|
prefetchConfig.temporal = hipExtDynDataPrefetchTemporalRegular;
|
|
prefetchConfig.regions[0] = region;
|
|
hipLaunchAttribute attr = makeDynDataPrefetchAttr(&prefetchConfig);
|
|
|
|
hipLaunchConfig_t config = {};
|
|
constexpr int blockSize = 256;
|
|
config.gridDim = dim3{(N + blockSize - 1) / blockSize, 1, 1};
|
|
config.blockDim = dim3{blockSize, 1, 1};
|
|
config.dynamicSmemBytes = 0;
|
|
config.stream = 0;
|
|
config.attrs = &attr;
|
|
config.numAttrs = 1;
|
|
|
|
int n = N;
|
|
void* args[] = {&d_A, &d_B, &d_C, const_cast<float*>(&alpha), &n};
|
|
HIP_CHECK(hipLaunchKernelExC(&config, reinterpret_cast<void*>(daxpyKernel), args));
|
|
HIP_CHECK(hipDeviceSynchronize());
|
|
|
|
HIP_CHECK(hipMemcpy(h_C.data(), d_C, bytes, hipMemcpyDeviceToHost));
|
|
|
|
for (int i = 0; i < N; ++i) {
|
|
float expected = 1.0f + alpha * 2.0f;
|
|
REQUIRE(h_C[i] == Catch::Approx(expected).epsilon(1e-5f));
|
|
}
|
|
|
|
HIP_CHECK(hipFree(d_A));
|
|
HIP_CHECK(hipFree(d_B));
|
|
HIP_CHECK(hipFree(d_C));
|
|
}
|
|
|
|
/**
|
|
* Test Description
|
|
* ------------------------
|
|
* Test all temporal hint combinations via hipLaunchAttributeExtDynDataPrefetch.
|
|
*
|
|
* Test source
|
|
* ------------------------
|
|
* - catch/unit/kernel/hipExtDynDataPrefetch.cc
|
|
* Test requirements
|
|
* ------------------------
|
|
* - HIP_VERSION >= 6.5
|
|
*/
|
|
HIP_TEST_CASE(Unit_hipExtDynDataPrefetch_TemporalHints) {
|
|
int maxRegions = 0;
|
|
HIP_CHECK(hipDeviceGetAttribute(&maxRegions, hipDeviceAttributeMaxDynDataPrefetchRegions, 0));
|
|
if (maxRegions < 1) {
|
|
HIP_SKIP_TEST("Device does not support prefetch regions");
|
|
return;
|
|
}
|
|
|
|
constexpr int N = 256;
|
|
constexpr float alpha = 1.0f;
|
|
size_t bytes = N * sizeof(float);
|
|
|
|
float* d_A = nullptr;
|
|
float* d_B = nullptr;
|
|
float* d_C = nullptr;
|
|
HIP_CHECK(hipMalloc(&d_A, bytes));
|
|
HIP_CHECK(hipMalloc(&d_B, bytes));
|
|
HIP_CHECK(hipMalloc(&d_C, bytes));
|
|
|
|
std::vector<float> h_A(N, 3.0f), h_B(N, 4.0f), h_C(N);
|
|
HIP_CHECK(hipMemcpy(d_A, h_A.data(), bytes, hipMemcpyHostToDevice));
|
|
HIP_CHECK(hipMemcpy(d_B, h_B.data(), bytes, hipMemcpyHostToDevice));
|
|
|
|
auto temporal = GENERATE(hipExtDynDataPrefetchTemporalRegular,
|
|
hipExtDynDataPrefetchTemporalHigh);
|
|
|
|
size_t width = (bytes / 256) * 256;
|
|
|
|
hipExtDynDataPrefetchRegion region = {};
|
|
region.address = d_A;
|
|
region.width = width;
|
|
region.height = 1;
|
|
region.stride = width;
|
|
|
|
hipExtDynDataPrefetchConfig prefetchConfig = {};
|
|
prefetchConfig.numRegions = 1;
|
|
prefetchConfig.temporal = temporal;
|
|
prefetchConfig.regions[0] = region;
|
|
hipLaunchAttribute attr = makeDynDataPrefetchAttr(&prefetchConfig);
|
|
|
|
hipLaunchConfig_t config = {};
|
|
config.gridDim = dim3{1, 1, 1};
|
|
config.blockDim = dim3{(unsigned)N, 1, 1};
|
|
config.dynamicSmemBytes = 0;
|
|
config.stream = 0;
|
|
config.attrs = &attr;
|
|
config.numAttrs = 1;
|
|
|
|
int n = N;
|
|
void* args[] = {&d_A, &d_B, &d_C, const_cast<float*>(&alpha), &n};
|
|
HIP_CHECK(hipLaunchKernelExC(&config, reinterpret_cast<void*>(daxpyKernel), args));
|
|
HIP_CHECK(hipDeviceSynchronize());
|
|
|
|
HIP_CHECK(hipMemcpy(h_C.data(), d_C, bytes, hipMemcpyDeviceToHost));
|
|
for (int i = 0; i < N; ++i) {
|
|
REQUIRE(h_C[i] == Catch::Approx(3.0f + alpha * 4.0f).epsilon(1e-5f));
|
|
}
|
|
|
|
HIP_CHECK(hipFree(d_A));
|
|
HIP_CHECK(hipFree(d_B));
|
|
HIP_CHECK(hipFree(d_C));
|
|
}
|
|
|
|
/**
|
|
* End doxygen group KernelTest.
|
|
* @}
|
|
*/
|