Merge 'develop' into 'amd-staging'
Change-Id: I01c1ed73eebf3dd931992ab9512d2ab5020ed803
[ROCm/hip-tests commit: fd130f4444]
此提交包含在:
@@ -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 >>>();
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
* @{
|
||||
|
||||
@@ -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);
|
||||
@@ -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,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
|
||||
|
||||
@@ -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,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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,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)
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,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;
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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()));
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,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,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
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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); }
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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})
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
本差異變更的檔案數量過多導致部分檔案未顯示 顯示更多
新增問題並參考
封鎖使用者