Merge 'develop' into 'amd-staging'

Change-Id: I01c1ed73eebf3dd931992ab9512d2ab5020ed803


[ROCm/hip-tests commit: fd130f4444]
此提交包含在:
Jenkins
2023-07-06 11:10:57 +00:00
當前提交 cdf16b7d54
共有 130 個檔案被更改,包括 9911 行新增3628 行删除
+11
查看文件
@@ -67,6 +67,17 @@ TEST_CASE("Unit_hipManagedKeyword_MultiGpu") {
int numDevices = 0;
HIP_CHECK(hipGetDeviceCount(&numDevices));
for (int i = 0; i < numDevices; i++){
int managed_memory = 0;
HIPCHECK(hipDeviceGetAttribute(&managed_memory,
hipDeviceAttributeManagedMemory,
i));
if (!managed_memory) {
HipTest::HIP_SKIP_TEST("managed memory access not supported on device");
return;
}
}
for (int i = 0; i < numDevices; i++) {
HIP_CHECK(hipSetDevice(i));
GPU_func<<< 1, 1 >>>();
+1 -1
查看文件
@@ -22,7 +22,7 @@ if(CMAKE_BUILD_TYPE MATCHES "^Debug$")
add_definitions(-DHT_LOG_ENABLE)
endif()
add_library(Main_Object EXCLUDE_FROM_ALL OBJECT main.cc hip_test_context.cc)
add_library(Main_Object EXCLUDE_FROM_ALL OBJECT main.cc hip_test_context.cc hip_test_features.cc)
if(HIP_PLATFORM MATCHES "amd")
set_property(TARGET Main_Object PROPERTY CXX_STANDARD 17)
else()
+11 -11
查看文件
@@ -9,17 +9,17 @@
"Unit_BuiltinAtomicsRTC__fminCoherentGlobalMem",
"Unit_BuiltInAtomicAdd_CoherentGlobalMemWithRtc",
"Unit_hipMemGetAddressRange_Negative",
"Unit_hipExternalMemoryGetMappedBuffer_Vulkan_Positive_Read_Write",
"Unit_hipExternalMemoryGetMappedBuffer_Vulkan_Negative_Parameters",
"Unit_hipImportExternalMemory_Vulkan_Negative_Parameters",
"Unit_hipWaitExternalSemaphoresAsync_Vulkan_Positive_Binary_Semaphore",
"Unit_hipWaitExternalSemaphoresAsync_Vulkan_Positive_Multiple_Semaphores",
"Unit_hipWaitExternalSemaphoresAsync_Vulkan_Negative_Parameters",
"Unit_hipSignalExternalSemaphoresAsync_Vulkan_Positive_Binary_Semaphore",
"Unit_hipSignalExternalSemaphoresAsync_Vulkan_Positive_Multiple_Semaphores",
"Unit_hipSignalExternalSemaphoresAsync_Vulkan_Negative_Parameters",
"Unit_hipImportExternalSemaphore_Vulkan_Negative_Parameters",
"Unit_hipDestroyExternalSemaphore_Vulkan_Negative_Parameters"
"Unit_hipExternalMemoryGetMappedBuffer_Vulkan_Positive_Read_Write",
"Unit_hipExternalMemoryGetMappedBuffer_Vulkan_Negative_Parameters",
"Unit_hipImportExternalMemory_Vulkan_Negative_Parameters",
"Unit_hipWaitExternalSemaphoresAsync_Vulkan_Positive_Binary_Semaphore",
"Unit_hipWaitExternalSemaphoresAsync_Vulkan_Positive_Multiple_Semaphores",
"Unit_hipWaitExternalSemaphoresAsync_Vulkan_Negative_Parameters",
"Unit_hipSignalExternalSemaphoresAsync_Vulkan_Positive_Binary_Semaphore",
"Unit_hipSignalExternalSemaphoresAsync_Vulkan_Positive_Multiple_Semaphores",
"Unit_hipSignalExternalSemaphoresAsync_Vulkan_Negative_Parameters",
"Unit_hipImportExternalSemaphore_Vulkan_Negative_Parameters",
"Unit_hipDestroyExternalSemaphore_Vulkan_Negative_Parameters"
]
}
+14 -9
查看文件
@@ -13,15 +13,17 @@
"Unit_hipInit_Negative",
"Unit_hipDeviceReset_Positive_Basic",
"Unit_hipDeviceReset_Positive_Threaded",
"Unit_hipOccupancyMaxActiveBlocksPerMultiprocessor_Negative_Parameters",
"Unit_hipGraphMemcpyNodeSetParamsToSymbol_Positive_Basic",
"Unit_hipGraphMemcpyNodeSetParamsFromSymbol_Positive_Basic",
"Unit_hipGraphExecMemcpyNodeSetParamsToSymbol_Positive_Basic",
"Unit_hipGraphExecMemcpyNodeSetParamsFromSymbol_Positive_Basic",
"Unit_hipKernelNameRef_Negative_Parameters",
"Unit_hipMemAdvise_AccessedBy_All_Devices",
"Unit_hipMemAdvise_No_Flag_Interference",
"Unit_hipGraphDestroyNode_Complx_ChkNumOfNodesNDep",
"Unit_hipGraphDestroyNode_Complx_ChkNumOfNodesNDep_ClonedGrph",
"Unit_hipGraphDestroyNode_Complx_ChkNumOfNodesNDep_ChldNode",
"Unit_hipMemGetAddressRange_Negative",
"NOTE: The following 2 tests are disabled due to defect - EXSWHTEC-238",
"Unit_hipDrvMemcpy3D_Positive_Array",
"Unit_hipDrvMemcpy3DAsync_Positive_Array",
"Unit_hipMemRangeGetAttribute_Positive_AccessedBy_Basic",
"Unit_hipMemRangeGetAttribute_Positive_AccessedBy_Partial_Range",
"Unit_hipMemRangeGetAttributes_Negative_Parameters",
@@ -29,9 +31,11 @@
"Unit_hipStreamAttachMemAsync_Positive_AttachGlobal",
"Unit_hipStreamAttachMemAsync_Negative_Parameters",
"Unit_hipMemGetAddressRange_Positive",
"Unit_hipStreamGetCaptureInfo_Nullstream_CaptureInfo",
"Unit_hipGraphAddMemcpyNode1D_Negative_Basic",
"intermittent issue: corrupted double-linked list",
"Unit_hipGraphRetainUserObject_Functional_2",
"intermittent issue: failure expected but sucess returned",
"Unit_hipMemAdvise_NegtveTsts",
"Note: Following four tests disabled due to defect - EXSWHTEC-203",
"Unit_hipGraphAddMemsetNode_Positive_Basic - uint16_t",
"Unit_hipGraphAddMemsetNode_Positive_Basic - uint32_t",
@@ -55,13 +59,10 @@
"Disabling test tracked SWDEV-391718",
"Unit_hipMemRangeGetAttribute_TstCountParam",
"Fails in Stress test SWDEV-398971",
"Unit_HMM_OverSubscriptionTst",
"SWDEV-398975 Seg faults in stress test",
"Unit_hipMemcpyWithStream_MultiThread",
"SWDEV-398977 fails in stress tests",
"Unit_hipMemset2DSync",
"SWDEV-398980 fails in Stress test",
"Unit_hipMemcpyPeer_Positive_Synchronization_Behavior",
"SWDEV-398981 fails in stress test",
"Unit_hipStreamCreateWithPriority_MulthreadDefaultflag",
"=== Below tests fail in stress test on 23/06/23 ===",
@@ -80,6 +81,10 @@
"Unit_hipGraphClone_Test_hipGraphExecMemcpyNodeSetParams",
"Unit_hipGraphClone_Test_hipGraphMemcpyNodeSetParams1D_and_exec",
"Unit_hipStreamValue_Wait64_Blocking_NoMask_And",
"Unit_hipStreamValue_Wait64_Blocking_NoMask_Nor"
"Unit_hipStreamValue_Wait64_Blocking_NoMask_Nor",
"=== Below tests fail in stress test on 30/06/23 ===",
"Unit_hipStreamValue_Wait32_Blocking_NoMask_Nor",
"Unit_hipStreamValue_Write - TestParams<uint32_t, PtrType::HostPtr>",
"Unit_hipMemcpyParam2DAsync_multiDevice-StreamOnDiffDevice"
]
}
+7 -1
查看文件
@@ -95,6 +95,7 @@
"Unit_hipStreamSynchronize_NullStreamAndStreamPerThread",
"Note: intermittent Seg fault failure ",
"Unit_hipGraphAddEventRecordNode_Functional_WithoutFlags",
"Unit_hipOccupancyMaxActiveBlocksPerMultiprocessor_Negative_Parameters",
"Unit_hipGraphMemcpyNodeSetParamsToSymbol_Positive_Basic",
"Unit_hipGraphExecMemcpyNodeSetParamsToSymbol_Positive_Basic",
"Unit_hipGraphMemcpyNodeSetParamsFromSymbol_Positive_Basic",
@@ -108,6 +109,9 @@
"Unit_hipGraphDestroyNode_Complx_ChkNumOfNodesNDep_ClonedGrph",
"Unit_hipGraphDestroyNode_Complx_ChkNumOfNodesNDep_ChldNode",
"Unit_hipMemGetAddressRange_Negative",
"NOTE: The following 2 tests are disabled due to defect - EXSWHTEC-238",
"Unit_hipDrvMemcpy3D_Positive_Array",
"Unit_hipDrvMemcpy3DAsync_Positive_Array",
"Unit_hipMemGetAddressRange_Positive",
"Note: devicelib hangs and failures",
"Unit_deviceAllocation_Malloc_PerThread_PrimitiveDataType",
@@ -166,6 +170,8 @@
"SWDEV-402082 - PAL Backend fails to reserve address on GPU except first one",
"Unit_hipGraphInstantiateWithFlags_FlagAutoFreeOnLaunch_check",
"SWDEV-398981 fails in stress test",
"Unit_hipStreamCreateWithPriority_MulthreadDefaultflag"
"Unit_hipStreamCreateWithPriority_MulthreadDefaultflag",
"Note: UUID returned empty on some windows nodes",
"Unit_hipDeviceGetUuid_Positive"
]
}
+1
查看文件
@@ -6,6 +6,7 @@
#include <regex>
#include "hip_test_context.hh"
#include "hip_test_filesystem.hh"
#include "hip_test_features.hh"
void TestContext::detectOS() {
#if (HT_WIN == 1)
+45
查看文件
@@ -0,0 +1,45 @@
#include "hip_test_features.hh"
#include <iostream>
#include <assert.h>
#include "hip_test_context.hh"
std::vector<std::unordered_set<std::string>> GCNArchFeatMap = {
{"gfx90a", "gfx940", "gfx941", "gfx942"}, // CT_FEATURE_FINEGRAIN_HWSUPPORT
{"gfx90a", "gfx940", "gfx941", "gfx942"}, // CT_FEATURE_HMM
{"gfx90a", "gfx940", "gfx941", "gfx942"}, // CT_FEATURE_TEXTURES_NOT_SUPPORTED
};
#if HT_AMD
std::string TrimAndGetGFXName(const std::string& full_gfx_name) {
std::string gfx_name("");
// Split the first part of the delimiter
std::string delimiter = ":";
auto pos = full_gfx_name.find(delimiter);
if (pos == std::string::npos) {
gfx_name = full_gfx_name;
} else {
gfx_name = full_gfx_name.substr(0, pos);
}
assert(gfx_name.substr(0,3) == "gfx");
return gfx_name;
}
#endif
// Check if the GCN Maps
bool CheckIfFeatSupported(enum CTFeatures test_feat, std::string gcn_arch) {
#if HT_NVIDIA
return true; // returning true since feature check does not exist for NV.
#elif HT_AMD
assert(test_feat >= 0 && test_feat < CTFeatures::CT_FEATURE_LAST);
gcn_arch = TrimAndGetGFXName(gcn_arch);
assert(gcn_arch != "");
return (GCNArchFeatMap[test_feat].find(gcn_arch) != GCNArchFeatMap[test_feat].cend());
#else
std::cout<<"Platform has to be either AMD or NVIDIA, asserting..."<<std::endl;
assert(false);
#endif
}
+4 -4
查看文件
@@ -352,13 +352,13 @@ template <> struct MemTraits<MemcpyAsync> {
namespace {
static __global__ void waitKernel(clock_t offset) {
static __global__ void waitKernel(size_t offset) {
auto start = clock();
while ((clock() - start) < offset) {
}
}
static __global__ void waitKernel_gfx11(clock_t offset) {
static __global__ void waitKernel_gfx11(size_t offset) {
#if HT_AMD
auto start = wall_clock64();
while ((wall_clock64() - start) < offset) {
@@ -374,8 +374,8 @@ static size_t findTicksPerSecond() {
int device;
HIP_CHECK(hipGetDevice(&device));
HIP_CHECK(hipGetDeviceProperties(&prop, device));
clock_t devFreq = static_cast<clock_t>(prop.clockRate); // in kHz
clock_t clockTicksPerSecond = devFreq * 1000;
size_t devFreq = static_cast<size_t>(prop.clockRate); // in kHz
size_t clockTicksPerSecond = devFreq * 1000;
// init
hipEvent_t start, stop;
+45 -1
查看文件
@@ -32,7 +32,43 @@ THE SOFTWARE.
/**
* @defgroup GraphTest Graph Management
* @{
* This section describes the graph management types & functions of HIP runtime API.
* This section describes tests for the graph management types & functions of HIP runtime API.
* @}
*/
/**
* @defgroup DeviceTest Device Management
* @{
* This section describes tests for device management functions of HIP runtime API.
* @}
*/
/**
* @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
* @{
* This section describes tests for the initialization and version functions of HIP runtime API.
* @}
*/
@@ -43,6 +79,14 @@ THE SOFTWARE.
* @}
*/
/**
* @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
* @{
+38
查看文件
@@ -0,0 +1,38 @@
/*
Copyright (c) 2021 - 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 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.
*/
#pragma once
#include <string>
#include <vector>
#include <assert.h>
#include <unordered_set>
// Catch Test Features
typedef enum CTFeatures {
CT_FEATURE_FINEGRAIN_HWSUPPORT = 0x0, // FINEGRAIN Supported Hardware.
CT_FEATURE_HMM = 0x1, // HMM Enabled
CT_FEATURE_TEXTURES_NOT_SUPPORTED = 0x2, // Textures not supported
CT_FEATURE_LAST = 0x3
} CTFeatures;
bool CheckIfFeatSupported(enum CTFeatures test_feat, std::string gcn_arch);
+13 -1
查看文件
@@ -31,6 +31,8 @@ THE SOFTWARE.
#include <random>
#include <fstream>
#include <streambuf>
#include <thread>
#include <future>
namespace hip {
/*
@@ -46,6 +48,7 @@ class SpawnProc {
std::string exeName;
std::string resultStr;
std::string tmpFileName;
std::future<int> ret_from_run;
bool captureOutput;
std::string getRandomString(size_t len = 6) {
@@ -68,7 +71,7 @@ class SpawnProc {
exeName = dir.string();
// On Windows, fs::exists returns false without extension.
if (TestContext::get().isWindows()) {
if(fs::path(exeName).extension().empty()) {
if (fs::path(exeName).extension().empty()) {
exeName += ".exe";
}
}
@@ -112,6 +115,15 @@ class SpawnProc {
#endif
}
void run_async(std::string commandLineArgs = "") {
ret_from_run = std::async(std::launch::async, &hip::SpawnProc::run, this, commandLineArgs);
}
int wait() {
ret_from_run.wait();
return ret_from_run.get();
}
std::string getOutput() { return resultStr; }
};
} // namespace hip
+1
查看文件
@@ -1,5 +1,6 @@
/*
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
+800
查看文件
@@ -0,0 +1,800 @@
/*
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 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.
*/
#pragma once
#include <variant>
#include <hip_test_common.hh>
#include <hip/hip_runtime_api.h>
#include <utils.hh>
#include <resource_guards.hh>
using PtrVariant = std::variant<hipPitchedPtr, hipArray_t>;
static hipMemcpyKind ReverseMemcpyDirection(const hipMemcpyKind direction) {
switch (direction) {
case hipMemcpyHostToDevice:
return hipMemcpyDeviceToHost;
case hipMemcpyDeviceToHost:
return hipMemcpyHostToDevice;
default:
return direction;
}
};
static hipMemcpy3DParms GetMemcpy3DParms(PtrVariant dst_ptr, hipPos dst_pos, PtrVariant src_ptr,
hipPos src_pos, hipExtent extent, hipMemcpyKind kind) {
hipMemcpy3DParms parms = {0};
if (std::holds_alternative<hipArray_t>(dst_ptr)) {
parms.dstArray = std::get<hipArray_t>(dst_ptr);
} else {
parms.dstPtr = std::get<hipPitchedPtr>(dst_ptr);
}
parms.dstPos = dst_pos;
if (std::holds_alternative<hipArray_t>(src_ptr)) {
parms.srcArray = std::get<hipArray_t>(src_ptr);
} else {
parms.srcPtr = std::get<hipPitchedPtr>(src_ptr);
}
parms.srcPos = src_pos;
parms.extent = extent;
parms.kind = kind;
return parms;
}
static bool operator==(const hipPitchedPtr& lhs, const hipPitchedPtr& rhs) {
// not checking for xsize currently as hipGraphMemcpyNodeGetParams returns incorrect value
return lhs.ptr == rhs.ptr && lhs.pitch == rhs.pitch && lhs.ysize == rhs.ysize;
}
static bool operator==(const hipPos& lhs, const hipPos& rhs) {
return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z;
}
static bool operator==(const hipExtent& lhs, const hipExtent& rhs) {
return lhs.width == rhs.width && lhs.height == rhs.height && lhs.depth == rhs.depth;
}
static bool operator==(const hipMemcpy3DParms& lhs, const hipMemcpy3DParms& rhs) {
return lhs.dstArray == rhs.dstArray && lhs.dstPtr == rhs.dstPtr && lhs.dstPos == rhs.dstPos &&
lhs.srcArray == rhs.srcArray && lhs.srcPtr == rhs.srcPtr && lhs.srcPos == rhs.srcPos &&
lhs.extent == rhs.extent && lhs.kind == rhs.kind;
}
template <bool async = false, bool graph = false, bool set_params = false>
hipError_t Memcpy3DWrapper(PtrVariant dst_ptr, hipPos dst_pos, PtrVariant src_ptr, hipPos src_pos,
hipExtent extent, hipMemcpyKind kind, hipStream_t stream = nullptr) {
auto parms = GetMemcpy3DParms(dst_ptr, dst_pos, src_ptr, src_pos, extent, kind);
if constexpr (graph) {
hipGraph_t g = nullptr;
HIP_CHECK(hipGraphCreate(&g, 0));
hipGraphNode_t node = nullptr;
if constexpr (set_params) {
auto reversed_parms = GetMemcpy3DParms(src_ptr, src_pos, dst_ptr, dst_pos, extent,
ReverseMemcpyDirection(kind));
HIP_CHECK(hipGraphAddMemcpyNode(&node, g, nullptr, 0, &reversed_parms));
HIP_CHECK(hipGraphMemcpyNodeSetParams(node, &parms));
} else {
HIP_CHECK(hipGraphAddMemcpyNode(&node, g, nullptr, 0, &parms));
}
hipMemcpy3DParms retrieved_params = {0};
HIP_CHECK(hipGraphMemcpyNodeGetParams(node, &retrieved_params));
REQUIRE(parms == retrieved_params);
hipGraphExec_t graph_exec = nullptr;
HIP_CHECK(hipGraphInstantiate(&graph_exec, g, nullptr, nullptr, 0));
HIP_CHECK(hipGraphLaunch(graph_exec, hipStreamPerThread));
HIP_CHECK(hipStreamSynchronize(hipStreamPerThread));
HIP_CHECK(hipGraphExecDestroy(graph_exec));
HIP_CHECK(hipGraphDestroy(g));
return hipSuccess;
}
if constexpr (async) {
return hipMemcpy3DAsync(&parms, stream);
} else {
return hipMemcpy3D(&parms);
}
}
template <bool should_synchronize, typename F>
void Memcpy3DDeviceToHostShell(F memcpy_func, const hipStream_t kernel_stream = nullptr) {
const auto kind = GENERATE(hipMemcpyDeviceToHost, hipMemcpyDefault);
constexpr hipExtent extent{127 * sizeof(int), 128, 8};
LinearAllocGuard3D<int> device_alloc(extent);
const size_t host_pitch = GENERATE_REF(device_alloc.width(), device_alloc.width() + 64);
LinearAllocGuard<int> host_alloc(LinearAllocs::hipHostMalloc,
host_pitch * device_alloc.height() * device_alloc.depth());
const dim3 threads_per_block(32, 32);
const dim3 blocks(device_alloc.width_logical() / threads_per_block.x + 1,
device_alloc.height() / threads_per_block.y + 1, device_alloc.depth());
Iota<<<blocks, threads_per_block>>>(device_alloc.ptr(), device_alloc.pitch(),
device_alloc.width_logical(), device_alloc.height(),
device_alloc.depth());
HIP_CHECK(hipGetLastError());
HIP_CHECK(memcpy_func(
make_hipPitchedPtr(host_alloc.ptr(), host_pitch, device_alloc.width(), device_alloc.height()),
make_hipPos(0, 0, 0), device_alloc.pitched_ptr(), make_hipPos(0, 0, 0), device_alloc.extent(),
kind, kernel_stream));
if constexpr (should_synchronize) {
HIP_CHECK(hipStreamSynchronize(kernel_stream));
}
const auto f = [extent](size_t x, size_t y, size_t z) {
constexpr auto width_logical = extent.width / sizeof(int);
return z * width_logical * extent.height + y * width_logical + x;
};
PitchedMemoryVerify(host_alloc.ptr(), host_pitch, device_alloc.width_logical(),
device_alloc.height(), device_alloc.depth(), f);
}
template <bool should_synchronize, bool enable_peer_access, typename F>
void Memcpy3DDeviceToDeviceShell(F memcpy_func, const hipStream_t kernel_stream = nullptr) {
const auto kind = GENERATE(hipMemcpyDeviceToDevice, hipMemcpyDefault);
constexpr hipExtent extent{127 * sizeof(int), 128, 8};
const auto device_count = HipTest::getDeviceCount();
const auto src_device = GENERATE_COPY(range(0, device_count));
const auto dst_device = GENERATE_COPY(range(0, device_count));
const size_t src_cols_mult = GENERATE(1, 2);
INFO("Src device: " << src_device << ", Dst device: " << dst_device);
HIP_CHECK(hipSetDevice(src_device));
if constexpr (enable_peer_access) {
if (src_device == dst_device) {
return;
}
int can_access_peer = 0;
HIP_CHECK(hipDeviceCanAccessPeer(&can_access_peer, src_device, dst_device));
if (!can_access_peer) {
INFO("Peer access cannot be enabled between devices " << src_device << " " << dst_device);
REQUIRE(can_access_peer);
}
HIP_CHECK(hipDeviceEnablePeerAccess(dst_device, 0));
}
LinearAllocGuard3D<int> src_alloc(extent);
HIP_CHECK(hipSetDevice(src_device));
LinearAllocGuard3D<int> dst_alloc(extent);
HIP_CHECK(hipSetDevice(src_device));
LinearAllocGuard<int> host_alloc(LinearAllocs::hipHostMalloc,
dst_alloc.width() * dst_alloc.height() * dst_alloc.depth());
const dim3 threads_per_block(32, 32);
const dim3 blocks(dst_alloc.width_logical() / threads_per_block.x + 1,
dst_alloc.height() / threads_per_block.y + 1, dst_alloc.depth());
// Using dst_alloc width and height to set only the elements that will be copied over to
// dst_alloc
Iota<<<blocks, threads_per_block>>>(src_alloc.ptr(), src_alloc.pitch(), dst_alloc.width_logical(),
dst_alloc.height(), dst_alloc.depth());
HIP_CHECK(hipGetLastError());
HIP_CHECK(memcpy_func(dst_alloc.pitched_ptr(), make_hipPos(0, 0, 0), src_alloc.pitched_ptr(),
make_hipPos(0, 0, 0), dst_alloc.extent(), kind, kernel_stream));
if constexpr (should_synchronize) {
HIP_CHECK(hipStreamSynchronize(kernel_stream));
}
HIP_CHECK(Memcpy3DWrapper(make_hipPitchedPtr(host_alloc.ptr(), dst_alloc.width(),
dst_alloc.width(), dst_alloc.height()),
make_hipPos(0, 0, 0), dst_alloc.pitched_ptr(), make_hipPos(0, 0, 0),
dst_alloc.extent(), hipMemcpyDeviceToHost));
const auto f = [extent](size_t x, size_t y, size_t z) {
constexpr auto width_logical = extent.width / sizeof(int);
return z * width_logical * extent.height + y * width_logical + x;
};
PitchedMemoryVerify(host_alloc.ptr(), dst_alloc.width(), dst_alloc.width_logical(),
dst_alloc.height(), dst_alloc.depth(), f);
}
template <bool should_synchronize, typename F>
void Memcpy3DHostToDeviceShell(F memcpy_func, const hipStream_t kernel_stream = nullptr) {
const auto kind = GENERATE(hipMemcpyHostToDevice, hipMemcpyDefault);
constexpr hipExtent extent{127 * sizeof(int), 128, 8};
LinearAllocGuard3D<int> device_alloc(extent);
const size_t host_pitch = GENERATE_REF(device_alloc.pitch(), 2 * device_alloc.pitch());
LinearAllocGuard<int> src_host_alloc(LinearAllocs::hipHostMalloc,
host_pitch * device_alloc.height() * device_alloc.depth());
LinearAllocGuard<int> dst_host_alloc(
LinearAllocs::hipHostMalloc,
device_alloc.width() * device_alloc.height() * device_alloc.depth());
const auto f = [extent](size_t x, size_t y, size_t z) {
constexpr auto width_logical = extent.width / sizeof(int);
return z * width_logical * extent.height + y * width_logical + x;
};
PitchedMemorySet(src_host_alloc.ptr(), host_pitch, device_alloc.width_logical(),
device_alloc.height(), device_alloc.depth(), f);
std::fill_n(dst_host_alloc.ptr(),
device_alloc.width_logical() * device_alloc.height() * device_alloc.depth(), 0);
HIP_CHECK(memcpy_func(device_alloc.pitched_ptr(), make_hipPos(0, 0, 0),
make_hipPitchedPtr(src_host_alloc.ptr(), host_pitch, device_alloc.width(),
device_alloc.height()),
make_hipPos(0, 0, 0), device_alloc.extent(), kind, kernel_stream));
if constexpr (should_synchronize) {
HIP_CHECK(hipStreamSynchronize(kernel_stream));
}
HIP_CHECK(Memcpy3DWrapper(make_hipPitchedPtr(dst_host_alloc.ptr(), device_alloc.width(),
device_alloc.width(), device_alloc.height()),
make_hipPos(0, 0, 0), device_alloc.pitched_ptr(), make_hipPos(0, 0, 0),
device_alloc.extent(), hipMemcpyDeviceToHost));
PitchedMemoryVerify(dst_host_alloc.ptr(), device_alloc.width(), device_alloc.width_logical(),
device_alloc.height(), device_alloc.depth(), f);
}
template <bool should_synchronize, typename F>
void Memcpy3DHostToHostShell(F memcpy_func, const hipStream_t kernel_stream = nullptr) {
const auto kind = GENERATE(hipMemcpyHostToHost, hipMemcpyDefault);
constexpr hipExtent extent{127 * sizeof(int), 128, 8};
const size_t padding = GENERATE_COPY(0, 64);
const size_t src_pitch = extent.width + padding;
LinearAllocGuard<int> src_host(LinearAllocs::hipHostMalloc,
src_pitch * extent.height * extent.depth);
LinearAllocGuard<int> dst_host(LinearAllocs::hipHostMalloc,
extent.width * extent.height * extent.depth);
const auto f = [extent](size_t x, size_t y, size_t z) {
constexpr auto width_logical = extent.width / sizeof(int);
return z * width_logical * extent.height + y * width_logical + x;
};
PitchedMemorySet(src_host.ptr(), src_pitch, extent.width / sizeof(int), extent.height,
extent.depth, f);
HIP_CHECK(
memcpy_func(make_hipPitchedPtr(dst_host.ptr(), extent.width, extent.width, extent.height),
make_hipPos(0, 0, 0),
make_hipPitchedPtr(src_host.ptr(), src_pitch, extent.width, extent.height),
make_hipPos(0, 0, 0), extent, kind, kernel_stream));
if constexpr (should_synchronize) {
HIP_CHECK(hipStreamSynchronize(kernel_stream));
}
PitchedMemoryVerify(dst_host.ptr(), extent.width, extent.width / sizeof(int), extent.height,
extent.depth, f);
}
template <bool should_synchronize, typename F>
void Memcpy3DArrayHostShell(F memcpy_func, const hipStream_t kernel_stream = nullptr) {
constexpr hipExtent extent{127, 128, 8};
LinearAllocGuard<int> src_host(LinearAllocs::hipHostMalloc,
extent.width * sizeof(int) * extent.height * extent.depth);
LinearAllocGuard<int> dst_host(LinearAllocs::hipHostMalloc,
extent.width * sizeof(int) * extent.height * extent.depth);
ArrayAllocGuard<int> src_array(extent);
ArrayAllocGuard<int> dst_array(extent);
const auto f = [extent](size_t x, size_t y, size_t z) {
return z * extent.width * extent.height + y * extent.width + x;
};
PitchedMemorySet(src_host.ptr(), extent.width * sizeof(int), extent.width, extent.height,
extent.depth, f);
// Host -> Array
HIP_CHECK(memcpy_func(src_array.ptr(), make_hipPos(0, 0, 0),
make_hipPitchedPtr(src_host.ptr(), extent.width * sizeof(int),
extent.width * sizeof(int), extent.height),
make_hipPos(0, 0, 0), extent, hipMemcpyHostToDevice, kernel_stream));
if constexpr (should_synchronize) {
HIP_CHECK(hipStreamSynchronize(kernel_stream));
}
// Array -> Array
HIP_CHECK(memcpy_func(dst_array.ptr(), make_hipPos(0, 0, 0), src_array.ptr(),
make_hipPos(0, 0, 0), extent, hipMemcpyDeviceToDevice, kernel_stream));
if constexpr (should_synchronize) {
HIP_CHECK(hipStreamSynchronize(kernel_stream));
}
// Array -> Host
HIP_CHECK(memcpy_func(make_hipPitchedPtr(dst_host.ptr(), extent.width * sizeof(int),
extent.width * sizeof(int), extent.height),
make_hipPos(0, 0, 0), dst_array.ptr(), make_hipPos(0, 0, 0), extent,
hipMemcpyDeviceToHost, kernel_stream));
if constexpr (should_synchronize) {
HIP_CHECK(hipStreamSynchronize(kernel_stream));
}
PitchedMemoryVerify(dst_host.ptr(), extent.width * sizeof(int), extent.width, extent.height,
extent.depth, f);
}
template <bool should_synchronize, typename F>
void Memcpy3DArrayDeviceShell(F memcpy_func, const hipStream_t kernel_stream = nullptr) {
constexpr hipExtent extent{127, 128, 8};
LinearAllocGuard<int> host_alloc(LinearAllocs::hipHostMalloc,
extent.width * sizeof(int) * extent.height * extent.depth);
ArrayAllocGuard<int> src_array(extent);
ArrayAllocGuard<int> dst_array(extent);
LinearAllocGuard3D<int> src_device(extent.width, extent.height, extent.depth);
LinearAllocGuard3D<int> dst_device(extent.width, extent.height, extent.depth);
const dim3 threads_per_block(32, 32);
const dim3 blocks(src_device.width_logical() / threads_per_block.x + 1,
src_device.height() / threads_per_block.y + 1, src_device.depth());
Iota<<<blocks, threads_per_block>>>(src_device.ptr(), src_device.pitch(),
src_device.width_logical(), src_device.height(),
src_device.depth());
HIP_CHECK(hipGetLastError());
// Device -> Array
HIP_CHECK(memcpy_func(src_array.ptr(), make_hipPos(0, 0, 0), src_device.pitched_ptr(),
make_hipPos(0, 0, 0), extent, hipMemcpyDeviceToDevice, kernel_stream));
if constexpr (should_synchronize) {
HIP_CHECK(hipStreamSynchronize(kernel_stream));
}
// Array -> Array
HIP_CHECK(memcpy_func(dst_array.ptr(), make_hipPos(0, 0, 0), src_array.ptr(),
make_hipPos(0, 0, 0), extent, hipMemcpyDeviceToDevice, kernel_stream));
if constexpr (should_synchronize) {
HIP_CHECK(hipStreamSynchronize(kernel_stream));
}
// Array -> Device
HIP_CHECK(memcpy_func(dst_device.pitched_ptr(), make_hipPos(0, 0, 0), dst_array.ptr(),
make_hipPos(0, 0, 0), extent, hipMemcpyDeviceToDevice, kernel_stream));
if constexpr (should_synchronize) {
HIP_CHECK(hipStreamSynchronize(kernel_stream));
}
// Device -> Host
HIP_CHECK(memcpy_func(make_hipPitchedPtr(host_alloc.ptr(), extent.width * sizeof(int),
extent.width * sizeof(int), extent.height),
make_hipPos(0, 0, 0), dst_device.pitched_ptr(), make_hipPos(0, 0, 0),
dst_device.extent(), hipMemcpyDeviceToHost, kernel_stream));
if constexpr (should_synchronize) {
HIP_CHECK(hipStreamSynchronize(kernel_stream));
}
const auto f = [extent](size_t x, size_t y, size_t z) {
return z * extent.width * extent.height + y * extent.width + x;
};
PitchedMemoryVerify(host_alloc.ptr(), extent.width * sizeof(int), extent.width, extent.height,
extent.depth, f);
}
template <typename F>
void Memcpy3DHtoDSyncBehavior(F memcpy_func, const bool should_sync,
const hipStream_t kernel_stream = nullptr) {
using LA = LinearAllocs;
const auto host_alloc_type = GENERATE(LA::malloc, LA::hipHostMalloc);
LinearAllocGuard3D<int> device_alloc(make_hipExtent(32 * sizeof(int), 32, 8));
LinearAllocGuard<int> host_alloc(
host_alloc_type, device_alloc.width() * device_alloc.height() * device_alloc.depth());
MemcpySyncBehaviorCheck(
std::bind(memcpy_func, device_alloc.pitched_ptr(), make_hipPos(0, 0, 0),
make_hipPitchedPtr(host_alloc.ptr(), device_alloc.width(), device_alloc.width(),
device_alloc.height()),
make_hipPos(0, 0, 0), device_alloc.extent(), hipMemcpyHostToDevice, kernel_stream),
should_sync, kernel_stream);
}
template <typename F>
void Memcpy3DDtoHPageableSyncBehavior(F memcpy_func, const bool should_sync,
const hipStream_t kernel_stream = nullptr) {
LinearAllocGuard3D<int> device_alloc(make_hipExtent(32 * sizeof(int), 32, 8));
LinearAllocGuard<int> host_alloc(
LinearAllocs::malloc, device_alloc.width() * device_alloc.height() * device_alloc.depth());
MemcpySyncBehaviorCheck(
std::bind(memcpy_func,
make_hipPitchedPtr(host_alloc.ptr(), device_alloc.width(), device_alloc.width(),
device_alloc.height()),
make_hipPos(0, 0, 0), device_alloc.pitched_ptr(), make_hipPos(0, 0, 0),
device_alloc.extent(), hipMemcpyDeviceToHost, kernel_stream),
should_sync, kernel_stream);
}
template <typename F>
void Memcpy3DDtoHPinnedSyncBehavior(F memcpy_func, const bool should_sync,
const hipStream_t kernel_stream = nullptr) {
LinearAllocGuard3D<int> device_alloc(make_hipExtent(32 * sizeof(int), 32, 8));
LinearAllocGuard<int> host_alloc(
LinearAllocs::hipHostMalloc,
device_alloc.width() * device_alloc.height() * device_alloc.depth());
MemcpySyncBehaviorCheck(
std::bind(memcpy_func,
make_hipPitchedPtr(host_alloc.ptr(), device_alloc.width(), device_alloc.width(),
device_alloc.height()),
make_hipPos(0, 0, 0), device_alloc.pitched_ptr(), make_hipPos(0, 0, 0),
device_alloc.extent(), hipMemcpyDeviceToHost, kernel_stream),
should_sync, kernel_stream);
}
template <typename F>
void Memcpy3DDtoDSyncBehavior(F memcpy_func, const bool should_sync,
const hipStream_t kernel_stream = nullptr) {
LinearAllocGuard3D<int> src_alloc(make_hipExtent(32 * sizeof(int), 32, 8));
LinearAllocGuard3D<int> dst_alloc(make_hipExtent(32 * sizeof(int), 32, 8));
MemcpySyncBehaviorCheck(
std::bind(memcpy_func, dst_alloc.pitched_ptr(), make_hipPos(0, 0, 0), src_alloc.pitched_ptr(),
make_hipPos(0, 0, 0), dst_alloc.extent(), hipMemcpyDeviceToDevice, kernel_stream),
should_sync, kernel_stream);
}
template <typename F>
void Memcpy3DHtoHSyncBehavior(F memcpy_func, const bool should_sync,
const hipStream_t kernel_stream = nullptr) {
using LA = LinearAllocs;
const auto src_alloc_type = GENERATE(LA::malloc, LA::hipHostMalloc);
const auto dst_alloc_type = GENERATE(LA::malloc, LA::hipHostMalloc);
LinearAllocGuard<int> src_alloc(src_alloc_type, 32 * sizeof(int) * 32 * 8);
LinearAllocGuard<int> dst_alloc(dst_alloc_type, 32 * sizeof(int) * 32 * 8);
MemcpySyncBehaviorCheck(
std::bind(memcpy_func,
make_hipPitchedPtr(dst_alloc.ptr(), 32 * sizeof(int), 32 * sizeof(int), 32),
make_hipPos(0, 0, 0),
make_hipPitchedPtr(src_alloc.ptr(), 32 * sizeof(int), 32 * sizeof(int), 32),
make_hipPos(0, 0, 0), make_hipExtent(32 * sizeof(int), 32, 8), hipMemcpyHostToHost,
kernel_stream),
should_sync, kernel_stream);
}
template <bool should_synchronize, typename F>
void Memcpy3DZeroWidthHeightDepth(F memcpy_func, const hipStream_t stream = nullptr) {
constexpr hipExtent extent{127 * sizeof(int), 128, 8};
const auto [width_mult, height_mult, depth_mult] =
GENERATE(std::make_tuple(0, 1, 1), std::make_tuple(1, 0, 1), std::make_tuple(1, 1, 0));
SECTION("Device to Host") {
LinearAllocGuard3D<uint8_t> device_alloc(extent);
LinearAllocGuard<uint8_t> host_alloc(
LinearAllocs::hipHostMalloc,
device_alloc.width() * device_alloc.height() * device_alloc.depth());
std::fill_n(host_alloc.ptr(),
device_alloc.width_logical() * device_alloc.height() * device_alloc.depth(), 42);
HIP_CHECK(hipMemset3D(device_alloc.pitched_ptr(), 1, device_alloc.extent()));
HIP_CHECK(memcpy_func(
make_hipPitchedPtr(host_alloc.ptr(), device_alloc.width(), device_alloc.width(),
device_alloc.height()),
make_hipPos(0, 0, 0), device_alloc.pitched_ptr(), make_hipPos(0, 0, 0),
make_hipExtent(device_alloc.width() * width_mult, device_alloc.height() * height_mult,
device_alloc.depth() * depth_mult),
hipMemcpyDeviceToHost, stream));
if constexpr (should_synchronize) {
HIP_CHECK(hipStreamSynchronize(stream));
}
ArrayFindIfNot(host_alloc.ptr(), static_cast<uint8_t>(42),
device_alloc.width_logical() * device_alloc.height() * device_alloc.depth());
}
SECTION("Device to Device") {
LinearAllocGuard3D<uint8_t> src_alloc(extent);
LinearAllocGuard3D<uint8_t> dst_alloc(extent);
LinearAllocGuard<uint8_t> host_alloc(
LinearAllocs::hipHostMalloc, dst_alloc.width() * dst_alloc.height() * dst_alloc.depth());
HIP_CHECK(hipMemset3D(src_alloc.pitched_ptr(), 1, src_alloc.extent()));
HIP_CHECK(hipMemset3D(dst_alloc.pitched_ptr(), 42, dst_alloc.extent()));
HIP_CHECK(
memcpy_func(dst_alloc.pitched_ptr(), make_hipPos(0, 0, 0), src_alloc.pitched_ptr(),
make_hipPos(0, 0, 0),
make_hipExtent(dst_alloc.width() * width_mult, dst_alloc.height() * height_mult,
dst_alloc.depth() * depth_mult),
hipMemcpyDeviceToDevice, stream));
if constexpr (should_synchronize) {
HIP_CHECK(hipStreamSynchronize(stream));
}
HIP_CHECK(Memcpy3DWrapper(make_hipPitchedPtr(host_alloc.ptr(), dst_alloc.width(),
dst_alloc.width(), dst_alloc.height()),
make_hipPos(0, 0, 0), dst_alloc.pitched_ptr(), make_hipPos(0, 0, 0),
dst_alloc.extent(), hipMemcpyDeviceToHost));
ArrayFindIfNot(host_alloc.ptr(), static_cast<uint8_t>(42),
dst_alloc.width_logical() * dst_alloc.height());
}
SECTION("Host to Device") {
LinearAllocGuard3D<uint8_t> device_alloc(extent);
LinearAllocGuard<uint8_t> src_host_alloc(
LinearAllocs::hipHostMalloc,
device_alloc.width() * device_alloc.height() * device_alloc.depth());
LinearAllocGuard<uint8_t> dst_host_alloc(
LinearAllocs::hipHostMalloc,
device_alloc.width() * device_alloc.height() * device_alloc.depth());
std::fill_n(src_host_alloc.ptr(),
device_alloc.width_logical() * device_alloc.height() * device_alloc.depth(), 1);
HIP_CHECK(hipMemset3D(device_alloc.pitched_ptr(), 42, device_alloc.extent()));
HIP_CHECK(memcpy_func(
device_alloc.pitched_ptr(), make_hipPos(0, 0, 0),
make_hipPitchedPtr(src_host_alloc.ptr(), device_alloc.width(), device_alloc.width(),
device_alloc.height()),
make_hipPos(0, 0, 0),
make_hipExtent(device_alloc.width() * width_mult, device_alloc.height() * height_mult,
device_alloc.depth() * depth_mult),
hipMemcpyHostToDevice, stream));
if constexpr (should_synchronize) {
HIP_CHECK(hipStreamSynchronize(stream));
}
HIP_CHECK(Memcpy3DWrapper(make_hipPitchedPtr(dst_host_alloc.ptr(), device_alloc.width(),
device_alloc.width(), device_alloc.height()),
make_hipPos(0, 0, 0), device_alloc.pitched_ptr(),
make_hipPos(0, 0, 0), device_alloc.extent(), hipMemcpyDeviceToHost));
ArrayFindIfNot(dst_host_alloc.ptr(), static_cast<uint8_t>(42),
device_alloc.width_logical() * device_alloc.height());
}
SECTION("Host to Host") {
const auto alloc_size = extent.width * extent.height * extent.depth;
LinearAllocGuard<uint8_t> src_alloc(LinearAllocs::hipHostMalloc, alloc_size);
LinearAllocGuard<uint8_t> dst_alloc(LinearAllocs::hipHostMalloc, alloc_size);
std::fill_n(src_alloc.ptr(), alloc_size, 1);
std::fill_n(dst_alloc.ptr(), alloc_size, 42);
HIP_CHECK(
memcpy_func(make_hipPitchedPtr(dst_alloc.ptr(), extent.width, extent.width, extent.height),
make_hipPos(0, 0, 0),
make_hipPitchedPtr(src_alloc.ptr(), extent.width, extent.width, extent.height),
make_hipPos(0, 0, 0),
make_hipExtent(extent.width * width_mult, extent.height * height_mult,
extent.depth * depth_mult),
hipMemcpyHostToHost, stream));
if constexpr (should_synchronize) {
HIP_CHECK(hipStreamSynchronize(stream));
}
ArrayFindIfNot(dst_alloc.ptr(), static_cast<uint8_t>(42), alloc_size);
}
}
constexpr auto MemTypeHost() {
#if HT_AMD
return hipMemoryTypeHost;
#else
return CU_MEMORYTYPE_HOST;
#endif
}
constexpr auto MemTypeDevice() {
#if HT_AMD
return hipMemoryTypeDevice;
#else
return CU_MEMORYTYPE_DEVICE;
#endif
}
constexpr auto MemTypeArray() {
#if HT_AMD
return hipMemoryTypeArray;
#else
return CU_MEMORYTYPE_ARRAY;
#endif
}
constexpr auto MemTypeUnified() {
#if HT_AMD
return hipMemoryTypeUnified;
#else
return CU_MEMORYTYPE_UNIFIED;
#endif
}
using DrvPtrVariant = std::variant<hipPitchedPtr, hiparray>;
template <bool async = false>
hipError_t DrvMemcpy3DWrapper(DrvPtrVariant dst_ptr, hipPos dst_pos, DrvPtrVariant src_ptr,
hipPos src_pos, hipExtent extent, hipMemcpyKind kind,
hipStream_t stream = nullptr) {
HIP_MEMCPY3D parms = {0};
if (std::holds_alternative<hiparray>(dst_ptr)) {
parms.dstMemoryType = MemTypeArray();
parms.dstArray = std::get<hiparray>(dst_ptr);
} else {
auto ptr = std::get<hipPitchedPtr>(dst_ptr);
parms.dstPitch = ptr.pitch;
switch (kind) {
case hipMemcpyDeviceToHost:
case hipMemcpyHostToHost:
parms.dstMemoryType = MemTypeHost();
parms.dstHost = ptr.ptr;
break;
case hipMemcpyDeviceToDevice:
case hipMemcpyHostToDevice:
parms.dstMemoryType = MemTypeDevice();
parms.dstDevice = reinterpret_cast<hipDeviceptr_t>(ptr.ptr);
break;
case hipMemcpyDefault:
parms.dstMemoryType = MemTypeUnified();
parms.dstDevice = reinterpret_cast<hipDeviceptr_t>(ptr.ptr);
break;
default:
assert(false);
}
}
if (std::holds_alternative<hiparray>(src_ptr)) {
parms.srcMemoryType = MemTypeArray();
parms.srcArray = std::get<hiparray>(src_ptr);
} else {
auto ptr = std::get<hipPitchedPtr>(src_ptr);
parms.srcPitch = ptr.pitch;
switch (kind) {
case hipMemcpyDeviceToHost:
case hipMemcpyDeviceToDevice:
parms.srcMemoryType = MemTypeDevice();
parms.srcDevice = reinterpret_cast<hipDeviceptr_t>(ptr.ptr);
break;
case hipMemcpyHostToDevice:
case hipMemcpyHostToHost:
parms.srcMemoryType = MemTypeHost();
parms.srcHost = ptr.ptr;
break;
case hipMemcpyDefault:
parms.srcMemoryType = MemTypeUnified();
parms.srcDevice = reinterpret_cast<hipDeviceptr_t>(ptr.ptr);
break;
default:
assert(false);
}
}
parms.WidthInBytes = extent.width;
parms.Height = extent.height;
parms.Depth = extent.depth;
parms.srcXInBytes = src_pos.x;
parms.srcY = src_pos.y;
parms.srcZ = src_pos.z;
parms.dstXInBytes = dst_pos.x;
parms.dstY = dst_pos.y;
parms.dstZ = dst_pos.z;
if constexpr (async) {
return hipDrvMemcpy3DAsync(&parms, stream);
} else {
return hipDrvMemcpy3D(&parms);
}
}
template <bool should_synchronize, typename F>
void DrvMemcpy3DArrayHostShell(F memcpy_func, const hipStream_t kernel_stream = nullptr) {
constexpr hipExtent extent{127 * sizeof(int), 128, 8};
LinearAllocGuard<int> src_host(LinearAllocs::hipHostMalloc,
extent.width * extent.height * extent.depth);
LinearAllocGuard<int> dst_host(LinearAllocs::hipHostMalloc,
extent.width * extent.height * extent.depth);
DrvArrayAllocGuard<int> src_array(extent);
DrvArrayAllocGuard<int> dst_array(extent);
const auto f = [extent](size_t x, size_t y, size_t z) {
constexpr auto width_logical = extent.width / sizeof(int);
return z * width_logical * extent.height + y * width_logical + x;
};
PitchedMemorySet(src_host.ptr(), extent.width, extent.width / sizeof(int), extent.height,
extent.depth, f);
// Host -> Array
HIP_CHECK(
memcpy_func(src_array.ptr(), make_hipPos(0, 0, 0),
make_hipPitchedPtr(src_host.ptr(), extent.width, extent.width, extent.height),
make_hipPos(0, 0, 0), extent, hipMemcpyHostToDevice, kernel_stream));
if constexpr (should_synchronize) {
HIP_CHECK(hipStreamSynchronize(kernel_stream));
}
// Array -> Array
HIP_CHECK(memcpy_func(dst_array.ptr(), make_hipPos(0, 0, 0), src_array.ptr(),
make_hipPos(0, 0, 0), extent, hipMemcpyDeviceToDevice, kernel_stream));
if constexpr (should_synchronize) {
HIP_CHECK(hipStreamSynchronize(kernel_stream));
}
// Array -> Host
HIP_CHECK(
memcpy_func(make_hipPitchedPtr(dst_host.ptr(), extent.width, extent.width, extent.height),
make_hipPos(0, 0, 0), dst_array.ptr(), make_hipPos(0, 0, 0), extent,
hipMemcpyDeviceToHost, kernel_stream));
if constexpr (should_synchronize) {
HIP_CHECK(hipStreamSynchronize(kernel_stream));
}
PitchedMemoryVerify(dst_host.ptr(), extent.width, extent.width / sizeof(int), extent.height,
extent.depth, f);
}
template <bool should_synchronize, typename F>
void DrvMemcpy3DArrayDeviceShell(F memcpy_func, const hipStream_t kernel_stream = nullptr) {
constexpr hipExtent extent{127 * sizeof(int), 128, 8};
LinearAllocGuard<int> host_alloc(LinearAllocs::hipHostMalloc,
extent.width * extent.height * extent.depth);
DrvArrayAllocGuard<int> src_array(extent);
DrvArrayAllocGuard<int> dst_array(extent);
LinearAllocGuard3D<int> src_device(extent);
LinearAllocGuard3D<int> dst_device(extent);
const dim3 threads_per_block(32, 32);
const dim3 blocks(src_device.width_logical() / threads_per_block.x + 1,
src_device.height() / threads_per_block.y + 1, src_device.depth());
Iota<<<blocks, threads_per_block>>>(src_device.ptr(), src_device.pitch(),
src_device.width_logical(), src_device.height(),
src_device.depth());
HIP_CHECK(hipGetLastError());
// Device -> Array
HIP_CHECK(memcpy_func(src_array.ptr(), make_hipPos(0, 0, 0), src_device.pitched_ptr(),
make_hipPos(0, 0, 0), extent, hipMemcpyDeviceToDevice, kernel_stream));
if constexpr (should_synchronize) {
HIP_CHECK(hipStreamSynchronize(kernel_stream));
}
// Array -> Array
HIP_CHECK(memcpy_func(dst_array.ptr(), make_hipPos(0, 0, 0), src_array.ptr(),
make_hipPos(0, 0, 0), extent, hipMemcpyDeviceToDevice, kernel_stream));
if constexpr (should_synchronize) {
HIP_CHECK(hipStreamSynchronize(kernel_stream));
}
// Array -> Device
HIP_CHECK(memcpy_func(dst_device.pitched_ptr(), make_hipPos(0, 0, 0), dst_array.ptr(),
make_hipPos(0, 0, 0), extent, hipMemcpyDeviceToDevice, kernel_stream));
if constexpr (should_synchronize) {
HIP_CHECK(hipStreamSynchronize(kernel_stream));
}
HIP_CHECK(
memcpy_func(make_hipPitchedPtr(host_alloc.ptr(), extent.width, extent.width, extent.height),
make_hipPos(0, 0, 0), dst_device.pitched_ptr(), make_hipPos(0, 0, 0),
dst_device.extent(), hipMemcpyDeviceToHost, kernel_stream));
if constexpr (should_synchronize) {
HIP_CHECK(hipStreamSynchronize(kernel_stream));
}
const auto f = [extent](size_t x, size_t y, size_t z) {
constexpr auto width_logical = extent.width / sizeof(int);
return z * width_logical * extent.height + y * width_logical + x;
};
PitchedMemoryVerify(host_alloc.ptr(), extent.width, extent.width / sizeof(int), extent.height,
extent.depth, f);
}
+17 -6
查看文件
@@ -17,16 +17,17 @@ OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/**
* hipDeviceTotalMem tests
* Scenario: Validate behavior of hipDeviceTotalMem for masked devices.
*/
#include <hip_test_common.hh>
#ifdef __linux__
#include <unistd.h>
#include <sys/wait.h>
/**
* @addtogroup hipDeviceTotalMem hipDeviceTotalMem
* @{
* @ingroup DriverTest
*/
#define MAX_SIZE 30
#define VISIBLE_DEVICE 0
@@ -141,7 +142,17 @@ static bool getTotalMemoryOfMaskedDevices(int actualNumGPUs) {
/**
* Scenario: Validate behavior of hipDeviceTotalMem for masked devices.
* Test Description
* ------------------------
* - Check that total memory is returned correctly when
* the devices are masked.
* Test source
* ------------------------
* - unit/multiproc/hipDeviceTotalMemMproc.cc
* Test requirements
* ------------------------
* - Multi-device test
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceTotalMem_MaskedDevices") {
int count = -1;
+74 -24
查看文件
@@ -17,23 +17,6 @@ OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/**
Testcase Scenarios
------------------
Functional:
1) Validate usecase of Event handle along with memory handle across multiple
processes with complex scenario.
Negative/Argument Validation:
1) Get event handle with eventHandle(nullptr).
2) Get event handle with event(nullptr).
3) Get event handle with invalid event object.
4) Get event handle for event allocated without Interprocess flag.
5) Open event handle with event(nullptr).
6) Open event handle with eventHandle as invalid.
*/
#include <hip_test_common.hh>
#include <hip_test_checkers.hh>
@@ -42,6 +25,14 @@ Negative/Argument Validation:
#include <sys/wait.h>
#include <unistd.h>
/**
* @addtogroup hipIpcGetEventHandle hipIpcGetEventHandle
* @{
* @ingroup DeviceTest
* `hipIpcGetEventHandle(hipIpcEventHandle_t* handle, hipEvent_t event)` -
* Gets an opaque interprocess handle for an event.
* This opaque handle may be copied into other processes and opened with hipIpcOpenEventHandle.
*/
#define BUF_SIZE 4096
#define MAX_DEVICES 16
@@ -65,7 +56,7 @@ typedef struct ipcBarrier {
bool allExit;
} ipcBarrier_t;
/**
/*
Get device count and list down devices with
P2P access with Device 0.
*/
@@ -118,7 +109,7 @@ static ipcBarrier_t *g_Barrier{};
static bool g_procSense;
static int g_processCnt;
/**
/*
Calling process waits for other processes to signal/complete.
*/
void processBarrier() {
@@ -147,7 +138,7 @@ __global__ void computeKernel(int *dst, int *src, int num) {
dst[idx] = src[idx] / num;
}
/**
/*
* 1) Process 0 allocates buffer in GPU0 memory and exports the memory handle.
* 2) Other processes opens memory handle of GPU0 memory, performs computation
* and records event.
@@ -235,8 +226,19 @@ void runMultiProcKernel(ipcEventInfo_t *shmEventInfo, int index) {
}
/**
Functional test demonstrating IPC event usage along with IPC memory handle
*/
* Test Description
* ------------------------
* - Validate use case of event handle along with memory handle
* across multiple processes with complex scenario.
* - Utilizes synchronization of processes and events.
* - Lauches kernels and validates computation results.
* Test source
* ------------------------
* - unit/multiproc/hipIpcEventHandle.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipIpcEventHandle_Functional") {
ipcDevices_t *shmDevices;
ipcEventInfo_t *shmEventInfo;
@@ -300,8 +302,38 @@ TEST_CASE("Unit_hipIpcEventHandle_Functional") {
}
/**
Performs API Parameter validation.
*/
* Test Description
* ------------------------
* - Validates handling of invalid arguments for
* [hipIpcGetEventHandle](@ref hipIpcGetEventHandle):
* -# When pointer to the event handle is `nullptr`
* - Expected output: return `hipErrorInvalidValue`
* -# When pointer to the event is `nullptr`
* - Expected output: return `hipErrorInvalidValue`
* -# When both pointers are `nullptr`
* - Expected output: return `hipErrorInvalidValue`
* -# When event is not valid
* - Expected output: return `hipErrorInvalidValue`
* -# When event is created without interprocess flag
* - Expected output: return `hipErrorInvalidResourceHandle` or `hipErrorInvalidConfiguration`
* -# When event is created without flags
* - Expected output: return `hipErrorInvalidResourceHandle`
* - Validates handling of invalid arguments for
* [hipIpcOpenEventHandle](@ref hipIpcOpenEventHandle)
* -# When pointer to the event is `nullptr`
* - Expected output: return `hipErrorInvalidValue`
* -# When pointer to the event handle is `nullptr`
* - Expected output: return `hipErrorInvalidValue`
* -# When attemted to open handle in the process that created it
* - Expected output: return `hipErrorInvalidContext`
* Test source
* ------------------------
* - unit/multiproc/hipIpcEventHandle.cc
* Test requirements
* ------------------------
* - Host specific (LINUX)
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipIpcEventHandle_ParameterValidation") {
hipEvent_t event;
hipIpcEventHandle_t eventHandle;
@@ -381,4 +413,22 @@ TEST_CASE("Unit_hipIpcEventHandle_ParameterValidation") {
#endif
}
/**
* End doxygen group hipIpcGetEventHandle.
* @}
*/
/**
* @addtogroup hipIpcOpenEventHandle hipIpcOpenEventHandle
* @{
* @ingroup DeviceTest
* `hipIpcOpenEventHandle(hipEvent_t* event, hipIpcEventHandle_t handle)` -
* Opens an interprocess event handles.
* Opens an interprocess event handle exported from another process with hipIpcGetEventHandle.
* ________________________
* Test cases from other modules:
* - @ref Unit_hipIpcEventHandle_Functional
* - @ref Unit_hipIpcEventHandle_ParameterValidation
*/
#endif
+58 -6
查看文件
@@ -17,12 +17,6 @@ OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/*
1)Testcase verifies the hipIpcMemAccess APIs by creating memory handle
in parent process and access it in child process.
2)Test case performs Parameter validation of hipIpcMemAccess APIs.
*/
#include <hip_test_common.hh>
#include <hip_test_checkers.hh>
@@ -34,6 +28,14 @@ in parent process and access it in child process.
#include <semaphore.h>
#include <unistd.h>
/**
* @addtogroup hipIpcOpenMemHandle hipIpcOpenMemHandle
* @{
* @ingroup DeviceTest
* `hipIpcOpenMemHandle(void** devPtr, hipIpcMemHandle_t handle, unsigned int flags)` -
* Opens an interprocess memory handle exported from another process
* and returns a device pointer usable in the local process.
*/
#define NUM_ELMTS 1024
#define NUM_THREADS 10
@@ -58,6 +60,23 @@ typedef struct mem_handle {
// and check for data consistencies and close the hipIpcCloseMemHandle
// release the parent and wait for parent to release itself(child)
/**
* Test Description
* ------------------------
* - Verifies that getting and opening mem handle works correctly
* in specific scenarion, and handles the case when the same device
* is used in both processes.
* - Creates memory from the parent process for each device.
* - Spawns child process and waits for it to finish.
* - Child process gets the handle and check data consistencies.
* Test source
* ------------------------
* - unit/multiproc/hipIpcMemAccessTest.cc
* Test requirements
* ------------------------
* - Host specific (LINUX)
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipIpcMemAccess_Semaphores") {
hip_ipc_t *shrd_mem = NULL;
pid_t pid;
@@ -161,6 +180,39 @@ TEST_CASE("Unit_hipIpcMemAccess_Semaphores") {
REQUIRE(shrd_mem->IfTestPassed == true);
}
/**
* Test Description
* ------------------------
* - Validates handling of valid and invalid arguments for
* [hipIpcGetMemHandle](@ref hipIpcGetMemHandle):
* -# When memory handle pointer is `nullptr`
* - Expected output: return `hipErrorInvalidValue`
* -# When device pointer is `nullptr`
* - Expected output: return `hipErrorInvalidValue`
* -# When both pointers are `nullptr`
* - Expected output: return `hipErrorInvalidValue`
* -# When both pointers are valid
* - Expected output: return `hipSuccess`
* - Validates handling of valid and invalid arguments for
* [hipIpcOpenMemHandle](@ref hipIpcOpenMemHandle):
* -# When device pointer is `nullptr`
* - Expected output: return `hipErrorInvalidValue`
* -# When memory handle pointer uninitialized
* - Expected output: return `hipErrorInvalidValue` or `hipErrorInvalidDevicePointer`
* -# When memory handle has random flags
* - Expected output: return `hipErrorInvalidValue`
* - Validates handling of valid and invalid arguments for
* [hipIpcCloseMemHandle](@ref hipIpcCloseMemHandle):
* -# When device pointer is `nullptr`
* - Expected output: return `hipErrorInvalidValue`
* Test source
* ------------------------
* - unit/multiproc/hipIpcMemAccessTest.cc
* Test requirements
* ------------------------
* - Host specific (LINUX)
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipIpcMemAccess_ParameterValidation") {
hipIpcMemHandle_t MemHandle;
hipIpcMemHandle_t MemHandleUninit;
+4 -2
查看文件
@@ -33,6 +33,7 @@
*/
#include <hip_test_common.hh>
#include <hip_test_features.hh>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/wait.h>
@@ -158,11 +159,12 @@ TEST_CASE("Unit_malloc_CoherentTst") {
hipDeviceProp_t prop;
HIPCHECK(hipGetDeviceProperties(&prop, 0));
char *p = NULL;
p = strstr(prop.gcnArchName, "gfx90a");
if (p) {
if (CheckIfFeatSupported(CTFeatures::CT_FEATURE_FINEGRAIN_HWSUPPORT, prop.gcnArchName)) {
WARN("gfx90a gpu found on this system!!");
GpuId[0] = 1;
}
// Write concatenated string and close writing end
write(fd1[1], GpuId, 2 * sizeof(int));
close(fd1[1]);
+7
查看文件
@@ -7,6 +7,13 @@ set(TEST_SRC
hipHostMallocStress.cc
)
if(UNIX)
set(TEST_SRC ${TEST_SRC}
hipHmmOvrSubscriptionTst.cc)
add_executable(hold_memory EXCLUDE_FROM_ALL hold_memory.cc)
add_dependencies(stress_test hold_memory)
endif()
hip_add_exe_to_target(NAME memory_stress
TEST_SRC ${TEST_SRC}
TEST_TARGET_NAME stress_test)
+114
查看文件
@@ -0,0 +1,114 @@
/*
Copyright (c) 2021-Present 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 Case Description: This test case tests the working of OverSubscription
feature which is part of HMM.*/
#include <hip_test_common.hh>
#include <hip_test_helper.hh>
#include <hip_test_process.hh>
__global__ void floatx2(float* ptr, size_t size) {
auto i = blockIdx.x * blockDim.x + threadIdx.x;
if (i < size) {
ptr[i] *= 2;
}
}
TEST_CASE("Stress_HMM_OverSubscriptionTst") {
int hmm = 0;
HIP_CHECK(hipDeviceGetAttribute(&hmm, hipDeviceAttributeManagedMemory, 0));
bool shouldRun = []() -> bool {
#if HT_AMD // For AMD this gcn arch needs to have xnack+
int device = 0;
hipDeviceProp_t props{};
HIP_CHECK(hipGetDevice(&device));
HIP_CHECK(hipGetDeviceProperties(&props, device));
std::string arch(props.gcnArchName);
return arch.find("xnack+") != std::string::npos;
#else // For CUDA this depends on SM and attribute check should be fine
return true;
#endif
}();
if (hmm == 1 && shouldRun) {
hip::SpawnProc proc("hold_memory", true);
proc.run_async();
size_t freeMem, totalMem;
HIP_CHECK(hipMemGetInfo(&freeMem, &totalMem));
constexpr float oversub_factor = 1.2f;
auto system_ram = HipTest::getMemoryAmount(); // In MB
// Take in account of system memory
size_t max_memory = std::min(freeMem / (1024 * 1024), system_ram);
size_t max_mem_used = (max_memory * oversub_factor) / 1024; // GB
auto OneGBTest = []() {
constexpr size_t oneGB = 1024 * 1024 * 1024;
hipStream_t stream;
HIP_CHECK_THREAD(hipStreamCreate(&stream));
float* data;
constexpr size_t alloc_elem = oneGB / sizeof(float);
HIP_CHECK_THREAD(hipMallocManaged(&data, oneGB, hipMemAttachGlobal));
constexpr float init_val = 1.1f;
std::for_each(data, data + alloc_elem, [](float& a) { a = init_val; });
// basic sanity - first and last val are same
REQUIRE_THREAD(data[0] == init_val);
REQUIRE_THREAD(data[alloc_elem - 1] == init_val);
// Page migrated to GPU
floatx2<<<(alloc_elem / 256) + 1, 256, 0, stream>>>(data, alloc_elem);
HIP_CHECK_THREAD(hipStreamSynchronize(stream));
// Back to host
REQUIRE_THREAD(
std::all_of(data, data + alloc_elem, [](float a) { return a == (2.0f * init_val); }));
HIP_CHECK_THREAD(hipFree(data));
HIP_CHECK_THREAD(hipStreamDestroy(stream));
};
std::vector<std::thread> thread_pool;
thread_pool.reserve(max_mem_used);
for (size_t i = 0; i < max_mem_used; i++) {
thread_pool.emplace_back(std::thread(OneGBTest));
}
std::for_each(thread_pool.begin(), thread_pool.end(),
[](std::thread& thread) { thread.join(); });
HIP_CHECK_THREAD_FINALIZE();
REQUIRE(proc.wait() == 0);
} else {
HipTest::HIP_SKIP_TEST("Tests only supposed to run on xnack+ devices");
}
}
+1 -1
查看文件
@@ -66,7 +66,7 @@ static void ReleaseResource(int *Hmm, hipStream_t *strm) {
/* The following test allocates a managed memory and prefetch it in
one-to-all and all-to-one fahsion followed by kernel launch within available
devices*/
TEST_CASE("Unit_hipMemPrefetchAsyncOneToAll") {
TEST_CASE("Stress_hipMemPrefetchAsyncOneToAll") {
int MangdMem = HmmAttrPrint();
if (MangdMem == 1) {
int *Hmm1 = nullptr, NumDevs, MemSz = (4096 * 4);
+45
查看文件
@@ -0,0 +1,45 @@
/*
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 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/hip_runtime.h>
#include <iostream>
#include <chrono>
#include <thread>
#define HIP_CHECK(call) \
{ \
auto res_ = (call); \
if (res_ != hipSuccess) { \
std::cout << "Failed in: " << #call << std::endl; \
return -1; \
} \
}
int main() {
size_t freeMem = 0, totalMem = 0;
HIP_CHECK(hipMemGetInfo(&freeMem, &totalMem));
void* ptr;
HIP_CHECK(hipMalloc(&ptr, 0.4 * totalMem)); // hold 40% of total gpu memory
std::cout << "Sleeping..." << std::endl;
std::this_thread::sleep_for(
std::chrono::seconds(4)); // sleep for few seconds till test complete
std::cout << "Waking up..." << std::endl;
HIP_CHECK(hipFree(ptr));
}
+31 -7
查看文件
@@ -23,8 +23,23 @@ THE SOFTWARE.
#include <hip_test_common.hh>
/**
* hipChooseDevice tests
* Scenario: Validates dev id value.
* @addtogroup hipChooseDevice hipChooseDevice
* @{
* @ingroup DeviceTest
* `hipChooseDevice(int* device, const hipDeviceProp_t* prop)` -
* Device which matches `hipDeviceProp_t` is returned.
*/
/**
* Test Description
* ------------------------
* - Validate chosen device against gotten device properties.
* Test source
* ------------------------
* - unit/device/hipChooseDevice.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipChooseDevice_ValidateDevId") {
hipDeviceProp_t prop;
@@ -36,21 +51,30 @@ TEST_CASE("Unit_hipChooseDevice_ValidateDevId") {
REQUIRE_FALSE(dev < 0);
REQUIRE_FALSE(dev >= numDevices);
}
/**
* hipChooseDevice tests
* Scenario1: Validates if dev = nullptr returns error code
* Scenario2: Validates if prop = nullptr returns error code
* Test Description
* ------------------------
* - Validates handling of invalid arguments:
* -# When pointer to the device is `nullptr`
* - Expected output: do not return `hipSuccess`
* -# When pointer to the properties is `nullptr`
* - Expected output: do not return `hipSuccess`
* Test source
* ------------------------
* - unit/device/hipChooseDevice.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipChooseDevice_NegTst") {
hipDeviceProp_t prop;
int dev = -1;
// Scenario1
SECTION("dev is nullptr") {
REQUIRE_FALSE(hipSuccess == hipChooseDevice(nullptr, &prop));
}
// Scenario2
SECTION("prop is nullptr") {
REQUIRE_FALSE(hipSuccess == hipChooseDevice(&dev, nullptr));
}
+37 -10
查看文件
@@ -23,16 +23,26 @@ THE SOFTWARE.
#include <hip_test_common.hh>
#include <hip_test_helper.hh>
/*
Positive tests:
- for each peer check other peer access
Negative tests:
- canAccessPeer pointer is nullptr
- deviceId is invalid
- peerDeviceId is invalid
*/
/**
* @addtogroup hipDeviceCanAccessPeer hipDeviceCanAccessPeer
* @{
* @ingroup PeerToPeerTest
* `hipDeviceCanAccessPeer(int* canAccessPeer, int deviceId, int peerDeviceId)` -
* Determine if a device can access a peer's memory.
*/
/**
* Test Description
* ------------------------
* - Verifies that each available device can access memory from all other devices.
* Test source
* ------------------------
* - unit/device/hipDeviceCanAccessPeer.cc
* Test requirements
* ------------------------
* - Multi-device
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceCanAccessPeer_positive") {
int canAccessPeer = 0;
int deviceCount = HipTest::getGeviceCount();
@@ -54,7 +64,24 @@ TEST_CASE("Unit_hipDeviceCanAccessPeer_positive") {
}
}
/**
* Test Description
* ------------------------
* - Verifies handling of invalid arguments:
* -# When output pointer to the peer result is `nullptr`
* - Expected output: return `hipErrorInvalidValue`
* -# When device ID is invalid (-1 or out of bounds)
* - Expected output: return `hipErrorInvalidDevice`
* -# When peer device ID is invalid (-1 or out of bounds)
* - Expected output: return `hipErrorInvalidDevice`
* Test source
* ------------------------
* - unit/device/hipDeviceCanAccessPeer.cc
* Test requirements
* ------------------------
* - Multi-device
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceCanAccessPeer_negative") {
int canAccessPeer = 0;
int deviceCount = HipTest::getGeviceCount();
+36 -16
查看文件
@@ -16,25 +16,35 @@ 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 :
Unit_hipDeviceComputeCapability_ValidateVersion - Check if hipDeviceComputeCapability api returns valid Major and Minor versions
Unit_hipDeviceComputeCapability_Negative - Test unsuccessful execution of hipDeviceComputeCapability when nullptr
or invalid device is set as input parameter
*/
/*
* Conformance test for checking functionality of
* hipError_t hipDeviceComputeCapability(int* major, int* minor, hipDevice_t device);
*/
#include <hip_test_common.hh>
/**
* hipDeviceComputeCapability negative tests
* Scenario1: Validates if &major = nullptr returns error code
* Scenario2: Validates if &minor = nullptr returns error code
* Scenario3: Validates if device is -1
* Scenario4: Validates if device is out of bounds
* @addtogroup hipDeviceComputeCapability hipDeviceComputeCapability
* @{
* @ingroup DriverTest
* `hipDeviceComputeCapability(int* major, int* minor, hipDevice_t device)` -
* Returns the compute capability of the device.
*/
/**
* Test Description
* ------------------------
* - Validates handling of invalid arguments:
* -# When output pointer to the major number is `nullptr`
* - Expected output: do not return `hipSuccess`
* -# When output pointer to the minor number is `nullptr`
* - Expected output: do not return `hipSuccess`
* -# When device ordinal is negative
* - Expected output: do not return `hipSuccess`
* -# When device ordinal is out of bounds
* - Expected output: do not return `hipSuccess`
* Test source
* ------------------------
* - unit/device/hipDeviceComputeCapability.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceComputeCapability_Negative") {
int major, minor, numDevices;
@@ -71,7 +81,17 @@ TEST_CASE("Unit_hipDeviceComputeCapability_Negative") {
}
}
// Scenario 5 : Check whether major and minor version value is valid.
/**
* Test Description
* ------------------------
* - Checks that valid major and minor numbers are returned.
* Test source
* ------------------------
* - unit/device/hipDeviceComputeCapability.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceComputeCapability_ValidateVersion") {
int major, minor;
hipDevice_t device;
+75 -10
查看文件
@@ -23,16 +23,29 @@ THE SOFTWARE.
#include <hip_test_common.hh>
#include <hip_test_helper.hh>
/*
Positive tests:
- for each peer change and check other peer access
/**
* @addtogroup hipDeviceEnablePeerAccess hipDeviceEnablePeerAccess
* @{
* @ingroup PeerToPeerTest
* `hipDeviceEnablePeerAccess(int peerDeviceId, unsigned int flags)` -
* Enable direct access from current device's virtual address space to memory allocations
* physically located on a peer device.
*/
Negative tests:
- peerDeviceId is invalid
- flag value is invalid
- peer access is enabled/disabled twice
- peer access is disabled before being enabled
*/
/**
* Test Description
* ------------------------
* - Enables peer access for each GPU pair.
* - Disables peer access for each GPU pair.
* Test source
* ------------------------
* - unit/device/hipDeviceEnableDisablePeerAccess.cc
* Test requirements
* ------------------------
* - PeerToPeer supported
* - Multi-device
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceEnableDisablePeerAccess_positive") {
int canAccessPeer = 0;
int deviceCount = HipTest::getGeviceCount();
@@ -56,7 +69,24 @@ TEST_CASE("Unit_hipDeviceEnableDisablePeerAccess_positive") {
}
}
/**
* Test Description
* ------------------------
* - Validates handling of invalid arguments:
* -# When peer device ID is invalid (-1 or out of bounds)
* - Expected output: return `hipErrorInvalidDevice`
* -# When flag is invalid (-1)
* - Expected output: return `hipErrorInvalidValue`
* -# When peer access has already been enabled
* - Expected output: return `hipErrorPeerAccessAleadyEnabled`
* Test source
* ------------------------
* - unit/device/hipDeviceEnableDisablePeerAccess.cc
* Test requirements
* ------------------------
* - Multi-device
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceEnablePeerAccess_negative") {
int deviceCount = HipTest::getGeviceCount();
if (deviceCount < 2) {
@@ -86,6 +116,41 @@ TEST_CASE("Unit_hipDeviceEnablePeerAccess_negative") {
}
}
/**
* End doxygen group hipDeviceEnablePeerAccess.
* @}
*/
/**
* @addtogroup hipDeviceDisablePeerAccess hipDeviceDisablePeerAccess
* @{
* @ingroup PeerToPeerTest
* hipDeviceDisablePeerAccess(int peerDeviceId)` -
* Disable direct access from current device's virtual address space
* to memory allocations physically located on a peer device.
* ________________________
* Test cases from other modules:
* - @ref Unit_hipDeviceEnableDisablePeerAccess_positive
*/
/**
* Test Description
* ------------------------
* - Validates handling of invalid arguments:
* -# When peer device ID is invalid (-1 or out of bounds)
* - Expected output: return `hipErrorInvalidDevice`
* -# When peer access is not enabled
* - Expected output: return `hipErrorPeerAccessNotEnabled`
* -# When peer access is already disabled
* - Expected output: return `hipErrorPeerAccessNotEnabled`
* Test source
* ------------------------
* - unit/device/hipDeviceEnableDisablePeerAccess.cc
* Test requirements
* ------------------------
* - Multi-device
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceDisablePeerAccess_negative") {
int deviceCount = HipTest::getGeviceCount();
if (deviceCount < 2) {
+55 -10
查看文件
@@ -20,11 +20,27 @@
#include <hip_test_common.hh>
/**
* @addtogroup hipDeviceGetByPCIBusId hipDeviceGetByPCIBusId
* @{
* @ingroup DriverTest
* `hipDeviceGetByPCIBusId(int* device, const char* pciBusId)` -
* Returns a handle to a compute device.
*/
#define SIZE 13
/**
* scenario: Validates device number from pciBusIdstr string
* Test Description
* ------------------------
* - Check that PCI bus ID is the same as the one returned from attributes.
* - Perform for each device.
* Test source
* ------------------------
* - unit/device/hipDeviceGetByPCIBusId.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceGetByPCIBusId_Functional") {
char pciBusId[SIZE]{};
@@ -49,10 +65,20 @@ TEST_CASE("Unit_hipDeviceGetByPCIBusId_Functional") {
}
}
/**
* Validates negative scenarios for hipDeviceGetByPCIBusId
* scenario: device = nullptr and pciBusIdstr = nullptr
* Test Description
* ------------------------
* - Validates handling of `nullptr` arguments:
* -# When the output pointer to the device is `nullptr`
* - Expected output: do not return `hipSuccess`
* -# When the PCI bus ID pointer is `nullptr`
* - Expected output: do not return `hipSuccess`
* Test source
* ------------------------
* - unit/device/hipDeviceGetByPCIBusId.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceGetByPCIBusId_NegativeNullChk") {
int device = -1;
@@ -66,9 +92,19 @@ TEST_CASE("Unit_hipDeviceGetByPCIBusId_NegativeNullChk") {
}
/**
* Validates negative scenarios for hipDeviceGetByPCIBusId
* scenario1: Pass an empty like ""
* scenario2: Pass an shorter string "0000:"
* Test Description
* ------------------------
* - Validates handling of invalid PCI bus ID strings:
* -# When PCI bus ID is an empty string
* - Expected output: do not return `hipSuccess`
* -# When PCI bus ID is a short string
* - Expected output: do not return `hipSuccess`
* Test source
* ------------------------
* - unit/device/hipDeviceGetByPCIBusId.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceGetByPCIBusId_NegativeInputString") {
int device = -1;
@@ -81,8 +117,17 @@ TEST_CASE("Unit_hipDeviceGetByPCIBusId_NegativeInputString") {
}
/**
* Validates negative scenarios for hipDeviceGetByPCIBusId
* scenario: Pass wrong bus id in pciBusIdstr
* Test Description
* ------------------------
* - Validates handling of invalid PCI bus ID values:
* -# Passes non-existing PCI bus ID
* - Expected output: do not return `hipSuccess`
* Test source
* ------------------------
* - unit/device/hipDeviceGetByPCIBusId.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceGetByPCIBusId_WrongBusID") {
int deviceCount = 0;
+36
查看文件
@@ -23,6 +23,25 @@ THE SOFTWARE.
#include <hip_test_common.hh>
#include <hip/hip_runtime_api.h>
/**
* @addtogroup hipDeviceGetDefaultMemPool hipDeviceGetDefaultMemPool
* @{
* @ingroup DeviceTest
* `hipDeviceGetDefaultMemPool(hipMemPool_t* mem_pool, int device)` -
* Returns the default memory pool of the specified device
*/
/**
* Test Description
* ------------------------
* - Check that MemPool can be fetched and is not `nullptr`.
* Test source
* ------------------------
* - unit/device/hipDeviceGetDefaultMemPool.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceGetDefaultMemPool_Positive_Basic") {
const int device = GENERATE(range(0, HipTest::getDeviceCount()));
@@ -39,6 +58,23 @@ TEST_CASE("Unit_hipDeviceGetDefaultMemPool_Positive_Basic") {
REQUIRE(mem_pool != nullptr);
}
/**
* Test Description
* ------------------------
* - Validates handling of invalid arguments:
* -# When output pointer to the MemPool is `nullptr`
* - Expected output: return `hipErrorInvalidValue`
* -# When device ID is equal to -1
* - Expected output: return 'hipErrorInvalidDevice'
* -# When device ID is out of bounds
* - Expected output: return 'hipErrorInvalidDevice'
* Test source
* ------------------------
* - unit/device/hipDeviceGetDefaultMemPool.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceGetDefaultMemPool_Negative_Parameters") {
hipMemPool_t mem_pool;
+37 -12
查看文件
@@ -17,34 +17,59 @@ OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/*
* Conformance test for checking functionality of
* hipError_t hipDeviceGetLimit(size_t* pValue, enum hipLimit_t limit);
*/
#include <hip_test_common.hh>
/**
* hipDeviceGetLimit tests
* Scenario1: Validates if pValue = nullptr returns hip error code.
* Scenario2: Validates if *pValue > 0 is returned for limit = hipLimitMallocHeapSize.
* Scenario3: Validates if error code is returned for limit = Invalid Flag = 0xff.
* @addtogroup hipDeviceGetLimit hipDeviceGetLimit
* @{
* @ingroup DeviceTest
* `hipDeviceGetLimit(size_t* pValue, enum hipLimit_t limit)` -
* Get Resource limits of current device.
*/
#include <hip_test_common.hh>
/**
* Test Description
* ------------------------
* - Validates handling of invalid arguments:
* -# When output pointer to the limit value is `nullptr`
* - Expected output: do not return `hipSuccess`
* -# When limit enum is out of bounds
* - Expected output: do not return `hipSuccess`
* Test source
* ------------------------
* - unit/device/hipDeviceGetLimit.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceGetLimit_NegTst") {
size_t Value = 0;
// Scenario1
SECTION("NULL check") {
REQUIRE_FALSE(hipDeviceGetLimit(nullptr, hipLimitMallocHeapSize)
== hipSuccess);
}
// Scenario3
SECTION("Invalid Input Flag") {
REQUIRE_FALSE(hipDeviceGetLimit(&Value, static_cast<hipLimit_t>(0xff)) ==
hipSuccess);
}
}
/**
* Test Description
* ------------------------
* - Validate that returned limit value for Malloc Heap size is valid.
* Test source
* ------------------------
* - unit/device/hipDeviceGetLimit.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceGetLimit_CheckValidityOfOutputVal") {
size_t Value = 0;
// Scenario2
REQUIRE(hipDeviceGetLimit(&Value, hipLimitMallocHeapSize) ==
hipSuccess);
REQUIRE_FALSE(Value <= 0);
+49 -11
查看文件
@@ -17,10 +17,6 @@ OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/*
* Conformance test for checking functionality of
* hipError_t hipDeviceGetName(char* name, int len, hipDevice_t device);
*/
#include <cstddef>
#include <hip_test_common.hh>
#include <cstring>
@@ -29,16 +25,34 @@ THE SOFTWARE.
#include <algorithm>
#include <iterator>
/**
* @addtogroup hipDeviceGetName hipDeviceGetName
* @{
* @ingroup DriverTest
* `hipDeviceGetName(char* name, int len, hipDevice_t device)` -
* Returns an identifer string for the device.
*/
constexpr size_t LEN = 256;
/**
* hipDeviceGetName tests
* Scenario1: Validates the name string with hipDeviceProp_t.name[256]
* Scenario2: Validates returned error code for name = nullptr
* Scenario3: Validates returned error code for len = 0
* Scenario4: Validates returned error code for len < 0
* Scenario5: Validates returned error code for an invalid device
* Scenario6: Validates partially filling the name into a char array
* Test Description
* ------------------------
* - Validates handling of invalid arguments:
* -# Valid devices and output pointer to the name is `nullptr`
* - Expected output: return `hipErrorInvalidValue`
* -# Valid devices and output name buffer length is 0
* - Expected output: return `hipErrorInvalidValue`
* -# Valid devices and output name buffer has length -1
* - Expected output: return `hipErrorInvalidValue`
* -# Invalid devices, device ordinal is out of bounds
* - Expected output: return `hipErrorInvalidDevice`
* Test source
* ------------------------
* - unit/device/hipDeviceGetName.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceGetName_NegTst") {
std::array<char, LEN> name;
@@ -87,6 +101,18 @@ TEST_CASE("Unit_hipDeviceGetName_NegTst") {
}
}
/**
* Test Description
* ------------------------
* - Get the device name for each device.
* - Compare the name with the name returned from device properties.
* Test source
* ------------------------
* - unit/device/hipDeviceGetName.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceGetName_CheckPropName") {
int numDevices = 0;
std::array<char, LEN> name;
@@ -103,6 +129,18 @@ TEST_CASE("Unit_hipDeviceGetName_CheckPropName") {
}
}
/**
* Test Description
* ------------------------
* - Set name buffer length to the half of the name length.
* - Check that device name is successfuly returned.
* Test source
* ------------------------
* - unit/device/hipDeviceGetName.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceGetName_PartialFill") {
#if HT_AMD
HipTest::HIP_SKIP_TEST("EXSWCPHIPT-108");
+40 -5
查看文件
@@ -25,9 +25,24 @@ THE SOFTWARE.
#include <string>
/**
* @brief Test all possible combination of attributes and devices for hipDeviceGetP2PAttribute.
* Verify that the output is within the range of acceptable values.
*
* @addtogroup hipDeviceGetP2PAttribute hipDeviceGetP2PAttribute
* @{
* @ingroup DriverTest
* `hipDeviceGetP2PAttribute(int* value, hipDeviceP2PAttr attr,
* int srcDevice, int dstDevice)` -
* Returns a value for attr of link between two devices.
*/
/**
* Test Description
* ------------------------
* - Get all possible combinations of attributes between all pairs of devices.
* Test source
* ------------------------
* - unit/device/hipDeviceGetP2PAttribute.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceGetP2PAttribute_Basic") {
#if HT_AMD
@@ -65,8 +80,28 @@ TEST_CASE("Unit_hipDeviceGetP2PAttribute_Basic") {
}
/**
* @brief Negative test scenarios for hipDeviceGetP2PAttribute
*
* Test Description
* ------------------------
* - Verifies handling of invalid arguments:
* -# When output pointer to the value is `nullptr`
* - Expected output: return `hipErrorInvalidValue`
* -# When attribute is invalid, out of bounds
* - Expected output: return `hipErrorInvalidValue`
* -# When device ordinal is negative (-1)
* - Expected output: return `hipErrorInvalidDevice`
* -# When device ordinal is out of bounds
* - Expected output: return `hipErrorInvalidDevice`
* -# When the src and dst devices are the same one
* - Expected output: return `hipErrorInvalidDevice`
* -# When some devices are hidden using environment variables
* - Expected output: different scenarios produce different return value
* Test source
* ------------------------
* - unit/device/hipDeviceGetP2PAttribute.cc
* Test requirements
* ------------------------
* - Platform specific (NVIDIA)
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceGetP2PAttribute_Negative") {
#if HT_AMD
+52 -7
查看文件
@@ -25,6 +25,14 @@
#include <hip_test_common.hh>
/**
* @addtogroup hipDeviceGetPCIBusId hipDeviceGetPCIBusId
* @{
* @ingroup DriverTest
* `hipDeviceGetPCIBusId(char* pciBusId, int len, int device)` -
* Returns a PCI Bus Id string for the device, overloaded to take int device ID.
*/
#define MAX_DEVICE_LENGTH 20
namespace hipDeviceGetPCIBusIdTests {
@@ -37,6 +45,18 @@ void getPciBusId(int deviceCount,
}
} // namespace hipDeviceGetPCIBusIdTests
/**
* Test Description
* ------------------------
* - Check that PCI bus ID is the same as the one returned from attributes.
* - Perform for each device.
* Test source
* ------------------------
* - unit/device/hipDeviceGetByPCIBusId.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceGetPCIBusId_Check_PciBusID_WithAttr") {
int deviceCount = 0;
HIP_CHECK(hipGetDeviceCount(&deviceCount));
@@ -71,6 +91,19 @@ TEST_CASE("Unit_hipDeviceGetPCIBusId_Check_PciBusID_WithAttr") {
" hipDeviceGetAttribute matched for all gpus\n");
}
/**
* Test Description
* ------------------------
* - Checks that an error is returned when the output buffer has length
* that is smaller than the full PCI bus ID.
* - Expected output: do not return `hipSuccess`
* Test source
* ------------------------
* - unit/device/hipDeviceGetPCIBusId.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceGetPCIBusId_Negative_PartialFill") {
std::array<char, MAX_DEVICE_LENGTH> busID;
@@ -95,14 +128,26 @@ TEST_CASE("Unit_hipDeviceGetPCIBusId_Negative_PartialFill") {
REQUIRE(std::all_of(strEnd+1, end, [](char& c) { return c == fillValue; }));
}
/**
* Validates negative scenarios for hipDeviceGetPCIBusId
* scenario1: pciBusId = nullptr
* scenario2: device = -1 (Invalid Device)
* scenario3: device = Non Existing Device
* scenario4: len = 0
* scenario5: len < 0
* Test Description
* ------------------------
* - Validates handling of invalid arguments:
* -# When output pointer to the PCI bus ID is `nullptr`
* - Expected output: do not return `hipSuccess`
* -# When the length of the output buffer is 0
* - Expected output: do not return `hipSuccess`
* -# When the length of the output buffer is less than 0
* - Expected output: do not return `hipSuccess`
* -# When the device ordinal is negative (-1)
* - Expected output: do not return `hipSuccess`
* -# When the device ordinal is out of bounds
* - Expected output: do not return `hipSuccess`
* Test source
* ------------------------
* - unit/device/hipDeviceGetPCIBusId.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceGetPCIBusId_NegTst") {
char pciBusId[MAX_DEVICE_LENGTH];
+33 -19
查看文件
@@ -16,23 +16,29 @@ 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 :
Unit_hipDeviceGetUuid_Positive - Check if hipDeviceGetUuid api returns valid UUID
Unit_hipDeviceGetUuid_Negative - Test unsuccessful execution of hipDeviceGetUuid when nullptr
or invalid device is set as input parameter
*/
/*
* Conformance test for checking functionality of
* hipError_t hipDeviceGetUuid(hipUUID* uuid, hipDevice_t device);
*/
#include <hip_test_common.hh>
#include <cstring>
#include <cstdio>
/**
* hipDeviceGetUuid positive test
* Scenario1: Validates the returned UUID
* @addtogroup hipDeviceGetUuid hipDeviceGetUuid
* @{
* @ingroup DriverTest
* `hipDeviceGetUuid(hipUUID* uuid, hipDevice_t device)` -
* Returns an UUID for the device.[BETA]
*/
/**
* Test Description
* ------------------------
* - Check that non-empty UUID is returned for each available device.
* Test source
* ------------------------
* - unit/device/hipDeviceGetUuid.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceGetUuid_Positive") {
hipDevice_t device;
@@ -57,10 +63,21 @@ TEST_CASE("Unit_hipDeviceGetUuid_Positive") {
}
/**
* hipDeviceGetUuid negative tests
* Scenario2: Validates returned error code for UUID = nullptr
* Scenario3: Validates returned error code if device is -1
* Scenario4: Validates returned error code if device is out of bounds
* Test Description
* ------------------------
* - Validates handling of invalid arguments:
* -# When output pointer to the UUID is `nullptr`
* - Expected output: do not return `hipSuccess`
* -# When device ordinal is negative
* - Expected output: do not return `hipSuccess`
* -# When device ordinal is out of bounds
* - Expected output: do not return `hipSuccess`
* Test source
* ------------------------
* - unit/device/hipDeviceGetUuid.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceGetUuid_Negative") {
int numDevices = 0;
@@ -70,11 +87,8 @@ TEST_CASE("Unit_hipDeviceGetUuid_Negative") {
if (numDevices > 0) {
HIP_CHECK(hipDeviceGet(&device, 0));
// Scenario 2
REQUIRE_FALSE(hipSuccess == hipDeviceGetUuid(nullptr, device));
// Scenario 3
REQUIRE_FALSE(hipSuccess == hipDeviceGetUuid(&uuid, -1));
// Scenario 4
REQUIRE_FALSE(hipSuccess == hipDeviceGetUuid(&uuid, numDevices));
}
}
+39 -2
查看文件
@@ -22,6 +22,30 @@ THE SOFTWARE.
#include <hip_test_common.hh>
#include <hip/hip_runtime_api.h>
/**
* @addtogroup hipDeviceReset hipDeviceReset
* @{
* @ingroup DeviceTest
* `hipDeviceReset(void)` -
* The state of current device is discarded and updated to a fresh state.
*
* Calling this function deletes all streams created, memory allocated, kernels running, events
* created. Make sure that no other thread is using the device or streams, memory, kernels, events
* associated with the current device.
*/
/**
* Test Description
* ------------------------
* - Validates that device reset frees allocated memory and
* reverts modified flags and configs to its default values.
* Test source
* ------------------------
* - unit/device/hipDeviceReset.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceReset_Positive_Basic") {
const auto device = GENERATE(range(0, HipTest::getDeviceCount()));
HIP_CHECK(hipSetDevice(device));
@@ -45,7 +69,7 @@ TEST_CASE("Unit_hipDeviceReset_Positive_Basic") {
: hipSharedMemBankSizeFourByte);
REQUIRE((shared_mem_config_ret == hipSuccess || shared_mem_config_ret == hipErrorNotSupported));
HIP_CHECK(hipSetDeviceFlags(flags_before ^ (1u << 2)));
HIP_CHECK(hipSetDeviceFlags(hipDeviceScheduleBlockingSync));
HIP_CHECK(hipDeviceReset());
@@ -74,6 +98,19 @@ TEST_CASE("Unit_hipDeviceReset_Positive_Basic") {
}
}
/**
* Test Description
* ------------------------
* - Resets device from another thread
* - Validates that device reset frees allocated memory from the main
* thread, and reverts modified flags and configs to its default values.
* Test source
* ------------------------
* - unit/device/hipDeviceReset.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceReset_Positive_Threaded") {
HIP_CHECK(hipSetDevice(0));
INFO("Current device is: " << 0);
@@ -97,7 +134,7 @@ TEST_CASE("Unit_hipDeviceReset_Positive_Threaded") {
REQUIRE((shared_mem_config_ret == hipSuccess || shared_mem_config_ret == hipErrorNotSupported));
HIP_CHECK(hipSetDeviceFlags(flags_before ^ (1u << 2)));
HIP_CHECK(hipSetDeviceFlags(hipDeviceScheduleBlockingSync));
std::thread([] {
HIP_CHECK_THREAD(hipSetDevice(0));
+97 -1
查看文件
@@ -24,13 +24,31 @@ THE SOFTWARE.
#include <hip_test_common.hh>
#include <threaded_zig_zag_test.hh>
/**
* @addtogroup hipDeviceSetCacheConfig hipDeviceSetCacheConfig
* @{
* @ingroup DeviceTest
* `hipDeviceSetCacheConfig(hipFuncCache_t cacheConfig)` -
* Set L1/Shared cache partition.
*/
namespace {
constexpr std::array<hipFuncCache_t, 4> kCacheConfigs{
hipFuncCachePreferNone, hipFuncCachePreferShared, hipFuncCachePreferL1,
hipFuncCachePreferEqual};
} // anonymous namespace
/**
* Test Description
* ------------------------
* - Check that `hipSuccess` is returned for all enumerators of `hipFuncCache_t`
* Test source
* ------------------------
* - unit/device/hipDeviceSetGetCacheConfig.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceSetCacheConfig_Positive_Basic") {
const auto device = GENERATE(range(0, HipTest::getDeviceCount()));
HIP_CHECK(hipSetDevice(device));
@@ -41,6 +59,21 @@ TEST_CASE("Unit_hipDeviceSetCacheConfig_Positive_Basic") {
HIP_CHECK(hipDeviceSetCacheConfig(cache_config));
}
/**
* Test Description
* ------------------------
* - Handle invalid cache config (-1):
* -# When platform is AMD
* - Expected output: return `hipErrorNotSupported`
* -# When platform is NVIDIA
* - Expected output: return `hipErrorInvalidValue`
* Test source
* ------------------------
* - unit/device/hipDeviceSetGetCacheConfig.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceSetCacheConfig_Negative_Parameters") {
#if HT_AMD
HIP_CHECK_ERROR(hipDeviceSetCacheConfig(static_cast<hipFuncCache_t>(-1)), hipSuccess);
@@ -49,6 +82,31 @@ TEST_CASE("Unit_hipDeviceSetCacheConfig_Negative_Parameters") {
#endif
}
/**
* End doxygen group hipDeviceSetCacheConfig.
* @}
*/
/**
* @addtogroup hipDeviceGetCacheConfig hipDeviceGetCacheConfig
* @{
* @ingroup DeviceTest
* `hipDeviceGetCacheConfig(hipFuncCache_t* cacheConfig)` -
* Get Cache configuration for a specific Device.
*/
/**
* Test Description
* ------------------------
* - Check that default cache config is returned if set
* has not been called previously.
* Test source
* ------------------------
* - unit/device/hipDeviceSetGetCacheConfig.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceGetCacheConfig_Positive_Default") {
const auto device = GENERATE(range(0, HipTest::getDeviceCount()));
HIP_CHECK(hipSetDevice(device));
@@ -59,6 +117,19 @@ TEST_CASE("Unit_hipDeviceGetCacheConfig_Positive_Default") {
REQUIRE(cache_config == hipFuncCachePreferNone);
}
/**
* Test Description
* ------------------------
* - Check that the returned cache configuration is equal to
* the one that is set previously.
* - Verify for multiple devices.
* Test source
* ------------------------
* - unit/device/hipDeviceSetGetCacheConfig.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceGetCacheConfig_Positive_Basic") {
const auto device = GENERATE(range(0, HipTest::getDeviceCount()));
HIP_CHECK(hipSetDevice(device));
@@ -74,6 +145,18 @@ TEST_CASE("Unit_hipDeviceGetCacheConfig_Positive_Basic") {
REQUIRE(returned_cache_config == cache_config);
}
/**
* Test Description
* ------------------------
* - Check that the returned cache configuration from the main thread
* is equal to the one that is set previously from different thread.
* Test source
* ------------------------
* - unit/device/hipDeviceSetGetCacheConfig.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceGetCacheConfig_Positive_Threaded") {
class HipDeviceSetGetCacheConfigTest : public ThreadedZigZagTest<HipDeviceSetGetCacheConfigTest> {
public:
@@ -99,6 +182,19 @@ TEST_CASE("Unit_hipDeviceGetCacheConfig_Positive_Threaded") {
test.run();
}
/**
* Test Description
* ------------------------
* - Verify handling of invalid arguments:
* -# When cache config is `nullptr`
* - Expected output: return `hipErrorInvalidValue`
* Test source
* ------------------------
* - unit/device/hipDeviceSetGetCacheConfig.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_HipDeviceGetCacheConfig_Negative_Parameters") {
HIP_CHECK_ERROR(hipDeviceGetCacheConfig(nullptr), hipErrorInvalidValue);
}
+107
查看文件
@@ -24,6 +24,16 @@ THE SOFTWARE.
#include <hip/hip_runtime_api.h>
#include <threaded_zig_zag_test.hh>
/**
* @addtogroup hipDeviceSetMemPool hipDeviceSetMemPool
* @{
* @ingroup DeviceTest
* `hipDeviceSetMemPool(int device, hipMemPool_t mem_pool)` -
* Sets the current memory pool of a device.
*
* The memory pool must be local to the specified device.
*/
static inline bool CheckMemPoolSupport(const int device) {
int mem_pool_support = 0;
HIP_CHECK(
@@ -50,6 +60,18 @@ static inline hipMemPool_t CreateMemPool(const int device) {
return mem_pool;
}
/**
* Test Description
* ------------------------
* - Validate behaviour when the valid MemPool is used, for multiple devices.
* Test source
* ------------------------
* - unit/device/hipDeviceSetGetMemPool.cc
* Test requirements
* ------------------------
* - Platform specific (AMD)
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceSetMemPool_Positive_Basic") {
const int device = GENERATE(range(0, HipTest::getDeviceCount()));
@@ -63,6 +85,24 @@ TEST_CASE("Unit_hipDeviceSetMemPool_Positive_Basic") {
HIP_CHECK(hipMemPoolDestroy(mem_pool));
}
/**
* Test Description
* ------------------------
* - Validate handling of invalid arguments:
* -# When pointer to MemPool is `nullptr`
* - Expected output: return `hipErrorInvalidValue`
* -# When device ID is equal to -1
* - Expected output: return `hipErrorInvalidValue`
* -# When device ID is out of bounds
* - Expected output: return `hipErrorInvalidValue`
* Test source
* ------------------------
* - unit/device/hipDeviceSetGetMemPool.cc
* Test requirements
* ------------------------
* - Platform specific (AMD)
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceSetMemPool_Negative_Parameters") {
hipMemPool_t mem_pool;
HIP_CHECK(hipDeviceGetDefaultMemPool(&mem_pool, 0));
@@ -80,6 +120,31 @@ TEST_CASE("Unit_hipDeviceSetMemPool_Negative_Parameters") {
}
}
/**
* End doxygen group hipDeviceSetMemPool.
* @}
*/
/**
* @addtogroup hipDeviceGetMemPool hipDeviceGetMemPool
* @{
* @ingroup DeviceTest
* `hipDeviceGetMemPool(hipMemPool_t* mem_pool, int device)` -
* Gets the current memory pool for the specified device
*/
/**
* Test Description
* ------------------------
* - Checks that returned MemPool is the default MemPool.
* Test source
* ------------------------
* - unit/device/hipDeviceSetGetMemPool.cc
* Test requirements
* ------------------------
* - Platform specific (AMD)
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceGetMemPool_Positive_Default") {
const int device = GENERATE(range(0, HipTest::getDeviceCount()));
@@ -96,6 +161,18 @@ TEST_CASE("Unit_hipDeviceGetMemPool_Positive_Default") {
REQUIRE(mem_pool == default_mem_pool);
}
/**
* Test Description
* ------------------------
* - Checks that returned MemPool is equal to the mempool that is set.
* Test source
* ------------------------
* - unit/device/hipDeviceSetGetMemPool.cc
* Test requirements
* ------------------------
* - Platform specific (AMD)
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceGetMemPool_Positive_Basic") {
const int device = GENERATE(range(0, HipTest::getDeviceCount()));
@@ -114,6 +191,18 @@ TEST_CASE("Unit_hipDeviceGetMemPool_Positive_Basic") {
HIP_CHECK(hipMemPoolDestroy(mem_pool));
}
/**
* Test Description
* ------------------------
* - Checks that returned MemPool is equal to the mempool that is set from a different thread.
* Test source
* ------------------------
* - unit/device/hipDeviceSetGetMemPool.cc
* Test requirements
* ------------------------
* - Platform specific (AMD)
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceGetMemPool_Positive_Threaded") {
class HipDeviceGetMemPoolTest : public ThreadedZigZagTest<HipDeviceGetMemPoolTest> {
public:
@@ -141,6 +230,24 @@ TEST_CASE("Unit_hipDeviceGetMemPool_Positive_Threaded") {
test.run();
}
/**
* Test Description
* ------------------------
* - Validates handling of invalid arguments:
* -# When output pointer to the MemPool is `nullptr`
* - Expected output: return `hipErrorInvalidValue`
* -# When device ID is equal to -1
* - Expected output: return `hipErrorInvalidValue`
* -# When device ID is out of bounds
* - Expected output: return `hipErrorInvalidValue`
* Test source
* ------------------------
* - unit/device/hipDeviceSetGetMemPool.cc
* Test requirements
* ------------------------
* - Platform specific (AMD)
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceGetMemPool_Negative_Parameters") {
hipMemPool_t mem_pool;
+95
查看文件
@@ -24,11 +24,30 @@ THE SOFTWARE.
#include <hip_test_common.hh>
#include <threaded_zig_zag_test.hh>
/**
* @addtogroup hipDeviceSetSharedMemConfig hipDeviceSetSharedMemConfig
* @{
* @ingroup DeviceTest
* `hipDeviceSetSharedMemConfig(hipSharedMemConfig config)` -
* The bank width of shared memory on current device is set.
*/
namespace {
constexpr std::array<hipSharedMemConfig, 3> kMemConfigs{
hipSharedMemBankSizeDefault, hipSharedMemBankSizeFourByte, hipSharedMemBankSizeEightByte};
} // anonymous namespace
/**
* Test Description
* ------------------------
* - Checks that all shared memory configs can be set.
* Test source
* ------------------------
* - unit/device/hipDeviceSetGetSharedMemConfig.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceSetSharedMemConfig_Positive_Basic") {
const auto device = GENERATE(range(0, HipTest::getDeviceCount()));
const auto mem_config = GENERATE(from_range(std::begin(kMemConfigs), std::end(kMemConfigs)));
@@ -38,11 +57,49 @@ TEST_CASE("Unit_hipDeviceSetSharedMemConfig_Positive_Basic") {
HIP_CHECK(hipDeviceSetSharedMemConfig(mem_config));
}
/**
* Test Description
* ------------------------
* - Validates handling of invalid arguments:
* -# When shared memory config has ordinal enum number -1:
* - AMD expected output: return `hipErrorNotSupported`
* - NVIDIA expected output: return `hipErrorInvalidValue`
* Test source
* ------------------------
* - unit/device/hipDeviceSetGetSharedMemConfig.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceSetSharedMemConfig_Negative_Parameters") {
HIP_CHECK_ERROR(hipDeviceSetSharedMemConfig(static_cast<hipSharedMemConfig>(-1)),
hipErrorInvalidValue);
}
/**
* End doxygen group hipDeviceSetSharedMemConfig.
* @}
*/
/**
* @addtogroup hipDeviceGetSharedMemConfig hipDeviceGetSharedMemConfig
* @{
* @ingroup DeviceTest
* `hipDeviceGetSharedMemConfig(hipSharedMemConfig* pConfig)` -
* Returns bank width of shared memory for current device.
*/
/**
* Test Description
* ------------------------
* - Checks that the returned shared memory configuration is the default one.
* Test source
* ------------------------
* - unit/device/hipDeviceSetGetSharedMemConfig.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceGetSharedMemConfig_Positive_Default") {
const auto device = GENERATE(range(0, HipTest::getDeviceCount()));
HIP_CHECK(hipSetDevice(device));
@@ -53,6 +110,18 @@ TEST_CASE("Unit_hipDeviceGetSharedMemConfig_Positive_Default") {
REQUIRE(mem_config == hipSharedMemBankSizeFourByte);
}
/**
* Test Description
* ------------------------
* - Checks that the returned shared memory configuration is equal
* to the one that is set previously.
* Test source
* ------------------------
* - unit/device/hipDeviceSetGetSharedMemConfig.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceGetSharedMemConfig_Positive_Basic") {
const auto device = GENERATE(range(0, HipTest::getDeviceCount()));
const auto mem_config = GENERATE(from_range(std::begin(kMemConfigs), std::end(kMemConfigs)));
@@ -74,6 +143,19 @@ TEST_CASE("Unit_hipDeviceGetSharedMemConfig_Positive_Basic") {
}
}
/**
* Test Description
* ------------------------
* - Checks that the returned shared memory configuration from
* the main thread is equal to the one that is set in a separate
* thread previously.
* Test source
* ------------------------
* - unit/device/hipDeviceSetGetSharedMemConfig.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceGetSharedMemConfig_Positive_Threaded") {
class HipDeviceGetSharedMemConfigTest
: public ThreadedZigZagTest<HipDeviceGetSharedMemConfigTest> {
@@ -107,6 +189,19 @@ TEST_CASE("Unit_hipDeviceGetSharedMemConfig_Positive_Threaded") {
test.run();
}
/**
* Test Description
* ------------------------
* - Verifies handling of invalid arguments:
* -# When pointer to the output shared memory configuration is `nullptr`:
* - Expected output: return `hipErrorInvalidValue`
* Test source
* ------------------------
* - unit/device/hipDeviceSetGetSharedMemConfig.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceGetSharedMemConfig_Negative_Parameters") {
HIP_CHECK_ERROR(hipDeviceGetSharedMemConfig(nullptr), hipErrorInvalidValue);
}
+17 -15
查看文件
@@ -17,12 +17,16 @@ OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/*
* Conformance test for checking functionality of
* hipError_t hipDeviceSetLimit ( enum hipLimit_t limit, size_t value );
*/
#include <hip_test_common.hh>
/**
* @addtogroup hipDeviceSetLimit hipDeviceSetLimit
* @{
* @ingroup DeviceTest
* `hipDeviceSetLimit(enum hipLimit_t limit, size_t value)` -
* Set Resource limits of current device.
*/
// Currently the HIGHER_VALUE is fixed to 16 KB based on currently
// set maximum value for hipLimitStackSize. In future, this value
// might need to change to avoid test case failure. In the same way
@@ -51,17 +55,15 @@ static bool testSetLimitFunc(hipLimit_t limit_to_test) {
}
/**
* hipDeviceSetLimit tests =>
*
* Scenario1: Single device Set-Get test for hipLimitStackSize flag.
*
* Scenario2: Single device Set-Get test for hipLimitPrintfFifoSize flag.
*
* Scenario3: Single device Set-Get test for hipLimitMallocHeapSize flag.
*
* Scenario4: Multidevice Set-Get test for all the flags
*
* Scenario5: Negative Scenario - Invalid flag value
* Test Description
* ------------------------
* - Sets different values for the resource limits.
* Test source
* ------------------------
* - unit/device/hipDeviceSetLimit.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceSetLimit_SetGet") {
size_t value = 0;
+46 -6
查看文件
@@ -20,14 +20,18 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/*
* Test for checking the functionality of
* hipError_t hipDeviceSynchronize();
*/
#include <hip_test_common.hh>
/**
* @addtogroup hipDeviceSynchronize hipDeviceSynchronize
* @{
* @ingroup DeviceTest
* `hipDeviceSynchronize(void)` -
* Waits on all active streams on current device.
* When this command is invoked, the host thread gets blocked until all the commands associated
* with streams associated with the device. HIP does not support multiple blocking modes (yet!).
*/
#define _SIZE sizeof(int) * 1024 * 1024
#define NUM_STREAMS 2
#define NUM_ITERS 1 << 30
@@ -44,6 +48,18 @@ static __global__ void Iter(int* Ad, int num) {
}
}
/**
* Test Description
* ------------------------
* - Performs synchronization when no work is enqueued on stream,
* utilizing multiple devices.
* Test source
* ------------------------
* - unit/device/hipDeviceSynchronize.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceSynchronize_Positive_Empty_Streams") {
const auto device = GENERATE(range(0, HipTest::getDeviceCount()));
HIP_CHECK(hipSetDevice(device));
@@ -55,6 +71,18 @@ TEST_CASE("Unit_hipDeviceSynchronize_Positive_Empty_Streams") {
HIP_CHECK(hipStreamDestroy(stream));
}
/**
* Test Description
* ------------------------
* - Performs synchronization between large kernel execution
* and asynchronous copying of the array, on default(null) stream.
* Test source
* ------------------------
* - unit/device/hipDeviceSynchronize.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceSynchronize_Positive_Nullstream") {
const auto device = GENERATE(range(0, HipTest::getDeviceCount()));
HIP_CHECK(hipSetDevice(device));
@@ -78,6 +106,18 @@ TEST_CASE("Unit_hipDeviceSynchronize_Positive_Nullstream") {
REQUIRE(1 << 30 == A_h[0] - 1);
}
/**
* Test Description
* ------------------------
* - Performs synchronization between large kernel execution
* and asynchronous copying of the array, on multiple streams.
* Test source
* ------------------------
* - unit/device/hipDeviceSynchronize.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceSynchronize_Functional") {
int* A[NUM_STREAMS];
int* Ad[NUM_STREAMS];
+47 -10
查看文件
@@ -17,19 +17,32 @@ OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/*
* Conformance test for checking functionality of
* hipError_t hipDeviceTotalMem(size_t* bytes, hipDevice_t device);
*/
#include <hip_test_common.hh>
/**
* @addtogroup hipDeviceTotalMem hipDeviceTotalMem
* @{
* @ingroup DriverTest
* `hipDeviceTotalMem(size_t* bytes, hipDevice_t device)` -
* Returns the total amount of memory on the device.
*/
/**
* hipDeviceTotalMem tests
* Scenario1: Validates if bytes = nullptr returns hip error code.
* Scenario2: Validates if error code is returned for device = -1.
* Scenario3: Validates if error code is returned for device = deviceCount.
* Scenario4: Compare total memory size with hipDeviceProp_t.totalGlobalMem for each device.
* Test Description
* ------------------------
* - Validate handling of invalid arguments:
* -# When output pointer to the total memory is `nullptr`
* - Expected output: return `hipErrorInvalidValue`
* -# When device ordinal is negative (-1)
* - Expected output: return `hipErrorInvalidDevice`
* -# When device ordinal is out of bounds
* - Expected output: return `hipErrorInvalidDevice`
* Test source
* ------------------------
* - unit/device/hipDeviceTotalMem.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceTotalMem_NegTst") {
#if HT_NVIDIA
@@ -54,7 +67,18 @@ TEST_CASE("Unit_hipDeviceTotalMem_NegTst") {
}
}
// Scenario 4
/**
* Test Description
* ------------------------
* - Check that the returned number of bytes is the same as the
* one from device attributes.
* Test source
* ------------------------
* - unit/device/hipDeviceTotalMem.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceTotalMem_ValidateTotalMem") {
size_t totMem;
int numDevices = 0;
@@ -77,6 +101,19 @@ TEST_CASE("Unit_hipDeviceTotalMem_ValidateTotalMem") {
REQUIRE(total == totMem);
}
/**
* Test Description
* ------------------------
* - Check that total memory is returned when other device is
* set than the one in the API call.
* Test source
* ------------------------
* - unit/device/hipDeviceTotalMem.cc
* Test requirements
* ------------------------
* - Multi-device test
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceTotalMem_NonSelectedDevice") {
auto deviceCount = HipTest::getDeviceCount();
if (deviceCount < 2) {
+34 -5
查看文件
@@ -18,13 +18,29 @@ 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 :
Unit_hipDriverGetVersion_Positive - Test simple reading of HIP driver version with hipDriverGetVersion api
Unit_hipDriverGetVersion_Negative - Test unsuccessful execution of hipDriverGetVersion when nullptr is set as input parameter
*/
#include <hip_test_common.hh>
/**
* @addtogroup hipDriverGetVersion hipDriverGetVersion
* @{
* @ingroup DriverTest
* `hipDriverGetVersion(int* driverVersion)` -
* Returns the approximate HIP driver version.
*/
/**
* Test Description
* ------------------------
* - Check that the returned driver version has valid value.
* - Both CUDA and HIP driver version can be returned, depending on the device.
* Test source
* ------------------------
* - unit/device/hipDriverGetVersion.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDriverGetVersion_Positive") {
int driverVersion = -1;
@@ -33,6 +49,19 @@ TEST_CASE("Unit_hipDriverGetVersion_Positive") {
INFO("Driver version " << driverVersion);
}
/**
* Test Description
* ------------------------
* - Validates handling of invalid arguments:
* -# When output pointer to the driver version is `nullptr`
* - Expected output: return `hipErrorInvalidValue`
* Test source
* ------------------------
* - unit/device/hipDriverGetVersion.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDriverGetVersion_Negative") {
// If initialization is attempted with nullptr, error shall be reported
HIP_CHECK_ERROR(hipDriverGetVersion(nullptr), hipErrorInvalidValue);
+55 -1
查看文件
@@ -23,7 +23,28 @@ THE SOFTWARE.
#include <hip_test_common.hh>
#include <hip/hip_runtime_api.h>
#if __linux__ && HT_AMD
/**
* @addtogroup hipExtGetLinkTypeAndHopCount hipExtGetLinkTypeAndHopCount
* @{
* @ingroup DeviceTest
* `hipExtGetLinkTypeAndHopCount(int device1, int device2, uint32_t* linktype, uint32_t* hopcount)` -
* Returns the link type and hop count between two devices.
*/
#if __linux__
#if HT_AMD
/**
* Test Description
* ------------------------
* - Check commutativity of devices for every device combination.
* Test source
* ------------------------
* - unit/device/hipExtGetLinkTypeAndHopCount.cc
* Test requirements
* ------------------------
* - Platform specific (AMD)
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipExtGetLinkTypeAndHopCount_Positive_Basic") {
const auto device1 = GENERATE(range(0, HipTest::getDeviceCount()));
const auto device2 = GENERATE(range(0, HipTest::getDeviceCount()));
@@ -44,6 +65,38 @@ TEST_CASE("Unit_hipExtGetLinkTypeAndHopCount_Positive_Basic") {
REQUIRE(link_type1 == link_type2);
}
/**
* Test Description
* ------------------------
* - Validates handling of invalid arguments:
* -# When creating the link between the same device
* - Expected output: return `hipErrorInvalidValue`
* -# When device ordinance for the first device is out of bounds
* - Expected output: return `hipErrorInvalidDevice`
* -# When device ordinance for the second device is out of bounds
* - Expected output: return `hipErrorInvalidDevice`
* -# When device ordinance for both devices is out of bounds
* - Expected output: return `hipErrorInvalidDevice`
* -# When device ordinance for the first device is < 0
* - Expected output: return `hipErrorInvalidValue`
* -# When device ordinance for the second device is < 0
* - Expected output: return `hipErrorInvalidValue`
* -# When device ordinance for both devices is < 0
* - Expected output: return `hipErrorInvalidValue`
* -# When pointer to the link type is `nullptr`
* - Expected output: return `hipErrorInvalidValue`
* -# When pointer to the hop count is `nullptr`
* - Expected output: return `hipErrorInvalidValue`
* -# When both pointers are `nullptr`
* - Expected output: return `hipErrorInvalidValue`
* Test source
* ------------------------
* - unit/device/hipExtGetLinkTypeAndHopCount.cc
* Test requirements
* ------------------------
* - Platform specific (AMD)
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipExtGetLinkTypeAndHopCount_Negative_Parameters") {
uint32_t link_type, hop_count;
SECTION("same device") {
@@ -98,3 +151,4 @@ TEST_CASE("Unit_hipExtGetLinkTypeAndHopCount_Negative_Parameters") {
}
}
#endif
#endif
+63 -8
查看文件
@@ -16,7 +16,6 @@ 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 device info API extensions for HIP
#include <string.h>
#ifdef __linux__
@@ -28,6 +27,14 @@ THE SOFTWARE.
#include <hip_test_common.hh>
/**
* @addtogroup hipDeviceGetAttribute hipDeviceGetAttribute
* @{
* @ingroup DeviceTest
* `hipDeviceGetAttribute(int* pi, hipDeviceAttribute_t attr, int deviceId)` -
* Query for a specific device attribute.
*/
static hipError_t test_hipDeviceGetAttribute(int deviceId,
hipDeviceAttribute_t attr,
int expectedValue = -1) {
@@ -64,6 +71,18 @@ static hipError_t test_hipDeviceGetHdpAddress(int deviceId,
return hipSuccess;
}
/**
* Test Description
* ------------------------
* - Validate various device attributes against device properties.
* - Matching attribute and property value shall be equal.
* Test source
* ------------------------
* - unit/device/hipGetDeviceAttribute.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipGetDeviceAttribute_CheckAttrValues") {
int deviceId;
HIP_CHECK(hipGetDevice(&deviceId));
@@ -235,7 +254,7 @@ TEST_CASE("Unit_hipGetDeviceAttribute_CheckAttrValues") {
hipDeviceAttributeUnifiedAddressing, 1/*true*/));
}
/**
/*
* Validate the hipDeviceAttributeFineGrainSupport property in AMD.
*/
#ifdef __linux__
@@ -264,7 +283,19 @@ static bool isRocmPathSet() {
return false;
}
// This is AMD specific property test
/**
* Test Description
* ------------------------
* - Validate fine grain support attribute against
* known values for different AMD architectures
* Test source
* ------------------------
* - unit/device/hipGetDeviceAttribute.cc
* Test requirements
* ------------------------
* - Platform specific (AMD)
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipGetDeviceAttribute_CheckFineGrainSupport") {
int deviceId;
int deviceCount = 0;
@@ -326,12 +357,25 @@ TEST_CASE("Unit_hipGetDeviceAttribute_CheckFineGrainSupport") {
}
#endif
#endif
/**
* Validates negative scenarios for hipDeviceGetAttribute
* scenario1: pi = nullptr
* scenario2: device = -1 (Invalid Device)
* scenario3: device = Non Existing Device
* scenario4: attr = Invalid Attribute
* Test Description
* ------------------------
* - Validates negative scenarios:
* -# When pointer to value is `nullptr`
* - Expected output: do not return `hipSuccess`
* -# When device ID is `-1`
* - Expected output: do not return `hipSuccess`
* -# When device ID is out of bounds
* - Expected output: do not return `hipSuccess`
* -# When attribute is invalid (-1)
* - Expected output: do not return `hipSuccess`
* Test source
* ------------------------
* - unit/device/hipGetDeviceAttribute.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceGetAttribute_NegTst") {
int deviceCount = 0;
@@ -526,6 +570,17 @@ template <size_t n> void printAttributes(const AttributeToStringMap<n>& attribut
std::flush(std::cout);
}
/**
* Test Description
* ------------------------
* - Print out all device attributes in agreed upon format.
* Test source
* ------------------------
* - unit/device/hipGetDeviceAttribute.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Print_Out_Attributes") {
const auto device = GENERATE(range(0, HipTest::getDeviceCount()));
hipDeviceProp_t properties;
+41 -8
查看文件
@@ -20,23 +20,45 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/*
* Conformance test for checking functionality of
* hipError_t hipGetDeviceCount(int* count);
*/
#include <hip_test_common.hh>
#include <hip_test_process.hh>
/**
* hipGetDeviceCount tests
* Scenario: Validates if &numDevices = nullptr returns error code.
* @addtogroup hipGetDeviceCount hipGetDeviceCount
* @{
* @ingroup DeviceTest
* `hipGetDeviceCount(int* count)` -
* Return number of compute-capable devices.
*/
/**
* Test Description
* ------------------------
* - Passes invalid pointer as output parameter for device count - `nullptr`
* Test source
* ------------------------
* - unit/device/hipGetDeviceCount.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipGetDeviceCount_NegTst") {
// Scenario1
REQUIRE_FALSE(hipGetDeviceCount(nullptr) == hipSuccess);
}
/**
* Test Description
* ------------------------
* - Validates correct functionality when the device visibility
* environment variables are set. Uses unit/device/hipDeviceCount_exe.cc
* to set visibility.
* Test source
* ------------------------
* - unit/device/hipGetDeviceCount.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipGetDeviceCount_HideDevices") {
int deviceCount = HipTest::getDeviceCount();
if (deviceCount < 2) {
@@ -59,6 +81,17 @@ TEST_CASE("Unit_hipGetDeviceCount_HideDevices") {
}
}
/**
* Test Description
* ------------------------
* - Prints device count to the standard output.
* Test source
* ------------------------
* - unit/device/hipGetDeviceCount.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Print_Out_Device_Count") {
std::cout << "Device Count: " << HipTest::getDeviceCount() << std::endl;
}
+48 -6
查看文件
@@ -22,6 +22,13 @@ THE SOFTWARE.
#include <hip_test_common.hh>
/**
* @addtogroup hipGetDeviceProperties hipGetDeviceProperties
* @{
* @ingroup DeviceTest
* `hipGetDeviceProperties(hipDeviceProp_t* prop, int deviceId)` -
* Returns device properties.
*/
#define NUM_OF_ARCHPROP 17
#define HIP_ARCH_HAS_GLOBAL_INT32_ATOMICS_IDX 0
@@ -66,7 +73,7 @@ __global__ void mykernel(int *archProp_d) {
getArchValuesFromDevice(archProp_d);
}
/**
/*
* Internal Functions
*/
static void validateDeviceMacro(int *archProp_h, hipDeviceProp_t *prop) {
@@ -121,7 +128,7 @@ static void validateDeviceMacro(int *archProp_h, hipDeviceProp_t *prop) {
CHECK_FALSE(prop->arch.hasDynamicParallelism !=
archProp_h[HIP_ARCH_HAS_DYNAMIC_PARALLEL_IDX]);
}
/**
/*
* Validates value of __HIP_ARCH_* with deviceProp.arch.has* as follows
* __HIP_ARCH_HAS_GLOBAL_INT32_ATOMICS__ == hasGlobalInt32Atomics
* __HIP_ARCH_HAS_GLOBAL_FLOAT_ATOMIC_EXCH__ == hasGlobalFloatAtomicExch
@@ -142,6 +149,18 @@ static void validateDeviceMacro(int *archProp_h, hipDeviceProp_t *prop) {
* __HIP_ARCH_HAS_DYNAMIC_PARALLEL__ == hasDynamicParallelism
*/
#if HT_AMD
/**
* Test Description
* ------------------------
* - Compare some device properties against properties derived from device code.
* Test source
* ------------------------
* - unit/device/hipGetDeviceProperties.cc
* Test requirements
* ------------------------
* - Platform specific (AMD)
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipGetDeviceProperties_ArchPropertiesTst") {
int *archProp_h, *archProp_d;
archProp_h = new int[NUM_OF_ARCHPROP];
@@ -174,11 +193,23 @@ TEST_CASE("Unit_hipGetDeviceProperties_ArchPropertiesTst") {
delete[] archProp_h;
}
#endif
/**
* Validates negative scenarios for hipGetDeviceProperties
* scenario1: props = nullptr
* scenario2: device = -1 (Invalid Device)
* scenario3: device = Non Existing Device
* Test Description
* ------------------------
* - Validates handling of invalid arguments:
* -# When output pointer to the properties is `nullptr`
* - Expected output: do not return `hipSuccess`
* -# When the device ID is equal to -1
* - Expected output: do not return `hipSuccess`
* -# When the device ID is out of bounds
* - Expected output: do not return `hipSuccess`
* Test source
* ------------------------
* - unit/device/hipGetDeviceProperties.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipGetDeviceProperties_NegTst") {
hipDeviceProp_t prop;
@@ -201,6 +232,17 @@ TEST_CASE("Unit_hipGetDeviceProperties_NegTst") {
}
}
/**
* Test Description
* ------------------------
* - Print out all properties in agreed upon format.
* Test source
* ------------------------
* - unit/device/hipGetDeviceProperties.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Print_Out_Properties") {
constexpr int w = 42;
const auto device = GENERATE(range(0, HipTest::getDeviceCount()));
+116 -34
查看文件
@@ -22,42 +22,32 @@ THE SOFTWARE.
#include <vector>
#include <mutex>
#include <condition_variable>
/**
* Conformance test for checking functionality of
* hipError_t hipGetDeviceFlags(unsigned int* flags);
* hipError_t hipSetDeviceFlags(unsigned flags);
*
*
* hipGetDeviceFlags and hipSetDeviceFlags tests.
* Scenario1: Validates if hipGetDeviceFlags returns hipErrorInvalidValue for flags = nullptr.
* Scenario2: Validates if hipSetDeviceFlags returns hipErrorInvalidValue for invalid flags.
* Scenario3: Validates if flags returned by hipGetDeviceFlags are valid.
* Scenario4: Validates that flags set with hipSetDeviceFlags can be retrieved with
* hipGetDeviceFlags.
* Scenario5: Validates that flags set with hipSetDeviceFlags can be retrieved on a seperate thread
* with hipGetDeviceFlags.
* @addtogroup hipGetDeviceFlags hipGetDeviceFlags
* @{
* @ingroup DeviceTest
* `hipGetDeviceFlags(unsigned int* flags)` -
* Gets the flags set for current device.
*/
/**
* Test Description
* ------------------------
* - Validates handling of invalid arguments:
* -# When output pointer to the flag is `nullptr`
* - Expected output: return `hipErrorInvalidValue`
* Test source
* ------------------------
* - unit/device/hipGetSetDeviceFlags.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipGetSetDeviceFlags_NullptrFlag") {
// Scenario1
HIP_CHECK_ERROR(hipGetDeviceFlags(nullptr), hipErrorInvalidValue);
}
TEST_CASE("Unit_hipGetSetDeviceFlags_InvalidFlag") {
#if HT_AMD
HipTest::HIP_SKIP_TEST("EXSWCPHIPT-115");
return;
#endif
// Scenario2
const unsigned int invalidFlag = GENERATE(0b011, // schedule flags should not overlap
0b101, // schedule flags should not overlap
0b110, // schedule flags should not overlap
0b111, // schedule flags should not overlap
0b100000, // out of bounds
0xFFFF);
CAPTURE(invalidFlag);
HIP_CHECK_ERROR(hipSetDeviceFlags(invalidFlag), hipErrorInvalidValue);
}
std::array<unsigned int, 16> getValidFlags() {
constexpr std::array<unsigned int, 4> scheduleFlags{hipDeviceScheduleAuto, hipDeviceScheduleSpin,
hipDeviceScheduleYield,
@@ -78,9 +68,19 @@ std::array<unsigned int, 16> getValidFlags() {
return validFlags;
}
/**
* Test Description
* ------------------------
* - Check returned flags against Cartesian product of all
* possible valid flag combinations.
* Test source
* ------------------------
* - unit/device/hipGetSetDeviceFlags.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipGetSetDeviceFlags_ValidFlag") {
// Scenario3
auto validFlags = getValidFlags();
unsigned int flag = 0;
@@ -88,8 +88,20 @@ TEST_CASE("Unit_hipGetSetDeviceFlags_ValidFlag") {
REQUIRE(std::find(std::begin(validFlags), std::end(validFlags), flag) != std::end(validFlags));
}
/**
* Test Description
* ------------------------
* - Validate that returned flags are equal to the ones that have
* been previously set.
* - Perform validation for all connected devices and all flag combinations.
* Test source
* ------------------------
* - unit/device/hipGetSetDeviceFlags.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipGetSetDeviceFlags_SetThenGet") {
// Scenario4
auto validFlags = getValidFlags();
auto devNo = GENERATE(range(0, HipTest::getDeviceCount()));
@@ -108,8 +120,19 @@ TEST_CASE("Unit_hipGetSetDeviceFlags_SetThenGet") {
REQUIRE((flag & hipDeviceScheduleMask) == getFlag);
}
/**
* Test Description
* ------------------------
* - Validate that the returned flags from the main thread are
* equal to the flags that are set from another thread.
* Test source
* ------------------------
* - unit/device/hipGetSetDeviceFlags.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipGetSetDeviceFlags_Threaded") {
// Scenario5
auto validFlags = getValidFlags();
auto devNo = GENERATE(range(0, HipTest::getDeviceCount()));
@@ -146,6 +169,19 @@ TEST_CASE("Unit_hipGetSetDeviceFlags_Threaded") {
HIP_CHECK_THREAD_FINALIZE();
}
/**
* Test Description
* ------------------------
* - Create context with flags and validate that valid
* flags are returned.
* - Perform validation for all connected devices and all flag combinations.
* Test source
* ------------------------
* - unit/device/hipGetSetDeviceFlags.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipGetDeviceFlags_Positive_Context") {
auto validFlags = getValidFlags();
const unsigned int flags =
@@ -163,4 +199,50 @@ TEST_CASE("Unit_hipGetDeviceFlags_Positive_Context") {
HIP_CHECK(hipCtxPopCurrent(&ctx));
HIP_CHECK(hipCtxDestroy(ctx));
}
/**
* End doxygen group hipGetDeviceFlags.
* @}
*/
/**
* @addtogroup hipSetDeviceFlags hipSetDeviceFlags
* @{
* @ingroup DeviceTest
* `hipSetDeviceFlags(unsigned flags)` -
* The current device behavior is changed according the flags passed.
* ________________________
* Test cases from other modules:
* - @ref Unit_hipGetSetDeviceFlags_SetThenGet
* - @ref Unit_hipGetSetDeviceFlags_Threaded
*/
/**
* Test Description
* ------------------------
* - Validates handling of invalid arguments:
* -# When flag combinations are invalid
* - Expected output: return `hipErrorInvalidValue`
* Test source
* ------------------------
* - unit/device/hipGetSetDeviceFlags.cc
* Test requirements
* ------------------------
* - Platform specific (NVIDIA)
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipGetSetDeviceFlags_InvalidFlag") {
#if HT_AMD
HipTest::HIP_SKIP_TEST("EXSWCPHIPT-115");
return;
#endif
const unsigned int invalidFlag = GENERATE(0b011, // schedule flags should not overlap
0b101, // schedule flags should not overlap
0b110, // schedule flags should not overlap
0b111, // schedule flags should not overlap
0b100000, // out of bounds
0xFFFF);
CAPTURE(invalidFlag);
HIP_CHECK_ERROR(hipSetDeviceFlags(invalidFlag), hipErrorInvalidValue);
}
+34 -5
查看文件
@@ -18,13 +18,29 @@ 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 :
Unit_hipInit_Positive - Test explicit HIP initalization with hipInit api
Unit_hipInit_Negative_InvalidFlag - Test unsuccessful HIP initalization with hipInit api when flag is invalid
*/
#include <hip_test_common.hh>
/**
* @addtogroup hipInit hipInit
* @{
* @ingroup DriverTest
* `hipInit(unsigned int flags)` -
* Explicitly initializes the HIP runtime.
*/
/**
* Test Description
* ------------------------
* - Initialize HIP runtime.
* - Call a HIP API and check that the runtime is initialized successfully.
* Test source
* ------------------------
* - unit/device/hipInit.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipInit_Positive") {
HIP_CHECK(hipInit(0));
@@ -34,6 +50,19 @@ TEST_CASE("Unit_hipInit_Positive") {
REQUIRE(count >= 0);
}
/**
* Test Description
* ------------------------
* - Validates handling of invalid arguments:
* -# When flag has invalid value equal to -1
* - Expected output: return `hipErrorInvalidValue`
* Test source
* ------------------------
* - unit/device/hipInit.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipInit_Negative") {
// If initialization is attempted with invalid flag, error shall be reported
unsigned int invalid_flag = 1;
+38
查看文件
@@ -27,6 +27,32 @@ THE SOFTWARE.
#include <hip_test_common.hh>
#include <hip/hip_runtime_api.h>
/**
* @addtogroup hipIpcCloseMemHandle hipIpcCloseMemHandle
* @{
* @ingroup DeviceTest
* `hipIpcCloseMemHandle(void* devPtr)` -
* Close memory mapped with hipIpcOpenMemHandle.
* Unmaps memory returned by hipIpcOpenMemHandle.
* ________________________
* Test cases from other modules:
* - @ref Unit_hipIpcMemAccess_Semaphores
* - @ref Unit_hipIpcMemAccess_ParameterValidation
*/
/**
* Test Description
* ------------------------
* - Checks that memory stays mapped if reference count doesn't reach zero.
* - Checks that memory stays mapped if handle is closed in second process.
* Test source
* ------------------------
* - unit/device/hipIpcCloseMemHandle.cc
* Test requirements
* ------------------------
* - Host specific (LINUX)
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipIpcCloseMemHandle_Positive_Reference_Counting") {
int fd[2];
REQUIRE(pipe(fd) == 0);
@@ -80,6 +106,18 @@ TEST_CASE("Unit_hipIpcCloseMemHandle_Positive_Reference_Counting") {
}
}
/**
* Test Description
* ------------------------
* - Closes the memory handle from the process that has created it.
* Test source
* ------------------------
* - unit/device/hipIpcCloseMemHandle.cc
* Test requirements
* ------------------------
* - Host specific (LINUX)
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipIpcCloseMemHandle_Negative_Close_In_Originating_Process") {
void* ptr;
hipIpcMemHandle_t handle;
+64
查看文件
@@ -25,6 +25,29 @@ THE SOFTWARE.
#include <hip_test_common.hh>
#include <hip/hip_runtime_api.h>
/**
* @addtogroup hipIpcGetMemHandle hipIpcGetMemHandle
* @{
* @ingroup DeviceTest
* `hipIpcGetMemHandle(hipIpcMemHandle_t* handle, void* devPtr)` -
* Gets an interprocess memory handle for an existing device memory allocation.
* ________________________
* Test cases from other modules:
* - @ref Unit_hipIpcMemAccess_ParameterValidation
*/
/**
* Test Description
* ------------------------
* - Check that unique handles are returned in consecutive calls.
* Test source
* ------------------------
* - unit/device/hipIpcGetMemHandle.cc
* Test requirements
* ------------------------
* - Host specific (LINUX)
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipIpcGetMemHandle_Positive_Unique_Handles_Separate_Allocations") {
void *ptr1, *ptr2;
hipIpcMemHandle_t handle1, handle2;
@@ -39,6 +62,19 @@ TEST_CASE("Unit_hipIpcGetMemHandle_Positive_Unique_Handles_Separate_Allocations"
HIP_CHECK(hipFree(ptr2));
}
/**
* Test Description
* ------------------------
* - Check that unique handles are returned for the same address,
* but separate allocations.
* Test source
* ------------------------
* - unit/device/hipIpcGetMemHandle.cc
* Test requirements
* ------------------------
* - Host specific (LINUX)
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipIpcGetMemHandle_Positive_Unique_Handles_Reused_Memory") {
void *ptr1 = nullptr, *ptr2 = nullptr;
hipIpcMemHandle_t handle1, handle2;
@@ -54,6 +90,20 @@ TEST_CASE("Unit_hipIpcGetMemHandle_Positive_Unique_Handles_Reused_Memory") {
HIP_CHECK(hipFree(ptr2));
}
/**
* Test Description
* ------------------------
* - Test if previously freed memory will generate an invalid handle:
* -# When memory is freed before getting handle
* - Expected output: return `hipErrorInvalidValue
* Test source
* ------------------------
* - unit/device/hipIpcGetMemHandle.cc
* Test requirements
* ------------------------
* - Host specific (LINUX)
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipIpcGetMemHandle_Negative_Handle_For_Freed_Memory") {
void* ptr;
hipIpcMemHandle_t handle;
@@ -62,6 +112,20 @@ TEST_CASE("Unit_hipIpcGetMemHandle_Negative_Handle_For_Freed_Memory") {
HIP_CHECK_ERROR(hipIpcGetMemHandle(&handle, ptr), hipErrorInvalidValue);
}
/**
* Test Description
* ------------------------
* - Test if out of bounds pointer will generate an error:
* -# When the memory pointer is too large
* - Expected output: return `hipErrorInvalidValue`
* Test source
* ------------------------
* - unit/device/hipIpcGetMemHandle.cc
* Test requirements
* ------------------------
* - Host specific (LINUX)
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipIpcGetMemHandle_Negative_Out_Of_Bound_Pointer") {
int* ptr;
constexpr size_t n = 1024;
+39
查看文件
@@ -28,6 +28,30 @@ THE SOFTWARE.
#include <hip_test_common.hh>
#include <hip/hip_runtime_api.h>
/**
* @addtogroup hipIpcOpenMemHandle hipIpcOpenMemHandle
* @{
* @ingroup DeviceTest
* `hipIpcOpenMemHandle(void** devPtr, hipIpcMemHandle_t handle, unsigned int flags)` -
* Opens an interprocess memory handle exported from another process
* and returns a device pointer usable in the local process.
*/
/**
* Test Description
* ------------------------
* - Handle the attempt to open memory handle in the same process
* that has created it.
* -# When the process is the same
* - Expected output: return `hipErrorInvalidContext`
* Test source
* ------------------------
* - unit/device/hipIpcOpenMemHandle.cc
* Test requirements
* ------------------------
* - Host specific (LINUX)
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipIpcOpenMemHandle_Negative_Open_In_Creating_Process") {
hipDeviceptr_t ptr1, ptr2;
hipIpcMemHandle_t handle;
@@ -39,6 +63,21 @@ TEST_CASE("Unit_hipIpcOpenMemHandle_Negative_Open_In_Creating_Process") {
HIP_CHECK(hipFree(reinterpret_cast<void*>(ptr1)));
}
/**
* Test Description
* ------------------------
* - Checks that opening the same memory handle from a different context
* returns error
* -# When different context
* - Expected output: return `hipErrorInvalidResourceHandle`
* Test source
* ------------------------
* - unit/device/hipIpcOpenMemHandle.cc
* Test requirements
* ------------------------
* - Host specific (LINUX)
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipIpcOpenMemHandle_Negative_Open_In_Two_Contexts_Same_Device") {
int fd[2];
REQUIRE(pipe(fd) == 0);
+33 -9
查看文件
@@ -16,21 +16,32 @@ 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 :
Unit_hipRuntimeGetVersion_Positive - Test simple reading of HIP runtime version with hipRuntimeGetVersion api
Unit_hipRuntimeGetVersion_Negative - Test unsuccessful execution of hipRuntimeGetVersion when nullptr is set as input parameter
*/
/*
* Conformance test for checking functionality of
* hipError_t hipRuntimeGetVersion(int* runtimeVersion);
#include <hip_test_common.hh>
/**
* @addtogroup hipRuntimeGetVersion hipRuntimeGetVersion
* @{
* @ingroup DriverTest
* `hipRuntimeGetVersion(int* runtimeVersion)` -
* Returns the approximate HIP runtime version.
* On HIP/HCC path this function returns HIP runtime patch version
* (a 5 digit code) however on
* HIP/NVCC path this function return CUDA runtime version.
*/
#include <hip_test_common.hh>
/**
* Test Description
* ------------------------
* - Checks that valid runtime version is returned.
* - Print out the runtime version.
* Test source
* ------------------------
* - unit/device/hipRuntimeGetVersion.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipRuntimeGetVersion_Positive") {
int runtimeVersion = -1;
HIP_CHECK(hipRuntimeGetVersion(&runtimeVersion));
@@ -38,6 +49,19 @@ TEST_CASE("Unit_hipRuntimeGetVersion_Positive") {
INFO("Runtime version " << runtimeVersion);
}
/**
* Test Description
* ------------------------
* - Validates handling of invalid arguments:
* -# When output pointer to the runtime version is nullptr
* - Expected output: do not return `hipSuccess`
* Test source
* ------------------------
* - unit/device/hipRuntimeGetVersion.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipRuntimeGetVersion_Negative") {
// If initialization is attempted with nullptr, error shall be reported
CHECK_FALSE(hipRuntimeGetVersion(nullptr) == hipSuccess);
+113 -5
查看文件
@@ -19,16 +19,31 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/*
* Verifies functionality of hipSetDevice/hipGetDevice api.
* -- Basic Test to set and get valid device numbers.
*/
#include <thread>
#include <hip_test_common.hh>
#include <threaded_zig_zag_test.hh>
/**
* @addtogroup hipSetDevice hipSetDevice
* @{
* @ingroup DeviceTest
* `hipSetDevice(int deviceId)` -
* Set default device to be used for subsequent hip API calls from this thread.
*/
/**
* Test Description
* ------------------------
* - Performs multiple set/get device operations and verifies
* that the device that is set is the one that is gotten.
* Test source
* ------------------------
* - unit/device/hipSetGetDevice.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipSetDevice_BasicSetGet") {
int numDevices = 0;
int device{};
@@ -46,6 +61,18 @@ TEST_CASE("Unit_hipSetDevice_BasicSetGet") {
}
}
/**
* Test Description
* ------------------------
* - Performs set/get operations for each detected
* device from multiple threads.
* Test source
* ------------------------
* - unit/device/hipSetGetDevice.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipGetSetDevice_MultiThreaded") {
auto maxThreads = std::thread::hardware_concurrency();
auto deviceCount = HipTest::getDeviceCount();
@@ -87,6 +114,18 @@ TEST_CASE("Unit_hipGetSetDevice_MultiThreaded") {
HIP_CHECK_THREAD_FINALIZE();
}
/**
* Test Description
* ------------------------
* - Performs set/get device for separate devices on two
* threads and validates device ordinance via memory allocation.
* Test source
* ------------------------
* - unit/device/hipSetGetDevice.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipSetGetDevice_Positive_Threaded_Basic") {
class HipSetGetDeviceThreadedTest : public ThreadedZigZagTest<HipSetGetDeviceThreadedTest> {
public:
@@ -125,6 +164,23 @@ TEST_CASE("Unit_hipSetGetDevice_Positive_Threaded_Basic") {
test.run();
}
/**
* Test Description
* ------------------------
* - Validates that get/set device APIs can handle invalid parameters
* -# Get device when device is `nullptr`
* - Expected output: return `hipErrorInvalidValue`
* -# Set device with ordinal number `-1`
* - Expected output: return `hipErrorInvalidDevice`
* -# Set device to the ID which is out of bounds
* - Expected output: return `hipErrorInvalidDevice`
* Test source
* ------------------------
* - unit/device/hipSetGetDevice.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipSetGetDevice_Negative") {
SECTION("Get Device - nullptr") { HIP_CHECK_ERROR(hipGetDevice(nullptr), hipErrorInvalidValue); }
@@ -135,6 +191,58 @@ TEST_CASE("Unit_hipSetGetDevice_Negative") {
}
}
/**
* End doxygen group hipSetDevice.
* @}
*/
/**
* @addtogroup hipGetDevice hipGetDevice
* @{
* @ingroup DeviceTest
* `hipGetDevice(int* deviceId)` -
* Return the default device id for the calling host thread.
* ________________________
* Test cases from other modules:
* - @ref Unit_hipSetDevice_BasicSetGet
* - @ref Unit_hipGetSetDevice_MultiThreaded
* - @ref Unit_hipSetGetDevice_Negative
*/
/**
* End doxygen group hipGetDevice.
* @}
*/
/**
* @addtogroup hipDeviceGet hipDeviceGet
* @{
* @ingroup DriverTest
* `hipDeviceGet(hipDevice_t* device, int ordinal)` -
* Returns a handle to a compute device.
* ________________________
* Test cases from other modules:
* - @ref Unit_hipSetDevice_BasicSetGet
* - @ref Unit_hipGetSetDevice_MultiThreaded
*/
/**
* Test Description
* ------------------------
* - Validates handling of invalid arguments:
* -# When output pointer to the device is `nullptr`
* - Expected output: return `hipErrorInvalidValue`
* -# When device ordinal is out of bounds
* - Expected output: return `hipErrorInvalidDevice`
* -# When device ordinal is negative
* - Expected output: return `hipErrorInvalidDevice`
* Test source
* ------------------------
* - unit/device/hipSetGetDevice.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipDeviceGet_Negative") {
// TODO enable after EXSWCPHIPT-104 is fixed
#if HT_NVIDIA
+7 -5
查看文件
@@ -22,11 +22,12 @@
AtomicAdd on FineGrainMemory
1. The following test scenario verifies
atomicAdd on fineGrain memory with -mno-unsafe-atomics flag
This testcase works only on gfx90a.
This testcase works only on gfx90a, gfx940, gfx941, gfx942.
*/
#include<hip_test_checkers.hh>
#include<hip_test_common.hh>
#include <hip_test_checkers.hh>
#include <hip_test_common.hh>
#include <hip_test_features.hh>
#define INC_VAL 10
@@ -53,7 +54,8 @@ TEMPLATE_TEST_CASE("Unit_AtomicAdd_Coherentwithnounsafeflag", "",
HIP_CHECK(hipGetDevice(&device));
HIP_CHECK(hipGetDeviceProperties(&prop, device));
std::string gfxName(prop.gcnArchName);
if ((gfxName == "gfx90a" || gfxName.find("gfx90a:")) == 0) {
if (CheckIfFeatSupported(CTFeatures::CT_FEATURE_FINEGRAIN_HWSUPPORT, gfxName)) {
if (prop.canMapHostMemory != 1) {
SUCCEED("Does not support HostPinned Memory");
} else {
@@ -86,7 +88,7 @@ TEMPLATE_TEST_CASE("Unit_AtomicAdd_Coherentwithnounsafeflag", "",
HIP_CHECK(hipHostFree(result));
}
} else {
SUCCEED("Memory model feature is only supported for gfx90a, Hence"
SUCCEED("Memory model feature is only supported for gfx90a, gfx940, gfx941, gfx942, Hence"
"skipping the testcase for this GPU " << device);
}
}
+4 -4
查看文件
@@ -22,12 +22,12 @@
AtomicAdd on FineGrainMemory
1. The following test scenario verifies
atomicAdd on fineGrain memory without any unsafeatomics flag
This testcase works only on gfx90a.
This testcase works only on gfx90a, gfx940, gfx941, gfx942.
*/
#include<hip_test_checkers.hh>
#include<hip_test_common.hh>
#include <hip_test_features.hh>
#define INC_VAL 10
#define INITIAL_VAL 5
@@ -52,7 +52,7 @@ TEMPLATE_TEST_CASE("Unit_AtomicAdd_Coherentwithoutflag", "",
HIP_CHECK(hipGetDevice(&device));
HIP_CHECK(hipGetDeviceProperties(&prop, device));
std::string gfxName(prop.gcnArchName);
if ((gfxName == "gfx90a" || gfxName.find("gfx90a:")) == 0) {
if (CheckIfFeatSupported(CTFeatures::CT_FEATURE_FINEGRAIN_HWSUPPORT, gfxName)) {
if (prop.canMapHostMemory != 1) {
SUCCEED("Does not support HostPinned Memory");
} else {
@@ -85,7 +85,7 @@ TEMPLATE_TEST_CASE("Unit_AtomicAdd_Coherentwithoutflag", "",
HIP_CHECK(hipHostFree(result));
}
} else {
SUCCEED("Memory model feature is only supported for gfx90a, Hence"
SUCCEED("Memory model feature is only supported for gfx90a, gfx940, gfx941, gfx942, Hence"
"skipping the testcase for this GPU " << device);
}
}
+4 -3
查看文件
@@ -22,11 +22,12 @@
AtomicAdd on FineGrainMemory
1. The following test scenario verifies
atomicAdd on fineGrain memory with -munsafe-fp-atomics flag
This testcase works only on gfx90a.
This testcase works only on gfx90a, gfx940, gfx941, gfx942.
*/
#include<hip_test_checkers.hh>
#include<hip_test_common.hh>
#include<hip_test_features.hh>
#define INC_VAL 10
#define INITIAL_VAL 5
@@ -52,7 +53,7 @@ TEMPLATE_TEST_CASE("Unit_AtomicAdd_CoherentwithUnsafeflag", "",
HIP_CHECK(hipGetDevice(&device));
HIP_CHECK(hipGetDeviceProperties(&prop, device));
std::string gfxName(prop.gcnArchName);
if ((gfxName == "gfx90a" || gfxName.find("gfx90a:")) == 0) {
if (CheckIfFeatSupported(CTFeatures::CT_FEATURE_FINEGRAIN_HWSUPPORT, gfxName)) {
if (prop.canMapHostMemory != 1) {
SUCCEED("Does not support HostPinned Memory");
} else {
@@ -94,7 +95,7 @@ TEMPLATE_TEST_CASE("Unit_AtomicAdd_CoherentwithUnsafeflag", "",
HIP_CHECK(hipHostFree(result));
}
} else {
SUCCEED("Memory model feature is only supported for gfx90a, Hence"
SUCCEED("Memory model feature is only supported for gfx90a, gfx940, gfx941, gfx942, Hence"
"skipping the testcase for this GPU " << device);
}
}
+4 -4
查看文件
@@ -22,12 +22,12 @@
AtomicAdd on CoarseGrainMemory
1. The following test scenario verifies
atomicAdd on CoarseGrain memory with -mno-unsafe-atomics flag
This testcase works only on gfx90a.
This testcase works only on gfx90a, gfx940, gfx941, gfx942.
*/
#include<hip_test_checkers.hh>
#include<hip_test_common.hh>
#include<hip_test_features.hh>
#define INC_VAL 10
#define INITIAL_VAL 5
@@ -52,7 +52,7 @@ TEMPLATE_TEST_CASE("Unit_AtomicAdd_NonCoherentwithnounsafeflag", "",
HIP_CHECK(hipGetDevice(&device));
HIP_CHECK(hipGetDeviceProperties(&prop, device));
std::string gfxName(prop.gcnArchName);
if ((gfxName == "gfx90a" || gfxName.find("gfx90a:")) == 0) {
if (CheckIfFeatSupported(CTFeatures::CT_FEATURE_FINEGRAIN_HWSUPPORT, gfxName)) {
if (prop.canMapHostMemory != 1) {
SUCCEED("Does not support HostPinned Memory");
} else {
@@ -86,7 +86,7 @@ TEMPLATE_TEST_CASE("Unit_AtomicAdd_NonCoherentwithnounsafeflag", "",
HIP_CHECK(hipHostFree(result));
}
} else {
SUCCEED("Memory model feature is only supported for gfx90a, Hence"
SUCCEED("Memory model feature is only supported for gfx90a, gfx940, gfx941, gfx942, Hence"
"skipping the testcase for this GPU " << device);
}
}
+4 -3
查看文件
@@ -22,11 +22,12 @@
AtomicAdd on CoarseGrainMemory
1. The following test scenario verifies
atomicAdd on CoarseGrain memory without any unsafeatomics flag
This testcase works only on gfx90a.
This testcase works only on gfx90a, gfx940, gfx941, gfx942.
*/
#include<hip_test_checkers.hh>
#include<hip_test_common.hh>
#include<hip_test_features.hh>
#define INC_VAL 10
#define INITIAL_VAL 5
@@ -52,7 +53,7 @@ TEMPLATE_TEST_CASE("Unit_AtomicAdd_NonCoherentwithoutflag", "",
HIP_CHECK(hipGetDevice(&device));
HIP_CHECK(hipGetDeviceProperties(&prop, device));
std::string gfxName(prop.gcnArchName);
if ((gfxName == "gfx90a" || gfxName.find("gfx90a:")) == 0) {
if (CheckIfFeatSupported(CTFeatures::CT_FEATURE_FINEGRAIN_HWSUPPORT, gfxName)) {
if (prop.canMapHostMemory != 1) {
SUCCEED("Does not support HostPinned Memory");
} else {
@@ -86,7 +87,7 @@ TEMPLATE_TEST_CASE("Unit_AtomicAdd_NonCoherentwithoutflag", "",
HIP_CHECK(hipHostFree(result));
}
} else {
SUCCEED("Memory model feature is only supported for gfx90a, Hence"
SUCCEED("Memory model feature is only supported for gfx90a, gfx940, gfx941, gfx942, Hence"
"skipping the testcase for this GPU " << device);
}
}
+4 -4
查看文件
@@ -22,12 +22,12 @@
AtomicAdd on CoarseGrainMemory
1. The following test scenario verifies
atomicAdd on CoarseGrain memory with -munsafe-fp-atomics flag
This testcase works only on gfx90a.
This testcase works only on gfx90a, gfx940, gfx941, gfx942.
*/
#include<hip_test_checkers.hh>
#include<hip_test_common.hh>
#include<hip_test_features.hh>
#define INC_VAL 10
#define INITIAL_VAL 5
@@ -52,7 +52,7 @@ TEMPLATE_TEST_CASE("Unit_AtomicAdd_NonCoherentwithUnsafeflag", "",
HIP_CHECK(hipGetDevice(&device));
HIP_CHECK(hipGetDeviceProperties(&prop, device));
std::string gfxName(prop.gcnArchName);
if ((gfxName == "gfx90a" || gfxName.find("gfx90a:")) == 0) {
if (CheckIfFeatSupported(CTFeatures::CT_FEATURE_FINEGRAIN_HWSUPPORT, gfxName)) {
if (prop.canMapHostMemory != 1) {
SUCCEED("Does not support HostPinned Memory");
} else {
@@ -93,7 +93,7 @@ TEMPLATE_TEST_CASE("Unit_AtomicAdd_NonCoherentwithUnsafeflag", "",
HIP_CHECK(hipHostFree(result));
}
} else {
SUCCEED("Memory model feature is only supported for gfx90a, Hence"
SUCCEED("Memory model feature is only supported for gfx90a, gfx940, gfx941, gfx942, Hence"
"skipping the testcase for this GPU " << device);
}
}
+9 -8
查看文件
@@ -28,6 +28,7 @@ This testfile verifies __builtin_amdgcn_global_atomic_fadd_f64 API scenarios
#include<hip_test_checkers.hh>
#include<hip_test_common.hh>
#include<hip_test_features.hh>
#include <hip/hiprtc.h>
#define INC_VAL 10
@@ -57,7 +58,7 @@ TEST_CASE("Unit_BuiltInAtomicAdd_CoherentGlobalMem") {
HIP_CHECK(hipGetDevice(&device));
HIP_CHECK(hipGetDeviceProperties(&prop, device));
std::string gfxName(prop.gcnArchName);
if ((gfxName == "gfx90a" || gfxName.find("gfx90a:")) == 0) {
if (CheckIfFeatSupported(CTFeatures::CT_FEATURE_FINEGRAIN_HWSUPPORT, gfxName)) {
if (prop.canMapHostMemory != 1) {
SUCCEED("Does support HostPinned Memory");
} else {
@@ -85,7 +86,7 @@ TEST_CASE("Unit_BuiltInAtomicAdd_CoherentGlobalMem") {
HIP_CHECK(hipFree(result));
}
} else {
SUCCEED("Memory model feature is only supported for gfx90a Hence"
SUCCEED("Memory model feature is only supported for gfx90a, gfx940, gfx941, gfx942 Hence"
"skipping the testcase for this GPU " << device);
}
}
@@ -103,7 +104,7 @@ TEST_CASE("Unit_BuiltInAtomicAdd_NonCoherentGlobalMem") {
HIP_CHECK(hipGetDevice(&device));
HIP_CHECK(hipGetDeviceProperties(&prop, device));
std::string gfxName(prop.gcnArchName);
if ((gfxName == "gfx90a" || gfxName.find("gfx90a:")) == 0) {
if (CheckIfFeatSupported(CTFeatures::CT_FEATURE_FINEGRAIN_HWSUPPORT, gfxName)) {
if (prop.canMapHostMemory != 1) {
SUCCEED("Does not support HostPinned Memory");
} else {
@@ -129,7 +130,7 @@ TEST_CASE("Unit_BuiltInAtomicAdd_NonCoherentGlobalMem") {
free(B_h);
}
} else {
SUCCEED("Memory model feature is only supported for gfx90a"
SUCCEED("Memory model feature is only supported for gfx90a, gfx940, gfx941, gfx942"
"Hence skipping the testcase for GPU-0");
}
}
@@ -146,7 +147,7 @@ TEST_CASE("Unit_BuiltInAtomicAdd_CoherentGlobalMemWithRtc") {
HIP_CHECK(hipGetDevice(&device));
HIP_CHECK(hipGetDeviceProperties(&prop, device));
std::string gfxName(prop.gcnArchName);
if ((gfxName == "gfx90a" || gfxName.find("gfx90a:")) == 0) {
if (CheckIfFeatSupported(CTFeatures::CT_FEATURE_FINEGRAIN_HWSUPPORT, gfxName)) {
if (prop.canMapHostMemory != 1) {
SUCCEED("Does not support HostPinned Memory");
} else {
@@ -208,7 +209,7 @@ TEST_CASE("Unit_BuiltInAtomicAdd_CoherentGlobalMemWithRtc") {
free(B_h);
}
} else {
SUCCEED("Memory model feature is only supported for gfx90a, Hence"
SUCCEED("Memory model feature is only supported for gfx90a, gfx940, gfx941, gfx942, Hence"
"skipping the testcase for this GPU " << device);
}
}
@@ -226,7 +227,7 @@ TEST_CASE("Unit_BuiltInAtomicAdd_NonCoherentGlobalMemWithRtc") {
HIP_CHECK(hipGetDevice(&device));
HIP_CHECK(hipGetDeviceProperties(&prop, device));
std::string gfxName(prop.gcnArchName);
if ((gfxName == "gfx90a" || gfxName.find("gfx90a:")) == 0) {
if (CheckIfFeatSupported(CTFeatures::CT_FEATURE_FINEGRAIN_HWSUPPORT, gfxName)) {
if (prop.canMapHostMemory != 1) {
SUCCEED("Does support HostPinned Memory");
} else {
@@ -288,7 +289,7 @@ TEST_CASE("Unit_BuiltInAtomicAdd_NonCoherentGlobalMemWithRtc") {
free(B_h);
}
} else {
SUCCEED("Memory model feature is only supported for gfx90a, Hence"
SUCCEED("Memory model feature is only supported for gfx90a, gfx940, gfx941, gfx942, Hence"
"skipping the testcase for this GPU " << device);
}
}
+17 -2
查看文件
@@ -86,11 +86,26 @@ add_custom_target(kerDevAllocSingleKer.code
-I${CMAKE_CURRENT_SOURCE_DIR}/../../../../include/
-I${CMAKE_CURRENT_SOURCE_DIR}/../../include --rocm-path=${ROCM_PATH})
# Accepted archs to compile this cmake file
set(ACCEPTED_OFFLOAD_ARCHS gfx90a gfx940 gfx941 gfx942)
function(CheckAcceptedArchs OFFLOAD_ARCH_STR_LOCAL)
set(ARCH_CHECK -1 PARENT_SCOPE)
string(REGEX MATCHALL "--offload-arch=gfx[0-9a-z]+" OFFLOAD_ARCH_LIST ${OFFLOAD_ARCH_STR_LOCAL})
foreach(OFFLOAD_ARCH IN LISTS OFFLOAD_ARCH_LIST)
string(REGEX MATCHALL "--offload-arch=(gfx[0-9a-z]+)" matches ${OFFLOAD_ARCH})
if (CMAKE_MATCH_COUNT EQUAL 1)
if (CMAKE_MATCH_1 IN_LIST ACCEPTED_OFFLOAD_ARCHS)
set(ARCH_CHECK 1 PARENT_SCOPE)
endif() # CMAKE_MATCH_1
endif() # CMAKE_MATCH_COUNT
endforeach() # OFFLOAD_ARCH_LIST
endfunction() # CheckAcceptedArchs
if(HIP_PLATFORM MATCHES "amd")
if (DEFINED OFFLOAD_ARCH_STR)
string(FIND ${OFFLOAD_ARCH_STR} "gfx90a" ARCH_CHECK)
CheckAcceptedArchs(${OFFLOAD_ARCH_STR})
elseif(DEFINED $ENV{HCC_AMDGPU_TARGET})
string(FIND $ENV{HCC_AMDGPU_TARGET} "gfx90a" ARCH_CHECK)
CheckAcceptedArchs($ENV{HCC_AMDGPU_TARGET})
else()
set(ARCH_CHECK -1)
endif()
+2 -1
查看文件
@@ -21,6 +21,7 @@ THE SOFTWARE.
*/
#include <hip_test_common.hh>
#include <hip_test_features.hh>
#include <hip/hiprtc.h>
#include <hip/hip_runtime.h>
@@ -52,7 +53,7 @@ TEST_CASE("Unit_unsafeAtomicAdd") {
HIP_CHECK(hipGetDeviceProperties(&props, device));
std::string gfxName(props.gcnArchName);
if (gfxName == "gfx90a" || gfxName.find("gfx90a:") == 0) {
if (CheckIfFeatSupported(CTFeatures::CT_FEATURE_FINEGRAIN_HWSUPPORT, gfxName)) {
hiprtcProgram prog;
hiprtcCreateProgram(&prog, // prog
kernel, // buffer
@@ -22,11 +22,12 @@
AtomicAdd on FineGrainMemory
1. The following test scenario verifies
unsafeatomicAdd on fineGrain memory with -mno-unsafe-fp-atomics flag
This testcase works only on gfx90a.
This testcase works only on gfx90a, gfx940, gfx941, gfx942.
*/
#include<hip_test_common.hh>
#include<hip_test_checkers.hh>
#include<hip_test_features.hh>
#define INC_VAL 10
#define INITIAL_VAL 5
@@ -52,7 +53,7 @@ TEMPLATE_TEST_CASE("Unit_unsafeAtomicAdd_CoherentwithnoUnsafeflag", "",
HIP_CHECK(hipGetDevice(&device));
HIP_CHECK(hipGetDeviceProperties(&prop, device));
std::string gfxName(prop.gcnArchName);
if ((gfxName == "gfx90a" || gfxName.find("gfx90a:")) == 0) {
if (CheckIfFeatSupported(CTFeatures::CT_FEATURE_FINEGRAIN_HWSUPPORT, gfxName)) {
if (prop.canMapHostMemory != 1) {
SUCCEED("Does not support HostPinned Memory");
} else {
@@ -94,7 +95,7 @@ TEMPLATE_TEST_CASE("Unit_unsafeAtomicAdd_CoherentwithnoUnsafeflag", "",
HIP_CHECK(hipHostFree(result));
}
} else {
SUCCEED("Memory model feature is only supported for gfx90a, Hence"
SUCCEED("Memory model feature is only supported for gfx90a, gfx940, gfx941, gfx942, Hence"
"skipping the testcase for this GPU " << device);
}
}
+4 -3
查看文件
@@ -22,11 +22,12 @@
AtomicAdd on FineGrainMemory
1. The following test scenario verifies
unsafeatomicAdd on fineGrain memory without atomics flag
This testcase works only on gfx90a.
This testcase works only on gfx90a, gfx940, gfx941, gfx942.
*/
#include<hip_test_checkers.hh>
#include<hip_test_common.hh>
#include<hip_test_features.hh>
#define INC_VAL 10
#define INITIAL_VAL 5
@@ -52,7 +53,7 @@ TEMPLATE_TEST_CASE("Unit_unsafeAtomicAdd_Coherentwithoutflag", "",
HIP_CHECK(hipGetDevice(&device));
HIP_CHECK(hipGetDeviceProperties(&prop, device));
std::string gfxName(prop.gcnArchName);
if ((gfxName == "gfx90a" || gfxName.find("gfx90a:")) == 0) {
if (CheckIfFeatSupported(CTFeatures::CT_FEATURE_FINEGRAIN_HWSUPPORT, gfxName)) {
if (prop.canMapHostMemory != 1) {
SUCCEED("Does not support HostPinned Memory");
} else {
@@ -94,7 +95,7 @@ TEMPLATE_TEST_CASE("Unit_unsafeAtomicAdd_Coherentwithoutflag", "",
HIP_CHECK(hipHostFree(result));
}
} else {
SUCCEED("Memory model feature is only supported for gfx90a, Hence"
SUCCEED("Memory model feature is only supported for gfx90a, gfx940, gfx941, gfx942, Hence"
"skipping the testcase for this GPU " << device);
}
}
+3 -2
查看文件
@@ -27,6 +27,7 @@ This testcase works only on gfx90a.
#include<hip_test_checkers.hh>
#include<hip_test_common.hh>
#include<hip_test_features.hh>
#define INC_VAL 10
#define INITIAL_VAL 5
@@ -53,7 +54,7 @@ TEMPLATE_TEST_CASE("Unit_unsafeAtomicAdd_CoherentwithUnsafeflag", "",
HIP_CHECK(hipGetDevice(&device));
HIP_CHECK(hipGetDeviceProperties(&prop, device));
std::string gfxName(prop.gcnArchName);
if ((gfxName == "gfx90a" || gfxName.find("gfx90a:")) == 0) {
if (CheckIfFeatSupported(CTFeatures::CT_FEATURE_FINEGRAIN_HWSUPPORT, gfxName)) {
if (prop.canMapHostMemory != 1) {
SUCCEED("Does not support HostPinned Memory");
} else {
@@ -95,7 +96,7 @@ TEMPLATE_TEST_CASE("Unit_unsafeAtomicAdd_CoherentwithUnsafeflag", "",
HIP_CHECK(hipHostFree(result));
}
} else {
SUCCEED("Memory model feature is only supported for gfx90a, Hence"
SUCCEED("Memory model feature is only supported for gfx90a, gfx940, gfx941, gfx942, Hence"
"skipping the testcase for this GPU " << device);
}
}
@@ -22,11 +22,12 @@
AtomicAdd on CoarseGrainMemory
1. The following test scenario verifies
unsafeAtomicAdd on CoarseGrain memory with -mno-unsafe-fp-atomics flag
This testcase works only on gfx90a.
This testcase works only on gfx90a, gfx940, gfx941, gfx942.
*/
#include<hip_test_checkers.hh>
#include<hip_test_common.hh>
#include<hip_test_features.hh>
#define INC_VAL 10
#define INITIAL_VAL 5
@@ -51,7 +52,7 @@ TEMPLATE_TEST_CASE("Unit_unsafeAtomicAdd_NonCoherentnounsafeatomicsflag", "",
HIP_CHECK(hipGetDevice(&device));
HIP_CHECK(hipGetDeviceProperties(&prop, device));
std::string gfxName(prop.gcnArchName);
if ((gfxName == "gfx90a" || gfxName.find("gfx90a:")) == 0) {
if (CheckIfFeatSupported(CTFeatures::CT_FEATURE_FINEGRAIN_HWSUPPORT, gfxName)) {
if (prop.canMapHostMemory != 1) {
SUCCEED("Does not support HostPinned Memory");
} else {
@@ -92,7 +93,7 @@ TEMPLATE_TEST_CASE("Unit_unsafeAtomicAdd_NonCoherentnounsafeatomicsflag", "",
HIP_CHECK(hipHostFree(result));
}
} else {
SUCCEED("Memory model feature is only supported for gfx90a, Hence"
SUCCEED("Memory model feature is only supported for gfx90a, gfx940, gfx941, gfx942, Hence"
"skipping the testcase for this GPU " << device);
}
}
+4 -3
查看文件
@@ -22,11 +22,12 @@
unsafeAtomicAdd on CoarseGrainMemory
1. The following test scenario verifies
unsafeAtomicAdd on CoarseGrain memory without any unsafeatomics flag
This testcase works only on gfx90a.
This testcase works only on gfx90a, gfx940, gfx941, gfx942.
*/
#include<hip_test_checkers.hh>
#include<hip_test_common.hh>
#include<hip_test_features.hh>
#define INC_VAL 10
#define INITIAL_VAL 5
@@ -51,7 +52,7 @@ TEMPLATE_TEST_CASE("Unit_unsafeAtomicAdd_NonCoherentwithoutflag", "",
HIP_CHECK(hipGetDevice(&device));
HIP_CHECK(hipGetDeviceProperties(&prop, device));
std::string gfxName(prop.gcnArchName);
if ((gfxName == "gfx90a" || gfxName.find("gfx90a:")) == 0) {
if (CheckIfFeatSupported(CTFeatures::CT_FEATURE_FINEGRAIN_HWSUPPORT, gfxName)) {
if (prop.canMapHostMemory != 1) {
SUCCEED("Does not support HostPinned Memory");
} else {
@@ -92,7 +93,7 @@ TEMPLATE_TEST_CASE("Unit_unsafeAtomicAdd_NonCoherentwithoutflag", "",
HIP_CHECK(hipHostFree(result));
}
} else {
SUCCEED("Memory model feature is only supported for gfx90a, Hence"
SUCCEED("Memory model feature is only supported for gfx90a, gfx940, gfx941, gfx942, Hence"
"skipping the testcase for this GPU " << device);
}
}
@@ -22,11 +22,12 @@
unsafeAtomicAdd on CoarseGrainMemory
1. The following test scenario verifies
unsafeAtomicAdd on CoarseGrain memory with unsafeatomics flag
This testcase works only on gfx90a.
This testcase works only on gfx90a, gfx940, gfx941, gfx942.
*/
#include<hip_test_checkers.hh>
#include<hip_test_common.hh>
#include<hip_test_features.hh>
#define INC_VAL 10
#define INITIAL_VAL 5
@@ -51,7 +52,7 @@ TEMPLATE_TEST_CASE("Unit_unsafeAtomicAdd_NonCoherentwithunsafeatomicsflag", "",
HIP_CHECK(hipGetDevice(&device));
HIP_CHECK(hipGetDeviceProperties(&prop, device));
std::string gfxName(prop.gcnArchName);
if ((gfxName == "gfx90a" || gfxName.find("gfx90a:")) == 0) {
if (CheckIfFeatSupported(CTFeatures::CT_FEATURE_FINEGRAIN_HWSUPPORT, gfxName)) {
if (prop.canMapHostMemory != 1) {
SUCCEED("Does not support HostPinned Memory");
} else {
@@ -92,7 +93,7 @@ TEMPLATE_TEST_CASE("Unit_unsafeAtomicAdd_NonCoherentwithunsafeatomicsflag", "",
HIP_CHECK(hipHostFree(result));
}
} else {
SUCCEED("Memory model feature is only supported for gfx90a, Hence"
SUCCEED("Memory model feature is only supported for gfx90a, gfx940, gfx941, gfx942, Hence"
"skipping the testcase for this GPU " << device);
}
}
+13 -12
查看文件
@@ -31,6 +31,7 @@ unsafeAtomicAdd Scenarios with hipRTC:
#include<hip_test_checkers.hh>
#include<hip_test_common.hh>
#include<hip_test_features.hh>
#include <hip/hiprtc.h>
#define INCREMENT_VAL 10
#define INITIAL_VAL 5
@@ -66,7 +67,7 @@ TEMPLATE_TEST_CASE("Unit_unsafeAtomicAdd_CoherentRTCnounsafeatomicflag", "",
HIP_CHECK(hipGetDeviceProperties(&props, device));
std::string gfxName(props.gcnArchName);
if ((gfxName == "gfx90a" || gfxName.find("gfx90a:")) == 0) {
if (CheckIfFeatSupported(CTFeatures::CT_FEATURE_FINEGRAIN_HWSUPPORT, gfxName)) {
hiprtcProgram prog;
if (std::is_same<TestType, float>::value) {
hiprtcCreateProgram(&prog, // prog
@@ -135,7 +136,7 @@ TEMPLATE_TEST_CASE("Unit_unsafeAtomicAdd_CoherentRTCnounsafeatomicflag", "",
}
HIP_CHECK(hipModuleUnload(module));
} else {
SUCCEED("Memory model feature is only supported for gfx90a, Hence"
SUCCEED("Memory model feature is only supported for gfx90a, gfx940, gfx941, gfx942, Hence"
"skipping the testcase for this GPU " << device);
}
}
@@ -156,7 +157,7 @@ TEMPLATE_TEST_CASE("Unit_unsafeAtomicAdd_CoherentRTCunsafeatomicflag", "",
HIP_CHECK(hipGetDeviceProperties(&props, device));
std::string gfxName(props.gcnArchName);
if ((gfxName == "gfx90a" || gfxName.find("gfx90a:")) == 0) {
if (CheckIfFeatSupported(CTFeatures::CT_FEATURE_FINEGRAIN_HWSUPPORT, gfxName)) {
hiprtcProgram prog;
if (std::is_same<TestType, float>::value) {
hiprtcCreateProgram(&prog, // prog
@@ -227,7 +228,7 @@ TEMPLATE_TEST_CASE("Unit_unsafeAtomicAdd_CoherentRTCunsafeatomicflag", "",
}
HIP_CHECK(hipModuleUnload(module));
} else {
SUCCEED("Memory model feature is only supported for gfx90a, Hence"
SUCCEED("Memory model feature is only supported for gfx90a, gfx940, gfx941, gfx942, Hence"
"skipping the testcase for this GPU " << device);
}
}
@@ -245,7 +246,7 @@ TEMPLATE_TEST_CASE("Unit_unsafeAtomicAdd_CoherentRTCwithoutflag", "",
HIP_CHECK(hipGetDeviceProperties(&props, device));
std::string gfxName(props.gcnArchName);
if ((gfxName == "gfx90a" || gfxName.find("gfx90a:")) == 0) {
if(CheckIfFeatSupported(CTFeatures::CT_FEATURE_FINEGRAIN_HWSUPPORT, gfxName)) {
hiprtcProgram prog;
if (std::is_same<TestType, float>::value) {
hiprtcCreateProgram(&prog, // prog
@@ -315,7 +316,7 @@ TEMPLATE_TEST_CASE("Unit_unsafeAtomicAdd_CoherentRTCwithoutflag", "",
}
HIP_CHECK(hipModuleUnload(module));
} else {
SUCCEED("Memory model feature is only supported for gfx90a, Hence"
SUCCEED("Memory model feature is only supported for gfx90a, gfx940, gfx941, gfx942, Hence"
"skipping the testcase for this GPU " << device);
}
}
@@ -332,7 +333,7 @@ TEMPLATE_TEST_CASE("Unit_unsafeAtomicAdd_NonCoherentRTCnounsafeatomicflag", "",
HIP_CHECK(hipGetDeviceProperties(&props, device));
std::string gfxName(props.gcnArchName);
if ((gfxName == "gfx90a" || gfxName.find("gfx90a:")) == 0) {
if (CheckIfFeatSupported(CTFeatures::CT_FEATURE_FINEGRAIN_HWSUPPORT, gfxName)) {
hiprtcProgram prog;
if (std::is_same<TestType, float>::value) {
hiprtcCreateProgram(&prog, // prog
@@ -401,7 +402,7 @@ TEMPLATE_TEST_CASE("Unit_unsafeAtomicAdd_NonCoherentRTCnounsafeatomicflag", "",
}
HIP_CHECK(hipModuleUnload(module));
} else {
SUCCEED("Memory model feature is only supported for gfx90a, Hence"
SUCCEED("Memory model feature is only supported for gfx90a, gfx940, gfx941, gfx942, Hence"
"skipping the testcase for this GPU " << device);
}
}
@@ -419,7 +420,7 @@ TEMPLATE_TEST_CASE("Unit_unsafeAtomicAdd_NonCoherentRTCunsafeatomicflag", "",
HIP_CHECK(hipGetDeviceProperties(&props, device));
std::string gfxName(props.gcnArchName);
if ((gfxName == "gfx90a" || gfxName.find("gfx90a:")) == 0) {
if(CheckIfFeatSupported(CTFeatures::CT_FEATURE_FINEGRAIN_HWSUPPORT, gfxName)) {
hiprtcProgram prog;
if (std::is_same<TestType, float>::value) {
hiprtcCreateProgram(&prog, // prog
@@ -489,7 +490,7 @@ TEMPLATE_TEST_CASE("Unit_unsafeAtomicAdd_NonCoherentRTCunsafeatomicflag", "",
}
HIP_CHECK(hipModuleUnload(module));
} else {
SUCCEED("Memory model feature is only supported for gfx90a, Hence"
SUCCEED("Memory model feature is only supported for gfx90a, gfx940, gfx941, gfx942, Hence"
"skipping the testcase for this GPU " << device);
}
}
@@ -507,7 +508,7 @@ TEMPLATE_TEST_CASE("Unit_unsafeAtomicAdd_NonCoherentRTC", "",
HIP_CHECK(hipGetDeviceProperties(&props, device));
std::string gfxName(props.gcnArchName);
if ((gfxName == "gfx90a" || gfxName.find("gfx90a:")) == 0) {
if (CheckIfFeatSupported(CTFeatures::CT_FEATURE_FINEGRAIN_HWSUPPORT, gfxName)) {
hiprtcProgram prog;
if (std::is_same<TestType, float>::value) {
hiprtcCreateProgram(&prog, // prog
@@ -577,7 +578,7 @@ TEMPLATE_TEST_CASE("Unit_unsafeAtomicAdd_NonCoherentRTC", "",
}
HIP_CHECK(hipModuleUnload(module));
} else {
SUCCEED("Memory model feature is only supported for gfx90a, Hence"
SUCCEED("Memory model feature is only supported for gfx90a, gfx940, gfx941, gfx942, Hence"
"skipping the testcase for this GPU " << device);
}
}
+34
查看文件
@@ -25,6 +25,26 @@ THE SOFTWARE.
#include <hip_test_common.hh>
#include <hip/hip_runtime_api.h>
/**
* @addtogroup hipGetErrorName hipGetErrorName
* @{
* @ingroup ErrorTest
* `hipGetErrorName(hipError_t hip_error)` -
* Return hip error as text string form.
*/
/**
* Test Description
* ------------------------
* - Validate that a non-empty string is returned for each supported
* device error enumeration.
* Test source
* ------------------------
* - unit/errorHandling/hipGetErrorName.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipGetErrorName_Positive_Basic") {
const char* error_string = nullptr;
const auto enumerator =
@@ -36,6 +56,20 @@ TEST_CASE("Unit_hipGetErrorName_Positive_Basic") {
REQUIRE(strlen(error_string) > 0);
}
/**
* Test Description
* ------------------------
* - Validate handling of invalid arguments:
* -# When error enumerator is invalid (-1)
* - AMD expected output: return "hipErrorUnknown"
* - NVIDIA expected output: return "cudaErrorUnknown"
* Test source
* ------------------------
* - unit/errorHandling/hipGetErrorName.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipGetErrorName_Negative_Parameters") {
const char* error_string = hipGetErrorName(static_cast<hipError_t>(-1));
REQUIRE(error_string != nullptr);
+33
查看文件
@@ -24,6 +24,26 @@ THE SOFTWARE.
#include <hip_test_common.hh>
#include <hip/hip_runtime_api.h>
/**
* @addtogroup hipGetErrorString hipGetErrorString
* @{
* @ingroup ErrorTest
* `hipGetErrorString(hipError_t hipError)` -
* Return handy text string message to explain the error which occurred.
*/
/**
* Test Description
* ------------------------
* - Validate that a non-empty string is returned for each supported
* device error enumeration.
* Test source
* ------------------------
* - unit/errorHandling/hipGetErrorString.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipGetErrorString_Positive_Basic") {
const char* error_string = nullptr;
const auto enumerator =
@@ -35,6 +55,19 @@ TEST_CASE("Unit_hipGetErrorString_Positive_Basic") {
REQUIRE(strlen(error_string) > 0);
}
/**
* Test Description
* ------------------------
* - Validate handling of invalid arguments:
* -# When error enumerator is invalid (-1)
* - Expected output: do not return `nullptr`
* Test source
* ------------------------
* - unit/errorHandling/hipGetErrorString.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipGetErrorString_Negative_Parameters") {
const char* error_string = hipGetErrorString(static_cast<hipError_t>(-1));
REQUIRE(error_string != nullptr);
+33
查看文件
@@ -24,6 +24,27 @@ THE SOFTWARE.
#include <hip/hip_runtime_api.h>
#include <threaded_zig_zag_test.hh>
/**
* @addtogroup hipGetLastError hipGetLastError
* @{
* @ingroup ErrorTest
* `hipGetLastError(void)` -
* Return last error returned by any HIP runtime API call and resets the stored error code to
* `hipSuccess`.
*/
/**
* Test Description
* ------------------------
* - Validate that `hipErrorInvalidValue` is returned after invalid `hipMalloc` call.
* - Validate that `hipSuccess` is returned afterwards.
* Test source
* ------------------------
* - unit/errorHandling/hipGetLastError.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipGetLastError_Positive_Basic") {
HIP_CHECK(hipGetLastError());
HIP_CHECK_ERROR(hipMalloc(nullptr, 1), hipErrorInvalidValue);
@@ -31,6 +52,18 @@ TEST_CASE("Unit_hipGetLastError_Positive_Basic") {
HIP_CHECK(hipGetLastError());
}
/**
* Test Description
* ------------------------
* - Validate that appropriate error is returned when working with multiple threads.
* - Cause error on purpose within one of the threads.
* Test source
* ------------------------
* - unit/errorHandling/hipGetLastError.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipGetLastError_Positive_Threaded") {
class HipGetLastErrorThreadedTest : public ThreadedZigZagTest<HipGetLastErrorThreadedTest> {
public:
+33
查看文件
@@ -24,6 +24,26 @@ THE SOFTWARE.
#include <hip/hip_runtime_api.h>
#include <threaded_zig_zag_test.hh>
/**
* @addtogroup hipPeekAtLastError hipPeekAtLastError
* @{
* @ingroup ErrorTest
* `hipPeekAtLastError(void)` -
* Return last error returned by any HIP runtime API call.
*/
/**
* Test Description
* ------------------------
* - Validate that `hipErrorInvalidValue` is returned after invalid `hipMalloc` call.
* - Validate that `hipSuccess` is returned again for getting the last error.
* Test source
* ------------------------
* - unit/errorHandling/hipPeekAtLastError.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipPeekAtLastError_Positive_Basic") {
HIP_CHECK(hipPeekAtLastError());
HIP_CHECK_ERROR(hipMalloc(nullptr, 1), hipErrorInvalidValue);
@@ -32,6 +52,19 @@ TEST_CASE("Unit_hipPeekAtLastError_Positive_Basic") {
HIP_CHECK(hipPeekAtLastError());
}
/**
* Test Description
* ------------------------
* - Validate that appropriate error is returned when working with multiple threads.
* - Validate that appropriate error is returned for getting the last erro when working with multiple threads.
* - Cause error on purpose within one of the threads.
* Test source
* ------------------------
* - unit/errorHandling/hipPeekAtLastError.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipPeekAtLastError_Positive_Threaded") {
class HipPeekAtLastErrorTest : public ThreadedZigZagTest<HipPeekAtLastErrorTest> {
public:
+19 -1
查看文件
@@ -26,6 +26,12 @@ THE SOFTWARE.
#include <hip_test_common.hh>
/**
* @addtogroup hipEventRecord hipEventRecord
* @{
* @ingroup EventTest
*/
int tests = -1;
enum SyncMode {
syncNone,
@@ -183,7 +189,19 @@ void runTests(int64_t numElements) {
HIP_CHECK(hipHostFree(C_h));
}
/**
* Test Description
* ------------------------
* - Complex test case used to create a lot of events.
* - Each event is enqueued to the stream.
* - Kernels are launched and synchronized.
* Test source
* ------------------------
* - unit/event/Unit_hipEvent.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipEvent") {
runTests(10000000);
}
+83 -10
查看文件
@@ -19,21 +19,43 @@ 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 :
Unit_hipEventElapsedTime_NullCheck - Test unsuccessful hipEventElapsedTime when either event passed as nullptr
Unit_hipEventElapsedTime_DisableTiming - Test unsuccessful hipEventElapsedTime when events are created with hipEventDisableTiming flag
Unit_hipEventElapsedTime_DifferentDevices - Test unsuccessful hipEventElapsedTime when events are recorded on different devices
Unit_hipEventElapsedTime_NotReady_Negative - Test unsuccessful hipEventElapsedTime when an event has not been completed
Unit_hipEventElapsedTime - Test time elapsed between two recorded events with hipEventElapsedTime api
*/
#include <hip_test_common.hh>
#include <hip_test_checkers.hh>
#include <iostream>
/**
* @addtogroup hipEventElapsedTime hipEventElapsedTime
* @{
* @ingroup EventTest
* `hipEventElapsedTime(float* ms, hipEvent_t start, hipEvent_t stop)` -
* Return the elapsed time between two events.
* ________________________
* Test cases from other modules:
* - @ref Unit_hipEvent
* - @ref Unit_hipEventIpc
* - @ref Unit_hipEventMGpuMThreads_1
* - @ref Unit_hipEventMGpuMThreads_2
* - @ref Unit_hipEventMGpuMThreads_3
*/
/**
* Test Description
* ------------------------
* - Validates handling of invalid arguments:
* -# When output parameter for time is `nullptr`
* - Expected output: return `hipErrorInvalidValue`
* -# When first event is `nullptr`
* - Expected output: return `hipErrorInvalidHandle`
* -# When second event is `nullptr`
* - Expected output: return `hipErrorInvalidValue`
* Test source
* ------------------------
* - unit/event/Unit_hipEventElapsedTime.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipEventElapsedTime_NullCheck") {
hipEvent_t start = nullptr, end = nullptr;
float tms = 1.0f;
@@ -45,6 +67,19 @@ TEST_CASE("Unit_hipEventElapsedTime_NullCheck") {
#endif
}
/**
* Test Description
* ------------------------
* - Calculates elapsed time when events are created with disable timing flag
* -# When flag is set to disable timing
* - Expected output: return `hipErrorInvalidValue`
* Test source
* ------------------------
* - unit/event/Unit_hipEventElapsedTime.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipEventElapsedTime_DisableTiming") {
float timeElapsed = 1.0f;
hipEvent_t start, stop;
@@ -55,6 +90,19 @@ TEST_CASE("Unit_hipEventElapsedTime_DisableTiming") {
HIP_CHECK(hipEventDestroy(stop));
}
/**
* Test Description
* ------------------------
* - Calculates elapsed time when events are recorded on different devices
* -# When start and stop events are recorded on different devices
* - Expected output: return `hipErrorInvalidValue`
* Test source
* ------------------------
* - unit/event/Unit_hipEventElapsedTime.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipEventElapsedTime_DifferentDevices") {
int devCount = 0;
HIP_CHECK(hipGetDeviceCount(&devCount));
@@ -86,6 +134,20 @@ TEST_CASE("Unit_hipEventElapsedTime_DifferentDevices") {
#if HT_AMD /* Disabled because frequency based wait is timing out on nvidia platforms */
/**
* Test Description
* ------------------------
* - Calculates elapsed time when an event has not been completed.
* -# When the stop event has not finished yet
* - Expected output: return `hipErrorNotReady`
* Test source
* ------------------------
* - unit/event/Unit_hipEventElapsedTime.cc
* Test requirements
* ------------------------
* - Platform specific (AMD)
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipEventElapsedTime_NotReady_Negative") {
hipEvent_t start;
HIP_CHECK(hipEventCreate(&start));
@@ -112,6 +174,17 @@ TEST_CASE("Unit_hipEventElapsedTime_NotReady_Negative") {
}
#endif // HT_AMD
/**
* Test Description
* ------------------------
* - Calculates elapsed time between two successfully created and recorded events.
* Test source
* ------------------------
* - unit/event/Unit_hipEventElapsedTime.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipEventElapsedTime") {
hipEvent_t start;
HIP_CHECK(hipEventCreate(&start));
+16
查看文件
@@ -27,7 +27,23 @@ THE SOFTWARE.
#include <hip_test_common.hh>
/**
* @addtogroup hipEventCreateWithFlags hipEventCreateWithFlags
* @{
* @ingroup EventTest
*/
/**
* Test Description
* ------------------------
* - Validate Event Management APIs when working with multiple processes.
* Test source
* ------------------------
* - unit/event/Unit_hipEventIpc.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipEventIpc") {
size_t N = 4 * 1024 * 1024;
unsigned threadsPerBlock = 256;
+39
查看文件
@@ -22,6 +22,12 @@
#include <ratio>
#include <chrono>
/**
* @addtogroup hipEventCreate hipEventCreate
* @{
* @ingroup EventTest
*/
int64_t timeNanos() {
using namespace std::chrono;
static auto t0 = steady_clock::now();
@@ -187,10 +193,32 @@ void testEventMGpuMThreads(int nThreads = 1) {
delete []threads;
}
/**
* Test Description
* ------------------------
* - Validate Event Management APIs when working with one thread.
* Test source
* ------------------------
* - unit/event/Unit_hipEventMGpuMThreads.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipEventMGpuMThreads_1") {
testEventMGpuMThreads(1);
}
/**
* Test Description
* ------------------------
* - Validate Event Management APIs when working with at least two threads.
* Test source
* ------------------------
* - unit/event/Unit_hipEventMGpuMThreads.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipEventMGpuMThreads_2") {
int numDevices = 0;
HIP_CHECK(hipGetDeviceCount(&numDevices));
@@ -201,6 +229,17 @@ TEST_CASE("Unit_hipEventMGpuMThreads_2") {
}
}
/**
* Test Description
* ------------------------
* - Validate Event Management APIs when working with at least three threads.
* Test source
* ------------------------
* - unit/event/Unit_hipEventMGpuMThreads.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipEventMGpuMThreads_3") {
int numDevices = 0;
HIP_CHECK(hipGetDeviceCount(&numDevices));
+22
查看文件
@@ -19,6 +19,17 @@ THE SOFTWARE.
#include <hip_test_common.hh>
/**
* @addtogroup hipEventQuery hipEventQuery
* @{
* @ingroup EventTest
* `hipEventQuery(hipEvent_t event)` -
* Query the status of the specified event.
* ________________________
* Test cases from other modules:
* - @ref Unit_hipEventIpc
*/
// Since we can not use atomic*_system on every gpu, we will use wait based on clock rate.
// This wont be accurate since current clock rate of a GPU varies depending on many variables
// including thermals, load, utilization etc
@@ -48,6 +59,17 @@ __global__ void waitKernel_gfx11(int clockRate, int seconds) {
#endif
}
/**
* Test Description
* ------------------------
* - Query events with a single and with multiple devices.
* Test source
* ------------------------
* - unit/event/Unit_hipEventQuery.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipEventQuery_DifferentDevice") {
hipEvent_t event1{}, event2{};
HIP_CHECK(hipEventCreate(&event1));
+42 -6
查看文件
@@ -19,12 +19,6 @@ 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 :
Unit_hipEventRecord- Test hipEventRecord serialization behavior
Unit_hipEventRecord_Negative - Test unsuccessful hipEventRecord when event is passed as nullptr
- Test unsuccessful hipEventRecord when event is created/recorded on different devices
*/
#include <hip_test_common.hh>
@@ -32,6 +26,33 @@ Unit_hipEventRecord_Negative - Test unsuccessful hipEventRecord when event is pa
#include <hip_test_checkers.hh>
#include <hip_test_context.hh>
/**
* @addtogroup hipEventRecord hipEventRecord
* @{
* @ingroup EventTest
* `hipEventRecord(hipEvent_t event, hipStream_t stream = NULL)` -
* Record an event in the specified stream.
* ________________________
* Test cases from other modules:
* - @ref Unit_hipEventIpc
* - @ref Unit_hipEventMGpuMThreads_1
* - @ref Unit_hipEventMGpuMThreads_2
* - @ref Unit_hipEventMGpuMThreads_3
*/
/**
* Test Description
* ------------------------
* - Creates regular events and events with flags.
* - Enqueues them to the streams and checks if events
* can be successfully used for synchronization.
* Test source
* ------------------------
* - unit/event/Unit_hipEventRecord.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipEventRecord") {
constexpr size_t N = 1024;
constexpr int iterations = 1;
@@ -117,6 +138,21 @@ TEST_CASE("Unit_hipEventRecord") {
TestContext::get().cleanContext();
}
/**
* Test Description
* ------------------------
* - Validates handling of invalid arguments:
* -# When event is `nullptr`
* - Expected output: return `hipErrorInvalidResourceHandle`
* -# When event is created on one device but recorded on the other one
* - Expected output: return `hipErrorInvalidHandle`
* Test source
* ------------------------
* - unit/event/Unit_hipEventRecord.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipEventRecord_Negative") {
SECTION("Nullptr event") {
HIP_CHECK_ERROR(hipEventRecord(nullptr, nullptr), hipErrorInvalidResourceHandle);
+140 -16
查看文件
@@ -31,31 +31,71 @@ Unit_hipEventCreate_IncompatibleFlags - Test unsuccessful event creation when in
#include <hip_test_common.hh>
/**
* @addtogroup hipEventCreate hipEventCreate
* @{
* @ingroup EventTest
*/
/**
* Test Description
* ------------------------
* - Validates handling of invalid arguments:
* -# When output pointer to the event is `nullptr`
* - Expected output: do not return `hipSuccess`
* Test source
* ------------------------
* - unit/event/Unit_hipEvent_Negative.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipEventCreate_NullCheck") {
auto res = hipEventCreate(nullptr);
REQUIRE(res != hipSuccess);
}
/**
* End doxygen group hipEventCreate.
* @}
*/
/**
* @addtogroup hipEventCreateWithFlags hipEventCreateWithFlags
* @{
* @ingroup EventTest
*/
/**
* Test Description
* ------------------------
* - Validates handling of `nullptr` arguments:
* -# When output pointer to the event is `nullptr`
* - Expected output: do not return `hipSuccess`
* Test source
* ------------------------
* - unit/event/Unit_hipEvent_Negative.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipEventCreateWithFlags_NullCheck") {
auto res = hipEventCreateWithFlags(nullptr, 0);
REQUIRE(res != hipSuccess);
}
TEST_CASE("Unit_hipEventSynchronize_NullCheck") {
auto res = hipEventSynchronize(nullptr);
REQUIRE(res != hipSuccess);
}
TEST_CASE("Unit_hipEventQuery_NullCheck") {
auto res = hipEventQuery(nullptr);
REQUIRE(res != hipSuccess);
}
TEST_CASE("Unit_hipEventDestroy_NullCheck") {
auto res = hipEventDestroy(nullptr);
REQUIRE(res != hipSuccess);
}
/**
* Test Description
* ------------------------
* - Validates handling of incompatible flags:
* -# When the flags are not supported on the device
* - Expected output: return `hipErrorInvalidValue`
* Test source
* ------------------------
* - unit/event/Unit_hipEvent_Negative.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipEventCreate_IncompatibleFlags") {
hipEvent_t event;
HIP_CHECK_ERROR(hipEventCreateWithFlags(&event, hipEventInterprocess), hipErrorInvalidValue);
@@ -79,4 +119,88 @@ TEST_CASE("Unit_hipEventCreate_IncompatibleFlags") {
unsigned invalidFlag{0x08000000};
HIP_CHECK_ERROR(hipEventCreateWithFlags(&event, invalidFlag), hipErrorInvalidValue);
}
}
/**
* End doxygen group hipEventCreateWithFlags.
* @}
*/
/**
* @addtogroup hipEventSynchronize hipEventSynchronize
* @{
* @ingroup EventTest
*/
/**
* Test Description
* ------------------------
* - Validates handling of invalid arguments:
* -# When event is `nullptr`
* - Expected output: do not return `hipSuccess`
* Test source
* ------------------------
* - unit/event/Unit_hipEvent_Negative.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipEventSynchronize_NullCheck") {
auto res = hipEventSynchronize(nullptr);
REQUIRE(res != hipSuccess);
}
/**
* End doxygen group hipEventSynchronize.
* @}
*/
/**
* @addtogroup hipEventQuery hipEventQuery
* @{
* @ingroup EventTest
*/
/**
* Test Description
* ------------------------
* - Validates handling of invalid arguments:
* -# When event is `nullptr`
* - Expected output: do not return `hipSuccess`
* Test source
* ------------------------
* - unit/event/Unit_hipEvent_Negative.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipEventQuery_NullCheck") {
auto res = hipEventQuery(nullptr);
REQUIRE(res != hipSuccess);
}
/**
* End doxygen group hipEventQuery.
* @}
*/
/**
* @addtogroup hipEventDestroy hipEventDestroy
* @{
* @ingroup EventTest
*/
/**
* Test Description
* ------------------------
* - Validates handling of invalid arguments:
* -# When event is `nullptr`
* - Expected output: do not return `hipSuccess`
* Test source
* ------------------------
* - unit/event/Unit_hipEvent_Negative.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipEventDestroy_NullCheck") {
auto res = hipEventDestroy(nullptr);
REQUIRE(res != hipSuccess);
}
+19 -4
查看文件
@@ -19,13 +19,28 @@ 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 :
Unit_hipEventCreate_Positive - Test simple event creation with hipEventCreate api
*/
#include <hip_test_common.hh>
/**
* @addtogroup hipEventCreate hipEventCreate
* @{
* @ingroup EventTest
* `hipEventCreate(hipEvent_t* event)` -
* Create an event.
*/
/**
* Test Description
* ------------------------
* - Successfully creates and event for each device.
* Test source
* ------------------------
* - unit/event/hipEventCreate.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipEventCreate_Positive") {
int id = GENERATE(range(0, HipTest::getDeviceCount()));
HIP_CHECK(hipSetDevice(id));
+19 -4
查看文件
@@ -19,13 +19,28 @@ 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 :
Unit_hipEventCreateWithFlags_Positive - Test simple event creation with hipEventCreateWithFlags api for each flag
*/
#include <hip_test_common.hh>
/**
* @addtogroup hipEventCreateWithFlags hipEventCreateWithFlags
* @{
* @ingroup EventTest
* `hipEventCreateWithFlags(hipEvent_t* event, unsigned flags)` -
* Create an event with the specified flags to control event behaviour.
*/
/**
* Test Description
* ------------------------
* - Successfully create an event with all defined device flags.
* Test source
* ------------------------
* - unit/event/hipEventCreateWithFlags.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipEventCreateWithFlags_Positive") {
#if HT_AMD
+49 -7
查看文件
@@ -26,12 +26,23 @@ THE SOFTWARE.
#include <hip_test_common.hh>
#include "hip/hip_runtime_api.h"
/**
* @addtogroup hipEventDestroy hipEventDestroy
* @{
* @ingroup EventTest
* `hipEventDestroy(hipEvent_t event)` -
* Destroy the specified event.
* ________________________
* Test cases from other modules:
* - @ref Unit_hipEventIpc
*/
#if HT_AMD /* Disabled because frequency based wait is timing out on nvidia platforms */
static constexpr size_t vectorSize{1024};
/**
* @brief Launches vectorAdd kernel with a delay
/*
* Launches vectorAdd kernel with a delay
*/
static inline void launchVectorAdd(float*& A_h, float*& B_h, float*& C_h,
std::chrono::milliseconds delay, hipStream_t stream = nullptr) {
@@ -46,10 +57,17 @@ static inline void launchVectorAdd(float*& A_h, float*& B_h, float*& C_h,
HipTest::vectorADD<<<1, 1, 0, stream>>>(A_d, B_d, C_d, vectorSize);
}
/**
* @brief Check that destroying an event before the kernel has finished running causes no errors.
*
* Test Description
* ------------------------
* - Destroys the event before launched kernel has finished running.
* Test source
* ------------------------
* - unit/event/hipEventDestroy.cc
* Test requirements
* ------------------------
* - Platform specific (AMD)
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipEventDestroy_Unfinished") {
hipEvent_t event;
@@ -69,8 +87,16 @@ TEST_CASE("Unit_hipEventDestroy_Unfinished") {
}
/**
* @brief Check that destroying an event enqueued to a stream causes no errors.
*
* Test Description
* ------------------------
* - Destroys the event that is enqueued into a stream.
* Test source
* ------------------------
* - unit/event/hipEventDestroy.cc
* Test requirements
* ------------------------
* - Platform specific (AMD)
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipEventDestroy_WithWaitingStream") {
hipEvent_t event;
@@ -94,6 +120,22 @@ TEST_CASE("Unit_hipEventDestroy_WithWaitingStream") {
HipTest::freeArraysForHost(A_h, B_h, C_h, true);
}
/**
* Test Description
* ------------------------
* - Validates handling of invalid arguments:
* -# When output pointer to the event is `nullptr`
* - Expected output: return `hipErrorInvalidResourceHandle`
* -# When event is destroyed twice
* - Expected output: return `hipErrorContextIsDestroyed`
* Test source
* ------------------------
* - unit/event/hipEventDestroy.cc
* Test requirements
* ------------------------
* - Platform specific (AMD)
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipEventDestroy_Negative") {
SECTION("Invalid Event") {
hipEvent_t event{nullptr};
+36 -6
查看文件
@@ -19,17 +19,25 @@ 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 :
Unit_hipEventSynchronize_Default_Positive- Test synchronization of an event that is completed after a simple kernel launch (on null/created stream)
Unit_hipEventSynchronize_NoEventRecord_Positive - Test synchronization of an event that has not been recorded
*/
#include <hip_test_common.hh>
#include <kernels.hh>
#include <hip_test_checkers.hh>
/**
* @addtogroup hipEventSynchronize hipEventSynchronize
* @{
* @ingroup EventTest
* `hipEventSynchronize(hipEvent_t event)` -
* Wait for an event to complete.
* ________________________
* Test cases from other modules:
* - @ref Unit_hipEventIpc
* - @ref Unit_hipEventMGpuMThreads_1
* - @ref Unit_hipEventMGpuMThreads_2
* - @ref Unit_hipEventMGpuMThreads_3
*/
void testSynchronize(hipStream_t stream) {
constexpr size_t N = 1024;
@@ -70,6 +78,17 @@ void testSynchronize(hipStream_t stream) {
HipTest::freeArrays(A_d, B_d, C_d, A_h, B_h, C_h, false);
}
/**
* Test Description
* ------------------------
* - Synchronization of an event that is completed after a simple kernel launch (on null/created stream).
* Test source
* ------------------------
* - unit/event/hipEventSynchronize.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipEventSynchronize_Default_Positive") {
hipStream_t stream{nullptr};
@@ -84,6 +103,17 @@ TEST_CASE("Unit_hipEventSynchronize_Default_Positive") {
}
}
/**
* Test Description
* ------------------------
* - Synchronization of an event that has not been recorded.
* Test source
* ------------------------
* - unit/event/hipEventSynchronize.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipEventSynchronize_NoEventRecord_Positive") {
constexpr size_t N = 1024;
+22 -11
查看文件
@@ -18,7 +18,11 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
# Common Tests - Test independent of all platforms
# FIXME: cjatin
# This is a temp hack to pass it on windows since it has a char limit for
# command line. Eventually we need to use rsp files with ninja on windows.
# But this exposes several problems with hipcc and build system on windows.
# While those are fixed, this hack should allow us to pass windows CI.
set(TEST_SRC
hipGraphAddEmptyNode.cc
hipGraphAddDependencies.cc
@@ -65,7 +69,20 @@ set(TEST_SRC
hipStreamBeginCapture.cc
hipStreamBeginCapture_old.cc
hipStreamIsCapturing.cc
hipStreamIsCapturing_old.cc
hipStreamIsCapturing_old.cc)
if(HIP_PLATFORM MATCHES "amd")
set(AMD_SRC
hipStreamCaptureExtModuleLaunchKernel.cc
)
set(TEST_SRC ${TEST_SRC} ${AMD_SRC})
endif()
hip_add_exe_to_target(NAME GraphsTest1
TEST_SRC ${TEST_SRC}
TEST_TARGET_NAME build_tests)
set(TEST_SRC
hipStreamGetCaptureInfo.cc
hipStreamGetCaptureInfo_old.cc
hipStreamEndCapture.cc
@@ -109,17 +126,11 @@ set(TEST_SRC
hipGraphExecDestroy.cc
hipGraphUpload.cc
hipGraphKernelNodeCopyAttributes.cc
hipGraphCycle.cc
hipGraphKernelNodeGetAttribute.cc
)
hipGraphKernelNodeSetAttribute.cc)
if(HIP_PLATFORM MATCHES "amd")
set(AMD_SRC
hipStreamCaptureExtModuleLaunchKernel.cc
)
set(TEST_SRC ${TEST_SRC} ${AMD_SRC})
endif()
hip_add_exe_to_target(NAME GraphsTest
hip_add_exe_to_target(NAME GraphsTest2
TEST_SRC ${TEST_SRC}
TEST_TARGET_NAME build_tests)
+94 -114
查看文件
@@ -6,23 +6,25 @@ 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
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY 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
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 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
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 of hipGraphAddHostNode API:
Test Case Scenarios of hipGraphAddHostNode API:
Functional:
1. Creates graph, Adds HostNode which updates the variable and validates the result
2. Create graph, Add Graphnodes and clones the graph. Add Hostnode to the cloned graph
2. Create graph, Add Graph nodes and clones the graph. Add Host node to the cloned graph
and validate the result
3. Creates graph which performs the square of number in the kernel function and the result
is validated in the callback function of hipGraphAddHostNode API
@@ -35,22 +37,22 @@ Negative:
4) Pass hipHostNodeParams::hipHostFn_t as nullptr and verify api doesn't crash, returns error code.
*/
#include <hip_test_common.hh>
#include <hip_test_checkers.hh>
#include <hip_test_common.hh>
#define SIZE 1024
static int *B_h;
static int *D_h;
static int* B_h;
static int* D_h;
static void callbackfunc(void *A_h) {
int *A = reinterpret_cast<int *>(A_h);
static void callbackfunc(void* A_h) {
int* A = reinterpret_cast<int*>(A_h);
for (int i = 0; i < SIZE; i++) {
A[i] = i;
}
}
static void __global__ vector_square(int *B_d, int *D_d) {
static void __global__ vector_square(int* B_d, int* D_d) {
for (int i = 0; i < SIZE; i++) {
D_d[i] = B_d[i] * B_d[i];
}
@@ -60,7 +62,7 @@ static void vectorsquare_callback(void* ptr) {
// of type void (*)(void*). This test is designed to
// work with global variables, hence the workaround to
// print this *ptr value to avoid type mismatch errors.
int *A = reinterpret_cast<int *>(ptr);
int* A = reinterpret_cast<int*>(ptr);
for (int i = 0; i < SIZE; i++) {
if (D_h[i] != B_h[i] * B_h[i]) {
@@ -70,8 +72,9 @@ static void vectorsquare_callback(void* ptr) {
}
}
}
/*
This testcase verifies the negative scenarios of
This test case verifies the negative scenarios of
hipGraphAddHostNode API
*/
TEST_CASE("Unit_hipGraphAddHostNode_Negative") {
@@ -79,101 +82,96 @@ TEST_CASE("Unit_hipGraphAddHostNode_Negative") {
hipGraph_t graph;
int *A_d{nullptr}, *C_d{nullptr};
int *A_h{nullptr}, *C_h{nullptr};
HipTest::initArrays<int>(&A_d, nullptr, &C_d,
&A_h, nullptr, &C_h, N, false);
HipTest::initArrays<int>(&A_d, nullptr, &C_d, &A_h, nullptr, &C_h, N, false);
HIP_CHECK(hipGraphCreate(&graph, 0));
hipGraphNode_t hostNode;
hipHostNodeParams hostParams = {0, 0};
std::vector<hipGraphNode_t> dependencies;
hostParams.fn = callbackfunc;
hostParams.userData = A_h;
SECTION("Passing nullptr to graph node") {
REQUIRE(hipGraphAddHostNode(nullptr, graph,
nullptr,
0, &hostParams) == hipErrorInvalidValue);
HIP_CHECK_ERROR(hipGraphAddHostNode(nullptr, graph, nullptr, 0, &hostParams),
hipErrorInvalidValue);
}
SECTION("Passing nullptr to graph") {
REQUIRE(hipGraphAddHostNode(&hostNode, nullptr,
nullptr,
0, &hostParams) == hipErrorInvalidValue);
HIP_CHECK_ERROR(hipGraphAddHostNode(&hostNode, nullptr, nullptr, 0, &hostParams),
hipErrorInvalidValue);
}
#if HT_NVIDIA
SECTION("Passing nullptr to host params") {
REQUIRE(hipGraphAddHostNode(&hostNode, graph,
nullptr,
0, nullptr) == hipErrorInvalidValue);
SECTION("Pass invalid numDependencies") {
HIP_CHECK_ERROR(hipGraphAddHostNode(&hostNode, graph, nullptr, 11, &hostParams),
hipErrorInvalidValue);
}
SECTION("Pass invalid numDependencies and valid list for dependencies") {
HIP_CHECK(hipGraphAddHostNode(&hostNode, graph, nullptr, 0, &hostParams));
dependencies.push_back(hostNode);
HIP_CHECK_ERROR(hipGraphAddHostNode(&hostNode, graph, dependencies.data(),
dependencies.size() + 1, &hostParams),
hipErrorInvalidValue);
}
SECTION("Passing nullptr to host params") {
HIP_CHECK_ERROR(hipGraphAddHostNode(&hostNode, graph, nullptr, 0, nullptr),
hipErrorInvalidValue);
}
#endif
SECTION("Passing nullptr to host func") {
hostParams.fn = nullptr;
REQUIRE(hipGraphAddHostNode(&hostNode, graph,
nullptr,
0, &hostParams) == hipErrorInvalidValue);
HIP_CHECK_ERROR(hipGraphAddHostNode(&hostNode, graph, nullptr, 0, &hostParams),
hipErrorInvalidValue);
}
HipTest::freeArrays<int>(A_d, nullptr, C_d, A_h, nullptr, C_h, false);
HIP_CHECK(hipGraphDestroy(graph));
}
/*
This testcase verifies hipGraphAddHostNode API in cloned graph
This test case verifies hipGraphAddHostNode API in cloned graph
Creates graph, Add graph nodes and clone the graph
Add HostNode to the cloned graph and validate the result
*/
TEST_CASE("Unit_hipGraphAddHostNode_ClonedGraphwithHostNode") {
TEST_CASE("Unit_hipGraphAddHostNode_ClonedGraphWithHostNode") {
constexpr size_t N = 1024;
constexpr size_t Nbytes = N * sizeof(int);
hipGraph_t graph;
hipGraphExec_t graphExec;
int *A_d{nullptr}, *C_d{nullptr};
int *A_h{nullptr}, *C_h{nullptr};
HipTest::initArrays<int>(&A_d, nullptr, &C_d,
&A_h, nullptr, &C_h, N, false);
HipTest::initArrays<int>(&A_d, nullptr, &C_d, &A_h, nullptr, &C_h, N, false);
HIP_CHECK(hipGraphCreate(&graph, 0));
hipGraphNode_t memcpyH2D_A, memcpyH2D_C,
memcpyD2H_AC;
hipGraphNode_t cloned_memcpyH2D_A, cloned_memcpyH2D_C,
cloned_memcpyD2H_AC;
hipGraphNode_t memcpyH2D_A, memcpyH2D_C, memcpyD2H_AC;
hipGraphNode_t cloned_memcpyH2D_A, cloned_memcpyH2D_C, cloned_memcpyD2H_AC;
hipStream_t streamForGraph;
HIP_CHECK(hipStreamCreate(&streamForGraph));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_A, graph, nullptr,
0, A_d, A_h,
Nbytes, hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_C, graph, nullptr,
0, C_d, C_h,
Nbytes, hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_AC, graph, nullptr,
0, A_h, C_d,
Nbytes, hipMemcpyDeviceToHost));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_A, graph, nullptr, 0, A_d, A_h, Nbytes,
hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_C, graph, nullptr, 0, C_d, C_h, Nbytes,
hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_AC, graph, nullptr, 0, A_h, C_d, Nbytes,
hipMemcpyDeviceToHost));
hipGraph_t clonedgraph;
HIP_CHECK(hipGraphClone(&clonedgraph, graph));
HIP_CHECK(hipGraphNodeFindInClone(&cloned_memcpyH2D_A, memcpyH2D_A,
clonedgraph));
HIP_CHECK(hipGraphNodeFindInClone(&cloned_memcpyH2D_C, memcpyH2D_C,
clonedgraph));
HIP_CHECK(hipGraphNodeFindInClone(&cloned_memcpyD2H_AC, memcpyD2H_AC,
clonedgraph));
HIP_CHECK(hipGraphNodeFindInClone(&cloned_memcpyH2D_A, memcpyH2D_A, clonedgraph));
HIP_CHECK(hipGraphNodeFindInClone(&cloned_memcpyH2D_C, memcpyH2D_C, clonedgraph));
HIP_CHECK(hipGraphNodeFindInClone(&cloned_memcpyD2H_AC, memcpyD2H_AC, clonedgraph));
hipGraphNode_t hostNode;
hipHostNodeParams hostParams = {0, 0};
hostParams.fn = callbackfunc;
hostParams.userData = A_h;
HIP_CHECK(hipGraphAddHostNode(&hostNode, clonedgraph,
nullptr,
0, &hostParams));
HIP_CHECK(hipGraphAddHostNode(&hostNode, clonedgraph, nullptr, 0, &hostParams));
HIP_CHECK(hipGraphAddDependencies(clonedgraph, &cloned_memcpyH2D_A,
&cloned_memcpyD2H_AC, 1));
HIP_CHECK(hipGraphAddDependencies(clonedgraph, &cloned_memcpyH2D_C,
&cloned_memcpyD2H_AC, 1));
HIP_CHECK(hipGraphAddDependencies(clonedgraph, &cloned_memcpyD2H_AC,
&hostNode, 1));
HIP_CHECK(hipGraphAddDependencies(clonedgraph, &cloned_memcpyH2D_A, &cloned_memcpyD2H_AC, 1));
HIP_CHECK(hipGraphAddDependencies(clonedgraph, &cloned_memcpyH2D_C, &cloned_memcpyD2H_AC, 1));
HIP_CHECK(hipGraphAddDependencies(clonedgraph, &cloned_memcpyD2H_AC, &hostNode, 1));
// Instantiate and launch the cloned graph
HIP_CHECK(hipGraphInstantiate(&graphExec, clonedgraph, nullptr, nullptr, 0));
@@ -183,7 +181,7 @@ TEST_CASE("Unit_hipGraphAddHostNode_ClonedGraphwithHostNode") {
// Verify execution result
for (size_t i = 0; i < N; i++) {
if (A_h[i] != static_cast<int>(i)) {
INFO("Validation failed i " << i << "C_h[i] "<< C_h[i]);
INFO("Validation failed i " << i << "C_h[i] " << C_h[i]);
REQUIRE(false);
}
}
@@ -196,9 +194,9 @@ TEST_CASE("Unit_hipGraphAddHostNode_ClonedGraphwithHostNode") {
}
/*
This testcase verifies the square of number by
This test case verifies the square of number by
creating graph, Add kernel node which does the square
of number and the result is validated byhipGrahAddHostNode API
of number and the result is validated by hipGraphAddHostNode API
*/
TEST_CASE("Unit_hipGraphAddHostNode_VectorSquare") {
constexpr size_t N = 1024;
@@ -206,9 +204,9 @@ TEST_CASE("Unit_hipGraphAddHostNode_VectorSquare") {
hipGraph_t graph;
hipGraphExec_t graphExec;
int *A_d{nullptr}, *A_h{nullptr}, *B_d{nullptr}, *D_d{nullptr};
int *param = reinterpret_cast<int *>(sizeof(int));;
HipTest::initArrays<int>(&A_d, &B_d, &D_d,
&A_h, &B_h, &D_h, N, false);
int* param = reinterpret_cast<int*>(sizeof(int));
HipTest::initArrays<int>(&A_d, &B_d, &D_d, &A_h, &B_h, &D_h, N, false);
HIP_CHECK(hipGraphCreate(&graph, 0));
hipGraphNode_t memcpyH2D_B, memcpyH2D_D, memcpyD2H_D, kernel_vecAdd;
hipKernelNodeParams kernelNodeParams{};
@@ -219,37 +217,27 @@ TEST_CASE("Unit_hipGraphAddHostNode_VectorSquare") {
hostParams.fn = vectorsquare_callback;
hostParams.userData = param;
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_B, graph, nullptr,
0, B_d, B_h,
Nbytes, hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_D, graph, nullptr,
0, D_d, D_h,
Nbytes, hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_B, graph, nullptr, 0, B_d, B_h, Nbytes,
hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_D, graph, nullptr, 0, D_d, D_h, Nbytes,
hipMemcpyHostToDevice));
void* kernelArgs2[] = {&B_d, &D_d};
kernelNodeParams.func = reinterpret_cast<void *>(vector_square);
kernelNodeParams.func = reinterpret_cast<void*>(vector_square);
kernelNodeParams.gridDim = dim3(1);
kernelNodeParams.blockDim = dim3(1);
kernelNodeParams.sharedMemBytes = 0;
kernelNodeParams.kernelParams = reinterpret_cast<void**>(kernelArgs2);
kernelNodeParams.extra = nullptr;
HIP_CHECK(hipGraphAddKernelNode(&kernel_vecAdd, graph, nullptr, 0,
&kernelNodeParams));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_D, graph, nullptr,
0, D_h, D_d,
Nbytes, hipMemcpyDeviceToHost));
HIP_CHECK(hipGraphAddKernelNode(&kernel_vecAdd, graph, nullptr, 0, &kernelNodeParams));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_D, graph, nullptr, 0, D_h, D_d, Nbytes,
hipMemcpyDeviceToHost));
HIP_CHECK(hipGraphAddHostNode(&hostNode, graph,
nullptr,
0, &hostParams));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_B, &kernel_vecAdd,
1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_D, &kernel_vecAdd,
1));
HIP_CHECK(hipGraphAddDependencies(graph, &kernel_vecAdd,
&memcpyD2H_D, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyD2H_D,
&hostNode, 1));
HIP_CHECK(hipGraphAddHostNode(&hostNode, graph, nullptr, 0, &hostParams));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_B, &kernel_vecAdd, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_D, &kernel_vecAdd, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &kernel_vecAdd, &memcpyD2H_D, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyD2H_D, &hostNode, 1));
// Instantiate and launch the graph
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
@@ -261,8 +249,9 @@ TEST_CASE("Unit_hipGraphAddHostNode_VectorSquare") {
HIP_CHECK(hipGraphDestroy(graph));
HIP_CHECK(hipStreamDestroy(streamForGraph));
}
/*
This testcase verifies the following scenario
This test case verifies the following scenario
Create graph, calls the host function and updates
the parameters in the callback function and
validates it.
@@ -274,36 +263,27 @@ TEST_CASE("Unit_hipGraphAddHostNode_BasicFunc") {
hipGraphExec_t graphExec;
int *A_d{nullptr}, *C_d{nullptr};
int *A_h{nullptr}, *C_h{nullptr};
HipTest::initArrays<int>(&A_d, nullptr, &C_d,
&A_h, nullptr, &C_h, N, false);
HipTest::initArrays<int>(&A_d, nullptr, &C_d, &A_h, nullptr, &C_h, N, false);
HIP_CHECK(hipGraphCreate(&graph, 0));
hipGraphNode_t memcpyH2D_A, memcpyD2H_AC, memcpyH2D_C;
hipStream_t streamForGraph;
HIP_CHECK(hipStreamCreate(&streamForGraph));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_A, graph, nullptr,
0, A_d, A_h,
Nbytes, hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_C, graph, nullptr,
0, C_d, C_h,
Nbytes, hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_AC, graph, nullptr,
0, A_h, C_d,
Nbytes, hipMemcpyDeviceToHost));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_A, graph, nullptr, 0, A_d, A_h, Nbytes,
hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_C, graph, nullptr, 0, C_d, C_h, Nbytes,
hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_AC, graph, nullptr, 0, A_h, C_d, Nbytes,
hipMemcpyDeviceToHost));
hipGraphNode_t hostNode;
hipHostNodeParams hostParams = {0, 0};
hostParams.fn = callbackfunc;
hostParams.userData = A_h;
HIP_CHECK(hipGraphAddHostNode(&hostNode, graph,
nullptr,
0, &hostParams));
HIP_CHECK(hipGraphAddHostNode(&hostNode, graph, nullptr, 0, &hostParams));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_A,
&memcpyD2H_AC, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_C,
&memcpyD2H_AC, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyD2H_AC,
&hostNode, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_A, &memcpyD2H_AC, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_C, &memcpyD2H_AC, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyD2H_AC, &hostNode, 1));
// Instantiate and launch the graph
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
@@ -313,7 +293,7 @@ TEST_CASE("Unit_hipGraphAddHostNode_BasicFunc") {
// Verify execution result
for (size_t i = 0; i < N; i++) {
if (A_h[i] != static_cast<int>(i)) {
INFO("Validation failed i " << i << "A_h[i] "<< A_h[i]);
INFO("Validation failed i " << i << "A_h[i] " << A_h[i]);
REQUIRE(false);
}
}
+244
查看文件
@@ -0,0 +1,244 @@
/*
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 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) Purpose is to check for topology of graph
2) Basic tests with manually added nodes, make graph cyclic
3) Basic tests with manually added nodes, remove edges from graph making sure
node levels are correct if graph is not cyclic in a previously cyclic graph.
*/
#include <hip_test_common.hh>
#include <hip_test_checkers.hh>
#include <hip_test_kernels.hh>
/**
* Tests basic functionality of cycle detection in hipGraph APIs by
* Adding manual empty nodes
* Cyclic graph, cycle formation first, then adding more nodes
*/
TEST_CASE("Unit_hipGraph_BasicCyclic1") {
hipGraph_t graph;
hipStream_t streamForGraph;
hipGraphExec_t graphExec;
hipGraphNode_t emptyNode1, emptyNode2, emptyNode3, emptyNode4, emptyNode5, emptyNode6;
HIP_CHECK(hipGraphCreate(&graph, 0));
// Create emptyNode and add it to graph with dependency
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode1, graph, nullptr, 0));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode2, graph, nullptr, 0));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode3, graph, nullptr, 0));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode4, graph, nullptr, 0));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode5, graph, nullptr, 0));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode6, graph, nullptr, 0));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode1, &emptyNode2, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode2, &emptyNode3, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode3, &emptyNode1, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode4, &emptyNode1, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode5, &emptyNode4, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode5, &emptyNode6, 1));
HIP_CHECK(hipStreamCreate(&streamForGraph));
REQUIRE(hipErrorInvalidValue == hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
HIP_CHECK(hipStreamDestroy(streamForGraph));
}
/**
* Tests basic functionality of cycle detection in hipGraph APIs by
* Adding manual empty nodes
* Cyclic graph, cycle formation first, Remove edge to resolve cycle
*/
TEST_CASE("Unit_hipGraph_BasicCyclic2") {
hipGraph_t graph;
hipStream_t streamForGraph;
hipGraphExec_t graphExec;
hipGraphNode_t emptyNode1, emptyNode2, emptyNode3, emptyNode4, emptyNode5;
HIP_CHECK(hipGraphCreate(&graph, 0));
// Create emptyNode and add it to graph with dependency
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode1, graph, nullptr, 0));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode2, graph, nullptr, 0));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode3, graph, nullptr, 0));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode4, graph, nullptr, 0));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode5, graph, nullptr, 0));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode1, &emptyNode2, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode2, &emptyNode3, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode3, &emptyNode1, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode4, &emptyNode1, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode5, &emptyNode4, 1));
HIP_CHECK(hipGraphRemoveDependencies(graph, &emptyNode3, &emptyNode1, 1));
HIP_CHECK(hipStreamCreate(&streamForGraph));
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
HIP_CHECK(hipStreamDestroy(streamForGraph));
}
/**
* Tests basic functionality of cycle detection in hipGraph APIs by
* Adding manual empty nodes
* Cyclic graph, cycle formation first, Remove edge causes disconnected graph which is still
* cyclic
*/
TEST_CASE("Unit_hipGraph_BasicCyclic3") {
hipGraph_t graph;
hipStream_t streamForGraph;
hipGraphExec_t graphExec;
hipGraphNode_t emptyNode1, emptyNode2, emptyNode3, emptyNode4, emptyNode5, emptyNode6;
HIP_CHECK(hipGraphCreate(&graph, 0));
// Create emptyNode and add it to graph with dependency
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode1, graph, nullptr, 0));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode2, graph, nullptr, 0));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode3, graph, nullptr, 0));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode4, graph, nullptr, 0));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode5, graph, nullptr, 0));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode6, graph, nullptr, 0));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode1, &emptyNode2, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode2, &emptyNode3, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode3, &emptyNode1, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode4, &emptyNode1, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode5, &emptyNode4, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode5, &emptyNode6, 1));
HIP_CHECK(hipGraphRemoveDependencies(graph, &emptyNode5, &emptyNode4, 1));
HIP_CHECK(hipStreamCreate(&streamForGraph));
REQUIRE(hipErrorInvalidValue == hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
HIP_CHECK(hipStreamDestroy(streamForGraph));
}
/**
* Tests basic functionality of cycle detection in hipGraph APIs by
* Adding manual empty nodes
* Uncyclic graph, removing edge from middle of linear graph
*/
TEST_CASE("Unit_hipGraph_BasicCyclic4") {
int N = 1024 * 1024;
int Nbytes = N * sizeof(int);
hipGraph_t graph;
hipGraphExec_t graphExec;
hipStream_t stream;
int *X_d, *Y_d, *X_h, *Y_h;
HipTest::initArrays<int>(&X_d, &Y_d, nullptr, &X_h, &Y_h, nullptr, N, false);
constexpr size_t memSetVal = 9;
hipGraphNode_t kMemCpyH2D_X, memcpyD2D, memcpyD2H_RC, emptyNode1;
HIP_CHECK(hipStreamCreate(&stream));
HIP_CHECK(hipGraphCreate(&graph, 0));
HIP_CHECK(hipGraphAddMemcpyNode1D(&kMemCpyH2D_X, graph, nullptr, 0, X_d, X_h, Nbytes,
hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2D, graph, nullptr, 0, Y_d, X_d, Nbytes,
hipMemcpyDeviceToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_RC, graph, nullptr, 0, Y_h, Y_d, Nbytes,
hipMemcpyDeviceToHost));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode1, graph, nullptr, 0));
HIP_CHECK(hipGraphAddDependencies(graph, &kMemCpyH2D_X, &emptyNode1, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode1, &memcpyD2D, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyD2D, &memcpyD2H_RC, 1));
HIP_CHECK(hipGraphRemoveDependencies(graph, &kMemCpyH2D_X, &emptyNode1, 1));
HIP_CHECK(hipGraphRemoveDependencies(graph, &emptyNode1, &memcpyD2D, 1));
HIP_CHECK(hipGraphDestroyNode(emptyNode1));
HIP_CHECK(hipGraphAddDependencies(graph, &kMemCpyH2D_X, &memcpyD2D, 1));
// Instantiate and launch the graph
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
HIP_CHECK(hipGraphLaunch(graphExec, stream));
HIP_CHECK(hipStreamSynchronize(stream));
// Verify graph result as X_h == Y_h
for (size_t i = 0; i < N; i++) {
if (Y_h[i] != X_h[i]) {
INFO("Validation failed for graph at index " << i << " Y_h[i] " << Y_h[i] << " X_h[i] "
<< X_h[i]);
REQUIRE(false);
}
}
HipTest::freeArrays<int>(X_d, Y_d, nullptr, X_h, Y_h, nullptr, false);
HIP_CHECK(hipGraphExecDestroy(graphExec));
HIP_CHECK(hipGraphDestroy(graph));
HIP_CHECK(hipStreamDestroy(stream));
}
/**
* Tests basic functionality of cycle detection in hipGraph APIs by
* Adding manual empty nodes
* cyclic graph, removing edge to resolve cycle and remove edge from middle of graph
*/
TEST_CASE("Unit_hipGraph_BasicCyclic5") {
int N = 1024 * 1024;
int Nbytes = N * sizeof(int);
hipGraph_t graph;
hipGraphExec_t graphExec;
hipStream_t stream;
int *X_d, *Y_d, *X_h, *Y_h;
HipTest::initArrays<int>(&X_d, &Y_d, nullptr, &X_h, &Y_h, nullptr, N, false);
constexpr size_t memSetVal = 9;
hipGraphNode_t kMemCpyH2D_X, memcpyD2D, memcpyD2H_RC, emptyNode1, emptyNode2, emptyNode3;
HIP_CHECK(hipStreamCreate(&stream));
HIP_CHECK(hipGraphCreate(&graph, 0));
HIP_CHECK(hipGraphAddMemcpyNode1D(&kMemCpyH2D_X, graph, nullptr, 0, X_d, X_h, Nbytes,
hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2D, graph, nullptr, 0, Y_d, X_d, Nbytes,
hipMemcpyDeviceToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_RC, graph, nullptr, 0, Y_h, Y_d, Nbytes,
hipMemcpyDeviceToHost));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode1, graph, nullptr, 0));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode2, graph, nullptr, 0));
HIP_CHECK(hipGraphAddEmptyNode(&emptyNode3, graph, nullptr, 0));
HIP_CHECK(hipGraphAddDependencies(graph, &kMemCpyH2D_X, &emptyNode1, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode1, &memcpyD2D, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyD2D, &memcpyD2H_RC, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyD2H_RC, &emptyNode2, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode2, &emptyNode3, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &emptyNode3, &memcpyD2H_RC, 1));
HIP_CHECK(hipGraphRemoveDependencies(graph, &kMemCpyH2D_X, &emptyNode1, 1));
HIP_CHECK(hipGraphRemoveDependencies(graph, &emptyNode1, &memcpyD2D, 1));
HIP_CHECK(hipGraphDestroyNode(emptyNode1));
HIP_CHECK(hipGraphAddDependencies(graph, &kMemCpyH2D_X, &memcpyD2D, 1));
HIP_CHECK(hipGraphRemoveDependencies(graph, &emptyNode3, &memcpyD2H_RC, 1));
// Instantiate and launch the graph
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
HIP_CHECK(hipGraphLaunch(graphExec, stream));
HIP_CHECK(hipStreamSynchronize(stream));
// Verify graph result as X_h == Y_h
for (size_t i = 0; i < N; i++) {
if (Y_h[i] != X_h[i]) {
INFO("Validation failed for graph at index " << i << " Y_h[i] " << Y_h[i] << " X_h[i] "
<< X_h[i]);
REQUIRE(false);
}
}
HipTest::freeArrays<int>(X_d, Y_d, nullptr, X_h, Y_h, nullptr, false);
HIP_CHECK(hipGraphExecDestroy(graphExec));
HIP_CHECK(hipGraphDestroy(graph));
HIP_CHECK(hipStreamDestroy(stream));
}
+140 -144
查看文件
@@ -6,164 +6,173 @@ 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
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY 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
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 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
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 of hipGraphExecHostNodeSetParams API:
Test Case Scenarios of hipGraphExecHostNodeSetParams API:
Functional:
1. Creates graph, Adds HostNode, update hostNode params using hipGraphExecHostNodeSetParams API
and validates the result
2. Create graph, Add Graphnodes and clones the graph. Add Hostnode to the cloned graph, update
2. Create graph, Add Graph nodes and clones the graph. Add Host node to the cloned graph, update
hostNode params using hipGraphExecHostNodeSetParams API and validate the result
Negative:
1) Pass hGraphExec as nullptr and verify api doen't crash, returns error code.
2) Pass node as nullptr and verify api doen't crash, returns error code.
1) Pass hGraphExec as nullptr and verify api doesn't crash, returns error code.
2) Pass node as nullptr and verify api doesn't crash, returns error code.
3) Pass pNodeParams as nullptr and verify api doesn't crash, returns error code.
3) Pass hipHostNodeParams::hipHostFn_t as nullptr and verify api doesn't crash, returns error code.
4) Pass unintialized host params and verify api doesn't crash, returns error code.
5) Pass unintialized graph and verify api doesn't crash, returns error code.
6) Pass nullptr to hostfunc and verify api doesn't crash, returns error code.
4) Pass uninitialized host params and verify api doesn't crash, returns error code.
5) Pass uninitialized graph and verify api doesn't crash, returns error code.
6) Pass nullptr to host func and verify api doesn't crash, returns error code.
*/
#include <hip_test_common.hh>
#include <hip_test_checkers.hh>
#include <hip_test_common.hh>
#define SIZE 1024
void callbackfunc(void *A_h) {
int *A = reinterpret_cast<int *>(A_h);
void callbackfunc(void* A_h) {
int* A = reinterpret_cast<int*>(A_h);
for (int i = 0; i < SIZE; i++) {
A[i] = i;
A[i] = i;
}
}
void callbackfunc_setparams(void *B_h) {
int *B = reinterpret_cast<int *>(B_h);
void callbackfunc_setparams(void* B_h) {
int* B = reinterpret_cast<int*>(B_h);
for (int i = 0; i < SIZE; i++) {
B[i] = i * i;
B[i] = i * i;
}
}
/*
This testcase verifies the negative scenarios of
This test case verifies the negative scenarios of
hipGraphExecHostNodeSetParams API
*/
TEST_CASE("Unit_hipGraphExecHostNodeSetParams_Negative") {
constexpr size_t N = 1024;
constexpr size_t Nbytes = N * sizeof(int);
hipGraph_t graph;
hipGraphExec_t graphExec;
int *A_d{nullptr}, *C_d{nullptr};
int *A_h{nullptr}, *C_h{nullptr};
HipTest::initArrays<int>(&A_d, nullptr, &C_d,
&A_h, nullptr, &C_h, N, false);
HIP_CHECK(hipGraphCreate(&graph, 0));
hipGraphNode_t memcpyH2D_A, memcpyD2H_AC, memcpyH2D_C;
hipStream_t streamForGraph;
HIP_CHECK(hipStreamCreate(&streamForGraph));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_A, graph, nullptr,
0, A_d, A_h,
Nbytes, hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_C, graph, nullptr,
0, C_d, C_h,
Nbytes, hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_AC, graph, nullptr,
0, A_h, C_d,
Nbytes, hipMemcpyDeviceToHost));
hipGraphNode_t hostNode;
hipHostNodeParams hostParams = {0, 0};
hostParams.fn = callbackfunc;
hostParams.userData = A_h;
HIP_CHECK(hipGraphAddHostNode(&hostNode, graph,
nullptr,
0, &hostParams));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_A,
&memcpyD2H_AC, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_C,
&memcpyD2H_AC, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyD2H_AC,
&hostNode, 1));
hipHostNodeParams sethostParams = {0, 0};
sethostParams.fn = callbackfunc_setparams;
sethostParams.userData = C_h;
// Instantiate and launch the graph
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
#if HT_NVIDIA
SECTION("Passing nullptr to graphExec") {
REQUIRE(hipGraphExecHostNodeSetParams(nullptr, hostNode, &sethostParams)
== hipErrorInvalidValue);
}
SECTION("Passing nullptr to hostParams") {
REQUIRE(hipGraphExecHostNodeSetParams(graphExec, hostNode, nullptr)
== hipErrorInvalidValue);
}
#endif
SECTION("Passing nullptr to graph") {
REQUIRE(hipGraphExecHostNodeSetParams(graphExec, nullptr, &sethostParams)
== hipErrorInvalidValue);
}
SECTION("Passing nullptr to host func") {
sethostParams.fn = nullptr;
REQUIRE(hipGraphExecHostNodeSetParams(graphExec, hostNode, &sethostParams)
== hipErrorInvalidValue);
}
SECTION("Passing unintialized hostParams") {
hipHostNodeParams unintParams = {0, 0};
REQUIRE(hipGraphExecHostNodeSetParams(graphExec, hostNode, &unintParams)
== hipErrorInvalidValue);
}
HIP_CHECK(hipGraphDestroy(graph));
}
/*
This testcase verifies hipGraphExecHostNodeSetParams API in cloned graph
Creates graph, Add graph nodes and clone the graph
Add HostNode to the cloned graph,update the host params using
hipGraphExecHostNodeSetParams API and validates the result
*/
TEST_CASE("Unit_hipGraphExecHostNodeSetParams_ClonedGraphwithHostNode") {
constexpr size_t N = 1024;
constexpr size_t Nbytes = N * sizeof(int);
hipGraph_t graph;
hipGraphExec_t graphExec;
int *A_d{nullptr}, *C_d{nullptr};
int *A_h{nullptr}, *C_h{nullptr};
HipTest::initArrays<int>(&A_d, nullptr, &C_d,
&A_h, nullptr, &C_h, N, false);
HipTest::initArrays<int>(&A_d, nullptr, &C_d, &A_h, nullptr, &C_h, N, false);
HIP_CHECK(hipGraphCreate(&graph, 0));
hipGraphNode_t memcpyH2D_A, memcpyH2D_C,
memcpyD2H_AC;
hipGraphNode_t memcpyH2D_A, memcpyD2H_AC, memcpyH2D_C;
hipStream_t streamForGraph;
HIP_CHECK(hipStreamCreate(&streamForGraph));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_A, graph, nullptr,
0, A_d, A_h,
Nbytes, hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_C, graph, nullptr,
0, C_d, C_h,
Nbytes, hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_AC, graph, nullptr,
0, A_h, C_d,
Nbytes, hipMemcpyDeviceToHost));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_A, graph, nullptr, 0, A_d, A_h, Nbytes,
hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_C, graph, nullptr, 0, C_d, C_h, Nbytes,
hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_AC, graph, nullptr, 0, A_h, C_d, Nbytes,
hipMemcpyDeviceToHost));
hipGraphNode_t hostNode;
hipHostNodeParams hostParams = {0, 0};
hostParams.fn = callbackfunc;
hostParams.userData = A_h;
HIP_CHECK(hipGraphAddHostNode(&hostNode, graph, nullptr, 0, &hostParams));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_A, &memcpyD2H_AC, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_C, &memcpyD2H_AC, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyD2H_AC, &hostNode, 1));
hipHostNodeParams sethostParams = {0, 0};
sethostParams.fn = callbackfunc_setparams;
sethostParams.userData = C_h;
hipGraphNode_t empty_node;
HIP_CHECK(hipGraphAddEmptyNode(&empty_node, graph, &hostNode, 1));
// Instantiate and launch the graph
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
SECTION("Passing nullptr to graphExec") {
HIP_CHECK_ERROR(hipGraphExecHostNodeSetParams(nullptr, hostNode, &sethostParams),
hipErrorInvalidValue);
}
SECTION("Passing nullptr to hostParams") {
HIP_CHECK_ERROR(hipGraphExecHostNodeSetParams(graphExec, hostNode, nullptr),
hipErrorInvalidValue);
}
SECTION("Passing nullptr to graph") {
HIP_CHECK_ERROR(hipGraphExecHostNodeSetParams(graphExec, nullptr, &sethostParams),
hipErrorInvalidValue);
}
SECTION("Passing nullptr to host func") {
sethostParams.fn = nullptr;
HIP_CHECK_ERROR(hipGraphExecHostNodeSetParams(graphExec, hostNode, &sethostParams),
hipErrorInvalidValue);
}
SECTION("Passing uninitialized hostParams") {
hipHostNodeParams unintParams = {0, 0};
HIP_CHECK_ERROR(hipGraphExecHostNodeSetParams(graphExec, hostNode, &unintParams),
hipErrorInvalidValue);
}
#if HT_NVIDIA // segfaults on AMD
SECTION("node is not a host node") {
HIP_CHECK_ERROR(hipGraphExecHostNodeSetParams(graphExec, empty_node, &sethostParams),
hipErrorInvalidValue);
}
#endif
SECTION("node is not instantiated") {
HIP_CHECK(hipGraphAddHostNode(&hostNode, graph, nullptr, 0, &hostParams));
HIP_CHECK_ERROR(hipGraphExecHostNodeSetParams(graphExec, hostNode, &sethostParams),
hipErrorInvalidValue);
}
HipTest::freeArrays<int>(A_d, nullptr, C_d, A_h, nullptr, C_h, false);
HIP_CHECK(hipGraphExecDestroy(graphExec));
HIP_CHECK(hipGraphDestroy(graph));
HIP_CHECK(hipStreamDestroy(streamForGraph));
}
/*
This test case verifies hipGraphExecHostNodeSetParams API in cloned graph
Creates graph, Add graph nodes and clone the graph
Add HostNode to the cloned graph,update the host params using
hipGraphExecHostNodeSetParams API and validates the result
*/
TEST_CASE("Unit_hipGraphExecHostNodeSetParams_ClonedGraphWithHostNode") {
constexpr size_t N = 1024;
constexpr size_t Nbytes = N * sizeof(int);
hipGraph_t graph;
hipGraphExec_t graphExec;
int *A_d{nullptr}, *C_d{nullptr};
int *A_h{nullptr}, *C_h{nullptr};
HipTest::initArrays<int>(&A_d, nullptr, &C_d, &A_h, nullptr, &C_h, N, false);
HIP_CHECK(hipGraphCreate(&graph, 0));
hipGraphNode_t memcpyH2D_A, memcpyH2D_C, memcpyD2H_AC;
hipStream_t streamForGraph;
HIP_CHECK(hipStreamCreate(&streamForGraph));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_A, graph, nullptr, 0, A_d, A_h, Nbytes,
hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_C, graph, nullptr, 0, C_d, C_h, Nbytes,
hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_AC, graph, nullptr, 0, A_h, C_d, Nbytes,
hipMemcpyDeviceToHost));
hipGraph_t clonedgraph;
HIP_CHECK(hipGraphClone(&clonedgraph, graph));
@@ -172,20 +181,15 @@ TEST_CASE("Unit_hipGraphExecHostNodeSetParams_ClonedGraphwithHostNode") {
hipHostNodeParams hostParams = {0, 0};
hostParams.fn = callbackfunc;
hostParams.userData = A_h;
HIP_CHECK(hipGraphAddHostNode(&hostNode, clonedgraph,
nullptr,
0, &hostParams));
HIP_CHECK(hipGraphAddHostNode(&hostNode, clonedgraph, nullptr, 0, &hostParams));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_A,
&memcpyD2H_AC, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_C,
&memcpyD2H_AC, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_A, &memcpyD2H_AC, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_C, &memcpyD2H_AC, 1));
hipHostNodeParams sethostParams = {0, 0};
sethostParams.fn = callbackfunc_setparams;
sethostParams.userData = C_h;
// Instantiate and launch the cloned graph
HIP_CHECK(hipGraphInstantiate(&graphExec, clonedgraph, nullptr, nullptr, 0));
HIP_CHECK(hipGraphExecHostNodeSetParams(graphExec, hostNode, &sethostParams));
@@ -195,7 +199,7 @@ TEST_CASE("Unit_hipGraphExecHostNodeSetParams_ClonedGraphwithHostNode") {
// Verify execution result
for (size_t i = 0; i < N; i++) {
if (C_h[i] != static_cast<int>(i * i)) {
INFO("Validation failed i " << i << "C_h[i] "<< C_h[i]);
INFO("Validation failed i " << i << "C_h[i] " << C_h[i]);
REQUIRE(false);
}
}
@@ -207,7 +211,7 @@ TEST_CASE("Unit_hipGraphExecHostNodeSetParams_ClonedGraphwithHostNode") {
}
/*
This testcase verifies the following scenario
This test case verifies the following scenario
Create graph, Adds host node to the graph,
updates the host params using hipGraphExecHostNodeSetParams API
and validates the result
@@ -219,36 +223,28 @@ TEST_CASE("Unit_hipGraphExecHostNodeSetParams_BasicFunc") {
hipGraphExec_t graphExec;
int *A_d{nullptr}, *C_d{nullptr};
int *A_h{nullptr}, *C_h{nullptr};
HipTest::initArrays<int>(&A_d, nullptr, &C_d,
&A_h, nullptr, &C_h, N, false);
HipTest::initArrays<int>(&A_d, nullptr, &C_d, &A_h, nullptr, &C_h, N, false);
HIP_CHECK(hipGraphCreate(&graph, 0));
hipGraphNode_t memcpyH2D_A, memcpyD2H_AC, memcpyH2D_C;
hipStream_t streamForGraph;
HIP_CHECK(hipStreamCreate(&streamForGraph));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_A, graph, nullptr,
0, A_d, A_h,
Nbytes, hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_C, graph, nullptr,
0, C_d, C_h,
Nbytes, hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_AC, graph, nullptr,
0, A_h, C_d,
Nbytes, hipMemcpyDeviceToHost));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_A, graph, nullptr, 0, A_d, A_h, Nbytes,
hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_C, graph, nullptr, 0, C_d, C_h, Nbytes,
hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_AC, graph, nullptr, 0, A_h, C_d, Nbytes,
hipMemcpyDeviceToHost));
hipGraphNode_t hostNode;
hipHostNodeParams hostParams = {0, 0};
hostParams.fn = callbackfunc;
hostParams.userData = A_h;
HIP_CHECK(hipGraphAddHostNode(&hostNode, graph,
nullptr,
0, &hostParams));
HIP_CHECK(hipGraphAddHostNode(&hostNode, graph, nullptr, 0, &hostParams));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_A,
&memcpyD2H_AC, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_C,
&memcpyD2H_AC, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyD2H_AC,
&hostNode, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_A, &memcpyD2H_AC, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_C, &memcpyD2H_AC, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyD2H_AC, &hostNode, 1));
hipHostNodeParams sethostParams = {0, 0};
sethostParams.fn = callbackfunc_setparams;
@@ -263,8 +259,8 @@ TEST_CASE("Unit_hipGraphExecHostNodeSetParams_BasicFunc") {
// Verify execution result
for (size_t i = 0; i < N; i++) {
if (C_h[i] != static_cast<int >(i * i)) {
INFO("Validation failed i " << i << "C_h[i] "<< C_h[i]);
if (C_h[i] != static_cast<int>(i * i)) {
INFO("Validation failed i " << i << "C_h[i] " << C_h[i]);
REQUIRE(false);
}
}
+74 -92
查看文件
@@ -6,55 +6,57 @@ 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
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY 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
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 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
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 of hipGraphHostNodeGetParams API:
Test Case Scenarios of hipGraphHostNodeGetParams API:
Functional Scenarios:
1) Create a graph, add Host node to graph with desired node params. Verify api fetches the node params
which were mentioned while adding the host node.
2) Set host node params with hipGraphHostNodeSetParams, now get the params and verify both are same.
3) Create graph, Add Graphnodes and clones the graph. Add Hostnode to the cloned graph, update
hostNode params using hipGraphHostNodeSetParams API now get the params and verify both are same
1) Create a graph, add Host node to graph with desired node params. Verify api fetches the node
params which were mentioned while adding the host node. 2) Set host node params with
hipGraphHostNodeSetParams, now get the params and verify both are same. 3) Create graph, Add Graph
nodes and clones the graph. Add Host node to the cloned graph, update hostNode params using
hipGraphHostNodeSetParams API now get the params and verify both are same
Negative Scenarios:
1) Pass pGraphNode as nullptr and verify api doesn’t crash, returns error code.
2) Pass pNodeParams as nullptr and verify api doesn’t crash, returns error code.
3) Pass unintialized graph node
3) Pass uninitialized graph node
*/
#include <hip_test_common.hh>
#include <hip_test_checkers.hh>
#include <hip_test_common.hh>
#define SIZE 1024
static void callbackfunc(void *A_h) {
int *A = reinterpret_cast<int *>(A_h);
static void callbackfunc(void* A_h) {
int* A = reinterpret_cast<int*>(A_h);
for (int i = 0; i < SIZE; i++) {
A[i] = i;
}
}
static void callbackfunc_setparams(void *B_h) {
int *B = reinterpret_cast<int *>(B_h);
static void callbackfunc_setparams(void* B_h) {
int* B = reinterpret_cast<int*>(B_h);
for (int i = 0; i < SIZE; i++) {
B[i] = i * i;
B[i] = i * i;
}
}
/*
This testcase verifies the negative scenarios of
This test case verifies the negative scenarios of
hipGraphHostNodeGetParams API
*/
TEST_CASE("Unit_hipGraphHostNodeGetParams_Negative") {
@@ -62,8 +64,7 @@ TEST_CASE("Unit_hipGraphHostNodeGetParams_Negative") {
hipGraph_t graph;
int *A_d{nullptr}, *C_d{nullptr};
int *A_h{nullptr}, *C_h{nullptr};
HipTest::initArrays<int>(&A_d, nullptr, &C_d,
&A_h, nullptr, &C_h, N, false);
HipTest::initArrays<int>(&A_d, nullptr, &C_d, &A_h, nullptr, &C_h, N, false);
HIP_CHECK(hipGraphCreate(&graph, 0));
@@ -71,63 +72,57 @@ TEST_CASE("Unit_hipGraphHostNodeGetParams_Negative") {
hipHostNodeParams hostParams = {0, 0};
hostParams.fn = callbackfunc;
hostParams.userData = A_h;
HIP_CHECK(hipGraphAddHostNode(&hostNode, graph,
nullptr,
0, &hostParams));
HIP_CHECK(hipGraphAddHostNode(&hostNode, graph, nullptr, 0, &hostParams));
hipHostNodeParams GethostParams;
SECTION("Passing nullptr to graph node") {
REQUIRE(hipGraphHostNodeGetParams(nullptr, &GethostParams)
== hipErrorInvalidValue);
HIP_CHECK_ERROR(hipGraphHostNodeGetParams(nullptr, &GethostParams), hipErrorInvalidValue);
}
SECTION("Passing nullptr to hostParams") {
REQUIRE(hipGraphHostNodeGetParams(hostNode, nullptr)
== hipErrorInvalidValue);
HIP_CHECK_ERROR(hipGraphHostNodeGetParams(hostNode, nullptr), hipErrorInvalidValue);
}
SECTION("Passing unintialized graphNode") {
hipGraphNode_t unint_graphnode{nullptr};
REQUIRE(hipGraphHostNodeGetParams(unint_graphnode, &GethostParams)
== hipErrorInvalidValue);
#if HT_NVIDIA // segfaults on AMD
SECTION("node is not a host node") {
hipGraphNode_t empty_node;
HIP_CHECK(hipGraphAddEmptyNode(&empty_node, graph, nullptr, 0));
HIP_CHECK_ERROR(hipGraphHostNodeGetParams(empty_node, &GethostParams), hipErrorInvalidValue);
}
#endif
HipTest::freeArrays<int>(A_d, nullptr, C_d, A_h, nullptr, C_h, false);
HIP_CHECK(hipGraphDestroy(graph));
}
/*
This testcase verifies hipGraphHostNodeGetParams API in cloned graph
This test case verifies hipGraphHostNodeGetParams API in cloned graph
Creates graph, Add graph nodes and clone the graph
Add HostNode to the cloned graph, update hostNode using hipGraphHostNodeSetParams,
then get the host node params using hipGraphHostNodeGetParams API and
compare it.
*/
TEST_CASE("Unit_hipGraphHostNodeGetParams_ClonedGraphwithHostNode") {
TEST_CASE("Unit_hipGraphHostNodeGetParams_ClonedGraphWithHostNode") {
constexpr size_t N = 1024;
constexpr size_t Nbytes = N * sizeof(int);
hipGraph_t graph;
hipGraphExec_t graphExec;
int *A_d{nullptr}, *C_d{nullptr};
int *A_h{nullptr}, *C_h{nullptr};
HipTest::initArrays<int>(&A_d, nullptr, &C_d,
&A_h, nullptr, &C_h, N, false);
HipTest::initArrays<int>(&A_d, nullptr, &C_d, &A_h, nullptr, &C_h, N, false);
HIP_CHECK(hipGraphCreate(&graph, 0));
hipGraphNode_t memcpyH2D_A, memcpyH2D_C,
memcpyD2H_AC;
hipGraphNode_t memcpyH2D_A, memcpyH2D_C, memcpyD2H_AC;
hipStream_t streamForGraph;
HIP_CHECK(hipStreamCreate(&streamForGraph));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_A, graph, nullptr,
0, A_d, A_h,
Nbytes, hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_C, graph, nullptr,
0, C_d, C_h,
Nbytes, hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_AC, graph, nullptr,
0, A_h, C_d,
Nbytes, hipMemcpyDeviceToHost));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_A,
&memcpyD2H_AC, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_C,
&memcpyD2H_AC, 1));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_A, graph, nullptr, 0, A_d, A_h, Nbytes,
hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_C, graph, nullptr, 0, C_d, C_h, Nbytes,
hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_AC, graph, nullptr, 0, A_h, C_d, Nbytes,
hipMemcpyDeviceToHost));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_A, &memcpyD2H_AC, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_C, &memcpyD2H_AC, 1));
hipGraph_t clonedgraph;
HIP_CHECK(hipGraphClone(&clonedgraph, graph));
@@ -136,17 +131,16 @@ TEST_CASE("Unit_hipGraphHostNodeGetParams_ClonedGraphwithHostNode") {
hipHostNodeParams hostParams = {0, 0};
hostParams.fn = callbackfunc;
hostParams.userData = A_h;
HIP_CHECK(hipGraphAddHostNode(&hostNode, clonedgraph,
nullptr,
0, &hostParams));
HIP_CHECK(hipGraphAddHostNode(&hostNode, clonedgraph, nullptr, 0, &hostParams));
hipHostNodeParams sethostParams = {0, 0};
sethostParams.fn = callbackfunc_setparams;
sethostParams.userData = C_h;
HIP_CHECK(hipGraphHostNodeSetParams(hostNode, &sethostParams));
hipHostNodeParams gethostParams;
HIP_CHECK(hipGraphHostNodeGetParams(hostNode, &gethostParams));
REQUIRE(memcmp(&sethostParams, &gethostParams, sizeof(hipHostNodeParams))
== 0);
REQUIRE(memcmp(&sethostParams, &gethostParams, sizeof(hipHostNodeParams)) == 0);
// Instantiate and launch the cloned graph
HIP_CHECK(hipGraphInstantiate(&graphExec, clonedgraph, nullptr, nullptr, 0));
HIP_CHECK(hipGraphLaunch(graphExec, streamForGraph));
@@ -155,10 +149,11 @@ TEST_CASE("Unit_hipGraphHostNodeGetParams_ClonedGraphwithHostNode") {
// Verify execution result
for (size_t i = 0; i < N; i++) {
if (C_h[i] != static_cast<int>(i * i)) {
INFO("Validation failed i " << i << "C_h[i] "<< C_h[i]);
INFO("Validation failed i " << i << "C_h[i] " << C_h[i]);
REQUIRE(false);
}
}
HIP_CHECK(hipGraphExecDestroy(graphExec));
HIP_CHECK(hipGraphDestroy(graph));
HIP_CHECK(hipGraphDestroy(clonedgraph));
@@ -167,7 +162,7 @@ TEST_CASE("Unit_hipGraphHostNodeGetParams_ClonedGraphwithHostNode") {
}
/*
This testcase verifies the following scenarios
This test case verifies the following scenarios
Create graph, Adds host node to the graph, updates it
with hipGraphHostNodeSetParams and gets the host node
params using hipGraphHostNodeGetParams API and validates
@@ -180,36 +175,28 @@ void hipGraphHostNodeGetParams_func(bool setparams) {
hipGraphExec_t graphExec;
int *A_d{nullptr}, *C_d{nullptr};
int *A_h{nullptr}, *C_h{nullptr};
HipTest::initArrays<int>(&A_d, nullptr, &C_d,
&A_h, nullptr, &C_h, N, false);
HipTest::initArrays<int>(&A_d, nullptr, &C_d, &A_h, nullptr, &C_h, N, false);
HIP_CHECK(hipGraphCreate(&graph, 0));
hipGraphNode_t memcpyH2D_A, memcpyD2H_AC, memcpyH2D_C;
hipStream_t streamForGraph;
HIP_CHECK(hipStreamCreate(&streamForGraph));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_A, graph, nullptr,
0, A_d, A_h,
Nbytes, hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_C, graph, nullptr,
0, C_d, C_h,
Nbytes, hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_AC, graph, nullptr,
0, A_h, C_d,
Nbytes, hipMemcpyDeviceToHost));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_A, graph, nullptr, 0, A_d, A_h, Nbytes,
hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_C, graph, nullptr, 0, C_d, C_h, Nbytes,
hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_AC, graph, nullptr, 0, A_h, C_d, Nbytes,
hipMemcpyDeviceToHost));
hipGraphNode_t hostNode;
hipHostNodeParams hostParams = {0, 0};
hostParams.fn = callbackfunc;
hostParams.userData = A_h;
HIP_CHECK(hipGraphAddHostNode(&hostNode, graph,
nullptr,
0, &hostParams));
HIP_CHECK(hipGraphAddHostNode(&hostNode, graph, nullptr, 0, &hostParams));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_A,
&memcpyD2H_AC, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_C,
&memcpyD2H_AC, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyD2H_AC,
&hostNode, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_A, &memcpyD2H_AC, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_C, &memcpyD2H_AC, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyD2H_AC, &hostNode, 1));
if (setparams) {
hipHostNodeParams sethostParams = {0, 0};
@@ -219,32 +206,30 @@ void hipGraphHostNodeGetParams_func(bool setparams) {
hipHostNodeParams gethostParams;
HIP_CHECK(hipGraphHostNodeGetParams(hostNode, &gethostParams));
REQUIRE(memcmp(&sethostParams, &gethostParams, sizeof(hipHostNodeParams))
== 0);
REQUIRE(memcmp(&sethostParams, &gethostParams, sizeof(hipHostNodeParams)) == 0);
} else {
hipHostNodeParams gethostParams;
HIP_CHECK(hipGraphHostNodeGetParams(hostNode, &gethostParams));
REQUIRE(memcmp(&hostParams, &gethostParams, sizeof(hipHostNodeParams))
== 0);
REQUIRE(memcmp(&hostParams, &gethostParams, sizeof(hipHostNodeParams)) == 0);
}
// Instantiate and launch the graph
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
HIP_CHECK(hipGraphLaunch(graphExec, streamForGraph));
HIP_CHECK(hipStreamSynchronize(streamForGraph));
// Verify execution result
if (setparams) {
for (size_t i = 0; i < N; i++) {
if (C_h[i] != static_cast<int>(i * i)) {
INFO("Validation failed i " << i << "C_h[i] "<< C_h[i]);
INFO("Validation failed i " << i << "C_h[i] " << C_h[i]);
REQUIRE(false);
}
}
} else {
for (size_t i = 0; i < N; i++) {
if (A_h[i] != static_cast<int>(i)) {
INFO("Validation failed i " << i << "C_h[i] "<< C_h[i]);
INFO("Validation failed i " << i << "C_h[i] " << C_h[i]);
REQUIRE(false);
}
}
@@ -255,21 +240,18 @@ void hipGraphHostNodeGetParams_func(bool setparams) {
HIP_CHECK(hipGraphDestroy(graph));
HIP_CHECK(hipStreamDestroy(streamForGraph));
}
/*
This testcase verifies hipGraphHostNodeGetParams API by
This test case verifies hipGraphHostNodeGetParams API by
adding host node to graph and gets the host params and
validates it
*/
TEST_CASE("Unit_hipGraphHostNodeGetParams_BasicFunc") {
hipGraphHostNodeGetParams_func(false);
}
TEST_CASE("Unit_hipGraphHostNodeGetParams_BasicFunc") { hipGraphHostNodeGetParams_func(false); }
/*
This testcase verifies hipGraphHostNodeGetParams API by
This test case verifies hipGraphHostNodeGetParams API by
adding host node to graph, updates host node params
using hipGraphHostNodeSetParams and gets the host params
validates it
*/
TEST_CASE("Unit_hipGraphHostNodeGetParams_SetParams") {
hipGraphHostNodeGetParams_func(true);
}
TEST_CASE("Unit_hipGraphHostNodeGetParams_SetParams") { hipGraphHostNodeGetParams_func(true); }
+57 -69
查看文件
@@ -6,24 +6,26 @@ 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
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY 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
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 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
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 of hipGraphHostNodeSetParams API:
Test Case Scenarios of hipGraphHostNodeSetParams API:
Functional:
1. Creates graph, Adds HostNode, update hostNode params using hipGraphHostNodeSetParams API
and validates the result
2. Create graph, Add Graphnodes and clones the graph. Add Hostnode to the cloned graph, update
2. Create graph, Add Graph nodes and clones the graph. Add Host node to the cloned graph, update
hostNode params using hipGraphHostNodeSetParams API and validate the result
Negative:
@@ -31,30 +33,30 @@ Negative:
1) Pass pGraphNode as nullptr and verify api doesn’t crash, returns error code.
2) Pass pNodeParams as nullptr and verify api doesn’t crash, returns error code.
3) Pass hipHostNodeParams::hipHostFn_t as nullptr and verify api doesn't crash, returns error code.
4) Pass unintialized host params
4) Pass uninitialized host params
*/
#include <hip_test_common.hh>
#include <hip_test_checkers.hh>
#include <hip_test_common.hh>
#define SIZE 1024
static void callbackfunc(void *A_h) {
int *A = reinterpret_cast<int *>(A_h);
static void callbackfunc(void* A_h) {
int* A = reinterpret_cast<int*>(A_h);
for (int i = 0; i < SIZE; i++) {
A[i] = i;
A[i] = i;
}
}
static void callbackfunc_setparams(void *B_h) {
int *B = reinterpret_cast<int *>(B_h);
static void callbackfunc_setparams(void* B_h) {
int* B = reinterpret_cast<int*>(B_h);
for (int i = 0; i < SIZE; i++) {
B[i] = i * i;
B[i] = i * i;
}
}
/*
This testcase verifies the negative scenarios of
This test case verifies the negative scenarios of
hipGraphHostNodeSetParams API
*/
TEST_CASE("Unit_hipGraphHostNodeSetParams_Negative") {
@@ -62,8 +64,7 @@ TEST_CASE("Unit_hipGraphHostNodeSetParams_Negative") {
hipGraph_t graph;
int *A_d{nullptr}, *C_d{nullptr};
int *A_h{nullptr}, *C_h{nullptr};
HipTest::initArrays<int>(&A_d, nullptr, &C_d,
&A_h, nullptr, &C_h, N, false);
HipTest::initArrays<int>(&A_d, nullptr, &C_d, &A_h, nullptr, &C_h, N, false);
HIP_CHECK(hipGraphCreate(&graph, 0));
@@ -71,65 +72,63 @@ TEST_CASE("Unit_hipGraphHostNodeSetParams_Negative") {
hipHostNodeParams hostParams;
hostParams.fn = callbackfunc;
hostParams.userData = A_h;
HIP_CHECK(hipGraphAddHostNode(&hostNode, graph,
nullptr,
0, &hostParams));
#if HT_NVIDIA
HIP_CHECK(hipGraphAddHostNode(&hostNode, graph, nullptr, 0, &hostParams));
SECTION("Passing nullptr to graph node") {
REQUIRE(hipGraphHostNodeSetParams(nullptr, &hostParams)
== hipErrorInvalidValue);
HIP_CHECK_ERROR(hipGraphHostNodeSetParams(nullptr, &hostParams), hipErrorInvalidValue);
}
SECTION("Passing nullptr to hostParams") {
REQUIRE(hipGraphHostNodeSetParams(hostNode, nullptr)
== hipErrorInvalidValue);
HIP_CHECK_ERROR(hipGraphHostNodeSetParams(hostNode, nullptr), hipErrorInvalidValue);
}
#endif
SECTION("Passing nullptr to host func") {
hostParams.fn = nullptr;
REQUIRE(hipGraphHostNodeSetParams(hostNode, &hostParams)
== hipErrorInvalidValue);
HIP_CHECK_ERROR(hipGraphHostNodeSetParams(hostNode, &hostParams), hipErrorInvalidValue);
}
SECTION("Passing unintialized hostParams") {
SECTION("Passing uninitialized hostParams") {
hipHostNodeParams unintParams = {0, 0};
REQUIRE(hipGraphHostNodeSetParams(hostNode, &unintParams)
== hipErrorInvalidValue);
HIP_CHECK_ERROR(hipGraphHostNodeSetParams(hostNode, &unintParams), hipErrorInvalidValue);
}
#if HT_NVIDIA // segfaults on AMD
SECTION("node is not a host node") {
hipGraphNode_t empty_node;
HIP_CHECK(hipGraphAddEmptyNode(&empty_node, graph, nullptr, 0));
HIP_CHECK_ERROR(hipGraphHostNodeSetParams(empty_node, &hostParams), hipErrorInvalidValue);
}
#endif
HipTest::freeArrays<int>(A_d, nullptr, C_d, A_h, nullptr, C_h, false);
HIP_CHECK(hipGraphDestroy(graph));
}
/*
This testcase verifies hipGraphHostNodeSetParams API in cloned graph
This test case verifies hipGraphHostNodeSetParams API in cloned graph
Creates graph, Add graph nodes and clone the graph
Add HostNode to the cloned graph,update the host params using
hipGraphHostNodeSetParams API and validates the result
*/
TEST_CASE("Unit_hipGraphHostNodeSetParams_ClonedGraphwithHostNode") {
TEST_CASE("Unit_hipGraphHostNodeSetParams_ClonedGraphWithHostNode") {
constexpr size_t N = 1024;
constexpr size_t Nbytes = N * sizeof(int);
hipGraph_t graph;
hipGraphExec_t graphExec;
int *A_d{nullptr}, *C_d{nullptr};
int *A_h{nullptr}, *C_h{nullptr};
HipTest::initArrays<int>(&A_d, nullptr, &C_d,
&A_h, nullptr, &C_h, N, false);
HipTest::initArrays<int>(&A_d, nullptr, &C_d, &A_h, nullptr, &C_h, N, false);
HIP_CHECK(hipGraphCreate(&graph, 0));
hipGraphNode_t memcpyH2D_C,
memcpyD2H_AC;
hipGraphNode_t memcpyH2D_C, memcpyD2H_AC;
hipStream_t streamForGraph;
HIP_CHECK(hipStreamCreate(&streamForGraph));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_C, graph, nullptr,
0, C_d, C_h,
Nbytes, hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_AC, graph, nullptr,
0, A_h, C_d,
Nbytes, hipMemcpyDeviceToHost));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_C, graph, nullptr, 0, C_d, C_h, Nbytes,
hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_AC, graph, nullptr, 0, A_h, C_d, Nbytes,
hipMemcpyDeviceToHost));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_C,
&memcpyD2H_AC, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_C, &memcpyD2H_AC, 1));
hipGraph_t clonedgraph;
HIP_CHECK(hipGraphClone(&clonedgraph, graph));
@@ -138,17 +137,13 @@ TEST_CASE("Unit_hipGraphHostNodeSetParams_ClonedGraphwithHostNode") {
hipHostNodeParams hostParams;
hostParams.fn = callbackfunc;
hostParams.userData = A_h;
HIP_CHECK(hipGraphAddHostNode(&hostNode, clonedgraph,
nullptr,
0, &hostParams));
HIP_CHECK(hipGraphAddHostNode(&hostNode, clonedgraph, nullptr, 0, &hostParams));
hipHostNodeParams sethostParams;
sethostParams.fn = callbackfunc_setparams;
sethostParams.userData = C_h;
HIP_CHECK(hipGraphHostNodeSetParams(hostNode, &sethostParams));
// Instantiate and launch the cloned graph
HIP_CHECK(hipGraphInstantiate(&graphExec, clonedgraph, nullptr, nullptr, 0));
HIP_CHECK(hipGraphLaunch(graphExec, streamForGraph));
@@ -157,7 +152,7 @@ TEST_CASE("Unit_hipGraphHostNodeSetParams_ClonedGraphwithHostNode") {
// Verify execution result
for (size_t i = 0; i < N; i++) {
if (C_h[i] != static_cast<int>(i * i)) {
INFO("Validation failed i " << i << "C_h[i] "<< C_h[i]);
INFO("Validation failed i " << i << "C_h[i] " << C_h[i]);
REQUIRE(false);
}
}
@@ -169,7 +164,7 @@ TEST_CASE("Unit_hipGraphHostNodeSetParams_ClonedGraphwithHostNode") {
}
/*
This testcase verifies the following scenario
This test case verifies the following scenario
Create graph, Adds host node to the graph,
updates the host params using hipGraphHostNodeSetParams API
and validates the result
@@ -181,31 +176,24 @@ TEST_CASE("Unit_hipGraphHostNodeSetParams_BasicFunc") {
hipGraphExec_t graphExec;
int *A_d{nullptr}, *C_d{nullptr};
int *A_h{nullptr}, *C_h{nullptr};
HipTest::initArrays<int>(&A_d, nullptr, &C_d,
&A_h, nullptr, &C_h, N, false);
HipTest::initArrays<int>(&A_d, nullptr, &C_d, &A_h, nullptr, &C_h, N, false);
HIP_CHECK(hipGraphCreate(&graph, 0));
hipGraphNode_t memcpyD2H_AC, memcpyH2D_C;
hipStream_t streamForGraph;
HIP_CHECK(hipStreamCreate(&streamForGraph));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_C, graph, nullptr,
0, C_d, C_h,
Nbytes, hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_AC, graph, nullptr,
0, A_h, C_d,
Nbytes, hipMemcpyDeviceToHost));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_C, graph, nullptr, 0, C_d, C_h, Nbytes,
hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_AC, graph, nullptr, 0, A_h, C_d, Nbytes,
hipMemcpyDeviceToHost));
hipGraphNode_t hostNode;
hipHostNodeParams hostParams;
hostParams.fn = callbackfunc;
hostParams.userData = A_h;
HIP_CHECK(hipGraphAddHostNode(&hostNode, graph,
nullptr,
0, &hostParams));
HIP_CHECK(hipGraphAddHostNode(&hostNode, graph, nullptr, 0, &hostParams));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_C,
&memcpyD2H_AC, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyD2H_AC,
&hostNode, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_C, &memcpyD2H_AC, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyD2H_AC, &hostNode, 1));
hipHostNodeParams sethostParams;
sethostParams.fn = callbackfunc_setparams;
@@ -220,7 +208,7 @@ TEST_CASE("Unit_hipGraphHostNodeSetParams_BasicFunc") {
// Verify execution result
for (size_t i = 0; i < N; i++) {
if (C_h[i] != static_cast<int>(i * i)) {
INFO("Validation failed i " << i << "C_h[i] "<< C_h[i]);
INFO("Validation failed i " << i << "C_h[i] " << C_h[i]);
REQUIRE(false);
}
}
+370
查看文件
@@ -0,0 +1,370 @@
/*
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_common.hh>
#include <hip_test_checkers.hh>
#include <hip_test_kernels.hh>
/**
* @addtogroup hipGraphKernelNodeSetAttribute hipGraphKernelNodeSetAttribute
* @{
* @ingroup GraphTest
* `hipGraphKernelNodeSetAttribute(hipGraphNode_t hNode,
* hipKernelNodeAttrID attr, const hipKernelNodeAttrValue* value )` -
* Sets node attribute.
*/
/**
* Test Description
* ------------------------
*  - Functional Test for API - hipGraphKernelNodeSetAttribute
* 1) Check hipGraphKernelNodeSetAttribute for AccessPolicyWindow attributes
* 2) Check hipGraphKernelNodeSetAttribute for cooperative attributes
* 3) Check hipGraphKernelNodeSetAttribute for window cooperative attributes
* Test source
* ------------------------
*  - unit/graph/hipGraphKernelNodeGetAttribute.cc
* Test requirements
* ------------------------
*  - HIP_VERSION >= 5.6
*/
static bool validateKernelNodeAttrValue(hipKernelNodeAttrValue in,
hipKernelNodeAttrValue out) {
if ((in.accessPolicyWindow.base_ptr != out.accessPolicyWindow.base_ptr) ||
(in.accessPolicyWindow.hitProp != out.accessPolicyWindow.hitProp) ||
(in.accessPolicyWindow.hitRatio != out.accessPolicyWindow.hitRatio) ||
(in.accessPolicyWindow.missProp != out.accessPolicyWindow.missProp) ||
(in.accessPolicyWindow.num_bytes != out.accessPolicyWindow.num_bytes) ||
(in.cooperative != out.cooperative)) {
return false;
}
return true;
}
TEST_CASE("Unit_hipGraphKernelNodeSetAttribute_Functional") {
constexpr size_t N = 1024;
constexpr size_t Nbytes = N * sizeof(int);
constexpr auto blocksPerCU = 6; // to hide latency
constexpr auto threadsPerBlock = 256;
hipGraph_t graph;
hipGraphExec_t graphExec;
hipGraphNode_t memcpy_A, memcpy_B, memcpy_C, kernel_vecAdd;
hipKernelNodeParams kNodeParams{};
hipStream_t stream;
int *A_d, *B_d, *C_d;
int *A_h, *B_h, *C_h;
size_t NElem{N};
HipTest::initArrays(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, N, false);
unsigned blocks = HipTest::setNumBlocks(blocksPerCU, threadsPerBlock, N);
HIP_CHECK(hipGraphCreate(&graph, 0));
HIP_CHECK(hipStreamCreate(&stream));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpy_A, graph, nullptr, 0, A_d, A_h,
Nbytes, hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpy_B, graph, nullptr, 0, B_d, B_h,
Nbytes, hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpy_C, graph, nullptr, 0, C_h, C_d,
Nbytes, hipMemcpyDeviceToHost));
void* kernelArgs[] = {&A_d, &B_d, &C_d, reinterpret_cast<void *>(&NElem)};
kNodeParams.func = reinterpret_cast<void *>(HipTest::vectorADD<int>);
kNodeParams.gridDim = dim3(blocks);
kNodeParams.blockDim = dim3(threadsPerBlock);
kNodeParams.sharedMemBytes = 0;
kNodeParams.kernelParams = reinterpret_cast<void**>(kernelArgs);
kNodeParams.extra = nullptr;
HIP_CHECK(hipGraphAddKernelNode(&kernel_vecAdd, graph, nullptr, 0,
&kNodeParams));
// Create dependencies
HIP_CHECK(hipGraphAddDependencies(graph, &memcpy_A, &kernel_vecAdd, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpy_B, &kernel_vecAdd, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &kernel_vecAdd, &memcpy_C, 1));
hipKernelNodeAttrValue value_in, value_out;
SECTION("Check hipGraphKernelNodeSetAttribute for AccessPolicyWindow") {
memset(&value_in, 0, sizeof(hipKernelNodeAttrValue));
memset(&value_out, 0, sizeof(hipKernelNodeAttrValue));
HIP_CHECK(hipGraphKernelNodeGetAttribute(kernel_vecAdd,
hipKernelNodeAttributeAccessPolicyWindow, &value_in));
value_in.accessPolicyWindow.hitRatio = 0.8;
value_in.accessPolicyWindow.hitProp = hipAccessPropertyPersisting;
value_in.accessPolicyWindow.missProp = hipAccessPropertyStreaming;
HIP_CHECK(hipGraphKernelNodeSetAttribute(kernel_vecAdd,
hipKernelNodeAttributeAccessPolicyWindow, &value_in));
HIP_CHECK(hipGraphKernelNodeGetAttribute(kernel_vecAdd,
hipKernelNodeAttributeAccessPolicyWindow, &value_out));
REQUIRE(true == validateKernelNodeAttrValue(value_in, value_out));
}
SECTION("Check hipGraphKernelNodeSetAttribute for cooperative") {
memset(&value_in, 0, sizeof(hipKernelNodeAttrValue));
memset(&value_out, 0, sizeof(hipKernelNodeAttrValue));
HIP_CHECK(hipGraphKernelNodeGetAttribute(kernel_vecAdd,
hipKernelNodeAttributeAccessPolicyWindow, &value_in));
value_in.cooperative = 2;
HIP_CHECK(hipGraphKernelNodeSetAttribute(kernel_vecAdd,
hipKernelNodeAttributeAccessPolicyWindow, &value_in));
HIP_CHECK(hipGraphKernelNodeGetAttribute(kernel_vecAdd,
hipKernelNodeAttributeAccessPolicyWindow, &value_out));
REQUIRE(true == validateKernelNodeAttrValue(value_in, value_out));
}
SECTION("Check hipGraphKernelNodeSetAttribute for window and cooperative") {
memset(&value_in, 0, sizeof(hipKernelNodeAttrValue));
memset(&value_out, 0, sizeof(hipKernelNodeAttrValue));
HIP_CHECK(hipGraphKernelNodeGetAttribute(kernel_vecAdd,
hipKernelNodeAttributeAccessPolicyWindow, &value_in));
value_in.cooperative = 8;
value_in.accessPolicyWindow.hitRatio = 0.1;
value_in.accessPolicyWindow.hitProp = hipAccessPropertyPersisting;
value_in.accessPolicyWindow.missProp = hipAccessPropertyNormal;
HIP_CHECK(hipGraphKernelNodeSetAttribute(kernel_vecAdd,
hipKernelNodeAttributeAccessPolicyWindow, &value_in));
HIP_CHECK(hipGraphKernelNodeGetAttribute(kernel_vecAdd,
hipKernelNodeAttributeAccessPolicyWindow, &value_out));
REQUIRE(true == validateKernelNodeAttrValue(value_in, value_out));
}
// Instantiate and launch the graph
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, NULL, NULL, 0));
HIP_CHECK(hipGraphLaunch(graphExec, stream));
HIP_CHECK(hipStreamSynchronize(stream));
// Verify graph execution result
HipTest::checkVectorADD<int>(A_h, B_h, C_h, N);
HipTest::freeArrays(A_d, B_d, C_d, A_h, B_h, C_h, false);
HIP_CHECK(hipGraphExecDestroy(graphExec));
HIP_CHECK(hipGraphDestroy(graph));
HIP_CHECK(hipStreamDestroy(stream));
}
/**
* Test Description
* ------------------------
*  - Negative/argument Test for API - hipGraphKernelNodeSetAttribute
* 1) Pass kernel node as nullptr for Set attribute api and verify
* 2) Pass KernelNodeAttrID as invalid value for Set attribute api and verify
* 3) Pass KernelNodeAttrID as INT_MAX value for Get attribute api and verify
* 4) Pass KernelNodeAttrValue as nullptr for Set attribute api and verify
* 5) Pass KernelNodeAttrID as hipKernelNodeAttributeAccessPolicyWindow
* and pass value missProp as hipAccessPropertyPersisting
* 6) Pass KernelNodeAttrID as hipKernelNodeAttributeAccessPolicyWindow
* and pass value hitProp as hipAccessPropertyPersisting
* 7) Pass KernelNodeAttrID as hipKernelNodeAttributeAccessPolicyWindow
* and pass value accessPolicyWindow.hitRatio as 1.4
* 8) Pass KernelNodeAttrID as hipKernelNodeAttributeAccessPolicyWindow
* and pass value accessPolicyWindow.hitRatio as 0
* 9) Pass KernelNodeAttrID as hipKernelNodeAttributeAccessPolicyWindow
* and pass value accessPolicyWindow.hitRatio as 1
* 10) Pass KernelNodeAttrID as hipKernelNodeAttributeAccessPolicyWindow
* and pass value accessPolicyWindow.hitRatio as -1.8
* 11) Pass KernelNodeAttrID as hipKernelNodeAttributeAccessPolicyWindow
* and pass value accessPolicyWindow.hitRatio as -0.6
* 12) Pass KernelNodeAttrID as hipKernelNodeAttributeAccessPolicyWindow
* and pass accessPolicyWindow.num_bytes as 1024 & hitRatio as 0.6
* 13) Pass KernelNodeAttrID as hipKernelNodeAttributeAccessPolicyWindow"
* and pass accessPolicyWindow.num_bytes as 1 GB & hitRatio as -0.6
* 14) Pass KernelNodeAttrID as hipKernelNodeAttributeAccessPolicyWindow
* and pass value accessPolicyWindow.num_bytes as 1 MB
* 15) Pass KernelNodeAttrID as hipKernelNodeAttributeAccessPolicyWindow
* and pass value base_ptr as nullptr
* Test source
* ------------------------
*  - unit/graph/hipGraphKernelNodeSetAttribute.cc
* Test requirements
* ------------------------
*  - HIP_VERSION >= 5.6
*/
TEST_CASE("Unit_hipGraphKernelNodeSetAttribute_Negative") {
constexpr size_t N = 1024;
constexpr size_t Nbytes = N * sizeof(int);
constexpr auto blocksPerCU = 6; // to hide latency
constexpr auto threadsPerBlock = 256;
hipGraph_t graph;
hipGraphNode_t memcpy_A, memcpy_B, memcpy_C, kernel_vecAdd;
hipKernelNodeParams kNodeParams{};
hipStream_t stream;
int *A_d, *B_d, *C_d;
int *A_h, *B_h, *C_h;
size_t NElem{N};
hipError_t ret;
HipTest::initArrays(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, N, false);
unsigned blocks = HipTest::setNumBlocks(blocksPerCU, threadsPerBlock, N);
HIP_CHECK(hipGraphCreate(&graph, 0));
HIP_CHECK(hipStreamCreate(&stream));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpy_A, graph, nullptr, 0, A_d, A_h,
Nbytes, hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpy_B, graph, nullptr, 0, B_d, B_h,
Nbytes, hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpy_C, graph, nullptr, 0, C_h, C_d,
Nbytes, hipMemcpyDeviceToHost));
void* kernelArgs[] = {&A_d, &B_d, &C_d, reinterpret_cast<void *>(&NElem)};
kNodeParams.func = reinterpret_cast<void *>(HipTest::vectorADD<int>);
kNodeParams.gridDim = dim3(blocks);
kNodeParams.blockDim = dim3(threadsPerBlock);
kNodeParams.sharedMemBytes = 0;
kNodeParams.kernelParams = reinterpret_cast<void**>(kernelArgs);
kNodeParams.extra = nullptr;
HIP_CHECK(hipGraphAddKernelNode(&kernel_vecAdd, graph, nullptr, 0,
&kNodeParams));
hipKernelNodeAttrValue value_in, value_out;
memset(&value_in, 0, sizeof(hipKernelNodeAttrValue));
memset(&value_out, 0, sizeof(hipKernelNodeAttrValue));
HIP_CHECK(hipGraphKernelNodeGetAttribute(kernel_vecAdd,
hipKernelNodeAttributeAccessPolicyWindow, &value_in));
memcpy(&value_out, &value_in, sizeof(hipKernelNodeAttrValue));
SECTION("Pass kernel node as nullptr for Set attribute api") {
ret = hipGraphKernelNodeSetAttribute(nullptr,
hipKernelNodeAttributeAccessPolicyWindow, &value_in);
REQUIRE(hipErrorInvalidValue == ret);
}
SECTION("Pass KernelNodeAttrID as invalid value for Set attribute api") {
ret = hipGraphKernelNodeSetAttribute(kernel_vecAdd,
hipKernelNodeAttrID(-1), &value_in);
REQUIRE(hipErrorInvalidValue == ret);
}
SECTION("Pass KernelNodeAttrID as INT_MAX value for Set attribute api") {
ret = hipGraphKernelNodeSetAttribute(kernel_vecAdd,
hipKernelNodeAttrID(INT_MAX), &value_in);
REQUIRE(hipErrorInvalidValue == ret);
}
#if HT_AMD // getting SIGSEGV error in Cuda Setup
SECTION("Pass KernelNodeAttrValue as nullptr for Set attribute api") {
ret = hipGraphKernelNodeSetAttribute(kernel_vecAdd,
hipKernelNodeAttributeAccessPolicyWindow, nullptr);
REQUIRE(hipErrorInvalidValue == ret);
}
#endif
SECTION("Pass KernelNodeAttrID as hipKernelNodeAttributeAccessPolicyWindow"
" and pass value missProp as hipAccessPropertyPersisting") {
memcpy(&value_in, &value_out, sizeof(hipKernelNodeAttrValue));
value_in.accessPolicyWindow.missProp = hipAccessPropertyPersisting;
ret = hipGraphKernelNodeSetAttribute(kernel_vecAdd,
hipKernelNodeAttributeAccessPolicyWindow, &value_in);
REQUIRE(hipErrorInvalidValue == ret);
}
SECTION("Pass KernelNodeAttrID as hipKernelNodeAttributeAccessPolicyWindow"
" and pass value hitProp as hipAccessPropertyPersisting") {
memcpy(&value_in, &value_out, sizeof(hipKernelNodeAttrValue));
value_in.accessPolicyWindow.hitProp = hipAccessPropertyPersisting;
ret = hipGraphKernelNodeSetAttribute(kernel_vecAdd,
hipKernelNodeAttributeAccessPolicyWindow, &value_in);
REQUIRE(hipSuccess == ret);
}
SECTION("Pass KernelNodeAttrID as hipKernelNodeAttributeAccessPolicyWindow"
" and pass value accessPolicyWindow.hitRatio as 1.4") {
memcpy(&value_in, &value_out, sizeof(hipKernelNodeAttrValue));
value_in.accessPolicyWindow.hitRatio = 1.4;
ret = hipGraphKernelNodeSetAttribute(kernel_vecAdd,
hipKernelNodeAttributeAccessPolicyWindow, &value_in);
REQUIRE(hipErrorInvalidValue == ret);
}
SECTION("Pass KernelNodeAttrID as hipKernelNodeAttributeAccessPolicyWindow"
" and pass value accessPolicyWindow.hitRatio as 0") {
memcpy(&value_in, &value_out, sizeof(hipKernelNodeAttrValue));
value_in.accessPolicyWindow.hitRatio = 0;
ret = hipGraphKernelNodeSetAttribute(kernel_vecAdd,
hipKernelNodeAttributeAccessPolicyWindow, &value_in);
REQUIRE(hipSuccess == ret);
}
SECTION("Pass KernelNodeAttrID as hipKernelNodeAttributeAccessPolicyWindow"
" and pass value accessPolicyWindow.hitRatio as 1") {
memcpy(&value_in, &value_out, sizeof(hipKernelNodeAttrValue));
value_in.accessPolicyWindow.hitRatio = 1;
ret = hipGraphKernelNodeSetAttribute(kernel_vecAdd,
hipKernelNodeAttributeAccessPolicyWindow, &value_in);
REQUIRE(hipSuccess == ret);
}
SECTION("Pass KernelNodeAttrID as hipKernelNodeAttributeAccessPolicyWindow"
" and pass value accessPolicyWindow.hitRatio as -1.8") {
memcpy(&value_in, &value_out, sizeof(hipKernelNodeAttrValue));
value_in.accessPolicyWindow.hitRatio = -1.8;
ret = hipGraphKernelNodeSetAttribute(kernel_vecAdd,
hipKernelNodeAttributeAccessPolicyWindow, &value_in);
REQUIRE(hipErrorInvalidValue == ret);
}
SECTION("Pass KernelNodeAttrID as hipKernelNodeAttributeAccessPolicyWindow"
" and pass value accessPolicyWindow.hitRatio as -0.6") {
memcpy(&value_in, &value_out, sizeof(hipKernelNodeAttrValue));
value_in.accessPolicyWindow.hitRatio = -0.6;
ret = hipGraphKernelNodeSetAttribute(kernel_vecAdd,
hipKernelNodeAttributeAccessPolicyWindow, &value_in);
REQUIRE(hipErrorInvalidValue == ret);
}
SECTION("Pass KernelNodeAttrID as hipKernelNodeAttributeAccessPolicyWindow"
" & pass accessPolicyWindow.num_bytes as 1024 & hitRatio as 0.6") {
memcpy(&value_in, &value_out, sizeof(hipKernelNodeAttrValue));
value_in.accessPolicyWindow.num_bytes = 1024;
value_in.accessPolicyWindow.hitRatio = 0.6;
ret = hipGraphKernelNodeSetAttribute(kernel_vecAdd,
hipKernelNodeAttributeAccessPolicyWindow, &value_in);
REQUIRE(hipErrorInvalidValue == ret);
}
SECTION("Pass KernelNodeAttrID as hipKernelNodeAttributeAccessPolicyWindow"
" & pass accessPolicyWindow.num_bytes as 1 GB & hitRatio as -0.6") {
memcpy(&value_in, &value_out, sizeof(hipKernelNodeAttrValue));
value_in.accessPolicyWindow.num_bytes = 1024 * 1024 * 1024;
value_in.accessPolicyWindow.hitRatio = -0.6;
ret = hipGraphKernelNodeSetAttribute(kernel_vecAdd,
hipKernelNodeAttributeAccessPolicyWindow, &value_in);
REQUIRE(hipErrorInvalidValue == ret);
}
SECTION("Pass KernelNodeAttrID as hipKernelNodeAttributeAccessPolicyWindow"
" and pass value accessPolicyWindow.num_bytes as 1 MB") {
memcpy(&value_in, &value_out, sizeof(hipKernelNodeAttrValue));
value_in.accessPolicyWindow.num_bytes = 1024 * 1024;
ret = hipGraphKernelNodeSetAttribute(kernel_vecAdd,
hipKernelNodeAttributeAccessPolicyWindow, &value_in);
REQUIRE(hipErrorInvalidValue == ret);
}
SECTION("Pass KernelNodeAttrID as hipKernelNodeAttributeAccessPolicyWindow"
" and pass value base_ptr as nullptr") {
memcpy(&value_in, &value_out, sizeof(hipKernelNodeAttrValue));
value_in.accessPolicyWindow.base_ptr = nullptr;
ret = hipGraphKernelNodeSetAttribute(kernel_vecAdd,
hipKernelNodeAttributeAccessPolicyWindow, &value_in);
REQUIRE(hipSuccess == ret);
}
HipTest::freeArrays(A_d, B_d, C_d, A_h, B_h, C_h, false);
HIP_CHECK(hipGraphDestroy(graph));
HIP_CHECK(hipStreamDestroy(stream));
}
+1 -3
查看文件
@@ -171,9 +171,7 @@ static __global__ void ker_vec_sub(int* A, int* B) {
A[i] = A[i] - B[i];
}
/**
Internal class for creating nested graphs.
*/
// Internal class for creating nested graphs.
class GraphKernelNodeGetSetParam {
const int N = 1024;
size_t Nbytes;
+3 -3
查看文件
@@ -23,8 +23,8 @@ THE SOFTWARE.
#include "user_object_common.hh"
/**
* Functional Test for API - hipUserObjectCreate
/*
Functional Test for API - hipUserObjectCreate
1) Call hipUserObjectCreate once and release it by calling hipUserObjectRelease
2) Call hipUserObjectCreate refCount as X and release it by calling
hipUserObjectRelease with same refCount.
@@ -33,7 +33,7 @@ THE SOFTWARE.
4) Call hipUserObjectCreate with refCount as X, retain it by calling
hipUserObjectRetain with count as Y and release it by calling
hipUserObjectRelease with count as X+Y.
*/
*/
/* 1) Call hipUserObjectCreate once and release it by
calling hipUserObjectRelease */
+4 -7
查看文件
@@ -29,7 +29,9 @@ set(TEST_SRC
hipMemcpy2DToArrayAsync.cc
hipMemcpy2DToArrayAsync_old.cc
hipMemcpy3D.cc
hipMemcpy3D_old.cc
hipMemcpy3DAsync.cc
hipMemcpy3DAsync_old.cc
hipMemcpyParam2D.cc
hipMemcpyParam2DAsync.cc
hipMemcpy2D.cc
@@ -90,7 +92,9 @@ set(TEST_SRC
hipArrayCreate.cc
hipArray3DCreate.cc
hipDrvMemcpy3D.cc
hipDrvMemcpy3D_old.cc
hipDrvMemcpy3DAsync.cc
hipDrvMemcpy3DAsync_old.cc
hipPointerGetAttribute.cc
hipDrvPtrGetAttributes.cc
hipMemPrefetchAsync.cc
@@ -120,13 +124,6 @@ else()
set(TEST_SRC ${TEST_SRC} hipGetSymbolSizeAddress.cc)
endif()
# skipped due to os related code in tests need to work on them when all the
# tests are enabled
if(UNIX)
set(TEST_SRC ${TEST_SRC} hipHmmOvrSubscriptionTst.cc
hipMemoryAllocateCoherent.cc)
endif()
hip_add_exe_to_target(NAME MemoryTest
TEST_SRC ${TEST_SRC}
TEST_TARGET_NAME build_tests COMMON_SHARED_SRC ${COMMON_SHARED_SRC})
+183 -529
查看文件
@@ -1,13 +1,16 @@
/*
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 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
@@ -16,558 +19,209 @@ 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 Scenarios
* 1. Verifying hipDrvMemcpy3D API for H2A,A2A,A2H scenarios
* 2. Verifying hipDrvMemcpy3D API for H2D,D2D,D2H scenarios
* 3. Verifying Negative Scenarios
* 4. Verifying Extent validation scenarios by passing 0
* 5. Verifying hipDrvMemcpy3D API by allocating Memory in
* one GPU and trigger hipDrvMemcpy3D from peer GPU for
* H2D,D2D,D2H scenarios
* 6. Verifying hipDrvMemcpy3D API by allocating Memory in
* one GPU and trigger hipDrvMemcpy3D from peer GPU for
* H2A,A2A,A2H scenarios
*
* Scenarios 3 is temporarily suspended on AMD
* Scenario 5&6 are not supported in CUDA platform
*/
#include "hip_test_common.hh"
#include "hip_test_checkers.hh"
#include <memcpy1d_tests_common.hh>
#include <memcpy3d_tests_common.hh>
template<typename T>
class DrvMemcpy3D {
int width, height, depth;
unsigned int size;
hipArray_Format formatKind;
hiparray arr, arr1;
size_t pitch_D, pitch_E;
HIP_MEMCPY3D myparms;
hipDeviceptr_t D_m, E_m;
T* hData{nullptr};
public:
DrvMemcpy3D(int l_width, int l_height, int l_depth,
hipArray_Format l_format);
DrvMemcpy3D() = delete;
void AllocateMemory();
void SetDefaultData();
void HostArray_DrvMemcpy3D(bool device_context_change = false);
void HostDevice_DrvMemcpy3D(bool device_context_change = false);
void Extent_Validation();
void NegativeTests();
void DeAllocateMemory();
};
#include <hip_test_common.hh>
#include <hip/hip_runtime_api.h>
#include <resource_guards.hh>
#include <utils.hh>
/* Intializes class variables */
template <typename T>
DrvMemcpy3D<T>::DrvMemcpy3D(int l_width, int l_height, int l_depth,
hipArray_Format l_format) {
width = l_width;
height = l_height;
depth = l_depth;
formatKind = l_format;
}
TEST_CASE("Unit_hipDrvMemcpy3D_Positive_Basic") {
constexpr bool async = false;
/* Allocating Memory */
template <typename T>
void DrvMemcpy3D<T>::AllocateMemory() {
size = width * height * depth * sizeof(T);
hData = reinterpret_cast<T*>(malloc(size));
memset(hData, 0, size);
for (int i = 0; i < depth; i++) {
for (int j = 0; j < height; j++) {
for (int k = 0; k < width; k++) {
hData[i*width*height + j*width +k] = i*width*height + j*width + k;
}
#if HT_NVIDIA // Disabled on AMD due to defect - EXSWHTEC-236
SECTION("Device to Host") { Memcpy3DDeviceToHostShell<async>(DrvMemcpy3DWrapper<>); }
#endif
SECTION("Device to Device") {
SECTION("Peer access disabled") {
Memcpy3DDeviceToDeviceShell<async, false>(DrvMemcpy3DWrapper<>);
}
SECTION("Peer access enabled") {
Memcpy3DDeviceToDeviceShell<async, true>(DrvMemcpy3DWrapper<>);
}
}
HIP_CHECK(hipMallocPitch(reinterpret_cast<void**>(&D_m),
&pitch_D, width*sizeof(T), height));
HIP_CHECK(hipMallocPitch(reinterpret_cast<void**>(&E_m),
&pitch_E, width*sizeof(T), height));
HIP_ARRAY3D_DESCRIPTOR *desc;
desc = reinterpret_cast<HIP_ARRAY3D_DESCRIPTOR*>
(malloc(sizeof(HIP_ARRAY3D_DESCRIPTOR)));
desc->Format = formatKind;
desc->NumChannels = 1;
desc->Width = width;
desc->Height = height;
desc->Depth = depth;
desc->Flags = hipArrayDefault;
HIP_CHECK(hipArray3DCreate(&arr, desc));
HIP_CHECK(hipArray3DCreate(&arr1, desc));
SECTION("Host to Device") { Memcpy3DHostToDeviceShell<async>(DrvMemcpy3DWrapper<>); }
#if HT_NVIDIA // Disabled on AMD due to defect - EXSWHTEC-236
SECTION("Host to Host") { Memcpy3DHostToHostShell<async>(DrvMemcpy3DWrapper<>); }
#endif
}
/* Setting the default data */
template <typename T>
void DrvMemcpy3D<T>::SetDefaultData() {
memset(&myparms, 0x0, sizeof(HIP_MEMCPY3D));
myparms.srcXInBytes = 0;
myparms.srcY = 0;
myparms.srcZ = 0;
myparms.srcLOD = 0;
myparms.dstXInBytes = 0;
myparms.dstY = 0;
myparms.dstZ = 0;
myparms.dstLOD = 0;
myparms.WidthInBytes = width*sizeof(T);
myparms.Height = height;
myparms.Depth = depth;
TEST_CASE("Unit_hipDrvMemcpy3D_Positive_Synchronization_Behavior") {
HIP_CHECK(hipDeviceSynchronize());
SECTION("Host to Device") { Memcpy3DHtoDSyncBehavior(DrvMemcpy3DWrapper<>, true); }
SECTION("Device to Pageable Host") {
Memcpy3DDtoHPageableSyncBehavior(DrvMemcpy3DWrapper<>, true);
}
#if HT_NVIDIA // Disabled on AMD due to defect - EXSWHTEC-236
SECTION("Device to Pinned Host") { Memcpy3DDtoHPinnedSyncBehavior(DrvMemcpy3DWrapper<>, true); }
#endif
SECTION("Device to Device") {
#if HT_NVIDIA
Memcpy3DDtoDSyncBehavior(DrvMemcpy3DWrapper<>, false);
#else
Memcpy3DDtoDSyncBehavior(DrvMemcpy3DWrapper<>, true);
#endif
}
#if HT_NVIDIA // Disabled on AMD due to defect - EXSWHTEC-232
SECTION("Host to Host") { Memcpy3DHtoHSyncBehavior(DrvMemcpy3DWrapper<>, true); }
#endif
}
/*
This function verifies the negative scenarios of
hipDrvMemcpy3D API
*/
template <typename T>
void DrvMemcpy3D<T>::NegativeTests() {
HIP_CHECK(hipSetDevice(0));
AllocateMemory();
SetDefaultData();
int deviceId;
HIP_CHECK(hipGetDevice(&deviceId));
unsigned int MaxPitch;
HIP_CHECK(hipDeviceGetAttribute(reinterpret_cast<int *>(&MaxPitch),
hipDeviceAttributeMaxPitch, deviceId));
myparms.srcHost = hData;
myparms.dstArray = arr;
myparms.srcPitch = width * sizeof(T);
myparms.srcHeight = height;
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_HOST;
myparms.dstMemoryType = CU_MEMORYTYPE_ARRAY;
#else
myparms.srcMemoryType = hipMemoryTypeHost;
myparms.dstMemoryType = hipMemoryTypeArray;
#endif
SECTION("Passing nullptr to Source Host") {
myparms.srcHost = nullptr;
REQUIRE(hipDrvMemcpy3D(&myparms) != hipSuccess);
}
SECTION("Passing both dst host and device") {
myparms.dstHost = hData;
myparms.dstArray = nullptr;
myparms.dstDevice = D_m;
myparms.WidthInBytes = pitch_D;
#if HT_NVIDIA
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
REQUIRE(hipDrvMemcpy3D(&myparms) != hipSuccess);
}
SECTION("Passing max value to WidthInBytes") {
myparms.WidthInBytes = std::numeric_limits<int>::max();
myparms.Height = std::numeric_limits<int>::max();
myparms.Depth = std::numeric_limits<int>::max();
REQUIRE(hipDrvMemcpy3D(&myparms) != hipSuccess);
}
SECTION("Passing width > max width size") {
myparms.WidthInBytes = width*sizeof(T) + 1;
REQUIRE(hipDrvMemcpy3D(&myparms) != hipSuccess);
}
SECTION("Passing height > max height size") {
myparms.Height = height + 1;
REQUIRE(hipDrvMemcpy3D(&myparms) != hipSuccess);
}
SECTION("Passing depth > max depth size") {
myparms.Depth = depth + 1;
REQUIRE(hipDrvMemcpy3D(&myparms) != hipSuccess);
}
SECTION("widthinbytes + srcXinBytes is out of bound") {
myparms.srcXInBytes = 1;
myparms.dstArray = nullptr;
myparms.dstDevice = hipDeviceptr_t(D_m);
myparms.dstPitch = pitch_D;
myparms.dstHeight = height;
#if HT_NVIDIA
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
REQUIRE(hipDrvMemcpy3D(&myparms) != hipSuccess);
}
SECTION("widthinbytes + dstXinBytes is out of bound") {
myparms.dstXInBytes = pitch_D;
myparms.dstArray = nullptr;
myparms.dstDevice = hipDeviceptr_t(D_m);
myparms.dstPitch = pitch_D;
myparms.dstHeight = height;
#if HT_NVIDIA
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
REQUIRE(hipDrvMemcpy3D(&myparms) != hipSuccess);
}
SECTION("srcY + height is out of bound") {
myparms.srcY = 1;
myparms.dstArray = nullptr;
myparms.dstDevice = hipDeviceptr_t(D_m);
myparms.dstPitch = pitch_D;
myparms.dstHeight = height;
#if HT_NVIDIA
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
REQUIRE(hipDrvMemcpy3D(&myparms) != hipSuccess);
}
SECTION("dstY + height out of bounds") {
myparms.dstY = 1;
myparms.dstArray = nullptr;
myparms.dstDevice = hipDeviceptr_t(D_m);
myparms.dstPitch = pitch_D;
myparms.dstHeight = height;
#if HT_NVIDIA
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
REQUIRE(hipDrvMemcpy3D(&myparms) != hipSuccess);
}
SECTION("src pitch greater than Max allowed pitch") {
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_DEVICE;
myparms.dstMemoryType = CU_MEMORYTYPE_HOST;
#else
myparms.srcMemoryType = hipMemoryTypeDevice;
myparms.dstMemoryType = hipMemoryTypeHost;
#endif
myparms.srcDevice = D_m;
myparms.srcHost = nullptr;
myparms.srcPitch = MaxPitch;
myparms.srcHeight = height;
myparms.dstHost = hData;
myparms.dstArray = nullptr;
myparms.dstPitch = width*sizeof(T);
myparms.dstHeight = height;
REQUIRE(hipDrvMemcpy3D(&myparms) != hipSuccess);
}
SECTION("dst pitch greater than Max allowed pitch") {
myparms.dstDevice = hipDeviceptr_t(D_m);
myparms.dstArray = nullptr;
myparms.dstPitch = MaxPitch+1;
myparms.dstHeight = height;
#if HT_NVIDIA
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
REQUIRE(hipDrvMemcpy3D(&myparms) != hipSuccess);
}
SECTION("Nullptr to src/dst device") {
myparms.dstDevice = hipDeviceptr_t(nullptr);
myparms.dstArray = nullptr;
myparms.dstPitch = pitch_D;
myparms.dstHeight = height;
#if HT_NVIDIA
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
REQUIRE(hipDrvMemcpy3D(&myparms) != hipSuccess);
}
SECTION("Nullptr to src/dst array") {
myparms.dstArray = nullptr;
REQUIRE(hipDrvMemcpy3D(&myparms) != hipSuccess);
}
SECTION("Nullptr to hipDrvMemcpy3D") {
REQUIRE(hipDrvMemcpy3D(nullptr) != hipSuccess);
}
DeAllocateMemory();
TEST_CASE("Unit_hipDrvMemcpy3D_Positive_Parameters") {
constexpr bool async = false;
Memcpy3DZeroWidthHeightDepth<async>(DrvMemcpy3DWrapper<async>);
}
/*
This function verifies the Extent validation scenarios of
hipDrvMemcpy3D API
*/
template <typename T>
void DrvMemcpy3D<T>::Extent_Validation() {
HIP_CHECK(hipSetDevice(0));
// Allocating the memory
AllocateMemory();
// Setting default data
SetDefaultData();
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_HOST;
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.srcMemoryType = hipMemoryTypeHost;
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
myparms.srcHost = hData;
myparms.srcPitch = width * sizeof(T);
myparms.srcHeight = height;
myparms.dstDevice = D_m;
myparms.dstPitch = pitch_D;
myparms.dstHeight = height;
SECTION("WidthInBytes is 0") {
myparms.WidthInBytes = 0;
HIP_CHECK(hipDrvMemcpy3D(&myparms));
}
SECTION("Height is 0") {
myparms.Height = 0;
HIP_CHECK(hipDrvMemcpy3D(&myparms));
}
SECTION("Depth is 0") {
myparms.Depth = 0;
HIP_CHECK(hipDrvMemcpy3D(&myparms));
}
DeAllocateMemory();
// Disabled on AMD due to defect - EXSWHTEC-238
TEST_CASE("Unit_hipDrvMemcpy3D_Positive_Array") {
constexpr bool async = false;
SECTION("Array from/to Host") { DrvMemcpy3DArrayHostShell<async>(DrvMemcpy3DWrapper<async>); }
SECTION("Array from/to Device") { DrvMemcpy3DArrayDeviceShell<async>(DrvMemcpy3DWrapper<async>); }
}
/*
This Function verifies following functionalities of hipDrvMemcpy3D API
1. Host to Device copy
2. Device to Device
3. Device to Host
In the end validates the results.
This functionality is verified in 2 scenarios
1. Basic scenario on same GPU device
2. Device context change scenario where memory is allocated in 1 GPU
and hipDrvMemcpy3D API is trigerred from another GPU
*/
template <typename T>
void DrvMemcpy3D<T>::HostDevice_DrvMemcpy3D(bool device_context_change) {
HIP_CHECK(hipSetDevice(0));
bool skip_test = false;
int peerAccess = 0;
AllocateMemory();
if (device_context_change) {
HIP_CHECK(hipDeviceCanAccessPeer(&peerAccess, 0, 1));
if (!peerAccess) {
WARN("skipped the testcase as no peer access");
skip_test = true;
} else {
HIP_CHECK(hipSetDevice(1));
TEST_CASE("Unit_hipDrvMemcpy3D_Negative_Parameters") {
constexpr hipExtent extent{128 * sizeof(int), 128, 8};
constexpr auto NegativeTests = [](hipPitchedPtr dst_ptr, hipPos dst_pos, hipPitchedPtr src_ptr,
hipPos src_pos, hipExtent extent, hipMemcpyKind kind) {
SECTION("dst_ptr.ptr == nullptr") {
hipPitchedPtr invalid_ptr = dst_ptr;
invalid_ptr.ptr = nullptr;
HIP_CHECK_ERROR(DrvMemcpy3DWrapper(invalid_ptr, dst_pos, src_ptr, src_pos, extent, kind),
hipErrorInvalidValue);
}
}
if (!skip_test) {
SetDefaultData();
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_HOST;
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.srcMemoryType = hipMemoryTypeHost;
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
myparms.srcHost = hData;
myparms.srcPitch = width * sizeof(T);
myparms.srcHeight = height;
myparms.dstDevice = hipDeviceptr_t(D_m);
myparms.dstPitch = pitch_D;
myparms.dstHeight = height;
HIP_CHECK(hipDrvMemcpy3D(&myparms));
// Device to Device
SetDefaultData();
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_DEVICE;
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.srcMemoryType = hipMemoryTypeDevice;
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
myparms.srcDevice = hipDeviceptr_t(D_m);
myparms.srcPitch = pitch_D;
myparms.srcHeight = height;
myparms.dstDevice = hipDeviceptr_t(E_m);
myparms.dstPitch = pitch_E;
myparms.dstHeight = height;
HIP_CHECK(hipDrvMemcpy3D(&myparms));
T *hOutputData = reinterpret_cast<T*>(malloc(size));
memset(hOutputData, 0, size);
// Device to host
SetDefaultData();
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_DEVICE;
myparms.dstMemoryType = CU_MEMORYTYPE_HOST;
#else
myparms.srcMemoryType = hipMemoryTypeDevice;
myparms.dstMemoryType = hipMemoryTypeHost;
#endif
myparms.srcDevice = hipDeviceptr_t(E_m);
myparms.srcPitch = pitch_E;
myparms.srcHeight = height;
myparms.dstHost = hOutputData;
myparms.dstPitch = width * sizeof(T);
myparms.dstHeight = height;
HIP_CHECK(hipDrvMemcpy3D(&myparms));
HipTest::checkArray(hData, hOutputData, width, height, depth);
free(hOutputData);
}
DeAllocateMemory();
}
/*
This Function verifies following functionalities of hipDrvMemcpy3D API
1. Host to Array copy
2. Array to Array
3. Array to Host
In the end validates the results.
This functionality is verified in 2 scenarios
1. Basic scenario on same GPU device
2. Device context change scenario where memory is allocated in 1 GPU
and hipDrvMemcpy3D API is trigerred from another GPU
*/
template <typename T>
void DrvMemcpy3D<T>::HostArray_DrvMemcpy3D(bool device_context_change) {
HIP_CHECK(hipSetDevice(0));
bool skip_test = false;
int peerAccess = 0;
AllocateMemory();
if (device_context_change) {
HIP_CHECK(hipDeviceCanAccessPeer(&peerAccess, 0, 1));
if (!peerAccess) {
WARN("skipped the testcase as no peer access");
skip_test = true;
} else {
HIP_CHECK(hipSetDevice(1));
SECTION("src_ptr.ptr == nullptr") {
hipPitchedPtr invalid_ptr = src_ptr;
invalid_ptr.ptr = nullptr;
HIP_CHECK_ERROR(DrvMemcpy3DWrapper(dst_ptr, dst_pos, invalid_ptr, src_pos, extent, kind),
hipErrorInvalidValue);
}
}
if (!skip_test) {
SetDefaultData();
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_HOST;
myparms.dstMemoryType = CU_MEMORYTYPE_ARRAY;
#else
myparms.srcMemoryType = hipMemoryTypeHost;
myparms.dstMemoryType = hipMemoryTypeArray;
#endif
myparms.srcHost = hData;
myparms.srcPitch = width * sizeof(T);
myparms.srcHeight = height;
myparms.dstArray = arr;
HIP_CHECK(hipDrvMemcpy3D(&myparms));
// Array to Array
SetDefaultData();
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_ARRAY;
myparms.dstMemoryType = CU_MEMORYTYPE_ARRAY;
#else
myparms.srcMemoryType = hipMemoryTypeArray;
myparms.dstMemoryType = hipMemoryTypeArray;
#endif
myparms.srcArray = arr;
myparms.dstArray = arr1;
HIP_CHECK(hipDrvMemcpy3D(&myparms));
T *hOutputData = reinterpret_cast<T*>(malloc(size));
memset(hOutputData, 0, size);
SetDefaultData();
// Device to host
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_ARRAY;
myparms.dstMemoryType = CU_MEMORYTYPE_HOST;
#else
myparms.srcMemoryType = hipMemoryTypeArray;
myparms.dstMemoryType = hipMemoryTypeHost;
#endif
myparms.srcArray = arr1;
myparms.dstHost = hOutputData;
myparms.dstPitch = width * sizeof(T);
myparms.dstHeight = height;
HIP_CHECK(hipDrvMemcpy3D(&myparms));
HipTest::checkArray(hData, hOutputData, width, height, depth);
free(hOutputData);
}
DeAllocateMemory();
}
/* DeAllocating the memory */
template <typename T>
void DrvMemcpy3D<T>::DeAllocateMemory() {
HIP_CHECK(hipArrayDestroy(arr));
HIP_CHECK(hipArrayDestroy(arr1));
free(hData);
}
/* Verifying hipDrvMemcpy3D API Host to Array for different datatypes */
TEMPLATE_TEST_CASE("Unit_hipDrvMemcpy3D_MultipleDataTypes", "",
uint8_t, int, float) {
for (int i = 1; i < 25; i++) {
if (std::is_same<TestType, float>::value) {
DrvMemcpy3D<TestType> memcpy3d_float(i, i, i, HIP_AD_FORMAT_FLOAT);
memcpy3d_float.HostArray_DrvMemcpy3D();
} else if (std::is_same<TestType, uint8_t>::value) {
DrvMemcpy3D<TestType> memcpy3d_intx(i, i, i, HIP_AD_FORMAT_UNSIGNED_INT8);
memcpy3d_intx.HostArray_DrvMemcpy3D();
} else if (std::is_same<TestType, int>::value) {
DrvMemcpy3D<TestType> memcpy3d_inty(i, i, i, HIP_AD_FORMAT_SIGNED_INT32);
memcpy3d_inty.HostArray_DrvMemcpy3D();
SECTION("dst_ptr.pitch < width") {
hipPitchedPtr invalid_ptr = dst_ptr;
invalid_ptr.pitch = extent.width - 1;
HIP_CHECK_ERROR(DrvMemcpy3DWrapper(invalid_ptr, dst_pos, src_ptr, src_pos, extent, kind),
hipErrorInvalidValue);
}
}
}
/* This testcase verifies H2D copy of hipDrvMemcpy3D API */
TEST_CASE("Unit_hipDrvMemcpy3D_HosttoDevice") {
DrvMemcpy3D<float> memcpy3d_D2H_float(10, 10, 1, HIP_AD_FORMAT_FLOAT);
memcpy3d_D2H_float.HostDevice_DrvMemcpy3D();
}
SECTION("src_ptr.pitch < width") {
hipPitchedPtr invalid_ptr = src_ptr;
invalid_ptr.pitch = extent.width - 1;
HIP_CHECK_ERROR(DrvMemcpy3DWrapper(dst_ptr, dst_pos, invalid_ptr, src_pos, extent, kind),
hipErrorInvalidValue);
}
/* This testcase verifies negative scenarios of hipDrvMemcpy3D API */
#if HT_NVIDIA
TEST_CASE("Unit_hipDrvMemcpy3D_Negative") {
DrvMemcpy3D<float> memcpy3d(10, 10, 1, HIP_AD_FORMAT_FLOAT);
memcpy3d.NegativeTests();
}
SECTION("dst_ptr.pitch > max pitch") {
int attr = 0;
HIP_CHECK(hipDeviceGetAttribute(&attr, hipDeviceAttributeMaxPitch, 0));
hipPitchedPtr invalid_ptr = dst_ptr;
invalid_ptr.pitch = attr;
HIP_CHECK_ERROR(DrvMemcpy3DWrapper(invalid_ptr, dst_pos, src_ptr, src_pos, extent, kind),
hipErrorInvalidValue);
}
SECTION("src_ptr.pitch > max pitch") {
int attr = 0;
HIP_CHECK(hipDeviceGetAttribute(&attr, hipDeviceAttributeMaxPitch, 0));
hipPitchedPtr invalid_ptr = src_ptr;
invalid_ptr.pitch = attr;
HIP_CHECK_ERROR(DrvMemcpy3DWrapper(dst_ptr, dst_pos, invalid_ptr, src_pos, extent, kind),
hipErrorInvalidValue);
}
#if HT_NVIDIA // Disabled on AMD due to defect - EXSWHTEC-237
SECTION("extent.width + dst_pos.x > dst_ptr.pitch") {
hipPos invalid_pos = dst_pos;
invalid_pos.x = dst_ptr.pitch - extent.width + 1;
HIP_CHECK_ERROR(DrvMemcpy3DWrapper(dst_ptr, invalid_pos, src_ptr, src_pos, extent, kind),
hipErrorInvalidValue);
}
SECTION("extent.width + src_pos.x > src_ptr.pitch") {
hipPos invalid_pos = src_pos;
invalid_pos.x = src_ptr.pitch - extent.width + 1;
HIP_CHECK_ERROR(DrvMemcpy3DWrapper(dst_ptr, dst_pos, src_ptr, invalid_pos, extent, kind),
hipErrorInvalidValue);
}
SECTION("dst_pos.y out of bounds") {
hipPos invalid_pos = dst_pos;
invalid_pos.y = 1;
HIP_CHECK_ERROR(DrvMemcpy3DWrapper(dst_ptr, invalid_pos, src_ptr, src_pos, extent, kind),
hipErrorInvalidValue);
}
SECTION("src_pos.y out of bounds") {
hipPos invalid_pos = src_pos;
invalid_pos.y = 1;
HIP_CHECK_ERROR(DrvMemcpy3DWrapper(dst_ptr, dst_pos, src_ptr, invalid_pos, extent, kind),
hipErrorInvalidValue);
}
SECTION("dst_pos.z out of bounds") {
hipPos invalid_pos = dst_pos;
invalid_pos.z = 1;
HIP_CHECK_ERROR(DrvMemcpy3DWrapper(dst_ptr, invalid_pos, src_ptr, src_pos, extent, kind),
hipErrorInvalidValue);
}
SECTION("src_pos.z out of bounds") {
hipPos invalid_pos = src_pos;
invalid_pos.z = 1;
HIP_CHECK_ERROR(DrvMemcpy3DWrapper(dst_ptr, dst_pos, src_ptr, invalid_pos, extent, kind),
hipErrorInvalidValue);
}
#endif
};
/* This testcase verifies extent validation scenarios of hipDrvMemcpy3D API */
TEST_CASE("Unit_hipDrvMemcpy3D_ExtentValidation") {
DrvMemcpy3D<float> memcpy3d(10, 10, 1, HIP_AD_FORMAT_FLOAT);
memcpy3d.Extent_Validation();
}
#if HT_AMD
/* This testcase verifies H2D copy in device context
change scenario for hipDrvMemcpy3D API */
TEST_CASE("Unit_hipDrvMemcpy3D_H2DDeviceContextChange") {
int numDevices = 0;
HIP_CHECK(hipGetDeviceCount(&numDevices));
if (numDevices > 1) {
DrvMemcpy3D<float> memcpy3d(10, 10, 1, HIP_AD_FORMAT_FLOAT);
memcpy3d.HostDevice_DrvMemcpy3D(true);
} else {
SUCCEED("skipped testcase as Device count is < 2");
SECTION("Host to Device") {
LinearAllocGuard3D<int> device_alloc(extent);
LinearAllocGuard<int> host_alloc(
LinearAllocs::hipHostMalloc,
device_alloc.pitch() * device_alloc.height() * device_alloc.depth());
NegativeTests(device_alloc.pitched_ptr(), make_hipPos(0, 0, 0),
make_hipPitchedPtr(host_alloc.ptr(), device_alloc.pitch(), device_alloc.width(),
device_alloc.height()),
make_hipPos(0, 0, 0), extent, hipMemcpyHostToDevice);
}
}
/* This testcase verifies Host to Array copy in device context
change scenario for hipDrvMemcpy3D API */
TEST_CASE("Unit_hipDrvMemcpy3D_Host2ArrayDeviceContextChange") {
int numDevices = 0;
HIP_CHECK(hipGetDeviceCount(&numDevices));
if (numDevices > 1) {
DrvMemcpy3D<float> memcpy3d(10, 10, 1, HIP_AD_FORMAT_FLOAT);
memcpy3d.HostArray_DrvMemcpy3D(true);
} else {
SUCCEED("skipped testcase as Device count is < 2");
SECTION("Device to Host") {
LinearAllocGuard3D<int> device_alloc(extent);
LinearAllocGuard<int> host_alloc(
LinearAllocs::hipHostMalloc,
device_alloc.pitch() * device_alloc.height() * device_alloc.depth());
NegativeTests(make_hipPitchedPtr(host_alloc.ptr(), device_alloc.pitch(), device_alloc.width(),
device_alloc.height()),
make_hipPos(0, 0, 0), device_alloc.pitched_ptr(), make_hipPos(0, 0, 0), extent,
hipMemcpyDeviceToHost);
}
}
#endif
SECTION("Host to Host") {
LinearAllocGuard<int> src_alloc(LinearAllocs::hipHostMalloc,
extent.width * extent.height * extent.depth);
LinearAllocGuard<int> dst_alloc(LinearAllocs::hipHostMalloc,
extent.width * extent.height * extent.depth);
NegativeTests(make_hipPitchedPtr(dst_alloc.ptr(), extent.width, extent.width, extent.height),
make_hipPos(0, 0, 0),
make_hipPitchedPtr(src_alloc.ptr(), extent.width, extent.width, extent.height),
make_hipPos(0, 0, 0), extent, hipMemcpyHostToHost);
}
SECTION("Device to Device") {
LinearAllocGuard3D<int> src_alloc(extent);
LinearAllocGuard3D<int> dst_alloc(extent);
NegativeTests(dst_alloc.pitched_ptr(), make_hipPos(0, 0, 0), src_alloc.pitched_ptr(),
make_hipPos(0, 0, 0), extent, hipMemcpyDeviceToDevice);
}
}
+210 -550
查看文件
@@ -1,13 +1,16 @@
/*
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 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
@@ -16,579 +19,236 @@ 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 Scenarios
* 1. Verifying hipDrvMemcpy3DAsync API for H2A,A2A,A2H scenarios
* 2. Verifying hipDrvMemcpy3DAsync API for H2D,D2D,D2H scenarios
* 3. Verifying Negative Scenarios
* 4. Verifying Extent validation scenarios by passing 0
* 5. Verifying hipDrvMemcpy3DAsync API by allocating Memory in
* one GPU and trigger hipDrvMemcpy3DAsync from peer GPU for
* H2D,D2D,D2H scenarios
* 6. Verifying hipDrvMemcpy3DAsync API by allocating Memory in
* one GPU and trigger hipDrvMemcpy3DAsync from peer GPU for
* H2A,A2A,A2H scenarios
*
* Scenarios 3 is temporarily excluded in AMD platform
* Scenario 5&6 are excluded in CUDA platform
*/
#include "hip_test_common.hh"
#include "hip_test_checkers.hh"
#include <memcpy1d_tests_common.hh>
#include <memcpy3d_tests_common.hh>
template<typename T>
class DrvMemcpy3DAsync {
int width, height, depth;
unsigned int size;
hipArray_Format formatKind;
hiparray arr, arr1;
hipStream_t stream;
size_t pitch_D, pitch_E;
HIP_MEMCPY3D myparms;
hipDeviceptr_t D_m, E_m;
T* hData{nullptr};
public:
DrvMemcpy3DAsync(int l_width, int l_height, int l_depth,
hipArray_Format l_format);
DrvMemcpy3DAsync() = delete;
void AllocateMemory();
void SetDefaultData();
void HostArray_DrvMemcpy3DAsync(bool device_context_change = false);
void HostDevice_DrvMemcpy3DAsync(bool device_context_change = false);
void Extent_Validation();
void NegativeTests();
void DeAllocateMemory();
};
#include <hip_test_common.hh>
#include <hip/hip_runtime_api.h>
#include <resource_guards.hh>
#include <utils.hh>
/* Intializes class variables */
template <typename T>
DrvMemcpy3DAsync<T>::DrvMemcpy3DAsync(int l_width, int l_height, int l_depth,
hipArray_Format l_format) {
width = l_width;
height = l_height;
depth = l_depth;
formatKind = l_format;
}
TEST_CASE("Unit_hipDrvMemcpy3DAsync_Positive_Basic") {
constexpr bool async = true;
/* Allocating Memory */
template <typename T>
void DrvMemcpy3DAsync<T>::AllocateMemory() {
size = width * height * depth * sizeof(T);
hData = reinterpret_cast<T*>(malloc(size));
memset(hData, 0, size);
for (int i = 0; i < depth; i++) {
for (int j = 0; j < height; j++) {
for (int k = 0; k < width; k++) {
hData[i*width*height + j*width +k] = i*width*height + j*width + k;
}
const auto stream_type = GENERATE(Streams::nullstream, Streams::perThread, Streams::created);
const StreamGuard stream_guard(stream_type);
const hipStream_t stream = stream_guard.stream();
#if HT_NVIDIA // Disabled on AMD due to defect - EXSWHTEC-236
SECTION("Device to Host") { Memcpy3DDeviceToHostShell<async>(DrvMemcpy3DWrapper<async>, stream); }
#endif
SECTION("Device to Device") {
SECTION("Peer access disabled") {
Memcpy3DDeviceToDeviceShell<async, false>(DrvMemcpy3DWrapper<async>, stream);
}
SECTION("Peer access enabled") {
Memcpy3DDeviceToDeviceShell<async, true>(DrvMemcpy3DWrapper<async>, stream);
}
}
HIP_CHECK(hipStreamCreate(&stream));
HIP_CHECK(hipMallocPitch(reinterpret_cast<void**>(&D_m),
&pitch_D, width*sizeof(T), height));
HIP_CHECK(hipMallocPitch(reinterpret_cast<void**>(&E_m),
&pitch_E, width*sizeof(T), height));
HIP_ARRAY3D_DESCRIPTOR *desc;
desc = reinterpret_cast<HIP_ARRAY3D_DESCRIPTOR*>
(malloc(sizeof(HIP_ARRAY3D_DESCRIPTOR)));
desc->Format = formatKind;
desc->NumChannels = 1;
desc->Width = width;
desc->Height = height;
desc->Depth = depth;
desc->Flags = hipArrayDefault;
HIP_CHECK(hipArray3DCreate(&arr, desc));
HIP_CHECK(hipArray3DCreate(&arr1, desc));
SECTION("Host to Device") { Memcpy3DHostToDeviceShell<async>(DrvMemcpy3DWrapper<async>, stream); }
#if HT_NVIDIA // Disabled on AMD due to defect - EXSWHTEC-236
SECTION("Host to Host") { Memcpy3DHostToHostShell<async>(DrvMemcpy3DWrapper<async>, stream); }
#endif
}
/* Setting the default data */
template <typename T>
void DrvMemcpy3DAsync<T>::SetDefaultData() {
memset(&myparms, 0x0, sizeof(HIP_MEMCPY3D));
myparms.srcXInBytes = 0;
myparms.srcY = 0;
myparms.srcZ = 0;
myparms.srcLOD = 0;
myparms.dstXInBytes = 0;
myparms.dstY = 0;
myparms.dstZ = 0;
myparms.dstLOD = 0;
myparms.WidthInBytes = width*sizeof(T);
myparms.Height = height;
myparms.Depth = depth;
TEST_CASE("Unit_hipDrvMemcpy3DAsync_Positive_Synchronization_Behavior") {
constexpr bool async = true;
HIP_CHECK(hipDeviceSynchronize());
SECTION("Host to Device") { Memcpy3DHtoDSyncBehavior(DrvMemcpy3DWrapper<async>, false); }
#if HT_NVIDIA // Disabled on AMD due to defect - EXSWHTEC-233
SECTION("Device to Pageable Host") {
Memcpy3DDtoHPageableSyncBehavior(DrvMemcpy3DWrapper<async>, true);
}
#endif
#if HT_NVIDIA // Disabled on AMD due to defect - EXSWHTEC-236
SECTION("Device to Pinned Host") {
Memcpy3DDtoHPinnedSyncBehavior(DrvMemcpy3DWrapper<async>, false);
}
#endif
SECTION("Device to Device") { Memcpy3DDtoDSyncBehavior(DrvMemcpy3DWrapper<async>, false); }
#if HT_NVIDIA // Disabled on AMD due to defect - EXSWHTEC-233
SECTION("Host to Host") { Memcpy3DHtoHSyncBehavior(DrvMemcpy3DWrapper<async>, true); }
#endif
}
/*
This function verifies the negative scenarios of
hipDrvMemcpy3DAsync API
*/
template <typename T>
void DrvMemcpy3DAsync<T>::NegativeTests() {
HIP_CHECK(hipSetDevice(0));
AllocateMemory();
SetDefaultData();
int deviceId;
HIP_CHECK(hipGetDevice(&deviceId));
unsigned int MaxPitch;
HIP_CHECK(hipDeviceGetAttribute(reinterpret_cast<int *>(&MaxPitch),
hipDeviceAttributeMaxPitch, deviceId));
myparms.srcHost = hData;
myparms.dstArray = arr;
myparms.srcPitch = width * sizeof(T);
myparms.srcHeight = height;
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_HOST;
myparms.dstMemoryType = CU_MEMORYTYPE_ARRAY;
#else
myparms.srcMemoryType = hipMemoryTypeHost;
myparms.dstMemoryType = hipMemoryTypeArray;
#endif
SECTION("Passing nullptr to Source Host") {
myparms.srcHost = nullptr;
REQUIRE(hipDrvMemcpy3DAsync(&myparms, stream) != hipSuccess);
}
SECTION("Passing both dst host and device") {
myparms.dstHost = hData;
myparms.dstArray = nullptr;
myparms.dstDevice = D_m;
myparms.WidthInBytes = pitch_D;
#if HT_NVIDIA
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
REQUIRE(hipDrvMemcpy3DAsync(&myparms, stream) != hipSuccess);
}
SECTION("Passing max value to WidthInBytes") {
myparms.WidthInBytes = std::numeric_limits<int>::max();
myparms.Height = std::numeric_limits<int>::max();
myparms.Depth = std::numeric_limits<int>::max();
REQUIRE(hipDrvMemcpy3DAsync(&myparms, stream) != hipSuccess);
}
SECTION("Passing width > max width size") {
myparms.WidthInBytes = width*sizeof(T) + 1;
REQUIRE(hipDrvMemcpy3DAsync(&myparms, stream) != hipSuccess);
}
SECTION("Passing height > max height size") {
myparms.Height = height + 1;
REQUIRE(hipDrvMemcpy3DAsync(&myparms, stream) != hipSuccess);
}
SECTION("Passing depth > max depth size") {
myparms.Depth = depth + 1;
REQUIRE(hipDrvMemcpy3DAsync(&myparms, stream) != hipSuccess);
}
SECTION("widthinbytes + srcXinBytes is out of bound") {
myparms.srcXInBytes = 1;
myparms.dstArray = nullptr;
myparms.dstDevice = hipDeviceptr_t(D_m);
myparms.dstPitch = pitch_D;
myparms.dstHeight = height;
#if HT_NVIDIA
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
REQUIRE(hipDrvMemcpy3DAsync(&myparms, stream) != hipSuccess);
}
SECTION("widthinbytes + dstXinBytes is out of bound") {
myparms.dstXInBytes = pitch_D;
myparms.dstArray = nullptr;
myparms.dstDevice = hipDeviceptr_t(D_m);
myparms.dstPitch = pitch_D;
myparms.dstHeight = height;
#if HT_NVIDIA
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
REQUIRE(hipDrvMemcpy3DAsync(&myparms, stream) != hipSuccess);
}
SECTION("srcY + height is out of bound") {
myparms.srcY = 1;
myparms.dstArray = nullptr;
myparms.dstDevice = hipDeviceptr_t(D_m);
myparms.dstPitch = pitch_D;
myparms.dstHeight = height;
#if HT_NVIDIA
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
REQUIRE(hipDrvMemcpy3DAsync(&myparms, stream) != hipSuccess);
}
SECTION("dstY + height out of bounds") {
myparms.dstY = 1;
myparms.dstArray = nullptr;
myparms.dstDevice = hipDeviceptr_t(D_m);
myparms.dstPitch = pitch_D;
myparms.dstHeight = height;
#if HT_NVIDIA
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
REQUIRE(hipDrvMemcpy3DAsync(&myparms, stream) != hipSuccess);
}
SECTION("src pitch greater than Max allowed pitch") {
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_DEVICE;
myparms.dstMemoryType = CU_MEMORYTYPE_HOST;
#else
myparms.srcMemoryType = hipMemoryTypeDevice;
myparms.dstMemoryType = hipMemoryTypeHost;
#endif
myparms.srcDevice = D_m;
myparms.srcHost = nullptr;
myparms.srcPitch = MaxPitch;
myparms.srcHeight = height;
myparms.dstHost = hData;
myparms.dstArray = nullptr;
myparms.dstPitch = width*sizeof(T);
myparms.dstHeight = height;
REQUIRE(hipDrvMemcpy3DAsync(&myparms, stream) != hipSuccess);
}
SECTION("dst pitch greater than Max allowed pitch") {
myparms.dstDevice = hipDeviceptr_t(D_m);
myparms.dstArray = nullptr;
myparms.dstPitch = MaxPitch+1;
myparms.dstHeight = height;
#if HT_NVIDIA
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
REQUIRE(hipDrvMemcpy3DAsync(&myparms, stream) != hipSuccess);
}
SECTION("Nullptr to src/dst device") {
myparms.dstDevice = hipDeviceptr_t(nullptr);
myparms.dstArray = nullptr;
myparms.dstPitch = pitch_D;
myparms.dstHeight = height;
#if HT_NVIDIA
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
REQUIRE(hipDrvMemcpy3DAsync(&myparms, stream) != hipSuccess);
}
SECTION("Nullptr to src/dst array") {
myparms.dstArray = nullptr;
REQUIRE(hipDrvMemcpy3DAsync(&myparms, stream) != hipSuccess);
}
SECTION("Nullptr to hipDrvMemcpy3DAsync") {
REQUIRE(hipDrvMemcpy3DAsync(nullptr, stream) != hipSuccess);
}
DeAllocateMemory();
TEST_CASE("Unit_hipDrvMemcpy3DAsync_Positive_Parameters") {
constexpr bool async = true;
Memcpy3DZeroWidthHeightDepth<async>(DrvMemcpy3DWrapper<async>);
}
/*
This function verifies the Extent validation scenarios of
hipDrvMemcpy3DAsync API
*/
template <typename T>
void DrvMemcpy3DAsync<T>::Extent_Validation() {
HIP_CHECK(hipSetDevice(0));
// Allocating the memory
AllocateMemory();
// Setting default data
SetDefaultData();
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_HOST;
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.srcMemoryType = hipMemoryTypeHost;
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
myparms.srcHost = hData;
myparms.srcPitch = width * sizeof(T);
myparms.srcHeight = height;
myparms.dstDevice = D_m;
myparms.dstPitch = pitch_D;
myparms.dstHeight = height;
SECTION("WidthInBytes is 0") {
myparms.WidthInBytes = 0;
HIP_CHECK(hipDrvMemcpy3DAsync(&myparms, stream));
HIP_CHECK(hipStreamSynchronize(stream));
}
SECTION("Height is 0") {
myparms.Height = 0;
HIP_CHECK(hipDrvMemcpy3DAsync(&myparms, stream));
HIP_CHECK(hipStreamSynchronize(stream));
}
SECTION("Depth is 0") {
myparms.Depth = 0;
HIP_CHECK(hipDrvMemcpy3DAsync(&myparms, stream));
HIP_CHECK(hipStreamSynchronize(stream));
}
DeAllocateMemory();
// Disabled on AMD due to defect - EXSWHTEC-238
TEST_CASE("Unit_hipDrvMemcpy3DAsync_Positive_Array") {
constexpr bool async = true;
SECTION("Array from/to Host") { DrvMemcpy3DArrayHostShell<async>(DrvMemcpy3DWrapper<async>); }
SECTION("Array from/to Device") { DrvMemcpy3DArrayDeviceShell<async>(DrvMemcpy3DWrapper<async>); }
}
/*
This Function verifies following functionalities of hipDrvMemcpy3DAsync API
1. Host to Device copy
2. Device to Device
3. Device to Host
In the end validates the results.
This functionality is verified in 2 scenarios
1. Basic scenario on same GPU device
2. Device context change scenario where memory is allocated in 1 GPU
and hipDrvMemcpy3DAsync API is trigerred from another GPU
*/
template <typename T>
void DrvMemcpy3DAsync<T>::HostDevice_DrvMemcpy3DAsync
(bool device_context_change) {
HIP_CHECK(hipSetDevice(0));
bool skip_test = false;
int peerAccess = 0;
AllocateMemory();
if (device_context_change) {
HIP_CHECK(hipDeviceCanAccessPeer(&peerAccess, 0, 1));
if (!peerAccess) {
WARN("skipped the testcase as no peer access");
skip_test = true;
} else {
HIP_CHECK(hipSetDevice(1));
TEST_CASE("Unit_hipDrvMemcpy3DAsync_Negative_Parameters") {
constexpr bool async = true;
constexpr hipExtent extent{128 * sizeof(int), 128, 8};
constexpr auto NegativeTests = [](hipPitchedPtr dst_ptr, hipPos dst_pos, hipPitchedPtr src_ptr,
hipPos src_pos, hipExtent extent, hipMemcpyKind kind) {
SECTION("dst_ptr.ptr == nullptr") {
hipPitchedPtr invalid_ptr = dst_ptr;
invalid_ptr.ptr = nullptr;
HIP_CHECK_ERROR(
DrvMemcpy3DWrapper<async>(invalid_ptr, dst_pos, src_ptr, src_pos, extent, kind),
hipErrorInvalidValue);
}
}
if (!skip_test) {
SetDefaultData();
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_HOST;
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.srcMemoryType = hipMemoryTypeHost;
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
myparms.srcHost = hData;
myparms.srcPitch = width * sizeof(T);
myparms.srcHeight = height;
myparms.dstDevice = hipDeviceptr_t(D_m);
myparms.dstPitch = pitch_D;
myparms.dstHeight = height;
HIP_CHECK(hipDrvMemcpy3DAsync(&myparms, stream));
HIP_CHECK(hipStreamSynchronize(stream));
// Device to Device
SetDefaultData();
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_DEVICE;
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.srcMemoryType = hipMemoryTypeDevice;
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
myparms.srcDevice = hipDeviceptr_t(D_m);
myparms.srcPitch = pitch_D;
myparms.srcHeight = height;
myparms.dstDevice = hipDeviceptr_t(E_m);
myparms.dstPitch = pitch_E;
myparms.dstHeight = height;
HIP_CHECK(hipDrvMemcpy3DAsync(&myparms, stream));
HIP_CHECK(hipStreamSynchronize(stream));
T *hOutputData = reinterpret_cast<T*>(malloc(size));
memset(hOutputData, 0, size);
// Device to host
SetDefaultData();
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_DEVICE;
myparms.dstMemoryType = CU_MEMORYTYPE_HOST;
#else
myparms.srcMemoryType = hipMemoryTypeDevice;
myparms.dstMemoryType = hipMemoryTypeHost;
#endif
myparms.srcDevice = hipDeviceptr_t(E_m);
myparms.srcPitch = pitch_E;
myparms.srcHeight = height;
myparms.dstHost = hOutputData;
myparms.dstPitch = width * sizeof(T);
myparms.dstHeight = height;
HIP_CHECK(hipDrvMemcpy3DAsync(&myparms, stream));
HIP_CHECK(hipStreamSynchronize(stream));
HipTest::checkArray(hData, hOutputData, width, height, depth);
free(hOutputData);
}
DeAllocateMemory();
}
/*
This Function verifies following functionalities of hipDrvMemcpy3DAsync API
1. Host to Array copy
2. Array to Array
3. Array to Host
In the end validates the results.
This functionality is verified in 2 scenarios
1. Basic scenario on same GPU device
2. Device context change scenario where memory is allocated in 1 GPU
and hipDrvMemcpy3DAsync API is trigerred from another GPU
*/
template <typename T>
void DrvMemcpy3DAsync<T>::HostArray_DrvMemcpy3DAsync
(bool device_context_change) {
HIP_CHECK(hipSetDevice(0));
bool skip_test = false;
int peerAccess = 0;
AllocateMemory();
if (device_context_change) {
HIP_CHECK(hipDeviceCanAccessPeer(&peerAccess, 0, 1));
if (!peerAccess) {
WARN("skipped the testcase as no peer access");
skip_test = true;
} else {
HIP_CHECK(hipSetDevice(1));
SECTION("src_ptr.ptr == nullptr") {
hipPitchedPtr invalid_ptr = src_ptr;
invalid_ptr.ptr = nullptr;
HIP_CHECK_ERROR(
DrvMemcpy3DWrapper<async>(dst_ptr, dst_pos, invalid_ptr, src_pos, extent, kind),
hipErrorInvalidValue);
}
}
if (!skip_test) {
SetDefaultData();
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_HOST;
myparms.dstMemoryType = CU_MEMORYTYPE_ARRAY;
#else
myparms.srcMemoryType = hipMemoryTypeHost;
myparms.dstMemoryType = hipMemoryTypeArray;
#endif
myparms.srcHost = hData;
myparms.srcPitch = width * sizeof(T);
myparms.srcHeight = height;
myparms.dstArray = arr;
HIP_CHECK(hipDrvMemcpy3DAsync(&myparms, stream));
HIP_CHECK(hipStreamSynchronize(stream));
// Array to Array
SetDefaultData();
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_ARRAY;
myparms.dstMemoryType = CU_MEMORYTYPE_ARRAY;
#else
myparms.srcMemoryType = hipMemoryTypeArray;
myparms.dstMemoryType = hipMemoryTypeArray;
#endif
myparms.srcArray = arr;
myparms.dstArray = arr1;
HIP_CHECK(hipDrvMemcpy3DAsync(&myparms, stream));
HIP_CHECK(hipStreamSynchronize(stream));
T *hOutputData = reinterpret_cast<T*>(malloc(size));
memset(hOutputData, 0, size);
SetDefaultData();
// Device to host
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_ARRAY;
myparms.dstMemoryType = CU_MEMORYTYPE_HOST;
#else
myparms.srcMemoryType = hipMemoryTypeArray;
myparms.dstMemoryType = hipMemoryTypeHost;
#endif
myparms.srcArray = arr1;
myparms.dstHost = hOutputData;
myparms.dstPitch = width * sizeof(T);
myparms.dstHeight = height;
HIP_CHECK(hipDrvMemcpy3DAsync(&myparms, stream));
HIP_CHECK(hipStreamSynchronize(stream));
HipTest::checkArray(hData, hOutputData, width, height, depth);
free(hOutputData);
}
DeAllocateMemory();
}
/* DeAllocating the memory */
template <typename T>
void DrvMemcpy3DAsync<T>::DeAllocateMemory() {
HIP_CHECK(hipArrayDestroy(arr));
HIP_CHECK(hipArrayDestroy(arr1));
HIP_CHECK(hipStreamDestroy(stream));
free(hData);
}
/* Verifying hipDrvMemcpy3DAsync API Host to Array for different datatypes */
TEMPLATE_TEST_CASE("Unit_hipDrvMemcpy3DAsync_MultipleDataTypes", "",
uint8_t, int, float) {
for (int i = 1; i < 25; i++) {
if (std::is_same<TestType, float>::value) {
DrvMemcpy3DAsync<TestType> memcpy3d_float(i, i, i,
HIP_AD_FORMAT_FLOAT);
memcpy3d_float.HostArray_DrvMemcpy3DAsync();
} else if (std::is_same<TestType, uint8_t>::value) {
DrvMemcpy3DAsync<TestType> memcpy3d_intx(i, i, i,
HIP_AD_FORMAT_UNSIGNED_INT8);
memcpy3d_intx.HostArray_DrvMemcpy3DAsync();
} else if (std::is_same<TestType, int>::value) {
DrvMemcpy3DAsync<TestType> memcpy3d_inty(i, i, i,
HIP_AD_FORMAT_SIGNED_INT32);
memcpy3d_inty.HostArray_DrvMemcpy3DAsync();
SECTION("dst_ptr.pitch < width") {
hipPitchedPtr invalid_ptr = dst_ptr;
invalid_ptr.pitch = extent.width - 1;
HIP_CHECK_ERROR(
DrvMemcpy3DWrapper<async>(invalid_ptr, dst_pos, src_ptr, src_pos, extent, kind),
hipErrorInvalidValue);
}
}
}
/* This testcase verifies H2D copy of hipDrvMemcpy3DAsync API */
TEST_CASE("Unit_hipDrvMemcpy3DAsync_HosttoDevice") {
DrvMemcpy3DAsync<float> memcpy3d_D2H_float(10, 10, 1, HIP_AD_FORMAT_FLOAT);
memcpy3d_D2H_float.HostDevice_DrvMemcpy3DAsync();
}
SECTION("src_ptr.pitch < width") {
hipPitchedPtr invalid_ptr = src_ptr;
invalid_ptr.pitch = extent.width - 1;
HIP_CHECK_ERROR(
DrvMemcpy3DWrapper<async>(dst_ptr, dst_pos, invalid_ptr, src_pos, extent, kind),
hipErrorInvalidValue);
}
/* This testcase verifies negative scenarios of hipDrvMemcpy3DAsync API */
#if HT_NVIDIA
TEST_CASE("Unit_hipDrvMemcpy3DAsync_Negative") {
DrvMemcpy3DAsync<float> memcpy3d(10, 10, 1, HIP_AD_FORMAT_FLOAT);
memcpy3d.NegativeTests();
}
SECTION("dst_ptr.pitch > max pitch") {
int attr = 0;
HIP_CHECK(hipDeviceGetAttribute(&attr, hipDeviceAttributeMaxPitch, 0));
hipPitchedPtr invalid_ptr = dst_ptr;
invalid_ptr.pitch = attr;
HIP_CHECK_ERROR(
DrvMemcpy3DWrapper<async>(invalid_ptr, dst_pos, src_ptr, src_pos, extent, kind),
hipErrorInvalidValue);
}
SECTION("src_ptr.pitch > max pitch") {
int attr = 0;
HIP_CHECK(hipDeviceGetAttribute(&attr, hipDeviceAttributeMaxPitch, 0));
hipPitchedPtr invalid_ptr = src_ptr;
invalid_ptr.pitch = attr;
HIP_CHECK_ERROR(
DrvMemcpy3DWrapper<async>(dst_ptr, dst_pos, invalid_ptr, src_pos, extent, kind),
hipErrorInvalidValue);
}
#if HT_NVIDIA // Disabled on AMD due to defect - EXSWHTEC-237
SECTION("extent.width + dst_pos.x > dst_ptr.pitch") {
hipPos invalid_pos = dst_pos;
invalid_pos.x = dst_ptr.pitch - extent.width + 1;
HIP_CHECK_ERROR(
DrvMemcpy3DWrapper<async>(dst_ptr, invalid_pos, src_ptr, src_pos, extent, kind),
hipErrorInvalidValue);
}
SECTION("extent.width + src_pos.x > src_ptr.pitch") {
hipPos invalid_pos = src_pos;
invalid_pos.x = src_ptr.pitch - extent.width + 1;
HIP_CHECK_ERROR(
DrvMemcpy3DWrapper<async>(dst_ptr, dst_pos, src_ptr, invalid_pos, extent, kind),
hipErrorInvalidValue);
}
SECTION("dst_pos.y out of bounds") {
hipPos invalid_pos = dst_pos;
invalid_pos.y = 1;
HIP_CHECK_ERROR(
DrvMemcpy3DWrapper<async>(dst_ptr, invalid_pos, src_ptr, src_pos, extent, kind),
hipErrorInvalidValue);
}
SECTION("src_pos.y out of bounds") {
hipPos invalid_pos = src_pos;
invalid_pos.y = 1;
HIP_CHECK_ERROR(
DrvMemcpy3DWrapper<async>(dst_ptr, dst_pos, src_ptr, invalid_pos, extent, kind),
hipErrorInvalidValue);
}
SECTION("dst_pos.z out of bounds") {
hipPos invalid_pos = dst_pos;
invalid_pos.z = 1;
HIP_CHECK_ERROR(
DrvMemcpy3DWrapper<async>(dst_ptr, invalid_pos, src_ptr, src_pos, extent, kind),
hipErrorInvalidValue);
}
SECTION("src_pos.z out of bounds") {
hipPos invalid_pos = src_pos;
invalid_pos.z = 1;
HIP_CHECK_ERROR(
DrvMemcpy3DWrapper<async>(dst_ptr, dst_pos, src_ptr, invalid_pos, extent, kind),
hipErrorInvalidValue);
}
#endif
/* This testcase verifies extent validation scenarios of
hipDrvMemcpy3DAsync API */
TEST_CASE("Unit_hipDrvMemcpy3DAsync_ExtentValidation") {
DrvMemcpy3DAsync<float> memcpy3d(10, 10, 1, HIP_AD_FORMAT_FLOAT);
memcpy3d.Extent_Validation();
}
/* This testcase verifies H2D copy in device context
change scenario for hipDrvMemcpy3DAsync API */
#if HT_AMD
TEST_CASE("Unit_hipDrvMemcpy3DAsync_H2DDeviceContextChange") {
int numDevices = 0;
HIP_CHECK(hipGetDeviceCount(&numDevices));
if (numDevices > 1) {
DrvMemcpy3DAsync<float> memcpy3d(10, 10, 1, HIP_AD_FORMAT_FLOAT);
memcpy3d.HostDevice_DrvMemcpy3DAsync(true);
} else {
SUCCEED("skipped testcase as Device count is < 2");
}
}
/* This testcase verifies Host to Array copy in device context
change scenario for hipDrvMemcpy3DAsync API */
TEST_CASE("Unit_hipDrvMemcpy3DAsync_Host2ArrayDeviceContextChange") {
int numDevices = 0;
HIP_CHECK(hipGetDeviceCount(&numDevices));
if (numDevices > 1) {
DrvMemcpy3DAsync<float> memcpy3d(10, 10, 10, HIP_AD_FORMAT_FLOAT);
memcpy3d.HostArray_DrvMemcpy3DAsync(true);
} else {
SUCCEED("skipped testcase as Device count is < 2");
}
}
#if HT_NVIDIA // Disabled on AMD due to defect - EXSWHTEC-235
SECTION("Invalid stream") {
StreamGuard stream_guard(Streams::created);
HIP_CHECK(hipStreamDestroy(stream_guard.stream()));
HIP_CHECK_ERROR(DrvMemcpy3DWrapper<async>(dst_ptr, dst_pos, src_ptr, src_pos, extent, kind,
stream_guard.stream()),
hipErrorContextIsDestroyed);
}
#endif
};
SECTION("Host to Device") {
LinearAllocGuard3D<int> device_alloc(extent);
LinearAllocGuard<int> host_alloc(
LinearAllocs::hipHostMalloc,
device_alloc.pitch() * device_alloc.height() * device_alloc.depth());
NegativeTests(device_alloc.pitched_ptr(), make_hipPos(0, 0, 0),
make_hipPitchedPtr(host_alloc.ptr(), device_alloc.pitch(), device_alloc.width(),
device_alloc.height()),
make_hipPos(0, 0, 0), extent, hipMemcpyHostToDevice);
}
SECTION("Device to Host") {
LinearAllocGuard3D<int> device_alloc(extent);
LinearAllocGuard<int> host_alloc(
LinearAllocs::hipHostMalloc,
device_alloc.pitch() * device_alloc.height() * device_alloc.depth());
NegativeTests(make_hipPitchedPtr(host_alloc.ptr(), device_alloc.pitch(), device_alloc.width(),
device_alloc.height()),
make_hipPos(0, 0, 0), device_alloc.pitched_ptr(), make_hipPos(0, 0, 0), extent,
hipMemcpyDeviceToHost);
}
SECTION("Host to Host") {
LinearAllocGuard<int> src_alloc(LinearAllocs::hipHostMalloc,
extent.width * extent.height * extent.depth);
LinearAllocGuard<int> dst_alloc(LinearAllocs::hipHostMalloc,
extent.width * extent.height * extent.depth);
NegativeTests(make_hipPitchedPtr(dst_alloc.ptr(), extent.width, extent.width, extent.height),
make_hipPos(0, 0, 0),
make_hipPitchedPtr(src_alloc.ptr(), extent.width, extent.width, extent.height),
make_hipPos(0, 0, 0), extent, hipMemcpyHostToHost);
}
SECTION("Device to Device") {
LinearAllocGuard3D<int> src_alloc(extent);
LinearAllocGuard3D<int> dst_alloc(extent);
NegativeTests(dst_alloc.pitched_ptr(), make_hipPos(0, 0, 0), src_alloc.pitched_ptr(),
make_hipPos(0, 0, 0), extent, hipMemcpyDeviceToDevice);
}
}
+594
查看文件
@@ -0,0 +1,594 @@
/*
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 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 Scenarios
* 1. Verifying hipDrvMemcpy3DAsync API for H2A,A2A,A2H scenarios
* 2. Verifying hipDrvMemcpy3DAsync API for H2D,D2D,D2H scenarios
* 3. Verifying Negative Scenarios
* 4. Verifying Extent validation scenarios by passing 0
* 5. Verifying hipDrvMemcpy3DAsync API by allocating Memory in
* one GPU and trigger hipDrvMemcpy3DAsync from peer GPU for
* H2D,D2D,D2H scenarios
* 6. Verifying hipDrvMemcpy3DAsync API by allocating Memory in
* one GPU and trigger hipDrvMemcpy3DAsync from peer GPU for
* H2A,A2A,A2H scenarios
*
* Scenarios 3 is temporarily excluded in AMD platform
* Scenario 5&6 are excluded in CUDA platform
*/
#include "hip_test_common.hh"
#include "hip_test_checkers.hh"
template<typename T>
class DrvMemcpy3DAsync {
int width, height, depth;
unsigned int size;
hipArray_Format formatKind;
hiparray arr, arr1;
hipStream_t stream;
size_t pitch_D, pitch_E;
HIP_MEMCPY3D myparms;
hipDeviceptr_t D_m, E_m;
T* hData{nullptr};
public:
DrvMemcpy3DAsync(int l_width, int l_height, int l_depth,
hipArray_Format l_format);
DrvMemcpy3DAsync() = delete;
void AllocateMemory();
void SetDefaultData();
void HostArray_DrvMemcpy3DAsync(bool device_context_change = false);
void HostDevice_DrvMemcpy3DAsync(bool device_context_change = false);
void Extent_Validation();
void NegativeTests();
void DeAllocateMemory();
};
/* Intializes class variables */
template <typename T>
DrvMemcpy3DAsync<T>::DrvMemcpy3DAsync(int l_width, int l_height, int l_depth,
hipArray_Format l_format) {
width = l_width;
height = l_height;
depth = l_depth;
formatKind = l_format;
}
/* Allocating Memory */
template <typename T>
void DrvMemcpy3DAsync<T>::AllocateMemory() {
size = width * height * depth * sizeof(T);
hData = reinterpret_cast<T*>(malloc(size));
memset(hData, 0, size);
for (int i = 0; i < depth; i++) {
for (int j = 0; j < height; j++) {
for (int k = 0; k < width; k++) {
hData[i*width*height + j*width +k] = i*width*height + j*width + k;
}
}
}
HIP_CHECK(hipStreamCreate(&stream));
HIP_CHECK(hipMallocPitch(reinterpret_cast<void**>(&D_m),
&pitch_D, width*sizeof(T), height));
HIP_CHECK(hipMallocPitch(reinterpret_cast<void**>(&E_m),
&pitch_E, width*sizeof(T), height));
HIP_ARRAY3D_DESCRIPTOR *desc;
desc = reinterpret_cast<HIP_ARRAY3D_DESCRIPTOR*>
(malloc(sizeof(HIP_ARRAY3D_DESCRIPTOR)));
desc->Format = formatKind;
desc->NumChannels = 1;
desc->Width = width;
desc->Height = height;
desc->Depth = depth;
desc->Flags = hipArrayDefault;
HIP_CHECK(hipArray3DCreate(&arr, desc));
HIP_CHECK(hipArray3DCreate(&arr1, desc));
}
/* Setting the default data */
template <typename T>
void DrvMemcpy3DAsync<T>::SetDefaultData() {
memset(&myparms, 0x0, sizeof(HIP_MEMCPY3D));
myparms.srcXInBytes = 0;
myparms.srcY = 0;
myparms.srcZ = 0;
myparms.srcLOD = 0;
myparms.dstXInBytes = 0;
myparms.dstY = 0;
myparms.dstZ = 0;
myparms.dstLOD = 0;
myparms.WidthInBytes = width*sizeof(T);
myparms.Height = height;
myparms.Depth = depth;
}
/*
This function verifies the negative scenarios of
hipDrvMemcpy3DAsync API
*/
template <typename T>
void DrvMemcpy3DAsync<T>::NegativeTests() {
HIP_CHECK(hipSetDevice(0));
AllocateMemory();
SetDefaultData();
int deviceId;
HIP_CHECK(hipGetDevice(&deviceId));
unsigned int MaxPitch;
HIP_CHECK(hipDeviceGetAttribute(reinterpret_cast<int *>(&MaxPitch),
hipDeviceAttributeMaxPitch, deviceId));
myparms.srcHost = hData;
myparms.dstArray = arr;
myparms.srcPitch = width * sizeof(T);
myparms.srcHeight = height;
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_HOST;
myparms.dstMemoryType = CU_MEMORYTYPE_ARRAY;
#else
myparms.srcMemoryType = hipMemoryTypeHost;
myparms.dstMemoryType = hipMemoryTypeArray;
#endif
SECTION("Passing nullptr to Source Host") {
myparms.srcHost = nullptr;
REQUIRE(hipDrvMemcpy3DAsync(&myparms, stream) != hipSuccess);
}
SECTION("Passing both dst host and device") {
myparms.dstHost = hData;
myparms.dstArray = nullptr;
myparms.dstDevice = D_m;
myparms.WidthInBytes = pitch_D;
#if HT_NVIDIA
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
REQUIRE(hipDrvMemcpy3DAsync(&myparms, stream) != hipSuccess);
}
SECTION("Passing max value to WidthInBytes") {
myparms.WidthInBytes = std::numeric_limits<int>::max();
myparms.Height = std::numeric_limits<int>::max();
myparms.Depth = std::numeric_limits<int>::max();
REQUIRE(hipDrvMemcpy3DAsync(&myparms, stream) != hipSuccess);
}
SECTION("Passing width > max width size") {
myparms.WidthInBytes = width*sizeof(T) + 1;
REQUIRE(hipDrvMemcpy3DAsync(&myparms, stream) != hipSuccess);
}
SECTION("Passing height > max height size") {
myparms.Height = height + 1;
REQUIRE(hipDrvMemcpy3DAsync(&myparms, stream) != hipSuccess);
}
SECTION("Passing depth > max depth size") {
myparms.Depth = depth + 1;
REQUIRE(hipDrvMemcpy3DAsync(&myparms, stream) != hipSuccess);
}
SECTION("widthinbytes + srcXinBytes is out of bound") {
myparms.srcXInBytes = 1;
myparms.dstArray = nullptr;
myparms.dstDevice = hipDeviceptr_t(D_m);
myparms.dstPitch = pitch_D;
myparms.dstHeight = height;
#if HT_NVIDIA
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
REQUIRE(hipDrvMemcpy3DAsync(&myparms, stream) != hipSuccess);
}
SECTION("widthinbytes + dstXinBytes is out of bound") {
myparms.dstXInBytes = pitch_D;
myparms.dstArray = nullptr;
myparms.dstDevice = hipDeviceptr_t(D_m);
myparms.dstPitch = pitch_D;
myparms.dstHeight = height;
#if HT_NVIDIA
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
REQUIRE(hipDrvMemcpy3DAsync(&myparms, stream) != hipSuccess);
}
SECTION("srcY + height is out of bound") {
myparms.srcY = 1;
myparms.dstArray = nullptr;
myparms.dstDevice = hipDeviceptr_t(D_m);
myparms.dstPitch = pitch_D;
myparms.dstHeight = height;
#if HT_NVIDIA
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
REQUIRE(hipDrvMemcpy3DAsync(&myparms, stream) != hipSuccess);
}
SECTION("dstY + height out of bounds") {
myparms.dstY = 1;
myparms.dstArray = nullptr;
myparms.dstDevice = hipDeviceptr_t(D_m);
myparms.dstPitch = pitch_D;
myparms.dstHeight = height;
#if HT_NVIDIA
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
REQUIRE(hipDrvMemcpy3DAsync(&myparms, stream) != hipSuccess);
}
SECTION("src pitch greater than Max allowed pitch") {
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_DEVICE;
myparms.dstMemoryType = CU_MEMORYTYPE_HOST;
#else
myparms.srcMemoryType = hipMemoryTypeDevice;
myparms.dstMemoryType = hipMemoryTypeHost;
#endif
myparms.srcDevice = D_m;
myparms.srcHost = nullptr;
myparms.srcPitch = MaxPitch;
myparms.srcHeight = height;
myparms.dstHost = hData;
myparms.dstArray = nullptr;
myparms.dstPitch = width*sizeof(T);
myparms.dstHeight = height;
REQUIRE(hipDrvMemcpy3DAsync(&myparms, stream) != hipSuccess);
}
SECTION("dst pitch greater than Max allowed pitch") {
myparms.dstDevice = hipDeviceptr_t(D_m);
myparms.dstArray = nullptr;
myparms.dstPitch = MaxPitch+1;
myparms.dstHeight = height;
#if HT_NVIDIA
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
REQUIRE(hipDrvMemcpy3DAsync(&myparms, stream) != hipSuccess);
}
SECTION("Nullptr to src/dst device") {
myparms.dstDevice = hipDeviceptr_t(nullptr);
myparms.dstArray = nullptr;
myparms.dstPitch = pitch_D;
myparms.dstHeight = height;
#if HT_NVIDIA
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
REQUIRE(hipDrvMemcpy3DAsync(&myparms, stream) != hipSuccess);
}
SECTION("Nullptr to src/dst array") {
myparms.dstArray = nullptr;
REQUIRE(hipDrvMemcpy3DAsync(&myparms, stream) != hipSuccess);
}
SECTION("Nullptr to hipDrvMemcpy3DAsync") {
REQUIRE(hipDrvMemcpy3DAsync(nullptr, stream) != hipSuccess);
}
DeAllocateMemory();
}
/*
This function verifies the Extent validation scenarios of
hipDrvMemcpy3DAsync API
*/
template <typename T>
void DrvMemcpy3DAsync<T>::Extent_Validation() {
HIP_CHECK(hipSetDevice(0));
// Allocating the memory
AllocateMemory();
// Setting default data
SetDefaultData();
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_HOST;
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.srcMemoryType = hipMemoryTypeHost;
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
myparms.srcHost = hData;
myparms.srcPitch = width * sizeof(T);
myparms.srcHeight = height;
myparms.dstDevice = D_m;
myparms.dstPitch = pitch_D;
myparms.dstHeight = height;
SECTION("WidthInBytes is 0") {
myparms.WidthInBytes = 0;
HIP_CHECK(hipDrvMemcpy3DAsync(&myparms, stream));
HIP_CHECK(hipStreamSynchronize(stream));
}
SECTION("Height is 0") {
myparms.Height = 0;
HIP_CHECK(hipDrvMemcpy3DAsync(&myparms, stream));
HIP_CHECK(hipStreamSynchronize(stream));
}
SECTION("Depth is 0") {
myparms.Depth = 0;
HIP_CHECK(hipDrvMemcpy3DAsync(&myparms, stream));
HIP_CHECK(hipStreamSynchronize(stream));
}
DeAllocateMemory();
}
/*
This Function verifies following functionalities of hipDrvMemcpy3DAsync API
1. Host to Device copy
2. Device to Device
3. Device to Host
In the end validates the results.
This functionality is verified in 2 scenarios
1. Basic scenario on same GPU device
2. Device context change scenario where memory is allocated in 1 GPU
and hipDrvMemcpy3DAsync API is trigerred from another GPU
*/
template <typename T>
void DrvMemcpy3DAsync<T>::HostDevice_DrvMemcpy3DAsync
(bool device_context_change) {
HIP_CHECK(hipSetDevice(0));
bool skip_test = false;
int peerAccess = 0;
AllocateMemory();
if (device_context_change) {
HIP_CHECK(hipDeviceCanAccessPeer(&peerAccess, 0, 1));
if (!peerAccess) {
WARN("skipped the testcase as no peer access");
skip_test = true;
} else {
HIP_CHECK(hipSetDevice(1));
}
}
if (!skip_test) {
SetDefaultData();
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_HOST;
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.srcMemoryType = hipMemoryTypeHost;
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
myparms.srcHost = hData;
myparms.srcPitch = width * sizeof(T);
myparms.srcHeight = height;
myparms.dstDevice = hipDeviceptr_t(D_m);
myparms.dstPitch = pitch_D;
myparms.dstHeight = height;
HIP_CHECK(hipDrvMemcpy3DAsync(&myparms, stream));
HIP_CHECK(hipStreamSynchronize(stream));
// Device to Device
SetDefaultData();
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_DEVICE;
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.srcMemoryType = hipMemoryTypeDevice;
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
myparms.srcDevice = hipDeviceptr_t(D_m);
myparms.srcPitch = pitch_D;
myparms.srcHeight = height;
myparms.dstDevice = hipDeviceptr_t(E_m);
myparms.dstPitch = pitch_E;
myparms.dstHeight = height;
HIP_CHECK(hipDrvMemcpy3DAsync(&myparms, stream));
HIP_CHECK(hipStreamSynchronize(stream));
T *hOutputData = reinterpret_cast<T*>(malloc(size));
memset(hOutputData, 0, size);
// Device to host
SetDefaultData();
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_DEVICE;
myparms.dstMemoryType = CU_MEMORYTYPE_HOST;
#else
myparms.srcMemoryType = hipMemoryTypeDevice;
myparms.dstMemoryType = hipMemoryTypeHost;
#endif
myparms.srcDevice = hipDeviceptr_t(E_m);
myparms.srcPitch = pitch_E;
myparms.srcHeight = height;
myparms.dstHost = hOutputData;
myparms.dstPitch = width * sizeof(T);
myparms.dstHeight = height;
HIP_CHECK(hipDrvMemcpy3DAsync(&myparms, stream));
HIP_CHECK(hipStreamSynchronize(stream));
HipTest::checkArray(hData, hOutputData, width, height, depth);
free(hOutputData);
}
DeAllocateMemory();
}
/*
This Function verifies following functionalities of hipDrvMemcpy3DAsync API
1. Host to Array copy
2. Array to Array
3. Array to Host
In the end validates the results.
This functionality is verified in 2 scenarios
1. Basic scenario on same GPU device
2. Device context change scenario where memory is allocated in 1 GPU
and hipDrvMemcpy3DAsync API is trigerred from another GPU
*/
template <typename T>
void DrvMemcpy3DAsync<T>::HostArray_DrvMemcpy3DAsync
(bool device_context_change) {
HIP_CHECK(hipSetDevice(0));
bool skip_test = false;
int peerAccess = 0;
AllocateMemory();
if (device_context_change) {
HIP_CHECK(hipDeviceCanAccessPeer(&peerAccess, 0, 1));
if (!peerAccess) {
WARN("skipped the testcase as no peer access");
skip_test = true;
} else {
HIP_CHECK(hipSetDevice(1));
}
}
if (!skip_test) {
SetDefaultData();
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_HOST;
myparms.dstMemoryType = CU_MEMORYTYPE_ARRAY;
#else
myparms.srcMemoryType = hipMemoryTypeHost;
myparms.dstMemoryType = hipMemoryTypeArray;
#endif
myparms.srcHost = hData;
myparms.srcPitch = width * sizeof(T);
myparms.srcHeight = height;
myparms.dstArray = arr;
HIP_CHECK(hipDrvMemcpy3DAsync(&myparms, stream));
HIP_CHECK(hipStreamSynchronize(stream));
// Array to Array
SetDefaultData();
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_ARRAY;
myparms.dstMemoryType = CU_MEMORYTYPE_ARRAY;
#else
myparms.srcMemoryType = hipMemoryTypeArray;
myparms.dstMemoryType = hipMemoryTypeArray;
#endif
myparms.srcArray = arr;
myparms.dstArray = arr1;
HIP_CHECK(hipDrvMemcpy3DAsync(&myparms, stream));
HIP_CHECK(hipStreamSynchronize(stream));
T *hOutputData = reinterpret_cast<T*>(malloc(size));
memset(hOutputData, 0, size);
SetDefaultData();
// Device to host
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_ARRAY;
myparms.dstMemoryType = CU_MEMORYTYPE_HOST;
#else
myparms.srcMemoryType = hipMemoryTypeArray;
myparms.dstMemoryType = hipMemoryTypeHost;
#endif
myparms.srcArray = arr1;
myparms.dstHost = hOutputData;
myparms.dstPitch = width * sizeof(T);
myparms.dstHeight = height;
HIP_CHECK(hipDrvMemcpy3DAsync(&myparms, stream));
HIP_CHECK(hipStreamSynchronize(stream));
HipTest::checkArray(hData, hOutputData, width, height, depth);
free(hOutputData);
}
DeAllocateMemory();
}
/* DeAllocating the memory */
template <typename T>
void DrvMemcpy3DAsync<T>::DeAllocateMemory() {
HIP_CHECK(hipArrayDestroy(arr));
HIP_CHECK(hipArrayDestroy(arr1));
HIP_CHECK(hipStreamDestroy(stream));
free(hData);
}
/* Verifying hipDrvMemcpy3DAsync API Host to Array for different datatypes */
TEMPLATE_TEST_CASE("Unit_hipDrvMemcpy3DAsync_MultipleDataTypes", "",
uint8_t, int, float) {
for (int i = 1; i < 25; i++) {
if (std::is_same<TestType, float>::value) {
DrvMemcpy3DAsync<TestType> memcpy3d_float(i, i, i,
HIP_AD_FORMAT_FLOAT);
memcpy3d_float.HostArray_DrvMemcpy3DAsync();
} else if (std::is_same<TestType, uint8_t>::value) {
DrvMemcpy3DAsync<TestType> memcpy3d_intx(i, i, i,
HIP_AD_FORMAT_UNSIGNED_INT8);
memcpy3d_intx.HostArray_DrvMemcpy3DAsync();
} else if (std::is_same<TestType, int>::value) {
DrvMemcpy3DAsync<TestType> memcpy3d_inty(i, i, i,
HIP_AD_FORMAT_SIGNED_INT32);
memcpy3d_inty.HostArray_DrvMemcpy3DAsync();
}
}
}
/* This testcase verifies H2D copy of hipDrvMemcpy3DAsync API */
TEST_CASE("Unit_hipDrvMemcpy3DAsync_HosttoDevice") {
DrvMemcpy3DAsync<float> memcpy3d_D2H_float(10, 10, 1, HIP_AD_FORMAT_FLOAT);
memcpy3d_D2H_float.HostDevice_DrvMemcpy3DAsync();
}
/* This testcase verifies negative scenarios of hipDrvMemcpy3DAsync API */
#if HT_NVIDIA
TEST_CASE("Unit_hipDrvMemcpy3DAsync_Negative") {
DrvMemcpy3DAsync<float> memcpy3d(10, 10, 1, HIP_AD_FORMAT_FLOAT);
memcpy3d.NegativeTests();
}
#endif
/* This testcase verifies extent validation scenarios of
hipDrvMemcpy3DAsync API */
TEST_CASE("Unit_hipDrvMemcpy3DAsync_ExtentValidation") {
DrvMemcpy3DAsync<float> memcpy3d(10, 10, 1, HIP_AD_FORMAT_FLOAT);
memcpy3d.Extent_Validation();
}
/* This testcase verifies H2D copy in device context
change scenario for hipDrvMemcpy3DAsync API */
#if HT_AMD
TEST_CASE("Unit_hipDrvMemcpy3DAsync_H2DDeviceContextChange") {
int numDevices = 0;
HIP_CHECK(hipGetDeviceCount(&numDevices));
if (numDevices > 1) {
DrvMemcpy3DAsync<float> memcpy3d(10, 10, 1, HIP_AD_FORMAT_FLOAT);
memcpy3d.HostDevice_DrvMemcpy3DAsync(true);
} else {
SUCCEED("skipped testcase as Device count is < 2");
}
}
/* This testcase verifies Host to Array copy in device context
change scenario for hipDrvMemcpy3DAsync API */
TEST_CASE("Unit_hipDrvMemcpy3DAsync_Host2ArrayDeviceContextChange") {
int numDevices = 0;
HIP_CHECK(hipGetDeviceCount(&numDevices));
if (numDevices > 1) {
DrvMemcpy3DAsync<float> memcpy3d(10, 10, 10, HIP_AD_FORMAT_FLOAT);
memcpy3d.HostArray_DrvMemcpy3DAsync(true);
} else {
SUCCEED("skipped testcase as Device count is < 2");
}
}
#endif
+573
查看文件
@@ -0,0 +1,573 @@
/*
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 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 Scenarios
* 1. Verifying hipDrvMemcpy3D API for H2A,A2A,A2H scenarios
* 2. Verifying hipDrvMemcpy3D API for H2D,D2D,D2H scenarios
* 3. Verifying Negative Scenarios
* 4. Verifying Extent validation scenarios by passing 0
* 5. Verifying hipDrvMemcpy3D API by allocating Memory in
* one GPU and trigger hipDrvMemcpy3D from peer GPU for
* H2D,D2D,D2H scenarios
* 6. Verifying hipDrvMemcpy3D API by allocating Memory in
* one GPU and trigger hipDrvMemcpy3D from peer GPU for
* H2A,A2A,A2H scenarios
*
* Scenarios 3 is temporarily suspended on AMD
* Scenario 5&6 are not supported in CUDA platform
*/
#include "hip_test_common.hh"
#include "hip_test_checkers.hh"
template<typename T>
class DrvMemcpy3D {
int width, height, depth;
unsigned int size;
hipArray_Format formatKind;
hiparray arr, arr1;
size_t pitch_D, pitch_E;
HIP_MEMCPY3D myparms;
hipDeviceptr_t D_m, E_m;
T* hData{nullptr};
public:
DrvMemcpy3D(int l_width, int l_height, int l_depth,
hipArray_Format l_format);
DrvMemcpy3D() = delete;
void AllocateMemory();
void SetDefaultData();
void HostArray_DrvMemcpy3D(bool device_context_change = false);
void HostDevice_DrvMemcpy3D(bool device_context_change = false);
void Extent_Validation();
void NegativeTests();
void DeAllocateMemory();
};
/* Intializes class variables */
template <typename T>
DrvMemcpy3D<T>::DrvMemcpy3D(int l_width, int l_height, int l_depth,
hipArray_Format l_format) {
width = l_width;
height = l_height;
depth = l_depth;
formatKind = l_format;
}
/* Allocating Memory */
template <typename T>
void DrvMemcpy3D<T>::AllocateMemory() {
size = width * height * depth * sizeof(T);
hData = reinterpret_cast<T*>(malloc(size));
memset(hData, 0, size);
for (int i = 0; i < depth; i++) {
for (int j = 0; j < height; j++) {
for (int k = 0; k < width; k++) {
hData[i*width*height + j*width +k] = i*width*height + j*width + k;
}
}
}
HIP_CHECK(hipMallocPitch(reinterpret_cast<void**>(&D_m),
&pitch_D, width*sizeof(T), height));
HIP_CHECK(hipMallocPitch(reinterpret_cast<void**>(&E_m),
&pitch_E, width*sizeof(T), height));
HIP_ARRAY3D_DESCRIPTOR *desc;
desc = reinterpret_cast<HIP_ARRAY3D_DESCRIPTOR*>
(malloc(sizeof(HIP_ARRAY3D_DESCRIPTOR)));
desc->Format = formatKind;
desc->NumChannels = 1;
desc->Width = width;
desc->Height = height;
desc->Depth = depth;
desc->Flags = hipArrayDefault;
HIP_CHECK(hipArray3DCreate(&arr, desc));
HIP_CHECK(hipArray3DCreate(&arr1, desc));
}
/* Setting the default data */
template <typename T>
void DrvMemcpy3D<T>::SetDefaultData() {
memset(&myparms, 0x0, sizeof(HIP_MEMCPY3D));
myparms.srcXInBytes = 0;
myparms.srcY = 0;
myparms.srcZ = 0;
myparms.srcLOD = 0;
myparms.dstXInBytes = 0;
myparms.dstY = 0;
myparms.dstZ = 0;
myparms.dstLOD = 0;
myparms.WidthInBytes = width*sizeof(T);
myparms.Height = height;
myparms.Depth = depth;
}
/*
This function verifies the negative scenarios of
hipDrvMemcpy3D API
*/
template <typename T>
void DrvMemcpy3D<T>::NegativeTests() {
HIP_CHECK(hipSetDevice(0));
AllocateMemory();
SetDefaultData();
int deviceId;
HIP_CHECK(hipGetDevice(&deviceId));
unsigned int MaxPitch;
HIP_CHECK(hipDeviceGetAttribute(reinterpret_cast<int *>(&MaxPitch),
hipDeviceAttributeMaxPitch, deviceId));
myparms.srcHost = hData;
myparms.dstArray = arr;
myparms.srcPitch = width * sizeof(T);
myparms.srcHeight = height;
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_HOST;
myparms.dstMemoryType = CU_MEMORYTYPE_ARRAY;
#else
myparms.srcMemoryType = hipMemoryTypeHost;
myparms.dstMemoryType = hipMemoryTypeArray;
#endif
SECTION("Passing nullptr to Source Host") {
myparms.srcHost = nullptr;
REQUIRE(hipDrvMemcpy3D(&myparms) != hipSuccess);
}
SECTION("Passing both dst host and device") {
myparms.dstHost = hData;
myparms.dstArray = nullptr;
myparms.dstDevice = D_m;
myparms.WidthInBytes = pitch_D;
#if HT_NVIDIA
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
REQUIRE(hipDrvMemcpy3D(&myparms) != hipSuccess);
}
SECTION("Passing max value to WidthInBytes") {
myparms.WidthInBytes = std::numeric_limits<int>::max();
myparms.Height = std::numeric_limits<int>::max();
myparms.Depth = std::numeric_limits<int>::max();
REQUIRE(hipDrvMemcpy3D(&myparms) != hipSuccess);
}
SECTION("Passing width > max width size") {
myparms.WidthInBytes = width*sizeof(T) + 1;
REQUIRE(hipDrvMemcpy3D(&myparms) != hipSuccess);
}
SECTION("Passing height > max height size") {
myparms.Height = height + 1;
REQUIRE(hipDrvMemcpy3D(&myparms) != hipSuccess);
}
SECTION("Passing depth > max depth size") {
myparms.Depth = depth + 1;
REQUIRE(hipDrvMemcpy3D(&myparms) != hipSuccess);
}
SECTION("widthinbytes + srcXinBytes is out of bound") {
myparms.srcXInBytes = 1;
myparms.dstArray = nullptr;
myparms.dstDevice = hipDeviceptr_t(D_m);
myparms.dstPitch = pitch_D;
myparms.dstHeight = height;
#if HT_NVIDIA
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
REQUIRE(hipDrvMemcpy3D(&myparms) != hipSuccess);
}
SECTION("widthinbytes + dstXinBytes is out of bound") {
myparms.dstXInBytes = pitch_D;
myparms.dstArray = nullptr;
myparms.dstDevice = hipDeviceptr_t(D_m);
myparms.dstPitch = pitch_D;
myparms.dstHeight = height;
#if HT_NVIDIA
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
REQUIRE(hipDrvMemcpy3D(&myparms) != hipSuccess);
}
SECTION("srcY + height is out of bound") {
myparms.srcY = 1;
myparms.dstArray = nullptr;
myparms.dstDevice = hipDeviceptr_t(D_m);
myparms.dstPitch = pitch_D;
myparms.dstHeight = height;
#if HT_NVIDIA
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
REQUIRE(hipDrvMemcpy3D(&myparms) != hipSuccess);
}
SECTION("dstY + height out of bounds") {
myparms.dstY = 1;
myparms.dstArray = nullptr;
myparms.dstDevice = hipDeviceptr_t(D_m);
myparms.dstPitch = pitch_D;
myparms.dstHeight = height;
#if HT_NVIDIA
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
REQUIRE(hipDrvMemcpy3D(&myparms) != hipSuccess);
}
SECTION("src pitch greater than Max allowed pitch") {
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_DEVICE;
myparms.dstMemoryType = CU_MEMORYTYPE_HOST;
#else
myparms.srcMemoryType = hipMemoryTypeDevice;
myparms.dstMemoryType = hipMemoryTypeHost;
#endif
myparms.srcDevice = D_m;
myparms.srcHost = nullptr;
myparms.srcPitch = MaxPitch;
myparms.srcHeight = height;
myparms.dstHost = hData;
myparms.dstArray = nullptr;
myparms.dstPitch = width*sizeof(T);
myparms.dstHeight = height;
REQUIRE(hipDrvMemcpy3D(&myparms) != hipSuccess);
}
SECTION("dst pitch greater than Max allowed pitch") {
myparms.dstDevice = hipDeviceptr_t(D_m);
myparms.dstArray = nullptr;
myparms.dstPitch = MaxPitch+1;
myparms.dstHeight = height;
#if HT_NVIDIA
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
REQUIRE(hipDrvMemcpy3D(&myparms) != hipSuccess);
}
SECTION("Nullptr to src/dst device") {
myparms.dstDevice = hipDeviceptr_t(nullptr);
myparms.dstArray = nullptr;
myparms.dstPitch = pitch_D;
myparms.dstHeight = height;
#if HT_NVIDIA
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
REQUIRE(hipDrvMemcpy3D(&myparms) != hipSuccess);
}
SECTION("Nullptr to src/dst array") {
myparms.dstArray = nullptr;
REQUIRE(hipDrvMemcpy3D(&myparms) != hipSuccess);
}
SECTION("Nullptr to hipDrvMemcpy3D") {
REQUIRE(hipDrvMemcpy3D(nullptr) != hipSuccess);
}
DeAllocateMemory();
}
/*
This function verifies the Extent validation scenarios of
hipDrvMemcpy3D API
*/
template <typename T>
void DrvMemcpy3D<T>::Extent_Validation() {
HIP_CHECK(hipSetDevice(0));
// Allocating the memory
AllocateMemory();
// Setting default data
SetDefaultData();
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_HOST;
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.srcMemoryType = hipMemoryTypeHost;
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
myparms.srcHost = hData;
myparms.srcPitch = width * sizeof(T);
myparms.srcHeight = height;
myparms.dstDevice = D_m;
myparms.dstPitch = pitch_D;
myparms.dstHeight = height;
SECTION("WidthInBytes is 0") {
myparms.WidthInBytes = 0;
HIP_CHECK(hipDrvMemcpy3D(&myparms));
}
SECTION("Height is 0") {
myparms.Height = 0;
HIP_CHECK(hipDrvMemcpy3D(&myparms));
}
SECTION("Depth is 0") {
myparms.Depth = 0;
HIP_CHECK(hipDrvMemcpy3D(&myparms));
}
DeAllocateMemory();
}
/*
This Function verifies following functionalities of hipDrvMemcpy3D API
1. Host to Device copy
2. Device to Device
3. Device to Host
In the end validates the results.
This functionality is verified in 2 scenarios
1. Basic scenario on same GPU device
2. Device context change scenario where memory is allocated in 1 GPU
and hipDrvMemcpy3D API is trigerred from another GPU
*/
template <typename T>
void DrvMemcpy3D<T>::HostDevice_DrvMemcpy3D(bool device_context_change) {
HIP_CHECK(hipSetDevice(0));
bool skip_test = false;
int peerAccess = 0;
AllocateMemory();
if (device_context_change) {
HIP_CHECK(hipDeviceCanAccessPeer(&peerAccess, 0, 1));
if (!peerAccess) {
WARN("skipped the testcase as no peer access");
skip_test = true;
} else {
HIP_CHECK(hipSetDevice(1));
}
}
if (!skip_test) {
SetDefaultData();
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_HOST;
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.srcMemoryType = hipMemoryTypeHost;
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
myparms.srcHost = hData;
myparms.srcPitch = width * sizeof(T);
myparms.srcHeight = height;
myparms.dstDevice = hipDeviceptr_t(D_m);
myparms.dstPitch = pitch_D;
myparms.dstHeight = height;
HIP_CHECK(hipDrvMemcpy3D(&myparms));
// Device to Device
SetDefaultData();
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_DEVICE;
myparms.dstMemoryType = CU_MEMORYTYPE_DEVICE;
#else
myparms.srcMemoryType = hipMemoryTypeDevice;
myparms.dstMemoryType = hipMemoryTypeDevice;
#endif
myparms.srcDevice = hipDeviceptr_t(D_m);
myparms.srcPitch = pitch_D;
myparms.srcHeight = height;
myparms.dstDevice = hipDeviceptr_t(E_m);
myparms.dstPitch = pitch_E;
myparms.dstHeight = height;
HIP_CHECK(hipDrvMemcpy3D(&myparms));
T *hOutputData = reinterpret_cast<T*>(malloc(size));
memset(hOutputData, 0, size);
// Device to host
SetDefaultData();
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_DEVICE;
myparms.dstMemoryType = CU_MEMORYTYPE_HOST;
#else
myparms.srcMemoryType = hipMemoryTypeDevice;
myparms.dstMemoryType = hipMemoryTypeHost;
#endif
myparms.srcDevice = hipDeviceptr_t(E_m);
myparms.srcPitch = pitch_E;
myparms.srcHeight = height;
myparms.dstHost = hOutputData;
myparms.dstPitch = width * sizeof(T);
myparms.dstHeight = height;
HIP_CHECK(hipDrvMemcpy3D(&myparms));
HipTest::checkArray(hData, hOutputData, width, height, depth);
free(hOutputData);
}
DeAllocateMemory();
}
/*
This Function verifies following functionalities of hipDrvMemcpy3D API
1. Host to Array copy
2. Array to Array
3. Array to Host
In the end validates the results.
This functionality is verified in 2 scenarios
1. Basic scenario on same GPU device
2. Device context change scenario where memory is allocated in 1 GPU
and hipDrvMemcpy3D API is trigerred from another GPU
*/
template <typename T>
void DrvMemcpy3D<T>::HostArray_DrvMemcpy3D(bool device_context_change) {
HIP_CHECK(hipSetDevice(0));
bool skip_test = false;
int peerAccess = 0;
AllocateMemory();
if (device_context_change) {
HIP_CHECK(hipDeviceCanAccessPeer(&peerAccess, 0, 1));
if (!peerAccess) {
WARN("skipped the testcase as no peer access");
skip_test = true;
} else {
HIP_CHECK(hipSetDevice(1));
}
}
if (!skip_test) {
SetDefaultData();
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_HOST;
myparms.dstMemoryType = CU_MEMORYTYPE_ARRAY;
#else
myparms.srcMemoryType = hipMemoryTypeHost;
myparms.dstMemoryType = hipMemoryTypeArray;
#endif
myparms.srcHost = hData;
myparms.srcPitch = width * sizeof(T);
myparms.srcHeight = height;
myparms.dstArray = arr;
HIP_CHECK(hipDrvMemcpy3D(&myparms));
// Array to Array
SetDefaultData();
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_ARRAY;
myparms.dstMemoryType = CU_MEMORYTYPE_ARRAY;
#else
myparms.srcMemoryType = hipMemoryTypeArray;
myparms.dstMemoryType = hipMemoryTypeArray;
#endif
myparms.srcArray = arr;
myparms.dstArray = arr1;
HIP_CHECK(hipDrvMemcpy3D(&myparms));
T *hOutputData = reinterpret_cast<T*>(malloc(size));
memset(hOutputData, 0, size);
SetDefaultData();
// Device to host
#if HT_NVIDIA
myparms.srcMemoryType = CU_MEMORYTYPE_ARRAY;
myparms.dstMemoryType = CU_MEMORYTYPE_HOST;
#else
myparms.srcMemoryType = hipMemoryTypeArray;
myparms.dstMemoryType = hipMemoryTypeHost;
#endif
myparms.srcArray = arr1;
myparms.dstHost = hOutputData;
myparms.dstPitch = width * sizeof(T);
myparms.dstHeight = height;
HIP_CHECK(hipDrvMemcpy3D(&myparms));
HipTest::checkArray(hData, hOutputData, width, height, depth);
free(hOutputData);
}
DeAllocateMemory();
}
/* DeAllocating the memory */
template <typename T>
void DrvMemcpy3D<T>::DeAllocateMemory() {
HIP_CHECK(hipArrayDestroy(arr));
HIP_CHECK(hipArrayDestroy(arr1));
free(hData);
}
/* Verifying hipDrvMemcpy3D API Host to Array for different datatypes */
TEMPLATE_TEST_CASE("Unit_hipDrvMemcpy3D_MultipleDataTypes", "",
uint8_t, int, float) {
for (int i = 1; i < 25; i++) {
if (std::is_same<TestType, float>::value) {
DrvMemcpy3D<TestType> memcpy3d_float(i, i, i, HIP_AD_FORMAT_FLOAT);
memcpy3d_float.HostArray_DrvMemcpy3D();
} else if (std::is_same<TestType, uint8_t>::value) {
DrvMemcpy3D<TestType> memcpy3d_intx(i, i, i, HIP_AD_FORMAT_UNSIGNED_INT8);
memcpy3d_intx.HostArray_DrvMemcpy3D();
} else if (std::is_same<TestType, int>::value) {
DrvMemcpy3D<TestType> memcpy3d_inty(i, i, i, HIP_AD_FORMAT_SIGNED_INT32);
memcpy3d_inty.HostArray_DrvMemcpy3D();
}
}
}
/* This testcase verifies H2D copy of hipDrvMemcpy3D API */
TEST_CASE("Unit_hipDrvMemcpy3D_HosttoDevice") {
DrvMemcpy3D<float> memcpy3d_D2H_float(10, 10, 1, HIP_AD_FORMAT_FLOAT);
memcpy3d_D2H_float.HostDevice_DrvMemcpy3D();
}
/* This testcase verifies negative scenarios of hipDrvMemcpy3D API */
#if HT_NVIDIA
TEST_CASE("Unit_hipDrvMemcpy3D_Negative") {
DrvMemcpy3D<float> memcpy3d(10, 10, 1, HIP_AD_FORMAT_FLOAT);
memcpy3d.NegativeTests();
}
#endif
/* This testcase verifies extent validation scenarios of hipDrvMemcpy3D API */
TEST_CASE("Unit_hipDrvMemcpy3D_ExtentValidation") {
DrvMemcpy3D<float> memcpy3d(10, 10, 1, HIP_AD_FORMAT_FLOAT);
memcpy3d.Extent_Validation();
}
#if HT_AMD
/* This testcase verifies H2D copy in device context
change scenario for hipDrvMemcpy3D API */
TEST_CASE("Unit_hipDrvMemcpy3D_H2DDeviceContextChange") {
int numDevices = 0;
HIP_CHECK(hipGetDeviceCount(&numDevices));
if (numDevices > 1) {
DrvMemcpy3D<float> memcpy3d(10, 10, 1, HIP_AD_FORMAT_FLOAT);
memcpy3d.HostDevice_DrvMemcpy3D(true);
} else {
SUCCEED("skipped testcase as Device count is < 2");
}
}
/* This testcase verifies Host to Array copy in device context
change scenario for hipDrvMemcpy3D API */
TEST_CASE("Unit_hipDrvMemcpy3D_Host2ArrayDeviceContextChange") {
int numDevices = 0;
HIP_CHECK(hipGetDeviceCount(&numDevices));
if (numDevices > 1) {
DrvMemcpy3D<float> memcpy3d(10, 10, 1, HIP_AD_FORMAT_FLOAT);
memcpy3d.HostArray_DrvMemcpy3D(true);
} else {
SUCCEED("skipped testcase as Device count is < 2");
}
}
#endif
-221
查看文件
@@ -1,221 +0,0 @@
/*
Copyright (c) 2021-Present 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 Case Description: This test case tests the working of OverSubscription
feature which is part of HMM.*/
#include <hip_test_common.hh>
#ifdef __linux__
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#endif
#include <list>
#define INIT_VAL 2.5
#define NUM_ELMS 268435456 // 268435456 * 4 = 1GB
#define ITERATIONS 10
#define ONE_GB 1024 * 1024 * 1024
static void GetTotGpuMem(int *TotMem);
static void DisplayHmmFlgs(int *Signal);
// Kernel function
__global__ void Square(int n, float *x) {
int index = blockIdx.x * blockDim.x + threadIdx.x;
int stride = blockDim.x * gridDim.x;
for (int i = index; i < n; i += stride) {
x[i] = x[i] + 10;
}
}
static void OneGBMemTest(int dev) {
int DataMismatch = 0;
float *HmmAG = nullptr;
hipStream_t strm;
HIP_CHECK(hipStreamCreate(&strm));
// Testing hipMemAttachGlobal Flag
HIP_CHECK(hipMallocManaged(&HmmAG, NUM_ELMS * sizeof(float),
hipMemAttachGlobal));
// Initializing HmmAG memory
for (int i = 0; i < NUM_ELMS; i++) {
HmmAG[i] = INIT_VAL;
}
int blockSize = 256;
int numBlocks = (NUM_ELMS + blockSize - 1) / blockSize;
dim3 dimGrid(numBlocks, 1, 1);
dim3 dimBlock(blockSize, 1, 1);
HIP_CHECK(hipSetDevice(dev));
for (int i = 0; i < ITERATIONS; ++i) {
Square<<<dimGrid, dimBlock, 0, strm>>>(NUM_ELMS, HmmAG);
}
HIP_CHECK(hipStreamSynchronize(strm));
for (int j = 0; j < NUM_ELMS; ++j) {
if (HmmAG[j] != (INIT_VAL + ITERATIONS * 10)) {
DataMismatch++;
break;
}
}
if (DataMismatch != 0) {
WARN("Data Mismatch observed when kernel launched on device: " << dev);
REQUIRE(false);
}
HIP_CHECK(hipFree(HmmAG));
HIP_CHECK(hipStreamDestroy(strm));
}
static void GetTotGpuMem(int *TotMem) {
size_t FreeMem, TotGpuMem;
HIP_CHECK(hipMemGetInfo(&FreeMem, &TotGpuMem));
TotMem[0] = (TotGpuMem/(ONE_GB));
TotMem[1] = 1;
}
static void DisplayHmmFlgs(int *Signal) {
int managed = 0;
WARN("The following are the attribute values related to HMM for"
" device 0:\n");
HIP_CHECK(hipDeviceGetAttribute(&managed,
hipDeviceAttributeDirectManagedMemAccessFromHost, 0));
WARN("hipDeviceAttributeDirectManagedMemAccessFromHost: " << managed);
HIP_CHECK(hipDeviceGetAttribute(&managed,
hipDeviceAttributeConcurrentManagedAccess, 0));
WARN("hipDeviceAttributeConcurrentManagedAccess: " << managed);
HIP_CHECK(hipDeviceGetAttribute(&managed,
hipDeviceAttributePageableMemoryAccess, 0));
WARN("hipDeviceAttributePageableMemoryAccess: " << managed);
HIP_CHECK(hipDeviceGetAttribute(&managed,
hipDeviceAttributePageableMemoryAccessUsesHostPageTables, 0));
WARN("hipDeviceAttributePageableMemoryAccessUsesHostPageTables:"
<< managed);
HIP_CHECK(hipDeviceGetAttribute(&managed, hipDeviceAttributeManagedMemory,
0));
WARN("hipDeviceAttributeManagedMemory: " << managed);
// Checking for Vega20 or MI100
hipDeviceProp_t prop;
HIP_CHECK(hipGetDeviceProperties(&prop, 0));
char *p = NULL;
p = strstr(prop.gcnArchName, "gfx906");
if (p) {
WARN("This system has MI60 gpu hence OverSubscription test will be");
WARN(" skipped");
Signal[2] = 1;
}
p = strstr(prop.gcnArchName, "gfx908");
if (p) {
WARN("This system has MI100 gpu hence OverSubscription test will be");
WARN(" skipped");
Signal[2] = 1;
}
Signal[1] = managed;
Signal[0] = 1;
}
TEST_CASE("Unit_HMM_OverSubscriptionTst") {
hipDeviceProp_t prop;
HIP_CHECK(hipGetDeviceProperties(&prop, 0));
char *p = nullptr;
p = strstr(prop.gcnArchName, "xnack+");
if (p == nullptr) {
INFO("Skipped due current device is non xnack device.");
return;
}
int HmmEnabled = 0;
// The following Shared Mem is to get Max GPU Mem
// The size requested is for three ints
// 1) To get Max GPU Mem in GB
// 2) To Signal parent that req. info is available to consume
// 3) To know if MI60 or MI100 gpu are there in the system
key_t key = ftok("shmTotMem", 66);
int shmid = shmget(key, (3 * sizeof(int)), 0666|IPC_CREAT);
int *TotGpuMem = reinterpret_cast<int*>(shmat(shmid, NULL, 0));
TotGpuMem[0] = 0; TotGpuMem[1] = 0;
// The following function DisplayHmmFlgs() displays the flag values related
// to HMM and also sends us ManagedMemory attribute value
if (fork() == 0) {
DisplayHmmFlgs(TotGpuMem);
exit(1);
}
while (TotGpuMem[0] == 0) {
sleep(2);
}
// The following if block will skip test if either of MI60 or MI100 is found
if (TotGpuMem[2] == 1) {
SUCCEED("Test is skipped!!");
REQUIRE(true);
} else {
HmmEnabled = TotGpuMem[1];
// Re-setting the shared memory values for further usage
TotGpuMem[0] = 0;
TotGpuMem[1] = 0;
std::list<pid_t> PidLst;
// The following function gets the MaxGpu memory in GBs and also launches
// OverSubscription test
if (HmmEnabled) {
if ((setenv("HSA_XNACK", "1", 1)) != 0) {
WARN("Unable to turn on HSA_XNACK, hence terminating the Test case!");
REQUIRE(false);
}
if (fork() == 0) {
GetTotGpuMem(TotGpuMem);
}
while (TotGpuMem[1] == 0) {
sleep(2);
}
int NumGB = TotGpuMem[0], TotalThreads = (NumGB + 10);
WARN("Launching " << TotalThreads);
WARN(" processes to test OverSubscription.");
pid_t pid;
for (int k = 0; k < TotalThreads; ++k) {
pid = fork();
PidLst.push_back(pid);
if (pid == 0) {
OneGBMemTest(0);
exit(10);
}
}
} else {
SUCCEED("GPU 0 doesn't support hipDeviceAttributeManagedMemory "
"attribute. Hence skipping the testing with Pass result.\n");
}
int status;
for (pid_t pd : PidLst) {
waitpid(pd, &status, 0);
if (!(WIFEXITED(status))) {
REQUIRE(false);
}
}
}
shmdt(TotGpuMem);
shmctl(shmid, IPC_RMID, NULL);
}
+5 -4
查看文件
@@ -67,6 +67,7 @@ THE SOFTWARE.
*/
#include <hip_test_common.hh>
#include <hip_test_features.hh>
#if __linux__
#include <unistd.h>
#include <sys/mman.h>
@@ -661,7 +662,7 @@ TEST_CASE("Unit_hipMemAdvise_TstAlignedAllocMem") {
WARN("Unable to turn on HSA_XNACK, hence terminating the Test case!");
REQUIRE(false);
}
// The following code block checks for gfx90a so as to skip if the device is not MI200
// The following code block checks for gfx90a,940,941,942 so as to skip if the device is not
hipDeviceProp_t prop;
int device;
@@ -669,7 +670,7 @@ TEST_CASE("Unit_hipMemAdvise_TstAlignedAllocMem") {
HIP_CHECK(hipGetDeviceProperties(&prop, device));
std::string gfxName(prop.gcnArchName);
if ((gfxName == "gfx90a" || gfxName.find("gfx90a:")) == 0) {
if (CheckIfFeatSupported(CTFeatures::CT_FEATURE_HMM, prop.gcnArchName)) {
int stat = 0;
if (fork() == 0) {
// The below part should be inside fork
@@ -726,9 +727,9 @@ TEST_CASE("Unit_hipMemAdvise_TstAlignedAllocMem") {
}
}
} else {
SUCCEED("Memory model feature is only supported for gfx90a, Hence"
SUCCEED("Memory model feature is only supported for gfx90a, gfx940, gx941, gfx942, Hence"
"skipping the testcase for this GPU " << device);
WARN("Memory model feature is only supported for gfx90a, Hence"
WARN("Memory model feature is only supported for gfx90a, gfx940, gx941, gfx942, Hence"
"skipping the testcase for this GPU " << device);
}
+39 -6
查看文件
@@ -16,17 +16,35 @@ 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 :
Unit_hipMemGetAddressRange_Positive - Test hipMemGetAddressRange api for various memory allocation
types and offsets Unit_hipMemGetAddressRange_Negative - Test unsuccessful execution of
hipMemGetAddressRange api when parameters are invalid
*/
#include <hip_test_common.hh>
#include <hip/hip_runtime_api.h>
#include <utils.hh>
#include <resource_guards.hh>
/**
* @addtogroup hipMemGetAddressRange hipMemGetAddressRange
* @{
* @ingroup PeerToPeerTest
* `hipMemGetAddressRange(hipDeviceptr_t* pbase, size_t* psize, hipDeviceptr_t dptr)` -
* Get information on memory allocations.
*/
/**
* Test Description
* ------------------------
* - Allocate memory and check if base and size match allocated memory values.
* - Check for various offset values from base memory address:
* - Host address range
* - Device address range
* - Pitch address range
* Test source
* ------------------------
* - unit/memory/hipMemGetAddressRange.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipMemGetAddressRange_Positive") {
hipDeviceptr_t base_ptr;
size_t mem_size = 0;
@@ -67,6 +85,21 @@ TEST_CASE("Unit_hipMemGetAddressRange_Positive") {
}
}
/**
* Test Description
* ------------------------
* - Validates handling of invalid arguments:
* -# When device handle is not valid
* - Expected output: return `hipErrorNotFound`
* -# When offset is greated than allocated size
* - Expected output: return `hipErrorNotFound`
* Test source
* ------------------------
* - unit/memory/hipMemGetAddressRange.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipMemGetAddressRange_Negative") {
hipDeviceptr_t base_ptr;
size_t mem_size = 0;
+15
查看文件
@@ -574,3 +574,18 @@ TEST_CASE("Unit_hipMemGetInfo_Negative") {
HIP_CHECK(hipFree(A_mem));
}
TEST_CASE("Unit_hipMemGetInfo_FreeLessThanTotal") {
unsigned int *A_mem{nullptr};
size_t freeMemInit, totalMemInit;
size_t freeMem, totalMem;
HIP_CHECK(hipMemGetInfo(&freeMemInit, &totalMemInit));
REQUIRE(freeMemInit <= totalMemInit);
HIP_CHECK(hipMalloc(&A_mem, 1024));
HIP_CHECK(hipMemGetInfo(&freeMem, &totalMem));
REQUIRE(freeMem < totalMem);
REQUIRE(totalMem == totalMemInit);
HIP_CHECK(hipFree(A_mem));
}

本差異變更的檔案數量過多導致部分檔案未顯示 顯示更多