SWDEV-388833 - [catch2][dtest] Kernel tests migrated from dtests to catch2 (#320)
Change-Id: Ibc0248300b8ce8b58d1025743ab5946721e9d7e5
[ROCm/hip-tests commit: 5d8dda1c38]
Tá an tiomantas seo le fáil i:
tiomanta ag
GitHub
tuismitheoir
981a0081d1
tiomantas
7e125561ef
@@ -30,16 +30,17 @@ THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup GraphTest Graph Management
|
||||
* @defgroup ContextTest Context Management
|
||||
* @{
|
||||
* This section describes tests for the graph management types & functions of HIP runtime API.
|
||||
* This section describes tests for the context management functions of HIP runtime API.
|
||||
* @warning All Context Management APIs are **deprecated** and shall not be implemented.
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup VectorTypeTest Vector types
|
||||
* @defgroup DeviceLanguageTest Device Language
|
||||
* @{
|
||||
* This section describes tests for the Vector type functions and operators.
|
||||
* This section describes tests for the Device Language API.
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -50,28 +51,6 @@ THE SOFTWARE.
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup EventTest Event Management
|
||||
* @{
|
||||
* This section describes tests for the event management functions of HIP runtime API.
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup ErrorTest Error Handling
|
||||
* @{
|
||||
* This section describes tests for the error handling functions of HIP runtime API.
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup PeerToPeerTest PeerToPeer Device Memory Access
|
||||
* @{
|
||||
* This section describes tests for the PeerToPeer device memory access functions of HIP runtime API.
|
||||
* @warning PeerToPeer support is experimental.
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup DriverTest Initialization and Version
|
||||
* @{
|
||||
@@ -79,56 +58,6 @@ THE SOFTWARE.
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup DeviceLanguageTest Device Language
|
||||
* @{
|
||||
* This section describes tests for the Device Language API.
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup ExecutionTest Execution Control
|
||||
* @{
|
||||
* This section describes tests for the execution control functions of HIP runtime API.
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup TextureTest Texture Management
|
||||
* @{
|
||||
* This section describes tests for the texture management functions of HIP runtime API.
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup ShflTest warp shuffle function Management
|
||||
* @{
|
||||
* This section describes the warp shuffle types & functions of HIP runtime API.
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup EventTest Event Management
|
||||
* @{
|
||||
* This section describes the event management types & functions of HIP runtime API.
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup ContextTest Context Management
|
||||
* @{
|
||||
* This section describes tests for the context management functions of HIP runtime API.
|
||||
* @warning All Context Management APIs are **deprecated** and shall not be implemented.
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup StreamTest Stream Management
|
||||
* @{
|
||||
* This section describes the stream management types & functions of HIP runtime API.
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup DynamicLoadingTest Kernel Loading Management
|
||||
* @{
|
||||
@@ -137,9 +66,30 @@ THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup MemoryTest memory Management APIs
|
||||
* @defgroup ErrorTest Error Handling
|
||||
* @{
|
||||
* This section describes the memory management types & functions of HIP runtime API.
|
||||
* This section describes tests for the error handling functions of HIP runtime API.
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup EventTest Event Management
|
||||
* @{
|
||||
* This section describes tests for the event management functions of HIP runtime API.
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup ExecutionTest Execution Control
|
||||
* @{
|
||||
* This section describes tests for the execution control functions of HIP runtime API.
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup GraphTest Graph Management
|
||||
* @{
|
||||
* This section describes tests for the graph management types & functions of HIP runtime API.
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -151,14 +101,44 @@ THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup DeviceLanguageTest Device Language
|
||||
* @defgroup MemoryTest memory Management APIs
|
||||
* @{
|
||||
* This section describes tests for the Device Language API.
|
||||
* This section describes the memory management types & functions of HIP runtime API.
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup DeviceLanguageTest Device Language
|
||||
* @defgroup PeerToPeerTest PeerToPeer Device Memory Access
|
||||
* @{
|
||||
* This section describes tests for the Device Language API.
|
||||
* This section describes tests for the PeerToPeer device memory access functions of HIP runtime API.
|
||||
* @warning PeerToPeer support is experimental.
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup ShflTest warp shuffle function Management
|
||||
* @{
|
||||
* This section describes the warp shuffle types & functions of HIP runtime API.
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup StreamTest Stream Management
|
||||
* @{
|
||||
* This section describes the stream management types & functions of HIP runtime API.
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup TextureTest Texture Management
|
||||
* @{
|
||||
* This section describes tests for the texture management functions of HIP runtime API.
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup VectorTypeTest Vector types
|
||||
* @{
|
||||
* This section describes tests for the Vector type functions and operators.
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -23,6 +23,13 @@ set(TEST_SRC
|
||||
hipMemFaultStackAllocation.cc
|
||||
hipLaunchBounds.cc
|
||||
hipShflTests.cc
|
||||
hipDynamicShared.cc
|
||||
hipDynamicShared2.cc
|
||||
hipEmptyKernel.cc
|
||||
hipGridLaunch.cc
|
||||
hipLanguageExtensions.cc
|
||||
hipLaunchParm.cc
|
||||
hipLaunchParmFunctor.cc
|
||||
hipTestConstant.cc
|
||||
hipTestGlobalVariable.cc
|
||||
hipTestMemKernel.cc
|
||||
@@ -47,6 +54,7 @@ endif()
|
||||
if(HIP_PLATFORM MATCHES "amd")
|
||||
set(AMD_SRC
|
||||
hipShflUpDownTest.cc
|
||||
hipExtLaunchKernelGGL.cc
|
||||
)
|
||||
set(TEST_SRC ${TEST_SRC} ${AMD_SRC})
|
||||
endif()
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
Copyright (c) 2023 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 <hip_test_kernels.hh>
|
||||
#include <hip_test_checkers.hh>
|
||||
#include <hip_test_common.hh>
|
||||
#include <hip_test_defgroups.hh>
|
||||
unsigned threadsPerBlock = 256;
|
||||
|
||||
template <unsigned batch, typename T>
|
||||
__device__ void sum(T* sdata, unsigned groupElements, unsigned tid) {
|
||||
T tmp;
|
||||
if (groupElements < batch)
|
||||
return;
|
||||
// sdata[tid] += sdata[tid - batch/2] does not work when block size is
|
||||
// greater than wave size because one wave may complete before another
|
||||
// wave.
|
||||
if (tid >= batch/2 && tid < groupElements)
|
||||
tmp = sdata[tid - batch/2];
|
||||
__syncthreads();
|
||||
if (tid >= batch/2 && tid < groupElements)
|
||||
sdata[tid] += tmp;
|
||||
__syncthreads();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
__global__ void testExternSharedKernel(const T* A_d, const T* B_d, T* C_d,
|
||||
size_t numElements, size_t groupElements) {
|
||||
// declare dynamic shared memory
|
||||
extern __shared__ double sdata0[];
|
||||
T* sdata = reinterpret_cast<T *>(sdata0);
|
||||
|
||||
size_t gid = (blockIdx.x * blockDim.x + threadIdx.x);
|
||||
size_t tid = threadIdx.x;
|
||||
|
||||
// initialize dynamic shared memory
|
||||
if (tid < groupElements) {
|
||||
sdata[tid] = static_cast<T>(tid);
|
||||
}
|
||||
__syncthreads();
|
||||
|
||||
// prefix sum inside dynamic shared memory
|
||||
sum<512>(sdata, groupElements, tid);
|
||||
sum<256>(sdata, groupElements, tid);
|
||||
sum<128>(sdata, groupElements, tid);
|
||||
sum<64>(sdata, groupElements, tid);
|
||||
sum<32>(sdata, groupElements, tid);
|
||||
sum<16>(sdata, groupElements, tid);
|
||||
sum<8>(sdata, groupElements, tid);
|
||||
sum<4>(sdata, groupElements, tid);
|
||||
sum<2>(sdata, groupElements, tid);
|
||||
C_d[gid] = A_d[gid] + B_d[gid] + sdata[tid % groupElements];
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void testExternShared(size_t N, unsigned groupElements) {
|
||||
size_t Nbytes = N * sizeof(T);
|
||||
|
||||
T *A_d, *B_d, *C_d;
|
||||
T *A_h, *B_h, *C_h;
|
||||
|
||||
HipTest::initArrays(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, N, false);
|
||||
unsigned blocks = N/threadsPerBlock;
|
||||
assert(N == blocks * threadsPerBlock);
|
||||
|
||||
HIP_CHECK(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice));
|
||||
HIP_CHECK(hipMemcpy(B_d, B_h, Nbytes, hipMemcpyHostToDevice));
|
||||
|
||||
// calculate the amount of dynamic shared memory required
|
||||
size_t groupMemBytes = groupElements * sizeof(double);
|
||||
|
||||
// launch kernel with dynamic shared memory
|
||||
hipLaunchKernelGGL(HIP_KERNEL_NAME(testExternSharedKernel<T>), dim3(blocks),
|
||||
dim3(threadsPerBlock), groupMemBytes, 0, A_d, B_d, C_d,
|
||||
N, groupElements);
|
||||
|
||||
HIP_CHECK(hipDeviceSynchronize());
|
||||
HIP_CHECK(hipMemcpy(C_h, C_d, Nbytes, hipMemcpyDeviceToHost));
|
||||
|
||||
// verify
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
size_t tid = (i % min(threadsPerBlock, groupElements));
|
||||
T sumFromSharedMemory = static_cast<T>(tid * (tid + 1) / 2);
|
||||
T expected = A_h[i] + B_h[i] + sumFromSharedMemory;
|
||||
REQUIRE(C_h[i] == expected);
|
||||
}
|
||||
HipTest::freeArrays(A_d, B_d, C_d, A_h, B_h, C_h, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @addtogroup hipLaunchKernelGGL hipLaunchKernelGGL
|
||||
* @{
|
||||
* @ingroup KernelTest
|
||||
* `void hipLaunchKernelGGL(F kernel, const dim3& numBlocks, const dim3& dimBlocks,
|
||||
std::uint32_t sharedMemBytes, hipStream_t stream, Args... args)` -
|
||||
* Method to invocate kernel functions
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - launch kernel with dynamic shared memory for float and double
|
||||
* datatypes and verify the results.
|
||||
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - catch/unit/kernel/hipDynamicShared.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.5
|
||||
*/
|
||||
|
||||
TEST_CASE("Unit_hipDynamicShared") {
|
||||
SECTION("test case with float for least size") {
|
||||
testExternShared<float>(1024, 4);
|
||||
testExternShared<float>(1024, 8);
|
||||
testExternShared<float>(1024, 16);
|
||||
testExternShared<float>(1024, 32);
|
||||
testExternShared<float>(1024, 64);
|
||||
}
|
||||
|
||||
SECTION("test case with float for max size") {
|
||||
testExternShared<float>(65536, 4);
|
||||
testExternShared<float>(65536, 8);
|
||||
testExternShared<float>(65536, 16);
|
||||
testExternShared<float>(65536, 32);
|
||||
testExternShared<float>(65536, 64);
|
||||
}
|
||||
|
||||
SECTION("test case with double for least size") {
|
||||
testExternShared<double>(1024, 4);
|
||||
testExternShared<double>(1024, 8);
|
||||
testExternShared<double>(1024, 16);
|
||||
testExternShared<double>(1024, 32);
|
||||
testExternShared<double>(1024, 64);
|
||||
}
|
||||
|
||||
SECTION("test case with double for max size") {
|
||||
testExternShared<double>(65536, 4);
|
||||
testExternShared<double>(65536, 8);
|
||||
testExternShared<double>(65536, 16);
|
||||
testExternShared<double>(65536, 32);
|
||||
testExternShared<double>(65536, 64);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
Copyright (c) 2023 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 <hip_test_kernels.hh>
|
||||
#include <hip_test_checkers.hh>
|
||||
#include <hip_test_common.hh>
|
||||
#include <hip_test_defgroups.hh>
|
||||
|
||||
#define LEN (16 * 1024)
|
||||
#define SIZE (LEN * sizeof(float))
|
||||
|
||||
__global__ void vectorAdd(float* Ad, float* Bd) {
|
||||
extern __shared__ float sBd[];
|
||||
int tx = threadIdx.x;
|
||||
for (int i = 0; i < LEN / 64; i++) {
|
||||
sBd[tx + i * 64] = Ad[tx + i * 64] + 1.0f;
|
||||
Bd[tx + i * 64] = sBd[tx + i * 64];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @addtogroup hipLaunchKernelGGL hipLaunchKernelGGL
|
||||
* @{
|
||||
* @ingroup KernelTest
|
||||
* `void hipLaunchKernelGGL(F kernel, const dim3& numBlocks, const dim3& dimBlocks,
|
||||
std::uint32_t sharedMemBytes, hipStream_t stream, Args... args)` -
|
||||
* Method to invocate kernel functions
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Assign max dynamic shared memory to kernel function and
|
||||
* verify the results.
|
||||
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - catch/unit/kernel/hipDynamicShared2.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.5
|
||||
*/
|
||||
|
||||
TEST_CASE("Unit_hipDynamicShared2") {
|
||||
float *A, *B, *Ad, *Bd;
|
||||
A = new float[LEN];
|
||||
B = new float[LEN];
|
||||
for (int i = 0; i < LEN; i++) {
|
||||
A[i] = 1.0f;
|
||||
B[i] = 1.0f;
|
||||
}
|
||||
HIP_CHECK(hipMalloc(&Ad, SIZE));
|
||||
HIP_CHECK(hipMalloc(&Bd, SIZE));
|
||||
HIP_CHECK(hipMemcpy(Ad, A, SIZE, hipMemcpyHostToDevice));
|
||||
HIP_CHECK(hipMemcpy(Bd, B, SIZE, hipMemcpyHostToDevice));
|
||||
|
||||
hipError_t ret = hipFuncSetAttribute(
|
||||
reinterpret_cast<const void*>(&vectorAdd),
|
||||
hipFuncAttributeMaxDynamicSharedMemorySize, SIZE);
|
||||
|
||||
REQUIRE(ret == hipSuccess);
|
||||
hipLaunchKernelGGL(vectorAdd, dim3(1, 1, 1), dim3(64, 1, 1), SIZE, 0, Ad, Bd);
|
||||
HIP_CHECK(hipGetLastError());
|
||||
HIP_CHECK(hipMemcpy(B, Bd, SIZE, hipMemcpyDeviceToHost));
|
||||
for (int i = 0; i < LEN; i++) {
|
||||
assert(B[i] > 1.0f && B[i] < 3.0f);
|
||||
}
|
||||
HIP_CHECK(hipFree(Ad));
|
||||
HIP_CHECK(hipFree(Bd));
|
||||
|
||||
delete[] A;
|
||||
delete[] B;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
Copyright (c) 2023 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 <hip_test_kernels.hh>
|
||||
#include <hip_test_checkers.hh>
|
||||
#include <hip_test_common.hh>
|
||||
#include <hip_test_defgroups.hh>
|
||||
|
||||
__global__ void Empty(int param) {}
|
||||
|
||||
/**
|
||||
* @addtogroup hipLaunchKernelGGL hipLaunchKernelGGL
|
||||
* @{
|
||||
* @ingroup KernelTest
|
||||
* `void hipLaunchKernelGGL(F kernel, const dim3& numBlocks, const dim3& dimBlocks,
|
||||
std::uint32_t sharedMemBytes, hipStream_t stream, Args... args)` -
|
||||
* Method to invocate kernel functions
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - pass empty Kernel function.
|
||||
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - catch/unit/kernel/hipEmptyKernel.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.5
|
||||
*/
|
||||
|
||||
TEST_CASE("Unit_hipEmptyKernel") {
|
||||
hipLaunchKernelGGL(HIP_KERNEL_NAME(Empty), dim3(1), dim3(1), 0, 0, 0);
|
||||
HIP_CHECK(hipDeviceSynchronize());
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
Copyright (c) 2023 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.
|
||||
*/
|
||||
// Test the Grid_Launch syntax.
|
||||
|
||||
#include <hip_test_kernels.hh>
|
||||
#include <hip_test_checkers.hh>
|
||||
#include <hip_test_common.hh>
|
||||
#include <hip_test_defgroups.hh>
|
||||
#include "hip/hip_ext.h"
|
||||
|
||||
static unsigned threadsPerBlock = 256;
|
||||
static unsigned blocksPerCU = 6;
|
||||
|
||||
struct _t {
|
||||
double _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
||||
};
|
||||
|
||||
typedef struct _t _T;
|
||||
|
||||
__global__ void sKernel(_T s, double *a) {
|
||||
*a = s._a + s._b + s._c + s._d + s._e + s._f + s._g + s._h + s._i + s._j;
|
||||
}
|
||||
|
||||
__global__ void mKernel(char f, int16_t a, int b, double c,
|
||||
int16_t d, int e, double* res) {
|
||||
*res = a + b + c + d + e + f;
|
||||
}
|
||||
|
||||
void testMixData() {
|
||||
double m = 0;
|
||||
double *d_m;
|
||||
HIP_CHECK(hipMalloc(&d_m, sizeof(double)));
|
||||
int a = 1, e = 10;
|
||||
int16_t b = 2, d = 4;
|
||||
double c = 3.0;
|
||||
char ff = 10;
|
||||
hipExtLaunchKernelGGL(mKernel, 1, 1, 0, 0, nullptr, nullptr, 0, ff,
|
||||
b, a, c, d, e, d_m);
|
||||
HIP_CHECK(hipMemcpy(&m, d_m, sizeof(double), hipMemcpyDeviceToHost));
|
||||
REQUIRE(m == 30.0);
|
||||
HIP_CHECK(hipFree(d_m));
|
||||
}
|
||||
|
||||
void testStruct() {
|
||||
double m = 0;
|
||||
double *d_m;
|
||||
HIP_CHECK(hipMalloc(&d_m, sizeof(double)));
|
||||
_T s{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||
hipExtLaunchKernelGGL(sKernel, 1, 1, 0, 0, nullptr, nullptr, 0, s, d_m);
|
||||
HIP_CHECK(hipMemcpy(&m, d_m, sizeof(double), hipMemcpyDeviceToHost));
|
||||
REQUIRE(m == 55.0);
|
||||
HIP_CHECK(hipFree(d_m));
|
||||
}
|
||||
|
||||
void test(size_t N) {
|
||||
size_t Nbytes = N * sizeof(int);
|
||||
int *A_d, *B_d, *C_d;
|
||||
int *A_h, *B_h, *C_h;
|
||||
|
||||
HipTest::initArrays(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, N);
|
||||
|
||||
unsigned blocks = HipTest::setNumBlocks(blocksPerCU, threadsPerBlock, N);
|
||||
|
||||
HIP_CHECK(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice));
|
||||
HIP_CHECK(hipMemcpy(B_d, B_h, Nbytes, hipMemcpyHostToDevice));
|
||||
|
||||
hipExtLaunchKernelGGL(HipTest::vectorADD, dim3(blocks),
|
||||
dim3(threadsPerBlock), 0, 0, nullptr, nullptr, 0,
|
||||
static_cast<const int*>(A_d),
|
||||
static_cast<const int*>(B_d), C_d, N);
|
||||
|
||||
HIP_CHECK(hipMemcpy(C_h, C_d, Nbytes, hipMemcpyDeviceToHost));
|
||||
HIP_CHECK(hipDeviceSynchronize());
|
||||
HipTest::checkVectorADD(A_h, B_h, C_h, N);
|
||||
}
|
||||
|
||||
/**
|
||||
* @addtogroup hipExtLaunchKernelGGL hipExtLaunchKernelGGL
|
||||
* @{
|
||||
* @ingroup KernelTest
|
||||
* `void hipExtLaunchKernelGGL(F kernel, const dim3& numBlocks, const dim3& dimBlocks,
|
||||
std::uint32_t sharedMemBytes, hipStream_t stream,
|
||||
hipEvent_t startEvent, hipEvent_t stopEvent, std::uint32_t flags,
|
||||
Args... args)` -
|
||||
* Launches kernel with dimention parameters and shared memory on stream with templated kernel and arguments
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Test case to verify sample array with hipExtLaunchKernelGGL()
|
||||
* and verify the results.
|
||||
* - Test case to verify struct data with hipExtLaunchKernelGGL()
|
||||
* and verify the results.
|
||||
* - Test case to verify mix datatypes with hipExtLaunchKernelGGL()
|
||||
* and verify the results.
|
||||
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - catch/unit/kernel/hipExtLaunchKernelGGL.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.5
|
||||
*/
|
||||
|
||||
TEST_CASE("Unit_hipExtLaunchKernelGGL") {
|
||||
SECTION("test run") {
|
||||
size_t N = 4 * 1024 * 1024;
|
||||
test(N);
|
||||
}
|
||||
SECTION("testStruct run") {
|
||||
testStruct();
|
||||
}
|
||||
SECTION("testMixData run") {
|
||||
testMixData();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
Copyright (c) 2023 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.
|
||||
*/
|
||||
// Test the Grid_Launch syntax.
|
||||
|
||||
#include <hip_test_kernels.hh>
|
||||
#include <hip_test_checkers.hh>
|
||||
#include <hip_test_common.hh>
|
||||
#include <hip_test_defgroups.hh>
|
||||
|
||||
static unsigned threadsPerBlock = 256;
|
||||
static unsigned blocksPerCU = 6;
|
||||
|
||||
// __device__ maps to __attribute__((hc))
|
||||
__device__ int foo(int i) { return i + 1; }
|
||||
|
||||
|
||||
template <typename T>
|
||||
__global__ void vectorADD2(T* A_d, T* B_d, T* C_d, size_t N) {
|
||||
size_t offset = (blockIdx.x * blockDim.x + threadIdx.x);
|
||||
size_t stride = blockDim.x * gridDim.x;
|
||||
|
||||
for (size_t i = offset; i < N; i += stride) {
|
||||
double foo = __hiloint2double(A_d[i], B_d[i]);
|
||||
C_d[i] = __double2loint(foo) + __double2hiint(foo);
|
||||
}
|
||||
}
|
||||
|
||||
int test_gl2(size_t N) {
|
||||
size_t Nbytes = N * sizeof(int);
|
||||
int *A_d, *B_d, *C_d;
|
||||
int *A_h, *B_h, *C_h;
|
||||
HipTest::initArrays(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, N);
|
||||
|
||||
unsigned blocks = HipTest::setNumBlocks(blocksPerCU, threadsPerBlock, N);
|
||||
|
||||
// Full vadd in one large chunk, to get things started:
|
||||
HIP_CHECK(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice));
|
||||
HIP_CHECK(hipMemcpy(B_d, B_h, Nbytes, hipMemcpyHostToDevice));
|
||||
hipLaunchKernelGGL(vectorADD2, dim3(blocks), dim3(threadsPerBlock),
|
||||
0, 0, A_d, B_d, C_d, N);
|
||||
HIP_CHECK(hipMemcpy(C_h, C_d, Nbytes, hipMemcpyDeviceToHost));
|
||||
HIP_CHECK(hipDeviceSynchronize());
|
||||
// verify
|
||||
HipTest::checkVectorADD(A_h, B_h, C_h, N);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if __HIP__
|
||||
int test_triple_chevron(size_t N) {
|
||||
size_t Nbytes = N * sizeof(int);
|
||||
int *A_d, *B_d, *C_d;
|
||||
int *A_h, *B_h, *C_h;
|
||||
HipTest::initArrays(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, N);
|
||||
|
||||
unsigned blocks = HipTest::setNumBlocks(blocksPerCU, threadsPerBlock, N);
|
||||
// Full vadd in one large chunk, to get things started:
|
||||
HIP_CHECK(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice));
|
||||
HIP_CHECK(hipMemcpy(B_d, B_h, Nbytes, hipMemcpyHostToDevice));
|
||||
vectorADD2<<<dim3(blocks), dim3(threadsPerBlock)>>>(A_d, B_d, C_d, N);
|
||||
HIP_CHECK(hipMemcpy(C_h, C_d, Nbytes, hipMemcpyDeviceToHost));
|
||||
HIP_CHECK(hipDeviceSynchronize());
|
||||
// verify
|
||||
HipTest::checkVectorADD(A_h, B_h, C_h, N);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @addtogroup hipLaunchKernelGGL hipLaunchKernelGGL
|
||||
* @{
|
||||
* @ingroup KernelTest
|
||||
* `void hipLaunchKernelGGL(F kernel, const dim3& numBlocks, const dim3& dimBlocks,
|
||||
std::uint32_t sharedMemBytes, hipStream_t stream, Args... args)` -
|
||||
* Method to invocate kernel functions
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Test case to verify the Grid_Launch syntax.
|
||||
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - catch/unit/kernel/hipGridLaunch.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.5
|
||||
*/
|
||||
|
||||
TEST_CASE("Unit_hipGridLaunch") {
|
||||
size_t N = 4 * 1024 * 1024;
|
||||
SECTION("Test test_gl2") {
|
||||
test_gl2(N);
|
||||
}
|
||||
|
||||
#if __HIP__
|
||||
SECTION("Test triple_chevron") {
|
||||
test_triple_chevron(N);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
Copyright (c) 2023 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 <hip_test_kernels.hh>
|
||||
#include <hip_test_common.hh>
|
||||
#include <hip_test_checkers.hh>
|
||||
#include <hip_test_defgroups.hh>
|
||||
#include <hip/math_functions.h>
|
||||
|
||||
// Simple tests for variable type qualifiers:
|
||||
__device__ int deviceVar;
|
||||
|
||||
// TODO-HCC __constant__ not working yet.
|
||||
__constant__ int constantVar1;
|
||||
|
||||
__constant__ __device__ int constantVar2;
|
||||
|
||||
// Test HOST space:
|
||||
__host__ void foo() { printf("foo!\n"); }
|
||||
|
||||
__device__ __noinline__ int sum1_noinline(int a) { return a + 1; }
|
||||
__device__ __forceinline__ int sum1_forceinline(int a) { return a + 1; }
|
||||
|
||||
|
||||
__device__ __host__ float PlusOne(float x) { return x + 1.0; }
|
||||
|
||||
__global__ void MyKernel(const float* a, const float* b, float* c,
|
||||
unsigned N) {
|
||||
unsigned gid = threadIdx.x;
|
||||
if (gid < N) {
|
||||
c[gid] = a[gid] + PlusOne(b[gid]);
|
||||
}
|
||||
}
|
||||
|
||||
void callMyKernel() {
|
||||
float *a, *b, *c;
|
||||
const unsigned blockSize = 256;
|
||||
unsigned N = blockSize;
|
||||
hipLaunchKernelGGL(MyKernel, dim3(N / blockSize), dim3(blockSize),
|
||||
0, 0, a, b, c, N);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
__global__ void vectorADD(T __restrict__* A_d, T* B_d, T* C_d, size_t N) {
|
||||
#ifdef NOT_YET
|
||||
int a = __shfl_up(x, 1);
|
||||
#endif
|
||||
float x = 1.0;
|
||||
float z = sin(x);
|
||||
#ifdef NOT_YET
|
||||
float fastZ = __sin(x);
|
||||
#endif
|
||||
__syncthreads();
|
||||
|
||||
size_t offset = (blockIdx.x * blockDim.x + threadIdx.x);
|
||||
size_t stride = blockDim.x * gridDim.x;
|
||||
|
||||
for (size_t i = offset; i < N; i += stride) {
|
||||
C_d[i] = A_d[i] + B_d[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @addtogroup hipLaunchKernelGGL hipLaunchKernelGGL
|
||||
* @{
|
||||
* @ingroup KernelTest
|
||||
* `void hipLaunchKernelGGL(F kernel, const dim3& numBlocks, const dim3& dimBlocks,
|
||||
std::uint32_t sharedMemBytes, hipStream_t stream, Args... args)` -
|
||||
* Method to invocate kernel functions
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Collection of code to make sure that various features
|
||||
* in the hip kernel language compile.
|
||||
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - catch/unit/kernel/hipLanguageExtensions.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.5
|
||||
*/
|
||||
|
||||
TEST_CASE("Unit_hipLanguageExtensions") {
|
||||
REQUIRE(true);
|
||||
}
|
||||
Tá difríocht comhad cosc orthu toisc go bhfuil sé ró-mhór
Difríocht Luchtaigh
@@ -0,0 +1,459 @@
|
||||
/*
|
||||
Copyright (c) 2023 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 <hip_test_kernels.hh>
|
||||
#include <hip_test_checkers.hh>
|
||||
#include <hip_test_common.hh>
|
||||
#include <hip_test_defgroups.hh>
|
||||
|
||||
class HipFunctorTests {
|
||||
public:
|
||||
// Test that a class functor can be passed to hiplaunchparam
|
||||
// and can be used in kernel
|
||||
void TestForSimpleClassFunctor(void);
|
||||
// Test that a templated class functor can be passed to hiplaunchparam
|
||||
// and can be used in kernel
|
||||
void TestForClassTemplateFunctor(void);
|
||||
// Test that a class functor object ptr can be passed to hiplaunchparam
|
||||
// and can be used in kernel
|
||||
void TestForClassObjPtrFunctor(void);
|
||||
// Test that a class object containing functor can be passed
|
||||
// to hiplaunchparam and can be used in kernel
|
||||
void TestForFunctorContainInClassObj(void);
|
||||
// Test that a stuct functor can be passed to hiplaunchparam
|
||||
// and can be used in kernel
|
||||
void TestForSimpleStructFunctor(void);
|
||||
// Test that a stuct functor object ptr can be passed to hiplaunchparam
|
||||
// and can be used in kernel
|
||||
void TestForStructObjPtrFunctor(void);
|
||||
// Test that a templated struct functor can be passed to hiplaunchparam
|
||||
// and can be used in kernel
|
||||
void TestForStructTemplateFunctor(void);
|
||||
// Test that a struct object containing functor can be
|
||||
// passed to hiplaunchparam and can be used in kernel
|
||||
void TestForFunctorContainInStructObj(void);
|
||||
};
|
||||
|
||||
static const int BLOCK_DIM_SIZE = 1024;
|
||||
static const int THREADS_PER_BLOCK = 1;
|
||||
|
||||
// class functor tests
|
||||
|
||||
// Simple doubler Functor
|
||||
class DoublerFunctor{
|
||||
public:
|
||||
__device__ int operator()(int x) { return x * 2;}
|
||||
};
|
||||
|
||||
// simple doubler functor passed to kernel
|
||||
__global__ void DoublerFunctorKernel(
|
||||
DoublerFunctor doubler_,
|
||||
bool* deviceResult) {
|
||||
int x = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
int result = doubler_(5);
|
||||
deviceResult[x] = (result == 10);
|
||||
}
|
||||
|
||||
void HipFunctorTests::TestForSimpleClassFunctor(void) {
|
||||
DoublerFunctor doubler;
|
||||
bool *deviceResults, *hostResults;
|
||||
HIP_CHECK(hipMalloc(&deviceResults, BLOCK_DIM_SIZE*sizeof(bool)));
|
||||
HIP_CHECK(hipHostMalloc(&hostResults, BLOCK_DIM_SIZE*sizeof(bool)));
|
||||
for (int k = 0; k < BLOCK_DIM_SIZE; ++k) {
|
||||
// initialize to false, will be set to
|
||||
// true if the functor is called in device code
|
||||
hostResults[k] = false;
|
||||
}
|
||||
|
||||
HIP_CHECK(hipMemcpy(deviceResults, hostResults, BLOCK_DIM_SIZE*sizeof(bool),
|
||||
hipMemcpyHostToDevice));
|
||||
hipLaunchKernelGGL(DoublerFunctorKernel, dim3(BLOCK_DIM_SIZE),
|
||||
dim3(THREADS_PER_BLOCK), 0, 0, doubler, deviceResults);
|
||||
|
||||
// Validation part of TestForSimpleClassFunctor
|
||||
HIP_CHECK(hipMemcpy(hostResults, deviceResults, BLOCK_DIM_SIZE*sizeof(bool),
|
||||
hipMemcpyDeviceToHost));
|
||||
for (int k = 0; k < BLOCK_DIM_SIZE; ++k)
|
||||
REQUIRE(hostResults[k] == true);
|
||||
HIP_CHECK(hipHostFree(hostResults));
|
||||
HIP_CHECK(hipFree(deviceResults));
|
||||
}
|
||||
|
||||
// pointer functor passed to kernel
|
||||
__global__ void PtrDoublerFunctorKernel(
|
||||
DoublerFunctor *doubler_,
|
||||
bool* deviceResult) {
|
||||
int x = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
int result = (*doubler_)(5);
|
||||
deviceResult[x] = (result == 10);
|
||||
}
|
||||
|
||||
void HipFunctorTests::TestForClassObjPtrFunctor(void) {
|
||||
DoublerFunctor* ptrdoubler = new DoublerFunctor[sizeof(int)];
|
||||
bool *deviceResults, *hostResults;
|
||||
HIP_CHECK(hipMalloc(&deviceResults, BLOCK_DIM_SIZE*sizeof(bool)));
|
||||
HIP_CHECK(hipHostMalloc(&hostResults, BLOCK_DIM_SIZE*sizeof(bool)));
|
||||
for (int k = 0; k < BLOCK_DIM_SIZE; ++k) {
|
||||
// initialize to false, will be set to
|
||||
// true if the functor is called in device code
|
||||
hostResults[k] = false;
|
||||
}
|
||||
|
||||
HIP_CHECK(hipMemcpy(deviceResults, hostResults, BLOCK_DIM_SIZE*sizeof(bool),
|
||||
hipMemcpyHostToDevice));
|
||||
hipLaunchKernelGGL(PtrDoublerFunctorKernel, dim3(BLOCK_DIM_SIZE),
|
||||
dim3(THREADS_PER_BLOCK), 0, 0, ptrdoubler, deviceResults);
|
||||
|
||||
// Validation part of TestForClassObjPtrFunctor
|
||||
HIP_CHECK(hipMemcpy(hostResults, deviceResults, BLOCK_DIM_SIZE*sizeof(bool),
|
||||
hipMemcpyDeviceToHost));
|
||||
for (int k = 0; k < BLOCK_DIM_SIZE; ++k)
|
||||
REQUIRE(hostResults[k] == true);
|
||||
HIP_CHECK(hipHostFree(hostResults));
|
||||
HIP_CHECK(hipFree(deviceResults));
|
||||
delete[] ptrdoubler;
|
||||
}
|
||||
|
||||
class compare {
|
||||
public:
|
||||
template<typename T1, typename T2>
|
||||
__device__ bool operator()(const T1& v1, const T2& v2) {
|
||||
return v1 > v2;
|
||||
}
|
||||
};
|
||||
|
||||
// template functor passed to kernel
|
||||
__global__ void TemplateFunctorKernel(
|
||||
compare compare_,
|
||||
bool* deviceResult) {
|
||||
int x = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
deviceResult[x] = compare_(2.2, 2.1);
|
||||
deviceResult[x] = compare_(2, 1);
|
||||
deviceResult[x] = compare_('b', 'a');
|
||||
}
|
||||
|
||||
void HipFunctorTests::TestForClassTemplateFunctor(void) {
|
||||
compare comparefunctor;
|
||||
bool *deviceResults, *hostResults;
|
||||
HIP_CHECK(hipMalloc(&deviceResults, BLOCK_DIM_SIZE*sizeof(bool)));
|
||||
HIP_CHECK(hipHostMalloc(&hostResults, BLOCK_DIM_SIZE*sizeof(bool)));
|
||||
for (int k = 0; k < BLOCK_DIM_SIZE; ++k) {
|
||||
// initialize to false, will be set to
|
||||
// true if the functor is called in device code
|
||||
hostResults[k] = false;
|
||||
}
|
||||
|
||||
HIP_CHECK(hipMemcpy(deviceResults, hostResults, BLOCK_DIM_SIZE*sizeof(bool),
|
||||
hipMemcpyHostToDevice));
|
||||
hipLaunchKernelGGL(TemplateFunctorKernel, dim3(BLOCK_DIM_SIZE),
|
||||
dim3(THREADS_PER_BLOCK), 0, 0, comparefunctor, deviceResults);
|
||||
|
||||
// Validation part of TestForClassTemplateFunctor
|
||||
HIP_CHECK(hipMemcpy(hostResults, deviceResults, BLOCK_DIM_SIZE*sizeof(bool),
|
||||
hipMemcpyDeviceToHost));
|
||||
for (int k = 0; k < BLOCK_DIM_SIZE; ++k)
|
||||
REQUIRE(hostResults[k] == true);
|
||||
HIP_CHECK(hipHostFree(hostResults));
|
||||
HIP_CHECK(hipFree(deviceResults));
|
||||
}
|
||||
|
||||
|
||||
// Doubler calculator
|
||||
class DoublerCalculator {
|
||||
public:
|
||||
int a, result;
|
||||
// fucntor contained in class object
|
||||
DoublerFunctor doubler;
|
||||
};
|
||||
|
||||
// doubler functor conatined in class obj passed to kernel
|
||||
__global__ void DoublerCalculatorFunctorKernel(
|
||||
DoublerCalculator doubler_,
|
||||
bool* deviceResult) {
|
||||
int x = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
int result = doubler_.doubler(doubler_.a);
|
||||
deviceResult[x] = (doubler_.result == result);
|
||||
}
|
||||
|
||||
void HipFunctorTests::TestForFunctorContainInClassObj(void) {
|
||||
DoublerCalculator Doubler;
|
||||
bool *deviceResults, *hostResults;
|
||||
HIP_CHECK(hipMalloc(&deviceResults, BLOCK_DIM_SIZE*sizeof(bool)));
|
||||
HIP_CHECK(hipHostMalloc(&hostResults, BLOCK_DIM_SIZE*sizeof(bool)));
|
||||
for (int k = 0; k < BLOCK_DIM_SIZE; ++k) {
|
||||
// initialize to false, will be set to
|
||||
// true if the functor is called in device code
|
||||
hostResults[k] = false;
|
||||
}
|
||||
|
||||
Doubler.a = 5;
|
||||
Doubler.result = 10;
|
||||
// pass comparefunctor to hipLaunchParm
|
||||
|
||||
HIP_CHECK(hipMemcpy(deviceResults, hostResults, BLOCK_DIM_SIZE*sizeof(bool),
|
||||
hipMemcpyHostToDevice));
|
||||
hipLaunchKernelGGL(DoublerCalculatorFunctorKernel, dim3(BLOCK_DIM_SIZE),
|
||||
dim3(THREADS_PER_BLOCK), 0, 0, Doubler, deviceResults);
|
||||
|
||||
// Validation part of TestForStructTemplateFunctor
|
||||
HIP_CHECK(hipMemcpy(hostResults, deviceResults, BLOCK_DIM_SIZE*sizeof(bool),
|
||||
hipMemcpyDeviceToHost));
|
||||
for (int k = 0; k < BLOCK_DIM_SIZE; ++k)
|
||||
REQUIRE(hostResults[k] == true);
|
||||
HIP_CHECK(hipHostFree(hostResults));
|
||||
HIP_CHECK(hipFree(deviceResults));
|
||||
}
|
||||
|
||||
// Struct functor tests
|
||||
|
||||
// Simple doubler Functor
|
||||
struct sDoublerFunctor {
|
||||
public:
|
||||
__device__ int operator()(int x) { return x * 2;}
|
||||
};
|
||||
|
||||
|
||||
// simple sturct doubler functor passed to kernel
|
||||
__global__ void structDoublerFunctorKernel(
|
||||
sDoublerFunctor doubler_,
|
||||
bool* deviceResult) {
|
||||
int x = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
int result = doubler_(5);
|
||||
deviceResult[x] = (result == 10);
|
||||
}
|
||||
|
||||
void HipFunctorTests::TestForSimpleStructFunctor(void) {
|
||||
sDoublerFunctor doubler;
|
||||
bool *deviceResults, *hostResults;
|
||||
HIP_CHECK(hipMalloc(&deviceResults, BLOCK_DIM_SIZE*sizeof(bool)));
|
||||
HIP_CHECK(hipHostMalloc(&hostResults, BLOCK_DIM_SIZE*sizeof(bool)));
|
||||
for (int k = 0; k < BLOCK_DIM_SIZE; ++k) {
|
||||
// initialize to false, will be set to
|
||||
// true if the functor is called in device code
|
||||
hostResults[k] = false;
|
||||
}
|
||||
|
||||
HIP_CHECK(hipMemcpy(deviceResults, hostResults, BLOCK_DIM_SIZE*sizeof(bool),
|
||||
hipMemcpyHostToDevice));
|
||||
hipLaunchKernelGGL(structDoublerFunctorKernel, dim3(BLOCK_DIM_SIZE),
|
||||
dim3(THREADS_PER_BLOCK), 0, 0, doubler, deviceResults);
|
||||
|
||||
// Validation part of TestForSimpleStructFunctor
|
||||
HIP_CHECK(hipMemcpy(hostResults, deviceResults, BLOCK_DIM_SIZE*sizeof(bool),
|
||||
hipMemcpyDeviceToHost));
|
||||
for (int k = 0; k < BLOCK_DIM_SIZE; ++k)
|
||||
REQUIRE(hostResults[k] == true);
|
||||
HIP_CHECK(hipHostFree(hostResults));
|
||||
HIP_CHECK(hipFree(deviceResults));
|
||||
}
|
||||
|
||||
// ptr functor passed to kernel
|
||||
__global__ void structPtrDoublerFunctorKernel(
|
||||
sDoublerFunctor *doubler_,
|
||||
bool* deviceResult) {
|
||||
int x = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
int result = (*doubler_)(5);
|
||||
deviceResult[x] = (result == 10);
|
||||
}
|
||||
|
||||
void HipFunctorTests::TestForStructObjPtrFunctor(void) {
|
||||
sDoublerFunctor* ptrdoubler = new sDoublerFunctor[sizeof(int)];
|
||||
bool *deviceResults, *hostResults;
|
||||
HIP_CHECK(hipMalloc(&deviceResults, BLOCK_DIM_SIZE*sizeof(bool)));
|
||||
HIP_CHECK(hipHostMalloc(&hostResults, BLOCK_DIM_SIZE*sizeof(bool)));
|
||||
for (int k = 0; k < BLOCK_DIM_SIZE; ++k) {
|
||||
// initialize to false, will be set to
|
||||
// true if the functor is called in device code
|
||||
hostResults[k] = false;
|
||||
}
|
||||
|
||||
HIP_CHECK(hipMemcpy(deviceResults, hostResults, BLOCK_DIM_SIZE*sizeof(bool),
|
||||
hipMemcpyHostToDevice));
|
||||
hipLaunchKernelGGL(structPtrDoublerFunctorKernel, dim3(BLOCK_DIM_SIZE),
|
||||
dim3(THREADS_PER_BLOCK), 0, 0, ptrdoubler, deviceResults);
|
||||
|
||||
// Validation part of TestForStructObjPtrFunctor
|
||||
HIP_CHECK(hipMemcpy(hostResults, deviceResults, BLOCK_DIM_SIZE*sizeof(bool),
|
||||
hipMemcpyDeviceToHost));
|
||||
for (int k = 0; k < BLOCK_DIM_SIZE; ++k)
|
||||
REQUIRE(hostResults[k] == true);
|
||||
HIP_CHECK(hipHostFree(hostResults));
|
||||
HIP_CHECK(hipFree(deviceResults));
|
||||
delete[] ptrdoubler;
|
||||
}
|
||||
|
||||
struct sCompare {
|
||||
public:
|
||||
template< typename T1, typename T2 >
|
||||
__device__ bool operator()(const T1& v1, const T2& v2) {
|
||||
return v1 > v2;
|
||||
}
|
||||
};
|
||||
|
||||
// template functor passed to kernel
|
||||
__global__ void structTemplateFunctorKernel(
|
||||
sCompare compare_,
|
||||
bool* deviceResult) {
|
||||
int x = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
deviceResult[x] = compare_(2.2, 2.1);
|
||||
deviceResult[x] = compare_(2, 1);
|
||||
deviceResult[x] = compare_('b', 'a');
|
||||
}
|
||||
|
||||
void HipFunctorTests::TestForStructTemplateFunctor(void) {
|
||||
sCompare comparefunctor;
|
||||
bool *deviceResults, *hostResults;
|
||||
HIP_CHECK(hipMalloc(&deviceResults, BLOCK_DIM_SIZE*sizeof(bool)));
|
||||
HIP_CHECK(hipHostMalloc(&hostResults, BLOCK_DIM_SIZE*sizeof(bool)));
|
||||
for (int k = 0; k < BLOCK_DIM_SIZE; ++k) {
|
||||
// initialize to false, will be set to
|
||||
// true if the functor is called in device code
|
||||
hostResults[k] = false;
|
||||
}
|
||||
|
||||
HIP_CHECK(hipMemcpy(deviceResults, hostResults, BLOCK_DIM_SIZE*sizeof(bool),
|
||||
hipMemcpyHostToDevice));
|
||||
|
||||
// pass comparefunctor to hipLaunchKernelGGL
|
||||
hipLaunchKernelGGL(structTemplateFunctorKernel, dim3(BLOCK_DIM_SIZE),
|
||||
dim3(THREADS_PER_BLOCK), 0, 0, comparefunctor, deviceResults);
|
||||
|
||||
// Validation part of TestForStructTemplateFunctor
|
||||
HIP_CHECK(hipMemcpy(hostResults, deviceResults, BLOCK_DIM_SIZE*sizeof(bool),
|
||||
hipMemcpyDeviceToHost));
|
||||
for (int k = 0; k < BLOCK_DIM_SIZE; ++k)
|
||||
REQUIRE(hostResults[k] == true);
|
||||
HIP_CHECK(hipHostFree(hostResults));
|
||||
HIP_CHECK(hipFree(deviceResults));
|
||||
}
|
||||
|
||||
// Doubler calculator struct
|
||||
struct sDoublerCalculator {
|
||||
public:
|
||||
int a, result;
|
||||
// fucntor contained in class object
|
||||
DoublerFunctor doubler;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// doubler functor contained in struct passed to kernel
|
||||
__global__ void DoublerCalculatorFunctorKernel(
|
||||
sDoublerCalculator doubler_,
|
||||
bool* deviceResult) {
|
||||
int x = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
int result = doubler_.doubler(doubler_.a);
|
||||
deviceResult[x] = (doubler_.result == result);
|
||||
}
|
||||
|
||||
void HipFunctorTests::TestForFunctorContainInStructObj(void) {
|
||||
sDoublerCalculator Doubler;
|
||||
bool *deviceResults, *hostResults;
|
||||
HIP_CHECK(hipMalloc(&deviceResults, BLOCK_DIM_SIZE*sizeof(bool)));
|
||||
HIP_CHECK(hipHostMalloc(&hostResults, BLOCK_DIM_SIZE*sizeof(bool)));
|
||||
for (int k = 0; k < BLOCK_DIM_SIZE; ++k) {
|
||||
// initialize to false, will be set to
|
||||
// true if the functor is called in device code
|
||||
hostResults[k] = false;
|
||||
}
|
||||
|
||||
Doubler.a = 5;
|
||||
Doubler.result = 10;
|
||||
HIP_CHECK(hipMemcpy(deviceResults, hostResults, BLOCK_DIM_SIZE*sizeof(bool),
|
||||
hipMemcpyHostToDevice));
|
||||
|
||||
|
||||
// pass comparefunctor to hipLaunchKernelGGL
|
||||
hipLaunchKernelGGL(DoublerCalculatorFunctorKernel, dim3(BLOCK_DIM_SIZE),
|
||||
dim3(THREADS_PER_BLOCK), 0, 0, Doubler, deviceResults);
|
||||
|
||||
// Validation part of TestForStructTemplateFunctor
|
||||
HIP_CHECK(hipMemcpy(hostResults, deviceResults, BLOCK_DIM_SIZE*sizeof(bool),
|
||||
hipMemcpyDeviceToHost));
|
||||
for (int k = 0; k < BLOCK_DIM_SIZE; ++k)
|
||||
REQUIRE(hostResults[k] == true);
|
||||
HIP_CHECK(hipHostFree(hostResults));
|
||||
HIP_CHECK(hipFree(deviceResults));
|
||||
}
|
||||
|
||||
/**
|
||||
* @addtogroup hipLaunchKernelGGL hipLaunchKernelGGL
|
||||
* @{
|
||||
* @ingroup KernelTest
|
||||
* `void hipLaunchKernelGGL(F kernel, const dim3& numBlocks, const dim3& dimBlocks,
|
||||
std::uint32_t sharedMemBytes, hipStream_t stream, Args... args)` -
|
||||
* Method to invocate kernel functions
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Test that a class functor can be passed to hiplaunchparam
|
||||
* and can be used in kernel.
|
||||
* - Test that a templated class functor can be passed to hiplaunchparam
|
||||
* and can be used in kernel.
|
||||
* - Test that a class functor object ptr can be passed to hiplaunchparam
|
||||
* and can be used in kernel.
|
||||
* - Test that a class object containing functor can be passed to hiplaunchparam
|
||||
* and can be used in kernel
|
||||
* - Test that a stuct functor can be passed to hiplaunchparam
|
||||
* and can be used in kernel
|
||||
* - Test that a stuct functor object ptr can be passed to hiplaunchparam
|
||||
* and can be used in kernel
|
||||
* - Test that a templated struct functor can be passed to hiplaunchparam
|
||||
* and can be used in kernel
|
||||
* - Test that a struct object containing functor can be passed to hiplaunchparam
|
||||
* and can be used in kernel
|
||||
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - catch/unit/kernel/hipLaunchParmFunctor.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.5
|
||||
*/
|
||||
|
||||
TEST_CASE("Unit_hipLaunchParmFunctor") {
|
||||
HipFunctorTests FunctorTests;
|
||||
|
||||
SECTION("test for simple class functor") {
|
||||
FunctorTests.TestForSimpleClassFunctor();
|
||||
}
|
||||
SECTION("test for class objptr functor") {
|
||||
FunctorTests.TestForClassObjPtrFunctor();
|
||||
}
|
||||
SECTION("test for class templete functor") {
|
||||
FunctorTests.TestForClassTemplateFunctor();
|
||||
}
|
||||
SECTION("test for simple struct functor") {
|
||||
FunctorTests.TestForSimpleStructFunctor();
|
||||
}
|
||||
SECTION("test for struct objptr functor") {
|
||||
FunctorTests.TestForStructObjPtrFunctor();
|
||||
}
|
||||
SECTION("test for struct templete functor") {
|
||||
FunctorTests.TestForStructTemplateFunctor();
|
||||
}
|
||||
SECTION("test for functor contain in classobj") {
|
||||
FunctorTests.TestForFunctorContainInClassObj();
|
||||
}
|
||||
SECTION("test for functor contain in structobj") {
|
||||
FunctorTests.TestForFunctorContainInStructObj();
|
||||
}
|
||||
}
|
||||
Tagairt in Eagrán Nua
Cuir bac ar úsáideoir