SWDEV-299127 - Merge 'develop' into 'amd-staging'
Change-Id: Icc24ccd7e75589d0665c7eea87ccafcec17634d7
[ROCm/hip commit: 483dd2595d]
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"DisabledTests":
|
||||
[
|
||||
"# Following test is related to ticket EXSWCPHIPT-41",
|
||||
"Unit_hipStreamGetPriority_happy",
|
||||
"Unit_hipStreamPerThread_DeviceReset_1"
|
||||
]
|
||||
|
||||
|
||||
@@ -73,7 +73,8 @@
|
||||
"Unit_hipGraphAddEventRecordNode_Functional_WithFlags",
|
||||
"Unit_hipGraphAddEventRecordNode_MultipleRun",
|
||||
"Unit_hipMalloc3D_Negative",
|
||||
"Unit_hipPointerGetAttribute_MappedMem"
|
||||
"Unit_hipPointerGetAttribute_MappedMem",
|
||||
"# Following test is related to ticket EXSWCPHIPT-41",
|
||||
"Unit_hipStreamGetPriority_happy"
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ THE SOFTWARE.
|
||||
|
||||
#define HIP_PRINT_STATUS(status) INFO(hipGetErrorName(status) << " at line: " << __LINE__);
|
||||
|
||||
// Not thread-safe
|
||||
#define HIP_CHECK(error) \
|
||||
{ \
|
||||
hipError_t localError = error; \
|
||||
@@ -37,6 +38,20 @@ THE SOFTWARE.
|
||||
} \
|
||||
}
|
||||
|
||||
// Check that an expression, errorExpr, evaluates to the expected error_t, expectedError.
|
||||
#define HIP_CHECK_ERROR(errorExpr, expectedError) \
|
||||
{ \
|
||||
hipError_t localError = errorExpr; \
|
||||
INFO("Matching Errors: " \
|
||||
<< " Expected Error: " << hipGetErrorString(expectedError) \
|
||||
<< " Expected Code: " << expectedError << '\n' \
|
||||
<< " Actual Error: " << hipGetErrorString(localError) \
|
||||
<< " Actual Code: " << localError << "\nStr: " << #errorExpr \
|
||||
<< "\nIn File: " << __FILE__ << " At line: " << __LINE__); \
|
||||
REQUIRE(localError == expectedError); \
|
||||
}
|
||||
|
||||
// Not thread-safe
|
||||
#define HIPRTC_CHECK(error) \
|
||||
{ \
|
||||
auto localError = error; \
|
||||
@@ -46,25 +61,26 @@ THE SOFTWARE.
|
||||
REQUIRE(false); \
|
||||
} \
|
||||
}
|
||||
|
||||
// Although its assert, it will be evaluated at runtime
|
||||
#define HIP_ASSERT(x) \
|
||||
{ REQUIRE((x)); }
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <chrono>
|
||||
#endif
|
||||
|
||||
#define HIPCHECK(error) \
|
||||
{ \
|
||||
hipError_t localError = error; \
|
||||
if ((localError != hipSuccess) && (localError != hipErrorPeerAccessAlreadyEnabled)) { \
|
||||
printf("error: '%s'(%d) from %s at %s:%d\n", hipGetErrorString(localError), \
|
||||
localError, #error, __FILE__, __LINE__); \
|
||||
abort(); \
|
||||
} \
|
||||
}
|
||||
{ \
|
||||
hipError_t localError = error; \
|
||||
if ((localError != hipSuccess) && (localError != hipErrorPeerAccessAlreadyEnabled)) { \
|
||||
printf("error: '%s'(%d) from %s at %s:%d\n", hipGetErrorString(localError), localError, \
|
||||
#error, __FILE__, __LINE__); \
|
||||
abort(); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define HIPASSERT(condition) \
|
||||
if (!(condition)) { \
|
||||
@@ -104,8 +120,8 @@ static inline int getDeviceCount() {
|
||||
|
||||
// Returns the current system time in microseconds
|
||||
static inline long long get_time() {
|
||||
return std::chrono::high_resolution_clock::now().time_since_epoch()
|
||||
/std::chrono::microseconds(1);
|
||||
return std::chrono::high_resolution_clock::now().time_since_epoch() /
|
||||
std::chrono::microseconds(1);
|
||||
}
|
||||
|
||||
static inline double elapsed_time(long long startTimeUs, long long stopTimeUs) {
|
||||
@@ -147,7 +163,16 @@ inline bool isImageSupported() {
|
||||
return imageSupport != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Causes the test to stop and be skipped at runtime.
|
||||
* reason: Message describing the reason the test has been skipped.
|
||||
*/
|
||||
static inline void HIP_SKIP_TEST(char const* const reason) noexcept {
|
||||
// ctest is setup to parse for "HIP_SKIP_THIS_TEST", at which point it will skip the test.
|
||||
std::cout << "Skipping test. Reason: " << reason << '\n' << "HIP_SKIP_THIS_TEST" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// This must be called in the beginning of image test app's main() to indicate whether image
|
||||
// is supported.
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
Copyright (c) 2022 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 WARRANNTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INNCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANNY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER INN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <hip_test_common.hh>
|
||||
|
||||
#include <memory>
|
||||
|
||||
// Stress allocation tests
|
||||
// Try to allocate as much memory as possible
|
||||
// But since max allocation can fail, we need to be happy with atleast 1/4th of memory
|
||||
TEST_CASE("Stress_hipMalloc_HighSizeAlloc") {
|
||||
size_t devMemTotal{0}, devMemFree{0};
|
||||
HIP_CHECK(hipMemGetInfo(&devMemFree, &devMemTotal));
|
||||
REQUIRE(devMemFree > 0);
|
||||
REQUIRE(devMemTotal > 0);
|
||||
|
||||
char* d_ptr{nullptr};
|
||||
size_t counter{0};
|
||||
|
||||
INFO("Free Mem Available: " << devMemFree << " bytes out of " << devMemTotal << " bytes!");
|
||||
while (hipMalloc(&d_ptr, devMemFree) != hipSuccess && devMemFree > 1) {
|
||||
counter++;
|
||||
devMemFree >>= 1; // reduce the memory to be allocated by half
|
||||
INFO("Attempt to allocate " << devMemFree << " bytes out of " << devMemTotal
|
||||
<< " bytes failed!");
|
||||
REQUIRE(counter <= 2); // Make sure that we are atleast able to allocate 1/4th of max memory
|
||||
}
|
||||
|
||||
HIP_CHECK(hipMemset(d_ptr, 1, devMemFree));
|
||||
auto ptr = std::unique_ptr<unsigned char[]>{new unsigned char[devMemFree]};
|
||||
HIP_CHECK(hipMemcpy(ptr.get(), d_ptr, devMemFree, hipMemcpyDeviceToHost));
|
||||
HIP_CHECK(hipFree(d_ptr));
|
||||
REQUIRE(std::all_of(ptr.get(), ptr.get() + devMemFree, [](unsigned char n) { return n == 1; }));
|
||||
}
|
||||
@@ -150,7 +150,7 @@ static int HmmAttrPrint() {
|
||||
// The following test case allocation, host access, device access of HMM
|
||||
// memory from size 1 to 10KB
|
||||
|
||||
TEST_CASE("Unit_hipMallocManaged_MultiSize") {
|
||||
TEST_CASE("Stress_hipMallocManaged_MultiSize") {
|
||||
IfTestPassed = true;
|
||||
int managed = HmmAttrPrint();
|
||||
if (managed == 1) {
|
||||
@@ -196,7 +196,7 @@ TEST_CASE("Unit_hipMallocManaged_MultiSize") {
|
||||
// The following test case tests the behavior of kernel with a HMM memory and
|
||||
// hipMalloc memory
|
||||
|
||||
TEST_CASE("Unit_hipMallocManaged_KrnlWth2MemTypes") {
|
||||
TEST_CASE("Stress_hipMallocManaged_KrnlWth2MemTypes") {
|
||||
IfTestPassed = true;
|
||||
int *Hmm = NULL, *Dptr = NULL, InitVal = 123;
|
||||
size_t NumElms = (1024 * 1024);
|
||||
@@ -241,7 +241,7 @@ TEST_CASE("Unit_hipMallocManaged_KrnlWth2MemTypes") {
|
||||
|
||||
// The following test case tests when the same Hmm memory is used for
|
||||
// launching multiple different kernels will results in any issue
|
||||
TEST_CASE("Unit_hipMallocManaged_MultiKrnlHmmAccess") {
|
||||
TEST_CASE("Stress_hipMallocManaged_MultiKrnlHmmAccess") {
|
||||
int managed = HmmAttrPrint();
|
||||
if (managed) {
|
||||
int InitVal = 123, NumElms = (1024 * 1024);
|
||||
@@ -253,7 +253,7 @@ TEST_CASE("Unit_hipMallocManaged_MultiKrnlHmmAccess") {
|
||||
}
|
||||
|
||||
// Testing the allocation of/scenarios around max possible memory
|
||||
TEST_CASE("Unit_hipMallocManaged_ExtremeSizes") {
|
||||
TEST_CASE("Stress_hipMallocManaged_ExtremeSizes") {
|
||||
int managed = HmmAttrPrint();
|
||||
if (managed == 1) {
|
||||
bool IfTestPassed = true;
|
||||
|
||||
@@ -26,117 +26,131 @@ THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <hip_test_common.hh>
|
||||
#define NUM 1024
|
||||
#define SIZE 1024 * 4
|
||||
|
||||
constexpr size_t NUM = 1024;
|
||||
constexpr size_t SIZE = 1024 * 4;
|
||||
|
||||
__device__ int globalIn[NUM];
|
||||
__device__ int globalOut[NUM];
|
||||
|
||||
__global__ void Assign(int* Out) {
|
||||
int tid = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
Out[tid] = globalIn[tid];
|
||||
globalOut[tid] = globalIn[tid];
|
||||
int tid = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
Out[tid] = globalIn[tid];
|
||||
globalOut[tid] = globalIn[tid];
|
||||
}
|
||||
|
||||
__device__ __constant__ int globalConstArr[NUM];
|
||||
__device__ __constant__ static float statConstVar = 1.0f;
|
||||
__device__ __constant__ int globalConst[NUM];
|
||||
|
||||
__global__ void checkGlobalConstAddress(int* addr, bool* out) {
|
||||
*out = (globalConstArr == addr);
|
||||
}
|
||||
__global__ void checkAddress(int* addr, bool* out) { *out = (globalConst == addr); }
|
||||
|
||||
__global__ void checkStaticConstVarAddress(float* addr, bool* out) {
|
||||
*out = (&statConstVar == addr);
|
||||
}
|
||||
|
||||
/**
|
||||
Calling hipMemcpyTo/FromSymbolAsync() using user declared stream obj and hipStreamPerThread.
|
||||
*/
|
||||
TEST_CASE("Unit_hipMemcpyToSymbolAsync_ToNFrom") {
|
||||
int *A, *Am, *B, *Ad, *C, *Cm;
|
||||
A = new int[NUM];
|
||||
B = new int[NUM];
|
||||
C = new int[NUM];
|
||||
for (int i = 0; i < NUM; i++) {
|
||||
A[i] = -1 * i;
|
||||
B[i] = 0;
|
||||
C[i] = 0;
|
||||
}
|
||||
int *A{nullptr}, *Am{nullptr}, *B{nullptr}, *Ad{nullptr}, *C{nullptr}, *Cm{nullptr};
|
||||
A = new int[NUM];
|
||||
B = new int[NUM];
|
||||
C = new int[NUM];
|
||||
|
||||
HIP_CHECK(hipMalloc(&Ad, SIZE));
|
||||
HIP_CHECK(hipHostMalloc(&Am, SIZE));
|
||||
HIP_CHECK(hipHostMalloc(&Cm, SIZE));
|
||||
for (int i = 0; i < NUM; i++) {
|
||||
Am[i] = -1 * i;
|
||||
Cm[i] = 0;
|
||||
}
|
||||
HIP_CHECK(hipMalloc((void**)&Ad, SIZE));
|
||||
HIP_CHECK(hipHostMalloc((void**)&Am, SIZE));
|
||||
HIP_CHECK(hipHostMalloc((void**)&Cm, SIZE));
|
||||
|
||||
hipStream_t stream;
|
||||
for (size_t i = 0; i < NUM; i++) {
|
||||
A[i] = -1 * static_cast<int>(i);
|
||||
B[i] = 0;
|
||||
C[i] = 0;
|
||||
Am[i] = -1 * static_cast<int>(i);
|
||||
Cm[i] = 0;
|
||||
}
|
||||
|
||||
|
||||
SECTION("Calling hipMemcpyTo/FromSymbol using stream") {
|
||||
hipStream_t stream{};
|
||||
HIP_CHECK(hipStreamCreate(&stream));
|
||||
HIP_CHECK(hipMemcpyToSymbolAsync(HIP_SYMBOL(globalIn), Am, SIZE, 0,
|
||||
hipMemcpyHostToDevice, stream));
|
||||
HIP_CHECK(
|
||||
hipMemcpyToSymbolAsync(HIP_SYMBOL(globalIn), Am, SIZE, 0, hipMemcpyHostToDevice, stream));
|
||||
HIP_CHECK(hipStreamSynchronize(stream));
|
||||
hipLaunchKernelGGL(Assign, dim3(1, 1, 1), dim3(NUM, 1, 1), 0, 0, Ad);
|
||||
HIP_CHECK(hipMemcpy(B, Ad, SIZE, hipMemcpyDeviceToHost));
|
||||
HIP_CHECK(hipMemcpyFromSymbolAsync(Cm, HIP_SYMBOL(globalOut), SIZE, 0,
|
||||
hipMemcpyDeviceToHost, stream));
|
||||
HIP_CHECK(hipMemcpyFromSymbolAsync(Cm, HIP_SYMBOL(globalOut), SIZE, 0, hipMemcpyDeviceToHost,
|
||||
stream));
|
||||
HIP_CHECK(hipStreamSynchronize(stream));
|
||||
for (int i = 0; i < NUM; i++) {
|
||||
REQUIRE(Am[i] == B[i]);
|
||||
REQUIRE(Am[i] == Cm[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < NUM; i++) {
|
||||
A[i] = -2 * i;
|
||||
B[i] = 0;
|
||||
}
|
||||
|
||||
HIP_CHECK(hipMemcpyToSymbol(HIP_SYMBOL(globalIn), A, SIZE, 0,
|
||||
hipMemcpyHostToDevice));
|
||||
hipLaunchKernelGGL(Assign, dim3(1, 1, 1), dim3(NUM, 1, 1), 0, 0, Ad);
|
||||
HIP_CHECK(hipMemcpy(B, Ad, SIZE, hipMemcpyDeviceToHost));
|
||||
HIP_CHECK(hipMemcpyFromSymbol(C, HIP_SYMBOL(globalOut), SIZE, 0,
|
||||
hipMemcpyDeviceToHost));
|
||||
for (int i = 0; i < NUM; i++) {
|
||||
REQUIRE(A[i] == B[i]);
|
||||
REQUIRE(A[i] == C[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < NUM; i++) {
|
||||
A[i] = -3 * i;
|
||||
B[i] = 0;
|
||||
}
|
||||
SECTION("Calling hipMemcpyTo/FromSymbol using user declared stream obj") {
|
||||
HIP_CHECK(hipMemcpyToSymbolAsync(HIP_SYMBOL(globalIn), A, SIZE, 0,
|
||||
hipMemcpyHostToDevice, stream));
|
||||
HIP_CHECK(hipStreamSynchronize(stream));
|
||||
hipLaunchKernelGGL(Assign, dim3(1, 1, 1), dim3(NUM, 1, 1), 0, 0, Ad);
|
||||
HIP_CHECK(hipMemcpy(B, Ad, SIZE, hipMemcpyDeviceToHost));
|
||||
HIP_CHECK(hipMemcpyFromSymbolAsync(C, HIP_SYMBOL(globalOut), SIZE, 0,
|
||||
hipMemcpyDeviceToHost, stream));
|
||||
HIP_CHECK(hipStreamSynchronize(stream));
|
||||
}
|
||||
SECTION("Calling hipMemcpyTo/FromSymbol using hipStreamPerThread") {
|
||||
HIP_CHECK(hipMemcpyToSymbolAsync(HIP_SYMBOL(globalIn), A, SIZE, 0,
|
||||
hipMemcpyHostToDevice, hipStreamPerThread));
|
||||
HIP_CHECK(hipStreamSynchronize(hipStreamPerThread));
|
||||
hipLaunchKernelGGL(Assign, dim3(1, 1, 1), dim3(NUM, 1, 1), 0, 0, Ad);
|
||||
HIP_CHECK(hipMemcpy(B, Ad, SIZE, hipMemcpyDeviceToHost));
|
||||
HIP_CHECK(hipMemcpyFromSymbolAsync(C, HIP_SYMBOL(globalOut), SIZE, 0,
|
||||
hipMemcpyDeviceToHost, hipStreamPerThread));
|
||||
HIP_CHECK(hipStreamSynchronize(hipStreamPerThread));
|
||||
}
|
||||
for (int i = 0; i < NUM; i++) {
|
||||
REQUIRE(A[i] == B[i]);
|
||||
REQUIRE(A[i] == C[i]);
|
||||
}
|
||||
HIP_CHECK(hipStreamDestroy(stream));
|
||||
HIP_CHECK(hipHostFree(Am));
|
||||
HIP_CHECK(hipHostFree(Cm));
|
||||
HIP_CHECK(hipFree(Ad));
|
||||
delete[] A;
|
||||
delete[] B;
|
||||
delete[] C;
|
||||
for (size_t i = 0; i < NUM; i++) {
|
||||
REQUIRE(Am[i] == B[i]);
|
||||
REQUIRE(Am[i] == Cm[i]);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Calling hipMemcpyTo/FromSymbol - validate value in host memory") {
|
||||
HIP_CHECK(hipMemcpyToSymbol(HIP_SYMBOL(globalIn), A, SIZE, 0, hipMemcpyHostToDevice));
|
||||
hipLaunchKernelGGL(Assign, dim3(1, 1, 1), dim3(NUM, 1, 1), 0, 0, Ad);
|
||||
HIP_CHECK(hipMemcpy(B, Ad, SIZE, hipMemcpyDeviceToHost));
|
||||
HIP_CHECK(hipMemcpyFromSymbol(C, HIP_SYMBOL(globalOut), SIZE, 0, hipMemcpyDeviceToHost));
|
||||
|
||||
for (size_t i = 0; i < NUM; i++) {
|
||||
REQUIRE(A[i] == B[i]);
|
||||
REQUIRE(A[i] == C[i]);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Calling hipMemcpyTo/FromSymbol using user declared stream obj") {
|
||||
hipStream_t stream{};
|
||||
HIP_CHECK(hipStreamCreate(&stream));
|
||||
HIP_CHECK(
|
||||
hipMemcpyToSymbolAsync(HIP_SYMBOL(globalIn), A, SIZE, 0, hipMemcpyHostToDevice, stream));
|
||||
HIP_CHECK(hipStreamSynchronize(stream));
|
||||
hipLaunchKernelGGL(Assign, dim3(1, 1, 1), dim3(NUM, 1, 1), 0, 0, Ad);
|
||||
HIP_CHECK(hipMemcpy(B, Ad, SIZE, hipMemcpyDeviceToHost));
|
||||
HIP_CHECK(
|
||||
hipMemcpyFromSymbolAsync(C, HIP_SYMBOL(globalOut), SIZE, 0, hipMemcpyDeviceToHost, stream));
|
||||
HIP_CHECK(hipStreamSynchronize(stream));
|
||||
HIP_CHECK(hipStreamDestroy(stream));
|
||||
|
||||
for (size_t i = 0; i < NUM; i++) {
|
||||
REQUIRE(A[i] == B[i]);
|
||||
REQUIRE(A[i] == C[i]);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Calling hipMemcpyTo/FromSymbol using hipStreamPerThread") {
|
||||
HIP_CHECK(hipMemcpyToSymbolAsync(HIP_SYMBOL(globalIn), A, SIZE, 0, hipMemcpyHostToDevice,
|
||||
hipStreamPerThread));
|
||||
HIP_CHECK(hipStreamSynchronize(hipStreamPerThread));
|
||||
hipLaunchKernelGGL(Assign, dim3(1, 1, 1), dim3(NUM, 1, 1), 0, 0, Ad);
|
||||
HIP_CHECK(hipMemcpy(B, Ad, SIZE, hipMemcpyDeviceToHost));
|
||||
HIP_CHECK(hipMemcpyFromSymbolAsync(C, HIP_SYMBOL(globalOut), SIZE, 0, hipMemcpyDeviceToHost,
|
||||
hipStreamPerThread));
|
||||
HIP_CHECK(hipStreamSynchronize(hipStreamPerThread));
|
||||
|
||||
for (size_t i = 0; i < NUM; i++) {
|
||||
REQUIRE(A[i] == B[i]);
|
||||
REQUIRE(A[i] == C[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Check for address on GPU and CPU side and compare it
|
||||
// If address mismatch report error
|
||||
// Validate size of symbol as well, compare it with output of hipGetSymbolSize
|
||||
SECTION("Validate address on GPU") {
|
||||
bool* checkOkD{nullptr};
|
||||
bool checkOk = false;
|
||||
size_t symbolSize = 0;
|
||||
int* symbolAddress{nullptr};
|
||||
HIP_CHECK(hipGetSymbolSize(&symbolSize, HIP_SYMBOL(globalConst)));
|
||||
HIP_CHECK(hipGetSymbolAddress((void**)&symbolAddress, HIP_SYMBOL(globalConst)));
|
||||
HIP_CHECK(hipMalloc((void**)&checkOkD, sizeof(bool)));
|
||||
hipLaunchKernelGGL(checkAddress, dim3(1, 1, 1), dim3(1, 1, 1), 0, 0, symbolAddress, checkOkD);
|
||||
HIP_CHECK(hipMemcpy(&checkOk, checkOkD, sizeof(bool), hipMemcpyDeviceToHost));
|
||||
HIP_CHECK(hipFree(checkOkD));
|
||||
HIP_ASSERT(checkOk);
|
||||
HIP_ASSERT((symbolSize == SIZE));
|
||||
}
|
||||
|
||||
HIP_CHECK(hipHostFree(Am));
|
||||
HIP_CHECK(hipHostFree(Cm));
|
||||
HIP_CHECK(hipFree(Ad));
|
||||
delete[] A;
|
||||
delete[] B;
|
||||
delete[] C;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -144,39 +158,64 @@ TEST_CASE("Unit_hipMemcpyToSymbolAsync_ToNFrom") {
|
||||
2) Validate get symbol address/size for static const variable.
|
||||
*/
|
||||
TEST_CASE("Unit_hipGetSymbolAddressAndSize_Validation") {
|
||||
bool *checkOkD;
|
||||
bool checkOk = false;
|
||||
size_t symbolSize{};
|
||||
int *symbolArrAddress{};
|
||||
float *symbolVarAddress{};
|
||||
bool* checkOkD{nullptr};
|
||||
bool checkOk = false;
|
||||
size_t symbolSize{};
|
||||
int* symbolArrAddress{};
|
||||
float* symbolVarAddress{};
|
||||
|
||||
SECTION("Validate symbol size/address of global const array") {
|
||||
HIP_CHECK(hipGetSymbolSize(&symbolSize, HIP_SYMBOL(globalConstArr)));
|
||||
HIP_CHECK(hipGetSymbolAddress(
|
||||
reinterpret_cast<void **>(&symbolArrAddress),
|
||||
HIP_SYMBOL(globalConstArr)));
|
||||
HIP_CHECK(hipMalloc(&checkOkD, sizeof(bool)));
|
||||
hipLaunchKernelGGL(checkGlobalConstAddress, dim3(1, 1, 1), dim3(1, 1, 1),
|
||||
0, 0, symbolArrAddress, checkOkD);
|
||||
HIP_CHECK(hipMemcpy(&checkOk, checkOkD, sizeof(bool),
|
||||
hipMemcpyDeviceToHost));
|
||||
HIP_CHECK(hipFree(checkOkD));
|
||||
HIP_ASSERT(checkOk);
|
||||
HIP_ASSERT(symbolSize == SIZE);
|
||||
}
|
||||
SECTION("Validate symbol size/address of global const array") {
|
||||
HIP_CHECK(hipGetSymbolSize(&symbolSize, HIP_SYMBOL(globalConstArr)));
|
||||
HIP_CHECK(hipGetSymbolAddress(reinterpret_cast<void**>(&symbolArrAddress),
|
||||
HIP_SYMBOL(globalConstArr)));
|
||||
HIP_CHECK(hipMalloc(&checkOkD, sizeof(bool)));
|
||||
hipLaunchKernelGGL(checkGlobalConstAddress, dim3(1, 1, 1), dim3(1, 1, 1), 0, 0,
|
||||
symbolArrAddress, checkOkD);
|
||||
HIP_CHECK(hipMemcpy(&checkOk, checkOkD, sizeof(bool), hipMemcpyDeviceToHost));
|
||||
HIP_CHECK(hipFree(checkOkD));
|
||||
HIP_ASSERT(checkOk);
|
||||
HIP_ASSERT(symbolSize == SIZE);
|
||||
}
|
||||
|
||||
SECTION("Validate symbol size/address of static const variable") {
|
||||
HIP_CHECK(hipGetSymbolSize(&symbolSize, HIP_SYMBOL(statConstVar)));
|
||||
HIP_CHECK(hipGetSymbolAddress(
|
||||
reinterpret_cast<void **>(&symbolVarAddress),
|
||||
HIP_SYMBOL(statConstVar)));
|
||||
HIP_CHECK(hipMalloc(&checkOkD, sizeof(bool)));
|
||||
hipLaunchKernelGGL(checkStaticConstVarAddress, dim3(1, 1, 1),
|
||||
dim3(1, 1, 1), 0, 0, symbolVarAddress, checkOkD);
|
||||
HIP_CHECK(hipMemcpy(&checkOk, checkOkD, sizeof(bool),
|
||||
hipMemcpyDeviceToHost));
|
||||
HIP_CHECK(hipFree(checkOkD));
|
||||
HIP_ASSERT(checkOk);
|
||||
HIP_ASSERT(symbolSize == sizeof(float));
|
||||
}
|
||||
SECTION("Validate symbol size/address of static const variable") {
|
||||
HIP_CHECK(hipGetSymbolSize(&symbolSize, HIP_SYMBOL(statConstVar)));
|
||||
HIP_CHECK(
|
||||
hipGetSymbolAddress(reinterpret_cast<void**>(&symbolVarAddress), HIP_SYMBOL(statConstVar)));
|
||||
HIP_CHECK(hipMalloc(&checkOkD, sizeof(bool)));
|
||||
hipLaunchKernelGGL(checkStaticConstVarAddress, dim3(1, 1, 1), dim3(1, 1, 1), 0, 0,
|
||||
symbolVarAddress, checkOkD);
|
||||
HIP_CHECK(hipMemcpy(&checkOk, checkOkD, sizeof(bool), hipMemcpyDeviceToHost));
|
||||
HIP_CHECK(hipFree(checkOkD));
|
||||
HIP_ASSERT(checkOk);
|
||||
HIP_ASSERT(symbolSize == sizeof(float));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Unit_hipGetSymbolAddress_Negative") {
|
||||
SECTION("Invalid symbol") {
|
||||
int notADeviceSymbol{0};
|
||||
int* addr{nullptr};
|
||||
HIP_CHECK_ERROR(
|
||||
hipGetSymbolAddress(reinterpret_cast<void**>(&addr), HIP_SYMBOL(notADeviceSymbol)),
|
||||
hipErrorInvalidSymbol);
|
||||
}
|
||||
|
||||
SECTION("Nullptr symbol") {
|
||||
int* addr{nullptr};
|
||||
HIP_CHECK_ERROR(hipGetSymbolAddress(reinterpret_cast<void**>(&addr), nullptr),
|
||||
hipErrorInvalidSymbol);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Unit_hipGetSymbolSize_Negative") {
|
||||
SECTION("Invalid symbol") {
|
||||
int notADeviceSymbol{0};
|
||||
size_t dsize{0};
|
||||
HIP_CHECK_ERROR(hipGetSymbolSize(&dsize, HIP_SYMBOL(notADeviceSymbol)), hipErrorInvalidSymbol);
|
||||
}
|
||||
|
||||
SECTION("Nullptr symbol") {
|
||||
size_t size{0};
|
||||
HIP_CHECK_ERROR(hipGetSymbolSize(&size, nullptr), hipErrorInvalidSymbol);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,14 +42,13 @@ set(TEST_SRC
|
||||
hipPointerGetAttributes.cc
|
||||
hipHostGetFlags.cc
|
||||
hipMallocManaged_MultiScenario.cc
|
||||
hipMemsetInvalidPtr.cc
|
||||
hipMemsetNegative.cc
|
||||
hipMemset.cc
|
||||
hipMemsetAsyncMultiThread.cc
|
||||
hipMemset3D.cc
|
||||
hipMemset2D.cc
|
||||
hipHostMallocTests.cc
|
||||
hipMemset3DFunctional.cc
|
||||
hipMemset3DNegative.cc
|
||||
hipMemset3DRegressMultiThread.cc
|
||||
hipMallocManagedFlagsTst.cc
|
||||
hipMemPrefetchAsyncExtTsts.cc
|
||||
@@ -108,14 +107,13 @@ set(TEST_SRC
|
||||
hipHostRegister.cc
|
||||
hipHostGetFlags.cc
|
||||
hipMallocManaged_MultiScenario.cc
|
||||
hipMemsetInvalidPtr.cc
|
||||
hipMemsetNegative.cc
|
||||
hipMemset.cc
|
||||
hipMemsetAsyncMultiThread.cc
|
||||
hipMemset3D.cc
|
||||
hipMemset2D.cc
|
||||
hipHostMallocTests.cc
|
||||
hipMemset3DFunctional.cc
|
||||
hipMemset3DNegative.cc
|
||||
hipMemset3DRegressMultiThread.cc
|
||||
hipMallocManagedFlagsTst.cc
|
||||
hipMemPrefetchAsyncExtTsts.cc
|
||||
|
||||
@@ -25,7 +25,6 @@ hipMallocArray API test scenarios
|
||||
4. Multithreaded scenario
|
||||
*/
|
||||
|
||||
|
||||
#include <hip_test_common.hh>
|
||||
|
||||
static constexpr auto NUM_W{4};
|
||||
@@ -53,20 +52,16 @@ static void MallocArray_DiffSizes(int gpu) {
|
||||
std::vector<size_t> array_size;
|
||||
array_size.push_back(NUM_W);
|
||||
array_size.push_back(BIGNUM_W);
|
||||
for (auto &size : array_size) {
|
||||
for (auto& size : array_size) {
|
||||
hipArray* A_d[ARRAY_LOOP];
|
||||
size_t tot, avail, ptot, pavail;
|
||||
hipChannelFormatDesc desc = hipCreateChannelDesc<float>();
|
||||
HIP_CHECK(hipMemGetInfo(&pavail, &ptot));
|
||||
for (int i = 0; i < ARRAY_LOOP; i++) {
|
||||
if (size == NUM_W) {
|
||||
HIP_CHECK(hipMallocArray(&A_d[i], &desc,
|
||||
NUM_W, NUM_H,
|
||||
hipArrayDefault));
|
||||
HIP_CHECK(hipMallocArray(&A_d[i], &desc, NUM_W, NUM_H, hipArrayDefault));
|
||||
} else {
|
||||
HIP_CHECK(hipMallocArray(&A_d[i], &desc,
|
||||
BIGNUM_W, BIGNUM_H,
|
||||
hipArrayDefault));
|
||||
HIP_CHECK(hipMallocArray(&A_d[i], &desc, BIGNUM_W, BIGNUM_H, hipArrayDefault));
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < ARRAY_LOOP; i++) {
|
||||
@@ -79,10 +74,6 @@ static void MallocArray_DiffSizes(int gpu) {
|
||||
}
|
||||
}
|
||||
|
||||
static void MallocArrayThreadFunc(int gpu) {
|
||||
MallocArray_DiffSizes(gpu);
|
||||
}
|
||||
|
||||
/*
|
||||
* This testcase verifies the negative scenarios of
|
||||
* hipMallocArray API
|
||||
@@ -92,56 +83,31 @@ TEST_CASE("Unit_hipMallocArray_Negative") {
|
||||
hipChannelFormatDesc desc = hipCreateChannelDesc<float>();
|
||||
#if HT_NVIDIA
|
||||
SECTION("NullPointer to Array") {
|
||||
REQUIRE(hipMallocArray(nullptr, &desc,
|
||||
NUM_W, NUM_H, hipArrayDefault) != hipSuccess);
|
||||
REQUIRE(hipMallocArray(nullptr, &desc, NUM_W, NUM_H, hipArrayDefault) != hipSuccess);
|
||||
}
|
||||
|
||||
SECTION("NullPointer to Channel Descriptor") {
|
||||
REQUIRE(hipMallocArray(&A_d, nullptr,
|
||||
NUM_W, NUM_H, hipArrayDefault) != hipSuccess);
|
||||
REQUIRE(hipMallocArray(&A_d, nullptr, NUM_W, NUM_H, hipArrayDefault) != hipSuccess);
|
||||
}
|
||||
#endif
|
||||
SECTION("Width 0 in hipMallocArray") {
|
||||
REQUIRE(hipMallocArray(&A_d, &desc,
|
||||
0, NUM_H, hipArrayDefault) != hipSuccess);
|
||||
REQUIRE(hipMallocArray(&A_d, &desc, 0, NUM_H, hipArrayDefault) != hipSuccess);
|
||||
}
|
||||
|
||||
SECTION("Height 0 in hipMallocArray") {
|
||||
REQUIRE(hipMallocArray(&A_d, &desc,
|
||||
NUM_W, 0, hipArrayDefault) == hipSuccess);
|
||||
REQUIRE(hipMallocArray(&A_d, &desc, NUM_W, 0, hipArrayDefault) == hipSuccess);
|
||||
}
|
||||
|
||||
SECTION("Invalid Flag") {
|
||||
REQUIRE(hipMallocArray(&A_d, &desc,
|
||||
NUM_W, NUM_H, 100) != hipSuccess);
|
||||
}
|
||||
SECTION("Invalid Flag") { REQUIRE(hipMallocArray(&A_d, &desc, NUM_W, NUM_H, 100) != hipSuccess); }
|
||||
|
||||
SECTION("Max int values") {
|
||||
REQUIRE(hipMallocArray(&A_d, &desc,
|
||||
std::numeric_limits<int>::max(),
|
||||
std::numeric_limits<int>::max(),
|
||||
hipArrayDefault) != hipSuccess);
|
||||
REQUIRE(hipMallocArray(&A_d, &desc, std::numeric_limits<int>::max(),
|
||||
std::numeric_limits<int>::max(), hipArrayDefault) != hipSuccess);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* This testcase verifies the basic scenario of
|
||||
* hipMallocArray API for different datatypes
|
||||
* of size 10
|
||||
*/
|
||||
TEMPLATE_TEST_CASE("Unit_hipMallocArray_Basic",
|
||||
"", int, unsigned int, float) {
|
||||
hipArray* A_d;
|
||||
hipChannelFormatDesc desc = hipCreateChannelDesc<TestType>();
|
||||
REQUIRE(hipMallocArray(&A_d, &desc,
|
||||
NUM_W, NUM_H,
|
||||
hipArrayDefault) == hipSuccess);
|
||||
HIP_CHECK(hipFreeArray(A_d));
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("Unit_hipMallocArray_DiffSizes") {
|
||||
MallocArray_DiffSizes(0);
|
||||
}
|
||||
TEST_CASE("Unit_hipMallocArray_DiffSizes") { MallocArray_DiffSizes(0); }
|
||||
|
||||
|
||||
/*
|
||||
@@ -156,10 +122,10 @@ TEST_CASE("Unit_hipMallocArray_MultiThread") {
|
||||
size_t tot, avail, ptot, pavail;
|
||||
HIP_CHECK(hipMemGetInfo(&pavail, &ptot));
|
||||
for (int i = 0; i < devCnt; i++) {
|
||||
threadlist.push_back(std::thread(MallocArrayThreadFunc, i));
|
||||
threadlist.push_back(std::thread(MallocArray_DiffSizes, i));
|
||||
}
|
||||
|
||||
for (auto &t : threadlist) {
|
||||
for (auto& t : threadlist) {
|
||||
t.join();
|
||||
}
|
||||
HIP_CHECK(hipMemGetInfo(&avail, &tot));
|
||||
@@ -170,3 +136,266 @@ TEST_CASE("Unit_hipMallocArray_MultiThread") {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
constexpr size_t BlockSize = 16;
|
||||
|
||||
template <class T, size_t N> struct type_and_size {
|
||||
using type = T;
|
||||
static constexpr size_t size = N;
|
||||
};
|
||||
|
||||
// scalars are interpreted as a vector of 1 length.
|
||||
// template <size_t N> using int_constant = std::integral_constant<size_t, N>;
|
||||
template <typename T> struct vector_info;
|
||||
template <> struct vector_info<int> : type_and_size<int, 1> {};
|
||||
template <> struct vector_info<float> : type_and_size<float, 1> {};
|
||||
template <> struct vector_info<short> : type_and_size<short, 1> {};
|
||||
template <> struct vector_info<char> : type_and_size<char, 1> {};
|
||||
template <> struct vector_info<unsigned int> : type_and_size<unsigned int, 1> {};
|
||||
template <> struct vector_info<unsigned short> : type_and_size<unsigned short, 1> {};
|
||||
template <> struct vector_info<unsigned char> : type_and_size<unsigned char, 1> {};
|
||||
|
||||
template <> struct vector_info<int2> : type_and_size<int, 2> {};
|
||||
template <> struct vector_info<float2> : type_and_size<float, 2> {};
|
||||
template <> struct vector_info<short2> : type_and_size<short, 2> {};
|
||||
template <> struct vector_info<char2> : type_and_size<char, 2> {};
|
||||
template <> struct vector_info<uint2> : type_and_size<unsigned int, 2> {};
|
||||
template <> struct vector_info<ushort2> : type_and_size<unsigned short, 2> {};
|
||||
template <> struct vector_info<uchar2> : type_and_size<unsigned char, 2> {};
|
||||
|
||||
template <> struct vector_info<int4> : type_and_size<int, 4> {};
|
||||
template <> struct vector_info<float4> : type_and_size<float, 4> {};
|
||||
template <> struct vector_info<short4> : type_and_size<short, 4> {};
|
||||
template <> struct vector_info<char4> : type_and_size<char, 4> {};
|
||||
template <> struct vector_info<uint4> : type_and_size<unsigned int, 4> {};
|
||||
template <> struct vector_info<ushort4> : type_and_size<unsigned short, 4> {};
|
||||
template <> struct vector_info<uchar4> : type_and_size<unsigned char, 4> {};
|
||||
|
||||
// Kernels ///////////////////////////////////////
|
||||
|
||||
// read from a texture using normalized coordinates
|
||||
constexpr size_t ChannelToRead = 1;
|
||||
template <typename T>
|
||||
__global__ void readFromTexture(T* output, hipTextureObject_t texObj, size_t width, size_t height,
|
||||
bool textureGather) {
|
||||
// Calculate normalized texture coordinates
|
||||
const unsigned int x = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
const unsigned int y = blockIdx.y * blockDim.y + threadIdx.y;
|
||||
const float u = x / (float)width;
|
||||
|
||||
// Read from texture and write to global memory
|
||||
if (height == 0) {
|
||||
output[x] = tex1D<T>(texObj, u);
|
||||
} else {
|
||||
const float v = y / (float)height;
|
||||
output[y * width + x] =
|
||||
textureGather ? tex2Dgather<T>(texObj, u, v, ChannelToRead) : tex2D<T>(texObj, u, v);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> __device__ void addOne(T* a) {
|
||||
using scalar_type = typename vector_info<T>::type;
|
||||
auto as = reinterpret_cast<scalar_type*>(a);
|
||||
for (size_t i = 0; i < vector_info<T>::size; ++i) {
|
||||
as[i] = as[i] + static_cast<scalar_type>(1);
|
||||
}
|
||||
}
|
||||
|
||||
// read from a surface and write to another
|
||||
template <typename T> __global__ void incSurface(hipSurfaceObject_t surf, size_t height) {
|
||||
// Calculate surface coordinates
|
||||
unsigned int x = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
unsigned int y = blockIdx.y * blockDim.y + threadIdx.y;
|
||||
if (height == 0) {
|
||||
T data;
|
||||
surf1Dread(&data, surf, x * sizeof(T));
|
||||
addOne(&data); // change the value to show that write works
|
||||
surf1Dwrite(data, surf, x * sizeof(T));
|
||||
} else {
|
||||
T data;
|
||||
surf2Dread(&data, surf, x * sizeof(T), y);
|
||||
addOne(&data); // change the value to show that write works
|
||||
surf2Dwrite(data, surf, x * sizeof(T), y);
|
||||
}
|
||||
}
|
||||
|
||||
// Helpers ///////////////////////////////////////
|
||||
|
||||
template <typename T> size_t getAllocSize(const size_t width, const size_t height) noexcept {
|
||||
return sizeof(T) * width * (height ? height : 1);
|
||||
}
|
||||
|
||||
template <typename T> void checkDataIsAscending(const std::vector<T>& hostData) {
|
||||
bool allMatch = true;
|
||||
size_t i = 0;
|
||||
for (; i < hostData.size(); ++i) {
|
||||
allMatch = allMatch && hostData[i] == static_cast<T>(i);
|
||||
if (!allMatch) break;
|
||||
}
|
||||
INFO("hostData[" << i << "] == " << static_cast<T>(hostData[i]));
|
||||
REQUIRE(allMatch);
|
||||
}
|
||||
|
||||
// Tests /////////////////////////////////////////
|
||||
|
||||
// Test the default array by generating a texture from it then reading from that texture.
|
||||
// Textures are read-only so write to the array then copy from the texture into normal device memory
|
||||
template <typename T>
|
||||
void testArrayAsTexture(hipArray_t arrayPtr, const size_t width, const size_t height) {
|
||||
using scalar_type = typename vector_info<T>::type;
|
||||
constexpr auto vec_size = vector_info<T>::size;
|
||||
|
||||
const auto h = height ? height : 1;
|
||||
const size_t pitch = width * sizeof(T); // no padding
|
||||
const auto size = pitch * h;
|
||||
|
||||
// create an array to initialize the hip array, then later use it to hold the result
|
||||
std::vector<scalar_type> hostData(width * h * vec_size);
|
||||
|
||||
// Setup backing array
|
||||
// assign ascending values to the data array to show indexing is working.
|
||||
std::iota(std::begin(hostData), std::end(hostData), 0);
|
||||
HIP_CHECK(
|
||||
hipMemcpy2DToArray(arrayPtr, 0, 0, hostData.data(), pitch, pitch, h, hipMemcpyHostToDevice));
|
||||
|
||||
|
||||
// create texture
|
||||
hipTextureObject_t textObj{};
|
||||
hipResourceDesc resDesc{};
|
||||
memset(&resDesc, 0, sizeof(hipResourceDesc));
|
||||
// enum to store how to resDesc.res union is being used
|
||||
resDesc.resType = hipResourceTypeArray;
|
||||
resDesc.res.array.array = arrayPtr;
|
||||
|
||||
hipTextureDesc textDesc{};
|
||||
memset(&textDesc, 0, sizeof(hipTextureDesc));
|
||||
textDesc.filterMode =
|
||||
hipFilterModePoint; // use the actual values in the texture, not normalized data
|
||||
textDesc.readMode = hipReadModeElementType; // don't convert the data to floats
|
||||
textDesc.normalizedCoords = 1; // use normalized coordinates (0.0-1.0)
|
||||
|
||||
HIP_CHECK(hipCreateTextureObject(&textObj, &resDesc, &textDesc, nullptr));
|
||||
|
||||
|
||||
// run kernel
|
||||
T* device_data{};
|
||||
HIP_CHECK(hipMalloc(&device_data, size));
|
||||
readFromTexture<<<dim3(width / BlockSize, height ? height / BlockSize : 1, 1),
|
||||
dim3(BlockSize, height ? BlockSize : 1, 1)>>>(device_data, textObj, width,
|
||||
height, false);
|
||||
HIP_CHECK(hipGetLastError()); // check for errors when running the kernel
|
||||
|
||||
// copy data back and then test it
|
||||
std::fill(std::begin(hostData), std::end(hostData), 0);
|
||||
HIP_CHECK(hipMemcpy(hostData.data(), device_data, size, hipMemcpyDeviceToHost));
|
||||
|
||||
checkDataIsAscending(hostData);
|
||||
|
||||
// clean up
|
||||
HIP_CHECK(hipDestroyTextureObject(textObj));
|
||||
HIP_CHECK(hipFree(device_data));
|
||||
}
|
||||
|
||||
// Test the an array created with the SurfaceLoadStore flag by generating a surface and reading from
|
||||
// it and writing to it.
|
||||
template <typename T>
|
||||
void testArrayAsSurface(hipArray_t arrayPtr, const size_t width, const size_t height) {
|
||||
using scalar_type = typename vector_info<T>::type;
|
||||
constexpr auto vec_size = vector_info<T>::size;
|
||||
|
||||
const auto h = height ? height : 1;
|
||||
const size_t pitch = width * sizeof(T); // no padding
|
||||
const auto size = pitch * h;
|
||||
|
||||
std::vector<scalar_type> hostData(width * h * vec_size);
|
||||
|
||||
// Setup backing array
|
||||
// assign ascending values to the data array to show indexing is working.
|
||||
std::iota(std::begin(hostData), std::end(hostData), 0);
|
||||
HIP_CHECK(
|
||||
hipMemcpy2DToArray(arrayPtr, 0, 0, hostData.data(), pitch, pitch, h, hipMemcpyHostToDevice));
|
||||
|
||||
|
||||
// create surface
|
||||
hipSurfaceObject_t surfObj{};
|
||||
hipResourceDesc resDesc;
|
||||
memset(&resDesc, 0, sizeof(hipResourceDesc));
|
||||
resDesc.resType = hipResourceTypeArray;
|
||||
|
||||
resDesc.res.array.array = arrayPtr;
|
||||
HIP_CHECK(hipCreateSurfaceObject(&surfObj, &resDesc));
|
||||
|
||||
|
||||
// run kernel
|
||||
T* device_data{};
|
||||
HIP_CHECK(hipMalloc(&device_data, size));
|
||||
// This will increment the values of the surface, so this is undone later
|
||||
incSurface<T><<<dim3(width / BlockSize, height ? height / BlockSize : 1, 1),
|
||||
dim3(BlockSize, height ? BlockSize : 1, 1)>>>(surfObj, height);
|
||||
HIP_CHECK(hipGetLastError()); // check for errors when running the kernel
|
||||
|
||||
|
||||
// copy data back and then test it
|
||||
std::fill(std::begin(hostData), std::end(hostData), 0);
|
||||
HIP_CHECK(hipMemcpy2DFromArray(hostData.data(), pitch, arrayPtr, 0, 0, pitch, h,
|
||||
hipMemcpyDeviceToHost));
|
||||
|
||||
|
||||
// undo the increment
|
||||
std::for_each(std::begin(hostData), std::end(hostData),
|
||||
[](scalar_type& x) { x -= static_cast<scalar_type>(1); });
|
||||
checkDataIsAscending(hostData);
|
||||
|
||||
// clean up
|
||||
HIP_CHECK(hipDestroySurfaceObject(surfObj));
|
||||
HIP_CHECK(hipFree(device_data));
|
||||
}
|
||||
|
||||
size_t getFreeMem() {
|
||||
size_t free = 0, total = 0;
|
||||
HIP_CHECK(hipMemGetInfo(&free, &total));
|
||||
return free;
|
||||
}
|
||||
|
||||
// The happy path of a default array and a SurfaceLoadStore array should work
|
||||
// Selection of types chosen to reduce compile times
|
||||
TEMPLATE_TEST_CASE("Unit_hipMallocArray_happy", "", uint, int, int4, ushort, short2, char, uchar2,
|
||||
char4, float, float2, float4) {
|
||||
#if HT_AMD
|
||||
HipTest::HIP_SKIP_TEST("EXSWCPHIPT-62");
|
||||
#endif
|
||||
|
||||
hipChannelFormatDesc desc = hipCreateChannelDesc<TestType>();
|
||||
|
||||
size_t init_free = getFreeMem();
|
||||
|
||||
// pointer to the array in device memory
|
||||
hipArray_t arrayPtr{};
|
||||
size_t width = 1024;
|
||||
size_t height = GENERATE(0, 1024);
|
||||
|
||||
SECTION("hipArrayDefault") {
|
||||
INFO("flag is hipArrayDefault");
|
||||
INFO("height: " << height);
|
||||
|
||||
HIP_CHECK(hipMallocArray(&arrayPtr, &desc, width, height, hipArrayDefault));
|
||||
testArrayAsTexture<TestType>(arrayPtr, width, height);
|
||||
}
|
||||
#if HT_NVIDIA // surfaces and texture gather not supported on AMD
|
||||
SECTION("hipArraySurfaceLoadStore") {
|
||||
INFO("flag is hipArraySurfaceLoadStore");
|
||||
INFO("height: " << height);
|
||||
|
||||
HIP_CHECK(hipMallocArray(&arrayPtr, &desc, width, height, hipArraySurfaceLoadStore));
|
||||
testArrayAsSurface<TestType>(arrayPtr, width, height);
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t final_free = getFreeMem();
|
||||
|
||||
const size_t alloc_size = getAllocSize<TestType>(width, height);
|
||||
// alloc will be chunked, so this is not exact
|
||||
REQUIRE(init_free - final_free >= alloc_size);
|
||||
|
||||
HIP_CHECK(hipFreeArray(arrayPtr));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved.
|
||||
Copyright (c) 2022 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
|
||||
@@ -51,14 +51,13 @@ Testcase Scenarios :
|
||||
#include <hip_test_checkers.hh>
|
||||
#include <hip_test_kernels.hh>
|
||||
|
||||
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
#include <atomic>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
|
||||
/* Buffer size for bigger chunks in alloc/free cycles */
|
||||
static constexpr auto BuffSizeBC = 5*1024*1024;
|
||||
static constexpr auto BuffSizeBC = 5 * 1024 * 1024;
|
||||
|
||||
/* Buffer size for smaller chunks in alloc/free cycles */
|
||||
static constexpr auto BuffSizeSC = 16;
|
||||
@@ -68,19 +67,18 @@ static constexpr auto BuffSizeSC = 16;
|
||||
static constexpr auto NumDiv = 100;
|
||||
|
||||
/* Max alloc/free iterations for smaller chunks */
|
||||
static constexpr auto MaxAllocFree_SmallChunks = (5000000/NumDiv);
|
||||
static constexpr auto MaxAllocFree_SmallChunks = (5000000 / NumDiv);
|
||||
|
||||
/* Max alloc/free iterations for bigger chunks */
|
||||
static constexpr auto MaxAllocFree_BigChunks = 10000;
|
||||
|
||||
/* Max alloc and pool iterations */
|
||||
static constexpr auto MaxAllocPoolIter = (2000000/NumDiv);
|
||||
static constexpr auto MaxAllocPoolIter = (2000000 / NumDiv);
|
||||
|
||||
/* Test status shared across threads */
|
||||
static std::atomic<bool> g_thTestPassed{true};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Validates data consistency on supplied gpu
|
||||
*/
|
||||
@@ -103,9 +101,8 @@ static bool validateMemoryOnGPU(int gpu, bool concurOnOneGPU = false) {
|
||||
HIP_CHECK(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice));
|
||||
HIP_CHECK(hipMemcpy(B_d, B_h, Nbytes, hipMemcpyHostToDevice));
|
||||
|
||||
hipLaunchKernelGGL(HipTest::vectorADD, dim3(blocks), dim3(threadsPerBlock),
|
||||
0, 0, static_cast<const int*>(A_d),
|
||||
static_cast<const int*>(B_d), C_d, N);
|
||||
hipLaunchKernelGGL(HipTest::vectorADD, dim3(blocks), dim3(threadsPerBlock), 0, 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));
|
||||
|
||||
@@ -121,9 +118,8 @@ static bool validateMemoryOnGPU(int gpu, bool concurOnOneGPU = false) {
|
||||
|
||||
if (!concurOnOneGPU && (prevAvl != curAvl || prevTot != curTot)) {
|
||||
// In concurrent calls on one GPU, we cannot verify leaking in this way
|
||||
UNSCOPED_INFO(
|
||||
"validateMemoryOnGPU : Memory allocation mismatch observed."
|
||||
<< "Possible memory leak.");
|
||||
UNSCOPED_INFO("validateMemoryOnGPU : Memory allocation mismatch observed."
|
||||
<< "Possible memory leak.");
|
||||
TestPassed = false;
|
||||
}
|
||||
|
||||
@@ -138,7 +134,7 @@ static bool regressAllocInLoop(int gpu) {
|
||||
bool TestPassed = true;
|
||||
size_t tot, avail, ptot, pavail, numBytes;
|
||||
int i = 0;
|
||||
int *ptr;
|
||||
int* ptr;
|
||||
|
||||
HIP_CHECK(hipSetDevice(gpu));
|
||||
numBytes = BuffSizeBC;
|
||||
@@ -150,11 +146,12 @@ static bool regressAllocInLoop(int gpu) {
|
||||
HIP_CHECK(hipMemGetInfo(&avail, &tot));
|
||||
HIP_CHECK(hipFree(ptr));
|
||||
|
||||
if (pavail-avail < numBytes) { // We expect pavail-avail >= numBytes
|
||||
UNSCOPED_INFO("LoopAllocation " << i << " : Memory allocation of " <<
|
||||
numBytes << " not matching with hipMemGetInfo - FAIL." << "pavail=" <<
|
||||
pavail << ", ptot=" << ptot << ", avail=" << avail << ", tot=" <<
|
||||
tot << ", pavail-avail=" << pavail-avail);
|
||||
if (pavail - avail < numBytes) { // We expect pavail-avail >= numBytes
|
||||
UNSCOPED_INFO("LoopAllocation " << i << " : Memory allocation of " << numBytes
|
||||
<< " not matching with hipMemGetInfo - FAIL."
|
||||
<< "pavail=" << pavail << ", ptot=" << ptot
|
||||
<< ", avail=" << avail << ", tot=" << tot
|
||||
<< ", pavail-avail=" << pavail - avail);
|
||||
TestPassed = false;
|
||||
break;
|
||||
}
|
||||
@@ -173,8 +170,8 @@ static bool regressAllocInLoop(int gpu) {
|
||||
HIP_CHECK(hipMemGetInfo(&avail, &tot));
|
||||
|
||||
if ((pavail != avail) || (ptot != tot)) {
|
||||
UNSCOPED_INFO("LoopAllocation : Memory allocation mismatch observed." <<
|
||||
"Possible memory leak.");
|
||||
UNSCOPED_INFO("LoopAllocation : Memory allocation mismatch observed."
|
||||
<< "Possible memory leak.");
|
||||
TestPassed &= false;
|
||||
}
|
||||
|
||||
@@ -203,9 +200,8 @@ static bool validateMemoryOnGpuMThread(int gpu, bool concurOnOneGPU = false) {
|
||||
HIPCHECK(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice));
|
||||
HIPCHECK(hipMemcpy(B_d, B_h, Nbytes, hipMemcpyHostToDevice));
|
||||
|
||||
hipLaunchKernelGGL(HipTest::vectorADD, dim3(blocks), dim3(threadsPerBlock),
|
||||
0, 0, static_cast<const int*>(A_d),
|
||||
static_cast<const int*>(B_d), C_d, N);
|
||||
hipLaunchKernelGGL(HipTest::vectorADD, dim3(blocks), dim3(threadsPerBlock), 0, 0,
|
||||
static_cast<const int*>(A_d), static_cast<const int*>(B_d), C_d, N);
|
||||
|
||||
HIPCHECK(hipMemcpy(C_h, C_d, Nbytes, hipMemcpyDeviceToHost));
|
||||
|
||||
@@ -238,7 +234,7 @@ static bool regressAllocInLoopMthread(int gpu) {
|
||||
bool TestPassed = true;
|
||||
size_t tot, avail, ptot, pavail, numBytes;
|
||||
int i = 0;
|
||||
int *ptr;
|
||||
int* ptr;
|
||||
|
||||
HIPCHECK(hipSetDevice(gpu));
|
||||
numBytes = BuffSizeBC;
|
||||
@@ -250,11 +246,12 @@ static bool regressAllocInLoopMthread(int gpu) {
|
||||
HIPCHECK(hipMemGetInfo(&avail, &tot));
|
||||
HIPCHECK(hipFree(ptr));
|
||||
|
||||
if (pavail-avail < numBytes) { // We expect pavail-avail >= numBytes
|
||||
UNSCOPED_INFO("LoopAllocation " << i << " : Memory allocation of " <<
|
||||
numBytes << " not matching with hipMemGetInfo - FAIL." << "pavail=" <<
|
||||
pavail << ", ptot=" << ptot << ", avail=" << avail << ", tot=" <<
|
||||
tot << ", pavail-avail=" << pavail-avail);
|
||||
if (pavail - avail < numBytes) { // We expect pavail-avail >= numBytes
|
||||
UNSCOPED_INFO("LoopAllocation " << i << " : Memory allocation of " << numBytes
|
||||
<< " not matching with hipMemGetInfo - FAIL."
|
||||
<< "pavail=" << pavail << ", ptot=" << ptot
|
||||
<< ", avail=" << avail << ", tot=" << tot
|
||||
<< ", pavail-avail=" << pavail - avail);
|
||||
TestPassed = false;
|
||||
break;
|
||||
}
|
||||
@@ -273,8 +270,8 @@ static bool regressAllocInLoopMthread(int gpu) {
|
||||
HIPCHECK(hipMemGetInfo(&avail, &tot));
|
||||
|
||||
if ((pavail != avail) || (ptot != tot)) {
|
||||
UNSCOPED_INFO("LoopAllocation : Memory allocation mismatch observed." <<
|
||||
"Possible memory leak.");
|
||||
UNSCOPED_INFO("LoopAllocation : Memory allocation mismatch observed."
|
||||
<< "Possible memory leak.");
|
||||
TestPassed &= false;
|
||||
}
|
||||
|
||||
@@ -285,18 +282,15 @@ static bool regressAllocInLoopMthread(int gpu) {
|
||||
* Thread func to regress alloc and check data consistency
|
||||
*/
|
||||
static void threadFunc(int gpu) {
|
||||
g_thTestPassed = regressAllocInLoopMthread(gpu)
|
||||
&& validateMemoryOnGpuMThread(gpu);
|
||||
g_thTestPassed = regressAllocInLoopMthread(gpu) && validateMemoryOnGpuMThread(gpu);
|
||||
|
||||
UNSCOPED_INFO("thread execution status on gpu" << gpu << ":" <<
|
||||
g_thTestPassed.load());
|
||||
UNSCOPED_INFO("thread execution status on gpu" << gpu << ":" << g_thTestPassed.load());
|
||||
}
|
||||
|
||||
|
||||
/* Performs Argument Validation of api */
|
||||
TEST_CASE("Unit_hipMalloc_ArgumentValidation") {
|
||||
int *ptr;
|
||||
hipError_t ret;
|
||||
int* ptr{nullptr};
|
||||
|
||||
SECTION("hipMalloc() when size(0)") {
|
||||
HIP_CHECK(hipMalloc(&ptr, 0));
|
||||
@@ -304,21 +298,17 @@ TEST_CASE("Unit_hipMalloc_ArgumentValidation") {
|
||||
REQUIRE(ptr == nullptr);
|
||||
}
|
||||
|
||||
SECTION("hipFree() when freeing nullptr ") {
|
||||
ptr = nullptr;
|
||||
// api should return success and shudnt crash
|
||||
SECTION("hipFree() when freeing nullptr") {
|
||||
HIP_CHECK(hipFree(ptr));
|
||||
}
|
||||
|
||||
SECTION("hipMalloc() with invalid argument") {
|
||||
constexpr auto sizeBytes = 100;
|
||||
ret = hipMalloc(nullptr, sizeBytes);
|
||||
REQUIRE(ret != hipSuccess);
|
||||
HIP_CHECK_ERROR(hipMalloc(nullptr, 100), hipErrorInvalidValue);
|
||||
}
|
||||
|
||||
SECTION("hipMalloc() with max size_t") {
|
||||
ret = hipMalloc(&ptr, std::numeric_limits<std::size_t>::max());
|
||||
REQUIRE(ret != hipSuccess);
|
||||
HIP_CHECK_ERROR(hipMalloc(&ptr, std::numeric_limits<std::size_t>::max()),
|
||||
hipErrorMemoryAllocation);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,12 +334,12 @@ TEST_CASE("Unit_hipMalloc_LoopRegressionAllocFreeCycles") {
|
||||
* of time.
|
||||
*/
|
||||
TEST_CASE("Unit_hipMalloc_AllocateAndPoolBuffers") {
|
||||
size_t avail, tot, pavail, ptot;
|
||||
bool ret;
|
||||
hipError_t err;
|
||||
std::vector<int *> ptrlist;
|
||||
size_t avail{0}, tot{0}, pavail{0}, ptot{0};
|
||||
bool ret{false};
|
||||
hipError_t err{};
|
||||
std::vector<int*> ptrlist{};
|
||||
constexpr auto BuffSize = 10;
|
||||
int devCnt, *ptr;
|
||||
int devCnt{0}, *ptr{nullptr};
|
||||
|
||||
// Get GPU count
|
||||
HIP_CHECK(hipGetDeviceCount(&devCnt));
|
||||
@@ -358,14 +348,13 @@ TEST_CASE("Unit_hipMalloc_AllocateAndPoolBuffers") {
|
||||
HIP_CHECK(hipMemGetInfo(&pavail, &ptot));
|
||||
|
||||
// Allocate small chunks of memory million times
|
||||
for (int i = 0; i < MaxAllocPoolIter ; i++) {
|
||||
for (int i = 0; i < MaxAllocPoolIter; i++) {
|
||||
if ((err = hipMalloc(&ptr, BuffSize)) != hipSuccess) {
|
||||
HIP_CHECK(hipMemGetInfo(&avail, &tot));
|
||||
|
||||
INFO("Loop regression pool allocation failure. " <<
|
||||
"Total gpu memory " << tot/(1024.0*1024.0) <<", Free memory " <<
|
||||
avail/(1024.0*1024.0) << " iter " << i << " error "
|
||||
<< hipGetErrorString(err));
|
||||
INFO("Loop regression pool allocation failure. "
|
||||
<< "Total gpu memory " << tot / (1024.0 * 1024.0) << ", Free memory "
|
||||
<< avail / (1024.0 * 1024.0) << " iter " << i << " error " << hipGetErrorString(err));
|
||||
|
||||
REQUIRE(false);
|
||||
}
|
||||
@@ -375,7 +364,7 @@ TEST_CASE("Unit_hipMalloc_AllocateAndPoolBuffers") {
|
||||
}
|
||||
|
||||
// Free ptrs at later point of time
|
||||
for ( auto &t : ptrlist ) {
|
||||
for (auto& t : ptrlist) {
|
||||
HIP_CHECK(hipFree(t));
|
||||
}
|
||||
|
||||
@@ -404,7 +393,7 @@ TEST_CASE("Unit_hipMalloc_Multithreaded_MultiGPU") {
|
||||
threadlist.push_back(std::thread(threadFunc, i));
|
||||
}
|
||||
|
||||
for (auto &t : threadlist) {
|
||||
for (auto& t : threadlist) {
|
||||
t.join();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,236 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2021 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 WARRANNTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNNESS 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 INN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
Testcase Scenarios :
|
||||
1) Test hipMemset3D() with uninitialized devPitchedPtr.
|
||||
2) Test hipMemset3DAsync() with uninitialized devPitchedPtr.
|
||||
|
||||
3) Reset devPitchedPtr to zero and check return value for hipMemset3D().
|
||||
4) Reset devPitchedPtr to zero and check return value for hipMemset3DAsync().
|
||||
|
||||
5) Test hipMemset3D() with extent.width as max size_t and keeping height,
|
||||
depth as valid values.
|
||||
6) Test hipMemset3DAsync() with extent.width as max size_t and keeping height,
|
||||
depth as valid values.
|
||||
7) Test hipMemset3D() with extent.height as max size_t and keeping width,
|
||||
depth as valid values.
|
||||
8) Test hipMemset3DAsync() with extent.height as max size_t and keeping width,
|
||||
depth as valid values.
|
||||
9) Test hipMemset3D() with extent.depth as max size_t and keeping height,
|
||||
width as valid values.
|
||||
10) Test hipMemset3DAsync() with extent.depth as max size_t and keeping height,
|
||||
width as valid values.
|
||||
|
||||
11) Device Ptr out bound and extent(0) passed for hipMemset3D().
|
||||
12) Device Ptr out bound and extent(0) passed for hipMemset3DAsync().
|
||||
|
||||
13) Device Ptr out bound and valid extent passed for hipMemset3D().
|
||||
14) Device Ptr out bound and valid extent passed for hipMemset3DAsync().
|
||||
*/
|
||||
|
||||
#include <hip_test_common.hh>
|
||||
|
||||
TEST_CASE("Unit_hipMemset3D_Negative") {
|
||||
hipError_t ret;
|
||||
hipPitchedPtr devPitchedPtr;
|
||||
constexpr int memsetval = 1;
|
||||
constexpr size_t numH = 256, numW = 256;
|
||||
constexpr size_t depth = 10;
|
||||
constexpr size_t width = numW * sizeof(char);
|
||||
hipExtent extent = make_hipExtent(width, numH, depth);
|
||||
|
||||
HIP_CHECK(hipMalloc3D(&devPitchedPtr, extent));
|
||||
|
||||
SECTION("Using uninitialized devpitched ptr") {
|
||||
hipPitchedPtr devPitchedUnPtr;
|
||||
|
||||
ret = hipMemset3D(devPitchedUnPtr, memsetval, extent);
|
||||
REQUIRE(ret != hipSuccess);
|
||||
}
|
||||
|
||||
SECTION("Reset devPitchedPtr to zero") {
|
||||
hipPitchedPtr rdevPitchedPtr{};
|
||||
|
||||
ret = hipMemset3D(rdevPitchedPtr, memsetval, extent);
|
||||
REQUIRE(ret != hipSuccess);
|
||||
}
|
||||
|
||||
SECTION("Pass extent fields as max size_t") {
|
||||
hipExtent extMW = make_hipExtent(std::numeric_limits<std::size_t>::max(),
|
||||
numH,
|
||||
depth);
|
||||
hipExtent extMH = make_hipExtent(width,
|
||||
std::numeric_limits<std::size_t>::max(),
|
||||
depth);
|
||||
hipExtent extMD = make_hipExtent(width,
|
||||
numH,
|
||||
std::numeric_limits<std::size_t>::max());
|
||||
|
||||
ret = hipMemset3D(devPitchedPtr, memsetval, extMW);
|
||||
REQUIRE(ret != hipSuccess);
|
||||
|
||||
ret = hipMemset3D(devPitchedPtr, memsetval, extMH);
|
||||
REQUIRE(ret != hipSuccess);
|
||||
|
||||
if ((TestContext::get()).isAmd()) {
|
||||
ret = hipMemset3D(devPitchedPtr, memsetval, extMD);
|
||||
REQUIRE(ret != hipSuccess);
|
||||
} else {
|
||||
WARN("Test is skipped for max depth."
|
||||
<< "Cuda doesn't check the maximum depth of extent field");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Device Ptr out bound and extent(0) passed for memset") {
|
||||
size_t pitch = devPitchedPtr.pitch;
|
||||
size_t slicePitch = pitch * extent.height;
|
||||
constexpr auto advanceOffset = 10;
|
||||
|
||||
// Point devptr to end of allocated memory
|
||||
char *devPtrMod = (reinterpret_cast<char *>(devPitchedPtr.ptr))
|
||||
+ depth * slicePitch;
|
||||
|
||||
// Advance devptr further to go out of boundary
|
||||
devPtrMod = devPtrMod + advanceOffset;
|
||||
hipPitchedPtr modDevPitchedPtr = make_hipPitchedPtr(devPtrMod, pitch,
|
||||
numW * sizeof(char), numH);
|
||||
hipExtent extent0{};
|
||||
ret = hipMemset3D(modDevPitchedPtr, memsetval, extent0);
|
||||
|
||||
// api expected to check extent0 and return success before going for ptr.
|
||||
REQUIRE(ret == hipSuccess);
|
||||
}
|
||||
|
||||
SECTION("Device Ptr out bound and valid extent passed for memset") {
|
||||
size_t pitch = devPitchedPtr.pitch;
|
||||
size_t slicePitch = pitch * extent.height;
|
||||
constexpr auto advanceOffset = 10;
|
||||
|
||||
// Point devptr to end of allocated memory
|
||||
char *devPtrMod = (reinterpret_cast<char *>(devPitchedPtr.ptr))
|
||||
+ depth * slicePitch;
|
||||
|
||||
// Advance devptr further to go out of boundary
|
||||
devPtrMod = devPtrMod + advanceOffset;
|
||||
hipPitchedPtr modDevPitchedPtr = make_hipPitchedPtr(devPtrMod, pitch,
|
||||
numW * sizeof(char), numH);
|
||||
ret = hipMemset3D(modDevPitchedPtr, memsetval, extent);
|
||||
|
||||
REQUIRE(ret != hipSuccess);
|
||||
}
|
||||
|
||||
HIP_CHECK(hipFree(devPitchedPtr.ptr));
|
||||
}
|
||||
|
||||
TEST_CASE("Unit_hipMemset3DAsync_Negative") {
|
||||
hipError_t ret;
|
||||
hipPitchedPtr devPitchedPtr;
|
||||
hipStream_t stream;
|
||||
constexpr int memsetval = 1;
|
||||
constexpr size_t numH = 256;
|
||||
constexpr size_t numW = 256;
|
||||
constexpr size_t depth = 10;
|
||||
constexpr size_t width = numW * sizeof(char);
|
||||
hipExtent extent = make_hipExtent(width, numH, depth);
|
||||
|
||||
HIP_CHECK(hipStreamCreate(&stream));
|
||||
HIP_CHECK(hipMalloc3D(&devPitchedPtr, extent));
|
||||
|
||||
SECTION("Using uninitialized devpitched ptr") {
|
||||
hipPitchedPtr devPitchedUnPtr;
|
||||
|
||||
ret = hipMemset3DAsync(devPitchedUnPtr, memsetval, extent, stream);
|
||||
REQUIRE(ret != hipSuccess);
|
||||
}
|
||||
|
||||
SECTION("Reset devPitchedPtr to zero") {
|
||||
hipPitchedPtr rdevPitchedPtr{};
|
||||
|
||||
ret = hipMemset3DAsync(rdevPitchedPtr, memsetval, extent, stream);
|
||||
REQUIRE(ret != hipSuccess);
|
||||
}
|
||||
|
||||
SECTION("Pass extent fields as max size_t") {
|
||||
hipExtent extMW = make_hipExtent(std::numeric_limits<std::size_t>::max(),
|
||||
numH,
|
||||
depth);
|
||||
hipExtent extMH = make_hipExtent(width,
|
||||
std::numeric_limits<std::size_t>::max(),
|
||||
depth);
|
||||
hipExtent extMD = make_hipExtent(width,
|
||||
numH,
|
||||
std::numeric_limits<std::size_t>::max());
|
||||
|
||||
ret = hipMemset3DAsync(devPitchedPtr, memsetval, extMW, stream);
|
||||
REQUIRE(ret != hipSuccess);
|
||||
|
||||
ret = hipMemset3DAsync(devPitchedPtr, memsetval, extMH, stream);
|
||||
REQUIRE(ret != hipSuccess);
|
||||
|
||||
if ((TestContext::get()).isAmd()) {
|
||||
ret = hipMemset3DAsync(devPitchedPtr, memsetval, extMD, stream);
|
||||
REQUIRE(ret != hipSuccess);
|
||||
} else {
|
||||
WARN("Test is skipped for max depth."
|
||||
<< "Cuda doesn't check the maximum depth of extent field");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Device Ptr out bound and extent(0) passed for memset") {
|
||||
size_t pitch = devPitchedPtr.pitch;
|
||||
size_t slicePitch = pitch * extent.height;
|
||||
constexpr auto advanceOffset = 10;
|
||||
|
||||
// Point devptr to end of allocated memory
|
||||
char *devPtrMod = (reinterpret_cast<char *>(devPitchedPtr.ptr))
|
||||
+ depth * slicePitch;
|
||||
|
||||
// Advance devptr further to go out of boundary
|
||||
devPtrMod = devPtrMod + advanceOffset;
|
||||
hipPitchedPtr modDevPitchedPtr = make_hipPitchedPtr(devPtrMod, pitch,
|
||||
numW * sizeof(char), numH);
|
||||
hipExtent extent0{};
|
||||
ret = hipMemset3DAsync(modDevPitchedPtr, memsetval, extent0, stream);
|
||||
|
||||
// api expected to check extent0 and return success before going for ptr.
|
||||
REQUIRE(ret == hipSuccess);
|
||||
}
|
||||
|
||||
SECTION("Device Ptr out bound and valid extent passed for memset") {
|
||||
size_t pitch = devPitchedPtr.pitch;
|
||||
size_t slicePitch = pitch * extent.height;
|
||||
constexpr auto advanceOffset = 10;
|
||||
|
||||
// Point devptr to end of allocated memory
|
||||
char *devPtrMod = (reinterpret_cast<char *>(devPitchedPtr.ptr))
|
||||
+ depth * slicePitch;
|
||||
|
||||
// Advance devptr further to go out of boundary
|
||||
devPtrMod = devPtrMod + advanceOffset;
|
||||
hipPitchedPtr modDevPitchedPtr = make_hipPitchedPtr(devPtrMod, pitch,
|
||||
numW * sizeof(char), numH);
|
||||
ret = hipMemset3DAsync(modDevPitchedPtr, memsetval, extent, stream);
|
||||
|
||||
REQUIRE(ret != hipSuccess);
|
||||
}
|
||||
|
||||
HIP_CHECK(hipStreamDestroy(stream));
|
||||
HIP_CHECK(hipFree(devPitchedPtr.ptr));
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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 WARRANNTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNNESS 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 INN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
Testcase Scenarios :
|
||||
1) Test hipMemset apis with invalid pointer and invalid 2D pitch.
|
||||
2) Test hipMemsetAsync apis with invalid pointer and invalid 2D pitch.
|
||||
*/
|
||||
|
||||
|
||||
#include <hip_test_common.hh>
|
||||
|
||||
#define N 50
|
||||
#define MEMSETVAL 0x42
|
||||
|
||||
/**
|
||||
* Testcase validates hipMemset apis behavior with
|
||||
* invalid pointer and invalid 2D pitch value.
|
||||
*/
|
||||
TEST_CASE("Unit_hipMemset_InvalidPtrTests") {
|
||||
hipError_t ret;
|
||||
constexpr int Nbytes = N*sizeof(char);
|
||||
char *A_d;
|
||||
|
||||
SECTION("hipMemset with null") {
|
||||
ret = hipMemset(NULL, MEMSETVAL , Nbytes);
|
||||
REQUIRE(ret != hipSuccess);
|
||||
}
|
||||
|
||||
SECTION("hipMemset with hostptr") {
|
||||
char *A_h;
|
||||
A_h = reinterpret_cast<char *>(malloc(Nbytes));
|
||||
|
||||
ret = hipMemset(A_h, MEMSETVAL, Nbytes);
|
||||
REQUIRE(ret != hipSuccess);
|
||||
|
||||
free(A_h);
|
||||
}
|
||||
|
||||
SECTION("hipMemsetD32 with null") {
|
||||
ret = hipMemsetD32(NULL, MEMSETVAL , Nbytes);
|
||||
REQUIRE(ret != hipSuccess);
|
||||
}
|
||||
|
||||
SECTION("hipMemsetD16 with null") {
|
||||
ret = hipMemsetD16(NULL, MEMSETVAL , Nbytes);
|
||||
REQUIRE(ret != hipSuccess);
|
||||
}
|
||||
|
||||
SECTION("hipMemsetD8 with null") {
|
||||
ret = hipMemsetD8(NULL, MEMSETVAL , Nbytes);
|
||||
REQUIRE(ret != hipSuccess);
|
||||
}
|
||||
|
||||
SECTION("hipMemset2D with null") {
|
||||
constexpr size_t NUM_H = 256, NUM_W = 256;
|
||||
size_t pitch_A;
|
||||
size_t width = NUM_W * sizeof(char);
|
||||
|
||||
HIP_CHECK(hipMallocPitch(reinterpret_cast<void**>(&A_d), &pitch_A,
|
||||
width , NUM_H));
|
||||
ret = hipMemset2D(NULL, pitch_A, MEMSETVAL, NUM_W, NUM_H);
|
||||
REQUIRE(ret != hipSuccess);
|
||||
|
||||
hipFree(A_d);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Testcase validates hipMemsetAsync apis behavior with
|
||||
* invalid pointer and invalid 2D pitch value.
|
||||
*/
|
||||
TEST_CASE("Unit_hipMemsetAsync_InvalidPtrTests") {
|
||||
hipError_t ret;
|
||||
constexpr int Nbytes = N*sizeof(char);
|
||||
char *A_d;
|
||||
|
||||
SECTION("hipMemsetAsync with null") {
|
||||
ret = hipMemsetAsync(NULL, MEMSETVAL, Nbytes , 0);
|
||||
REQUIRE(ret != hipSuccess);
|
||||
}
|
||||
|
||||
SECTION("hipMemsetD32Async with null") {
|
||||
ret = hipMemsetD32Async(NULL, MEMSETVAL , Nbytes, 0);
|
||||
REQUIRE(ret != hipSuccess);
|
||||
}
|
||||
|
||||
SECTION("hipMemsetD16Async with null") {
|
||||
ret = hipMemsetD16Async(NULL, MEMSETVAL , Nbytes, 0);
|
||||
REQUIRE(ret != hipSuccess);
|
||||
}
|
||||
|
||||
SECTION("hipMemsetD8Async with null") {
|
||||
ret = hipMemsetD8Async(NULL, MEMSETVAL , Nbytes, 0);
|
||||
REQUIRE(ret != hipSuccess);
|
||||
}
|
||||
|
||||
SECTION("hipMemset2DAsync with null") {
|
||||
constexpr size_t NUM_H = 256, NUM_W = 256;
|
||||
size_t pitch_A;
|
||||
size_t width = NUM_W * sizeof(char);
|
||||
|
||||
HIP_CHECK(hipMallocPitch(reinterpret_cast<void**>(&A_d), &pitch_A,
|
||||
width , NUM_H));
|
||||
ret = hipMemset2DAsync(NULL, pitch_A, MEMSETVAL, NUM_W, NUM_H, 0);
|
||||
REQUIRE(ret != hipSuccess);
|
||||
|
||||
hipFree(A_d);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 WARRANNTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNNESS 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 INN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <hip_test_common.hh>
|
||||
#include <limits>
|
||||
#include "hip/driver_types.h"
|
||||
|
||||
static constexpr size_t memsetVal{0x42};
|
||||
static constexpr hipExtent validExtent{184, 57, 16};
|
||||
static constexpr size_t height{validExtent.height};
|
||||
static constexpr size_t width{validExtent.width};
|
||||
static constexpr hipStream_t nullStream{nullptr};
|
||||
|
||||
inline void testHipMemsetApis(void* dst, int value, size_t sizeBytes,
|
||||
hipError_t expectedReturn = hipErrorInvalidValue) {
|
||||
HIP_CHECK_ERROR(hipMemset(dst, value, sizeBytes), expectedReturn);
|
||||
HIP_CHECK_ERROR(hipMemsetAsync(dst, value, sizeBytes, nullStream), expectedReturn);
|
||||
|
||||
hipDeviceptr_t devicePtrDst = reinterpret_cast<hipDeviceptr_t>(dst);
|
||||
HIP_CHECK_ERROR(hipMemsetD32(devicePtrDst, value, sizeBytes), expectedReturn);
|
||||
HIP_CHECK_ERROR(hipMemsetD32Async(devicePtrDst, value, sizeBytes, nullStream), expectedReturn);
|
||||
HIP_CHECK_ERROR(hipMemsetD16(devicePtrDst, value, sizeBytes), expectedReturn);
|
||||
HIP_CHECK_ERROR(hipMemsetD16Async(devicePtrDst, value, sizeBytes, nullStream), expectedReturn);
|
||||
HIP_CHECK_ERROR(hipMemsetD8(devicePtrDst, value, sizeBytes), expectedReturn);
|
||||
HIP_CHECK_ERROR(hipMemsetD8Async(devicePtrDst, value, sizeBytes, nullStream), expectedReturn);
|
||||
}
|
||||
|
||||
inline void testHipMemset2DApis(void* dst, size_t pitch, int value, size_t width, size_t height,
|
||||
hipError_t expectedReturn = hipErrorInvalidValue) {
|
||||
HIP_CHECK_ERROR(hipMemset2D(dst, pitch, value, width, height), expectedReturn);
|
||||
HIP_CHECK_ERROR(hipMemset2DAsync(dst, pitch, value, width, height, nullStream), expectedReturn);
|
||||
}
|
||||
|
||||
|
||||
inline void testHipMemset3DApis(hipPitchedPtr& pitchedDevPtr, int value, const hipExtent& extent,
|
||||
hipError_t expectedReturn = hipErrorInvalidValue) {
|
||||
HIP_CHECK_ERROR(hipMemset3D(pitchedDevPtr, value, extent), expectedReturn);
|
||||
HIP_CHECK_ERROR(hipMemset3DAsync(pitchedDevPtr, value, extent, nullStream), expectedReturn);
|
||||
}
|
||||
|
||||
TEST_CASE("Unit_hipMemset_Negative_InvalidPtr") {
|
||||
void* dst;
|
||||
|
||||
SECTION("Uninitialized Dst") {}
|
||||
SECTION("Nullptr as dst") { dst = nullptr; }
|
||||
|
||||
std::unique_ptr<char[]> hostPtr;
|
||||
SECTION("Host Pointer as Dst") {
|
||||
hostPtr.reset(new char[width]);
|
||||
dst = hostPtr.get();
|
||||
}
|
||||
|
||||
testHipMemsetApis(dst, memsetVal, width);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("Unit_hipMemset_Negative_OutOfBoundsSize") {
|
||||
#if HT_AMD
|
||||
HipTest::HIP_SKIP_TEST("EXSWCPHIPT-20");
|
||||
#endif
|
||||
|
||||
#if !HT_AMD
|
||||
void* dst;
|
||||
constexpr size_t outOfBoundsSize{width + 1};
|
||||
HIP_CHECK(hipMalloc(&dst, width));
|
||||
|
||||
testHipMemsetApis(dst, memsetVal, outOfBoundsSize);
|
||||
HIP_CHECK(hipFree(dst));
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_CASE("Unit_hipMemset_Negative_OutOfBoundsPtr") {
|
||||
void* dst;
|
||||
HIP_CHECK(hipMalloc(&dst, width));
|
||||
void* outOfBoundsPtr{reinterpret_cast<char*>(dst) + width + 1};
|
||||
testHipMemsetApis(outOfBoundsPtr, memsetVal, width);
|
||||
HIP_CHECK(hipFree(dst));
|
||||
}
|
||||
|
||||
TEST_CASE("Unit_hipMemset2D_Negative_InvalidPtr") {
|
||||
void* dst;
|
||||
SECTION("Uninitialized Dst") {}
|
||||
SECTION("Nullptr as Dst") { dst = nullptr; }
|
||||
|
||||
std::unique_ptr<char[]> hostPtr;
|
||||
SECTION("Host Pointer as Dst") {
|
||||
hostPtr.reset(new char[height * width]);
|
||||
dst = hostPtr.get();
|
||||
}
|
||||
|
||||
void* A_d;
|
||||
size_t pitch_A;
|
||||
HIP_CHECK(hipMallocPitch(&A_d, &pitch_A, width, height));
|
||||
testHipMemset2DApis(dst, pitch_A, memsetVal, width, height);
|
||||
hipFree(A_d);
|
||||
}
|
||||
|
||||
TEST_CASE("Unit_hipMemset2D_Negative_InvalidSizes") {
|
||||
#if HT_AMD
|
||||
HipTest::HIP_SKIP_TEST("EXSWCPHIPT-52");
|
||||
#endif
|
||||
|
||||
void* dst;
|
||||
size_t realPitch;
|
||||
HIP_CHECK(hipMallocPitch(&dst, &realPitch, width, height));
|
||||
|
||||
SECTION("Invalid Pitch") {
|
||||
size_t invalidPitch = 1;
|
||||
testHipMemset2DApis(dst, invalidPitch, memsetVal, width, height);
|
||||
}
|
||||
|
||||
SECTION("Invalid Width") {
|
||||
size_t invalidWidth = realPitch + 1;
|
||||
testHipMemset2DApis(dst, realPitch, memsetVal, invalidWidth, height);
|
||||
}
|
||||
|
||||
#if !HT_AMD /* EXSWCPHIPT-52 */
|
||||
SECTION("Invalid height") {
|
||||
size_t invalidHeight = height + 1;
|
||||
testHipMemset2DApis(dst, realPitch, memsetVal, width, invalidHeight);
|
||||
}
|
||||
#endif
|
||||
HIP_CHECK(hipFree(dst));
|
||||
}
|
||||
|
||||
TEST_CASE("Unit_hipMemset2D_Negative_OutOfBoundsPtr") {
|
||||
void* dst;
|
||||
size_t realPitch;
|
||||
|
||||
HIP_CHECK(hipMallocPitch(&dst, &realPitch, width, height));
|
||||
void* outOfBoundsPtr{reinterpret_cast<char*>(dst) + realPitch * height + 1};
|
||||
testHipMemset2DApis(outOfBoundsPtr, realPitch, memsetVal, width, height);
|
||||
HIP_CHECK(hipFree(dst));
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("Unit_hipMemset3D_Negative_InvalidPtr") {
|
||||
hipPitchedPtr pitchedDevPtr;
|
||||
|
||||
SECTION("Uninitialized PitchedDevPtr") {}
|
||||
SECTION("Zero Initialized PitchedDevPtr") { pitchedDevPtr = {}; }
|
||||
|
||||
testHipMemset3DApis(pitchedDevPtr, memsetVal, validExtent);
|
||||
}
|
||||
|
||||
TEST_CASE("Unit_hipMemset3D_Negative_ModifiedPtr") {
|
||||
hipPitchedPtr pitchedDevPtr;
|
||||
|
||||
HIP_CHECK(hipMalloc3D(&pitchedDevPtr, validExtent));
|
||||
void* allocatedMemory{pitchedDevPtr.ptr};
|
||||
|
||||
SECTION("Nullptr Dst") { pitchedDevPtr.ptr = nullptr; }
|
||||
|
||||
std::unique_ptr<char[]> hostPtr;
|
||||
SECTION("Host Pointer as Dst") {
|
||||
hostPtr.reset(new char[validExtent.width * validExtent.height * validExtent.depth]);
|
||||
pitchedDevPtr.ptr = hostPtr.get();
|
||||
}
|
||||
|
||||
SECTION("Invalid Pitch") { pitchedDevPtr.pitch = 1; }
|
||||
|
||||
CAPTURE(pitchedDevPtr.ptr, pitchedDevPtr.pitch, pitchedDevPtr.xsize, pitchedDevPtr.ysize);
|
||||
testHipMemset3DApis(pitchedDevPtr, memsetVal, validExtent);
|
||||
HIP_CHECK(hipFree(allocatedMemory));
|
||||
}
|
||||
|
||||
TEST_CASE("Unit_hipMemset3D_Negative_InvalidSizes") {
|
||||
#if HT_AMD
|
||||
HipTest::HIP_SKIP_TEST("EXSWCPHIPT-52");
|
||||
#endif
|
||||
|
||||
hipPitchedPtr pitchedDevPtr;
|
||||
HIP_CHECK(hipMalloc3D(&pitchedDevPtr, validExtent));
|
||||
hipExtent invalidExtent{validExtent};
|
||||
|
||||
SECTION("Max Width") { invalidExtent.width = std::numeric_limits<std::size_t>::max(); }
|
||||
|
||||
SECTION("Max Height") { invalidExtent.height = std::numeric_limits<std::size_t>::max(); }
|
||||
|
||||
#if !HT_NVIDIA /* This case hangs on Nvidia */
|
||||
SECTION("Max Depth") { invalidExtent.depth = std::numeric_limits<std::size_t>::max(); }
|
||||
#endif
|
||||
|
||||
SECTION("Invalid Width") { invalidExtent.width = pitchedDevPtr.pitch + 1; }
|
||||
|
||||
#if !HT_AMD /* EXSWCPHIPT-52 */
|
||||
SECTION("Invalid height") { invalidExtent.height += 1; }
|
||||
|
||||
SECTION("Invalid depth") { invalidExtent.depth += 1; }
|
||||
#endif
|
||||
|
||||
CAPTURE(invalidExtent.width, invalidExtent.height, invalidExtent.depth);
|
||||
testHipMemset3DApis(pitchedDevPtr, memsetVal, invalidExtent);
|
||||
HIP_CHECK(hipFree(pitchedDevPtr.ptr));
|
||||
}
|
||||
|
||||
TEST_CASE("Unit_hipMemset3D_Negative_OutOfBounds") {
|
||||
hipPitchedPtr pitchedDevPtr;
|
||||
|
||||
HIP_CHECK(hipMalloc3D(&pitchedDevPtr, validExtent));
|
||||
hipPitchedPtr outOfBoundsPtr{pitchedDevPtr};
|
||||
outOfBoundsPtr.ptr = reinterpret_cast<char*>(pitchedDevPtr.ptr) +
|
||||
pitchedDevPtr.pitch * validExtent.height * validExtent.depth + 1;
|
||||
|
||||
SECTION("Extent Equal to 0") {
|
||||
hipExtent zeroExtent{0, 0, 0};
|
||||
testHipMemset3DApis(outOfBoundsPtr, memsetVal, zeroExtent, hipSuccess);
|
||||
}
|
||||
|
||||
SECTION("Valid Extent") { testHipMemset3DApis(outOfBoundsPtr, memsetVal, validExtent); }
|
||||
|
||||
HIP_CHECK(hipFree(pitchedDevPtr.ptr));
|
||||
}
|
||||
@@ -336,3 +336,72 @@ TEST_CASE("Unit_hipPointerGetAttributes_MultiThread") {
|
||||
std::thread t4(clusterAllocs, 1000, 1, 4);
|
||||
if (serialize) t4.join();
|
||||
}
|
||||
|
||||
TEST_CASE("Unit_hipPointerGetAttributes_Negative") {
|
||||
SECTION("Invalid Attributes Pointer") {
|
||||
int* dPtr{nullptr};
|
||||
HIP_CHECK(hipMalloc(&dPtr, sizeof(int)));
|
||||
HIP_CHECK_ERROR(hipPointerGetAttributes(nullptr, dPtr), hipErrorInvalidValue);
|
||||
HIP_CHECK(hipFree(dPtr));
|
||||
}
|
||||
|
||||
SECTION("Invalid Device Pointer") {
|
||||
hipPointerAttribute_t attributes{};
|
||||
HIP_CHECK_ERROR(hipPointerGetAttributes(&attributes, nullptr), hipErrorInvalidValue);
|
||||
}
|
||||
}
|
||||
|
||||
// Run this test for all devices for DeviceMemory, HostMemory, ManagedMemory and MappedMemory
|
||||
TEST_CASE("Unit_hipPointerGetAttributes_GpuIter") {
|
||||
int deviceCount{0};
|
||||
HIP_CHECK(hipGetDeviceCount(&deviceCount));
|
||||
REQUIRE(deviceCount != 0);
|
||||
|
||||
// Memory Types
|
||||
enum MemoryTypes { DeviceMemory = 0, HostMemory, MappedMemory };
|
||||
auto MemoryType =
|
||||
GENERATE(MemoryTypes::DeviceMemory, MemoryTypes::HostMemory, MemoryTypes::MappedMemory);
|
||||
|
||||
INFO("Memory Type: " << MemoryType);
|
||||
|
||||
int* ptr{nullptr};
|
||||
for (int i = 0; i < deviceCount; i++) {
|
||||
HIP_CHECK(hipSetDevice(i));
|
||||
|
||||
ptr = nullptr;
|
||||
if (MemoryType == MemoryTypes::DeviceMemory) {
|
||||
HIP_CHECK(hipMalloc(&ptr, sizeof(int)));
|
||||
} else if (MemoryType == MemoryTypes::HostMemory) {
|
||||
HIP_CHECK(hipHostMalloc(&ptr, sizeof(int)));
|
||||
} else if (MemoryType == MemoryTypes::MappedMemory) {
|
||||
HIP_CHECK(hipHostMalloc(&ptr, sizeof(int), hipHostMallocMapped));
|
||||
}
|
||||
|
||||
REQUIRE(ptr != nullptr);
|
||||
hipPointerAttribute_t attributes{};
|
||||
HIP_CHECK(hipPointerGetAttributes(&attributes, ptr));
|
||||
|
||||
REQUIRE(attributes.device == i); // Device Check
|
||||
|
||||
// Memory address and type check
|
||||
if (MemoryType == MemoryTypes::DeviceMemory) {
|
||||
REQUIRE(attributes.memoryType == hipMemoryTypeDevice);
|
||||
REQUIRE(attributes.devicePointer == ptr);
|
||||
REQUIRE(attributes.hostPointer == nullptr);
|
||||
} else if (MemoryType == MemoryTypes::HostMemory) {
|
||||
REQUIRE(attributes.memoryType == hipMemoryTypeHost);
|
||||
REQUIRE(attributes.hostPointer == ptr);
|
||||
} else if (MemoryType == MemoryTypes::MappedMemory) {
|
||||
int* devicePtr{nullptr};
|
||||
HIP_CHECK(hipHostGetDevicePointer(reinterpret_cast<void**>(&devicePtr), ptr, 0));
|
||||
REQUIRE(attributes.hostPointer == ptr);
|
||||
REQUIRE(attributes.hostPointer == devicePtr);
|
||||
}
|
||||
|
||||
if (MemoryType == MemoryTypes::DeviceMemory) {
|
||||
HIP_CHECK(hipFree(ptr));
|
||||
} else if (MemoryType == MemoryTypes::MappedMemory || MemoryType == MemoryTypes::HostMemory) {
|
||||
HIP_CHECK(hipHostFree(ptr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved.
|
||||
Copyright (c) 2022 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
|
||||
@@ -16,59 +16,77 @@ 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.
|
||||
*/
|
||||
/**
|
||||
|
||||
/*
|
||||
Testcase Scenarios :
|
||||
1) Negative tests for hipStreamGetPriority api.
|
||||
2) Create stream and check default priority of stream is within range.
|
||||
3) Create stream with high or low priority and check priority is set as expected.
|
||||
4) Create stream with higher priority or lower priority for the priority range returned.
|
||||
4) Create stream with higher priority or lower priority for the priority range returned, the stream
|
||||
priority should be clamped to the priority range.
|
||||
5) Create stream with CUMask and check priority is returned as expected.
|
||||
*/
|
||||
|
||||
#include <hip_test_common.hh>
|
||||
|
||||
/**
|
||||
* Negative tests for hipStreamGetPriority api.
|
||||
* Check the error returned when an invalid pointer to a priority is used.
|
||||
*/
|
||||
TEST_CASE("Unit_hipStreamGetPriority_Negative") {
|
||||
hipStream_t stream = 0;
|
||||
REQUIRE(hipStreamGetPriority(stream, nullptr) == hipErrorInvalidValue);
|
||||
TEST_CASE("Unit_hipStreamGetPriority_InvalidPriorityPointer") {
|
||||
hipStream_t stream{};
|
||||
HIP_CHECK(hipStreamCreate(&stream));
|
||||
HIP_CHECK_ERROR(hipStreamGetPriority(stream, nullptr), hipErrorInvalidValue);
|
||||
HIP_CHECK(hipStreamDestroy(stream));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create stream with higher priority for the priority range returned.
|
||||
* Create stream and check priority.
|
||||
*/
|
||||
TEST_CASE("Unit_hipStreamGetPriority_higher") {
|
||||
TEST_CASE("Unit_hipStreamGetPriority_happy") {
|
||||
int priority_low = 0;
|
||||
int priority_high = 0;
|
||||
int devID = GENERATE(range(0, HipTest::getDeviceCount()));
|
||||
HIP_CHECK(hipSetDevice(devID));
|
||||
HIP_CHECK(hipDeviceGetStreamPriorityRange(&priority_low, &priority_high));
|
||||
hipStream_t stream;
|
||||
HIP_CHECK(hipStreamCreateWithPriority(&stream, hipStreamNonBlocking,
|
||||
priority_high-1));
|
||||
hipStream_t stream{};
|
||||
int priority = 0;
|
||||
HIP_CHECK(hipStreamGetPriority(stream, &priority));
|
||||
REQUIRE(priority == priority_high);
|
||||
HIP_CHECK(hipStreamDestroy(stream));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create stream with lower priority for the priority range returned.
|
||||
*/
|
||||
TEST_CASE("Unit_hipStreamGetPriority_lower") {
|
||||
int priority_low = 0;
|
||||
int priority_high = 0;
|
||||
int devID = GENERATE(range(0, HipTest::getDeviceCount()));
|
||||
HIP_CHECK(hipSetDevice(devID));
|
||||
HIP_CHECK(hipDeviceGetStreamPriorityRange(&priority_low, &priority_high));
|
||||
hipStream_t stream;
|
||||
HIP_CHECK(hipStreamCreateWithPriority(&stream, hipStreamNonBlocking,
|
||||
priority_low+1));
|
||||
int priority = 0;
|
||||
HIP_CHECK(hipStreamGetPriority(stream, &priority));
|
||||
REQUIRE(priority_low == priority);
|
||||
HIP_CHECK(hipStreamDestroy(stream));
|
||||
SECTION("Null Stream") {
|
||||
HIP_CHECK(hipStreamGetPriority(nullptr, &priority));
|
||||
// valid priority
|
||||
REQUIRE(priority_low >= priority);
|
||||
REQUIRE(priority >= priority_high);
|
||||
}
|
||||
SECTION("Created Stream") {
|
||||
SECTION("Default Priority") {
|
||||
HIP_CHECK(hipStreamCreate(&stream));
|
||||
HIP_CHECK(hipStreamGetPriority(stream, &priority));
|
||||
// valid priority
|
||||
// Lower the value higher the priority, higher the value lower the priority
|
||||
REQUIRE(priority_low >= priority);
|
||||
REQUIRE(priority >= priority_high);
|
||||
}
|
||||
SECTION("High Priority") {
|
||||
HIP_CHECK(hipStreamCreateWithPriority(&stream, hipStreamDefault, priority_high));
|
||||
HIP_CHECK(hipStreamGetPriority(stream, &priority));
|
||||
REQUIRE(priority == priority_high);
|
||||
}
|
||||
SECTION("Higher Priority") {
|
||||
HIP_CHECK(hipStreamCreateWithPriority(&stream, hipStreamNonBlocking, priority_high - 1));
|
||||
HIP_CHECK(hipStreamGetPriority(stream, &priority));
|
||||
REQUIRE(priority == priority_high);
|
||||
}
|
||||
SECTION("Low Priority") {
|
||||
HIP_CHECK(hipStreamCreateWithPriority(&stream, hipStreamDefault, priority_low));
|
||||
HIP_CHECK(hipStreamGetPriority(stream, &priority));
|
||||
REQUIRE(priority_low == priority);
|
||||
}
|
||||
SECTION("Lower Priority") {
|
||||
HIP_CHECK(hipStreamCreateWithPriority(&stream, hipStreamNonBlocking, priority_low + 1));
|
||||
HIP_CHECK(hipStreamGetPriority(stream, &priority));
|
||||
REQUIRE(priority_low == priority);
|
||||
}
|
||||
HIP_CHECK(hipStreamDestroy(stream));
|
||||
}
|
||||
}
|
||||
|
||||
#if HT_AMD
|
||||
@@ -76,7 +94,7 @@ TEST_CASE("Unit_hipStreamGetPriority_lower") {
|
||||
* Create stream with CUMask and check priority is returned as expected.
|
||||
*/
|
||||
TEST_CASE("Unit_hipStreamGetPriority_StreamsWithCUMask") {
|
||||
hipStream_t stream;
|
||||
hipStream_t stream{};
|
||||
int priority = 0;
|
||||
int priority_normal = 0;
|
||||
int priority_low = 0;
|
||||
|
||||
Reference in New Issue
Block a user