SWDEV-1 - Merge github PRs to amd-staging

Change-Id: I2944a63ddc2eec8dc1403d9790ffffbaec343385
This commit is contained in:
Rakesh Roy
2024-03-04 11:51:34 +05:30
366 changed files with 55399 additions and 2073 deletions
+17 -1
View File
@@ -148,11 +148,27 @@ set(TEST_SRC
hipGraphKernelNodeGetAttribute.cc
hipGraphKernelNodeSetAttribute.cc
hipGraphMemAllocNodeGetParams.cc
hipDrvGraphAddMemcpyNode.cc
hipGraphAddMemAllocNode.cc
hipGraphAddMemFreeNode.cc
hipDrvGraphMemcpyNodeGetParams.cc
hipDrvGraphMemcpyNodeSetParams.cc
hipDeviceSetGraphMemAttribute.cc
hipDeviceGetGraphMemAttribute.cc
hipDeviceGraphMemTrim.cc
)
if(HIP_PLATFORM MATCHES "amd")
set(AMD_SRC
# hipGraphAddNode, hipGraphNodeParams, hipMemcpyNodeParams are not mapped to Nvidia
hipGraphAddNode.cc
# hipDrvGraphAddMemsetNode, HIP_MEMSET_NODE_PARAMS are not mapped to Nvidia
hipDrvGraphAddMemsetNode.cc
# hipDrvGraphAddMemcpyNode not mapped to Nvidia
hipDrvGraphAddMemcpyNode.cc
)
set(TEST_SRC ${TEST_SRC} ${AMD_SRC})
endif()
add_custom_target(add_Kernel.code COMMAND ${CMAKE_CXX_COMPILER} --genco ${OFFLOAD_ARCH_STR} ${CMAKE_CURRENT_SOURCE_DIR}/add_Kernel.cpp -o ${CMAKE_CURRENT_BINARY_DIR}/../graph/add_Kernel.code -I${HIP_PATH}/include/ -I${CMAKE_CURRENT_SOURCE_DIR}/../../include --rocm-path=${ROCM_PATH})
hip_add_exe_to_target(NAME GraphsTest2
@@ -26,14 +26,14 @@ THE SOFTWARE.
#include <resource_guards.hh>
#include <utils.hh>
template <typename T, typename F> void GraphMemsetNodeCommonPositive(F f) {
template <typename T, typename Tp, typename F> void GraphMemsetNodeCommonPositive(F f) {
const size_t width = GENERATE(1, 64, kPageSize / sizeof(T) + 1);
const size_t height = GENERATE(1, 2, 1024);
DYNAMIC_SECTION("Width: " << width << " Height: " << height) {
LinearAllocGuard2D<T> alloc(width, height);
constexpr T set_value = 42;
hipMemsetParams params = {};
Tp params = {};
params.dst = alloc.ptr();
params.elementSize = sizeof(T);
params.width = width;
@@ -50,7 +50,7 @@ template <typename T, typename F> void GraphMemsetNodeCommonPositive(F f) {
}
}
template <typename F> void MemsetCommonNegative(F f, hipMemsetParams params) {
template <typename F, typename T> void MemsetCommonNegative(F f, T params) {
SECTION("pMemsetParams == nullptr") { HIP_CHECK_ERROR(f(nullptr), hipErrorInvalidValue); }
SECTION("pMemsetParams.dst == nullptr") {
@@ -0,0 +1,205 @@
/*
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 <resource_guards.hh>
#include <utils.hh>
/**
* @addtogroup hipDeviceGetGraphMemAttribute hipDeviceGetGraphMemAttribute
* @{
* @ingroup GraphTest
* `hipDeviceGetGraphMemAttribute(int device, hipGraphMemAttributeType attr, void* value)` -
* Get the mem attribute for graphs.
*/
static constexpr auto element_count{64 * 1024 * 1024};
/* Create graph with memory node */
static void createGraph(hipGraphExec_t* graph_exec, int** device_alloc = nullptr) {
constexpr size_t num_bytes = element_count * sizeof(int);
hipGraph_t graph;
HIP_CHECK(hipGraphCreate(&graph, 0));
hipGraphNode_t alloc_node;
hipMemAllocNodeParams alloc_param;
memset(&alloc_param, 0, sizeof(alloc_param));
alloc_param.bytesize = num_bytes;
alloc_param.poolProps.allocType = hipMemAllocationTypePinned;
alloc_param.poolProps.location.id = 0;
alloc_param.poolProps.location.type = hipMemLocationTypeDevice;
HIP_CHECK(hipGraphAddMemAllocNode(&alloc_node, graph, nullptr, 0, &alloc_param));
REQUIRE(alloc_param.dptr != nullptr);
int* A_d = reinterpret_cast<int*>(alloc_param.dptr);
if (device_alloc == nullptr) {
hipGraphNode_t free_node;
HIP_CHECK(hipGraphAddMemFreeNode(&free_node, graph, &alloc_node, 1, (void*)A_d));
} else {
*device_alloc = A_d;
}
// Instantiate graph
HIP_CHECK(hipGraphInstantiate(graph_exec, graph, nullptr, nullptr, 0));
HIP_CHECK(hipGraphDestroy(graph));
}
/* check if memory attributes for graphs contain expected values */
static void checkGraphMemAttribute(size_t used_mem, size_t high_mem) {
size_t read_mem;
hipGraphMemAttributeType attr = hipGraphMemAttrUsedMemCurrent;
HIP_CHECK(hipDeviceGetGraphMemAttribute(0, attr, reinterpret_cast<void*>(&read_mem)));
REQUIRE(read_mem == used_mem);
attr = hipGraphMemAttrReservedMemCurrent;
HIP_CHECK(hipDeviceGetGraphMemAttribute(0, attr, reinterpret_cast<void*>(&read_mem)));
REQUIRE(read_mem == used_mem);
attr = hipGraphMemAttrUsedMemHigh;
HIP_CHECK(hipDeviceGetGraphMemAttribute(0, attr, reinterpret_cast<void*>(&read_mem)));
REQUIRE(read_mem == high_mem);
attr = hipGraphMemAttrReservedMemHigh;
HIP_CHECK(hipDeviceGetGraphMemAttribute(0, attr, reinterpret_cast<void*>(&read_mem)));
REQUIRE(read_mem == high_mem);
}
/**
* Test Description
* ------------------------
* - Basic test to verify that hipDeviceGetGraphMemAttribute return correct memory attribute values
* when graphs with allocation nodes are launched, and after memory is freed to OS.
* Test source
* ------------------------
* - /unit/graph/hipDeviceGetGraphMemAttribute.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.0
*/
TEST_CASE("Unit_hipDeviceGetGraphMemAttribute_Positive_DoubleMemory") {
hipGraphExec_t graph_exec1, graph_exec2;
int *dev_p1, *dev_p2;
StreamGuard stream_guard(Streams::created);
hipStream_t stream = stream_guard.stream();
createGraph(&graph_exec1, &dev_p1);
HIP_CHECK(hipGraphLaunch(graph_exec1, stream));
HIP_CHECK(hipStreamSynchronize(stream));
checkGraphMemAttribute(element_count * sizeof(int), element_count * sizeof(int));
createGraph(&graph_exec2, &dev_p2);
HIP_CHECK(hipGraphLaunch(graph_exec2, stream));
HIP_CHECK(hipStreamSynchronize(stream));
checkGraphMemAttribute(2 * element_count * sizeof(int), 2 * element_count * sizeof(int));
HIP_CHECK(hipFree(dev_p1));
HIP_CHECK(hipFree(dev_p2));
HIP_CHECK(hipGraphExecDestroy(graph_exec1));
HIP_CHECK(hipGraphExecDestroy(graph_exec2));
HIP_CHECK(hipDeviceGraphMemTrim(0));
checkGraphMemAttribute(0, 2 * element_count * sizeof(int));
}
/**
* Test Description
* ------------------------
* - Basic test to verify that hipDeviceGetGraphMemAttribute return correct memory attribute values
* when graphs with allocation and free nodes are launched, and after memory is freed to OS.
* Test source
* ------------------------
* - /unit/graph/hipDeviceGetGraphMemAttribute.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.0
*/
TEST_CASE("Unit_hipDeviceGetGraphMemAttribute_Positive_ReuseMemory") {
hipGraphExec_t graph_exec1, graph_exec2;
StreamGuard stream_guard(Streams::created);
hipStream_t stream = stream_guard.stream();
createGraph(&graph_exec1);
HIP_CHECK(hipGraphLaunch(graph_exec1, stream));
HIP_CHECK(hipStreamSynchronize(stream));
checkGraphMemAttribute(element_count * sizeof(int), element_count * sizeof(int));
createGraph(&graph_exec2);
HIP_CHECK(hipGraphLaunch(graph_exec2, stream));
HIP_CHECK(hipStreamSynchronize(stream));
checkGraphMemAttribute(element_count * sizeof(int), element_count * sizeof(int));
HIP_CHECK(hipGraphExecDestroy(graph_exec1));
HIP_CHECK(hipGraphExecDestroy(graph_exec2));
HIP_CHECK(hipDeviceGraphMemTrim(0));
checkGraphMemAttribute(0, element_count * sizeof(int));
}
/**
* Test Description
* ------------------------
* - Test to verify hipDeviceGetGraphMemAttribute behavior with invalid arguments:
* -# Device is not valid
* -# Attribute value is not valid
* -# Get value is nullptr
* Test source
* ------------------------
* - /unit/graph/hipDeviceGetGraphMemAttribute.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.0
*/
TEST_CASE("Unit_hipDeviceGetGraphMemAttribute_Negative_Parameters") {
int device_id = 0;
HIP_CHECK(hipSetDevice(device_id));
int num_dev = 0;
HIP_CHECK(hipGetDeviceCount(&num_dev));
hipGraphMemAttributeType attr = hipGraphMemAttrUsedMemHigh;
size_t get_value = 0;
SECTION("Device is not valid") {
HIP_CHECK_ERROR(
hipDeviceGetGraphMemAttribute(num_dev, attr, reinterpret_cast<void*>(&get_value)),
hipErrorInvalidDevice);
}
SECTION("Attribute value is not valid") {
HIP_CHECK_ERROR(hipDeviceGetGraphMemAttribute(0, static_cast<hipGraphMemAttributeType>(0x7),
reinterpret_cast<void*>(&get_value)),
hipErrorInvalidValue);
}
SECTION("Get value is nullptr") {
HIP_CHECK_ERROR(hipDeviceGetGraphMemAttribute(0, attr, nullptr), hipErrorInvalidValue);
}
}
+73
View File
@@ -0,0 +1,73 @@
/*
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>
/**
* @addtogroup hipDeviceGraphMemTrim hipDeviceGraphMemTrim
* @{
* @ingroup GraphTest
* `hipDeviceGraphMemTrim(int device)` - Free unused memory on specific device used for graph back
* to OS.
*/
/**
* Test Description
* ------------------------
* - Basic test to verify that unused memory used for graph can be freed on each device.
* Test source
* ------------------------
* - /unit/graph/hipDeviceGraphMemTrim.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.0
*/
TEST_CASE("Unit_hipDeviceGraphMemTrim_Positive_Default") {
const auto device = GENERATE(range(0, HipTest::getDeviceCount()));
// Check for each device
HIP_CHECK(hipDeviceGraphMemTrim(device));
}
/**
* Test Description
* ------------------------
* - Test to verify hipDeviceGraphMemTrim behavior with invalid arguments:
* -# Device is not valid
* Test source
* ------------------------
* - /unit/graph/hipDeviceGraphMemTrim.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.0
*/
TEST_CASE("Unit_hipDeviceGraphMemTrim_Negative_Parameters") {
int device_id = 0;
HIP_CHECK(hipSetDevice(device_id));
int num_dev = 0;
HIP_CHECK(hipGetDeviceCount(&num_dev));
SECTION("Device is not valid") {
HIP_CHECK_ERROR(hipDeviceGraphMemTrim(num_dev), hipErrorInvalidDevice);
}
}
@@ -0,0 +1,117 @@
/*
Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include <hip_test_common.hh>
/**
* @addtogroup hipDeviceSetGraphMemAttribute hipDeviceSetGraphMemAttribute
* @{
* @ingroup GraphTest
* `hipDeviceSetGraphMemAttribute(int device, hipGraphMemAttributeType attr, void* value)` -
* Set the mem attribute for graphs.
*/
static void GraphSetGetAttribute(int device, hipGraphMemAttributeType attr, size_t set_value) {
size_t get_value = 100;
HIP_CHECK(hipDeviceSetGraphMemAttribute(device, attr, &set_value));
HIP_CHECK(hipDeviceGetGraphMemAttribute(device, attr, &get_value));
REQUIRE(get_value == set_value);
}
/**
* Test Description
* ------------------------
* - Basic test to verify that valid attributes can be reset to zero.
* Test source
* ------------------------
* - /unit/graph/hipDeviceSetGraphMemAttribute.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.0
*/
TEST_CASE("Unit_hipDeviceSetGraphMemAttribute_Positive_Default") {
const auto device = GENERATE(range(0, HipTest::getDeviceCount()));
const auto attr_type = GENERATE(hipGraphMemAttrUsedMemHigh, hipGraphMemAttrReservedMemHigh);
// Check if attributes can be reset
size_t set_value = 0;
GraphSetGetAttribute(device, attr_type, set_value);
}
/**
* Test Description
* ------------------------
* - Test to verify hipDeviceSetGraphMemAttribute behavior with invalid arguments:
* -# Device is not valid
* -# Attribute value is not supported
* -# Attribute value is not valid
* -# Set hipGraphMemAttrUsedMemHigh to non-zero
* -# Set hipGraphMemAttrReservedMemHigh to non-zero
* Test source
* ------------------------
* - /unit/graph/hipDeviceSetGraphMemAttribute.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.0
*/
TEST_CASE("Unit_hipDeviceSetGraphMemAttribute_Negative_Parameters") {
int device_id = 0;
HIP_CHECK(hipSetDevice(device_id));
int num_dev = 0;
HIP_CHECK(hipGetDeviceCount(&num_dev));
hipGraphMemAttributeType attr = hipGraphMemAttrUsedMemHigh;
size_t set_value = 0;
SECTION("device is not valid") {
HIP_CHECK_ERROR(
hipDeviceSetGraphMemAttribute(num_dev, attr, reinterpret_cast<void*>(&set_value)),
hipErrorInvalidDevice);
}
SECTION("Attribute value is not supported") {
HIP_CHECK_ERROR(hipDeviceSetGraphMemAttribute(0, hipGraphMemAttrUsedMemCurrent,
reinterpret_cast<void*>(&set_value)),
hipErrorInvalidValue);
}
SECTION("Attribute value is not valid") {
HIP_CHECK_ERROR(hipDeviceSetGraphMemAttribute(0, static_cast<hipGraphMemAttributeType>(0x7),
reinterpret_cast<void*>(&set_value)),
hipErrorInvalidValue);
}
SECTION("Set hipGraphMemAttrUsedMemHigh to non-zero") {
size_t invalid_value = 1;
HIP_CHECK_ERROR(hipDeviceSetGraphMemAttribute(0, attr, reinterpret_cast<void*>(&invalid_value)),
hipErrorInvalidValue);
}
SECTION("Set hipGraphMemAttrReservedMemHigh to non-zero") {
attr = hipGraphMemAttrReservedMemHigh;
size_t invalid_value = 1;
HIP_CHECK_ERROR(hipDeviceSetGraphMemAttribute(0, attr, reinterpret_cast<void*>(&invalid_value)),
hipErrorInvalidValue);
}
}
@@ -17,11 +17,30 @@ OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include <functional>
#include <hip_test_common.hh>
#include <hip_test_defgroups.hh>
#include <hip_test_checkers.hh>
#include <memcpy3d_tests_common.hh>
#include "numeric"
#include "graph_tests_common.hh"
#define XSIZE 32
/**
* @addtogroup hipDrvGraphAddMemcpyNode hipDrvGraphAddMemcpyNode
* @{
* @ingroup GraphTest
* `hipDrvGraphAddMemcpyNode(hipGraphNode_t *pGraphNode, hipGraph_t graph, const
* hipGraphNode_t *pDependencies, size_t numDependencies, const HIP_MEMCPY3D* copyParams, hipCtx_t
ctx)`
- Creates a memcpy node and adds it to a graph
*/
// APIs hipDrvGraphMemcpyNodeGetParams, hipDrvGraphMemcpyNodeSetParams are yet to be implemented in HIP runtime.
#if 0
/**
* Test Description
* ------------------------
@@ -362,3 +381,282 @@ TEST_CASE("Unit_hipDrvGraphAddMemcpyNode_MulitDevice") {
}
}
#endif
/**
* Test Description
* ------------------------
* - Verify basic API behavior. A Memcpy node is created with parameters set according to the
* test run, after which the graph is run and the memcpy results are verified.
* The test is run for all possible memcpy directions, with both the corresponding memcpy
* kind and hipMemcpyDefault, as well as half page and full page allocation sizes.
* Test source
* ------------------------
* - unit/graph/hipDrvGraphAddMemcpyNode.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.0
*/
TEST_CASE("Unit_hipDrvGraphAddMemcpyNode_Positive_Basic") {
using namespace std::placeholders;
constexpr bool async = false;
HIP_CHECK(hipInit(0));
hipDevice_t device;
hipCtx_t context;
HIP_CHECK(hipDeviceGet(&device, 0));
HIP_CHECK(hipCtxCreate(&context, 0, device));
SECTION("Device to host") {
Memcpy3DDeviceToHostShell<async>(
std::bind(DrvMemcpy3DGraphWrapper<>, _1, _2, _3, _4, _5, _6, context, _7));
}
SECTION("Host to device") {
Memcpy3DHostToDeviceShell<async>(
std::bind(DrvMemcpy3DGraphWrapper<>, _1, _2, _3, _4, _5, _6, context, _7));
}
SECTION("Host to host") {
Memcpy3DHostToHostShell<async>(
std::bind(DrvMemcpy3DGraphWrapper<>, _1, _2, _3, _4, _5, _6, context, _7));
}
SECTION("Device to device") {
SECTION("Peer access enabled") {
Memcpy3DDeviceToDeviceShell<async, true>(
std::bind(DrvMemcpy3DGraphWrapper<>, _1, _2, _3, _4, _5, _6, context, _7));
}
SECTION("Peer access disabled") {
Memcpy3DDeviceToDeviceShell<async, false>(
std::bind(DrvMemcpy3DGraphWrapper<>, _1, _2, _3, _4, _5, _6, context, _7));
}
}
HIP_CHECK(hipCtxPopCurrent(&context));
HIP_CHECK(hipCtxDestroy(context));
}
TEST_CASE("Unit_hipDrvGraphAddMemcpyNode_Positive_Array") {
CHECK_IMAGE_SUPPORT
using namespace std::placeholders;
constexpr bool async = false;
HIP_CHECK(hipInit(0));
hipDevice_t device;
hipCtx_t context;
HIP_CHECK(hipDeviceGet(&device, 0));
HIP_CHECK(hipCtxCreate(&context, 0, device));
SECTION("Array from/to Host") {
DrvMemcpy3DArrayHostShell<async>(
std::bind(DrvMemcpy3DGraphWrapper<>, _1, _2, _3, _4, _5, _6, context, _7));
}
SECTION("Array from/to Device") {
DrvMemcpy3DArrayDeviceShell<async>(
std::bind(DrvMemcpy3DGraphWrapper<>, _1, _2, _3, _4, _5, _6, context, _7));
}
HIP_CHECK(hipCtxPopCurrent(&context));
HIP_CHECK(hipCtxDestroy(context));
}
#endif // if 0
/**
* Test Description
* ------------------------
* - Verify API behaviour with invalid arguments:
* -# node is nullptr
* -# graph is nullptr
* -# pDependencies is nullptr when numDependencies is not zero
* -# A node in pDependencies originates from a different graph
* -# numDependencies is invalid
* -# A node is duplicated in pDependencies
* -# dst is nullptr
* -# src is nullptr
* -# dstPitch < width
* -# srcPitch < width
* -# dstPitch > max pitch
* -# srcPitch > max pitch
* -# WidthInBytes + dstXInBytes > dstPitch
* -# WidthInBytes + srcXInBytes > srcPitch
* -# dstY out of bounds
* -# srcY out of bounds
* -# dstZ out of bounds
* -# srcZ out of bounds
* Test source
* ------------------------
* - unit/graph/hipDrvGraphAddMemcpyNode.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.0
*/
TEST_CASE("Unit_hipDrvGraphAddMemcpyNode_Negative_Parameters") {
using namespace std::placeholders;
HIP_CHECK(hipInit(0));
hipDevice_t device;
hipCtx_t context;
HIP_CHECK(hipDeviceGet(&device, 0));
HIP_CHECK(hipCtxCreate(&context, 0, device));
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,
hipCtx_t context) {
hipGraph_t graph = nullptr;
HIP_CHECK(hipGraphCreate(&graph, 0));
hipGraphNode_t node = nullptr;
auto params = GetDrvMemcpy3DParms(dst_ptr, dst_pos, src_ptr, src_pos, extent, kind);
GraphAddNodeCommonNegativeTests(
std::bind(hipDrvGraphAddMemcpyNode, _1, _2, _3, _4, &params, context), graph);
SECTION("dst_ptr.ptr == nullptr") {
hipPitchedPtr invalid_ptr = dst_ptr;
invalid_ptr.ptr = nullptr;
auto params = GetDrvMemcpy3DParms(invalid_ptr, dst_pos, src_ptr, src_pos, extent, kind);
HIP_CHECK_ERROR(hipDrvGraphAddMemcpyNode(&node, graph, nullptr, 0, &params, context),
hipErrorInvalidValue);
}
SECTION("src_ptr.ptr == nullptr") {
hipPitchedPtr invalid_ptr = src_ptr;
invalid_ptr.ptr = nullptr;
auto params = GetDrvMemcpy3DParms(dst_ptr, dst_pos, invalid_ptr, src_pos, extent, kind);
HIP_CHECK_ERROR(hipDrvGraphAddMemcpyNode(&node, graph, nullptr, 0, &params, context),
hipErrorInvalidValue);
}
SECTION("dstPitch < width") {
hipPitchedPtr invalid_ptr = dst_ptr;
invalid_ptr.pitch = extent.width - 1;
auto params = GetDrvMemcpy3DParms(invalid_ptr, dst_pos, src_ptr, src_pos, extent, kind);
HIP_CHECK_ERROR(hipDrvGraphAddMemcpyNode(&node, graph, nullptr, 0, &params, context),
hipErrorInvalidPitchValue);
}
SECTION("srcPitch < width") {
hipPitchedPtr invalid_ptr = src_ptr;
invalid_ptr.pitch = extent.width - 1;
auto params = GetDrvMemcpy3DParms(dst_ptr, dst_pos, invalid_ptr, src_pos, extent, kind);
HIP_CHECK_ERROR(hipDrvGraphAddMemcpyNode(&node, graph, nullptr, 0, &params, context),
hipErrorInvalidPitchValue);
}
SECTION("dstPitch > max pitch") {
int attr = 0;
HIP_CHECK(hipDeviceGetAttribute(&attr, hipDeviceAttributeMaxPitch, 0));
hipPitchedPtr invalid_ptr = dst_ptr;
invalid_ptr.pitch = attr;
auto params = GetDrvMemcpy3DParms(invalid_ptr, dst_pos, src_ptr, src_pos, extent, kind);
HIP_CHECK_ERROR(hipDrvGraphAddMemcpyNode(&node, graph, nullptr, 0, &params, context),
hipErrorInvalidValue);
}
SECTION("srcPitch > max pitch") {
int attr = 0;
HIP_CHECK(hipDeviceGetAttribute(&attr, hipDeviceAttributeMaxPitch, 0));
hipPitchedPtr invalid_ptr = src_ptr;
invalid_ptr.pitch = attr;
auto params = GetDrvMemcpy3DParms(dst_ptr, dst_pos, invalid_ptr, src_pos, extent, kind);
HIP_CHECK_ERROR(hipDrvGraphAddMemcpyNode(&node, graph, nullptr, 0, &params, context),
hipErrorInvalidValue);
}
SECTION("WidthInBytes + dstXInBytes > dstPitch") {
hipPos invalid_pos = dst_pos;
invalid_pos.x = dst_ptr.pitch - extent.width + 1;
auto params = GetDrvMemcpy3DParms(dst_ptr, invalid_pos, src_ptr, src_pos, extent, kind);
HIP_CHECK_ERROR(hipDrvGraphAddMemcpyNode(&node, graph, nullptr, 0, &params, context),
hipErrorInvalidValue);
}
SECTION("WidthInBytes + srcXInBytes > srcPitch") {
hipPos invalid_pos = src_pos;
invalid_pos.x = src_ptr.pitch - extent.width + 1;
auto params = GetDrvMemcpy3DParms(dst_ptr, dst_pos, src_ptr, invalid_pos, extent, kind);
HIP_CHECK_ERROR(hipDrvGraphAddMemcpyNode(&node, graph, nullptr, 0, &params, context),
hipErrorInvalidValue);
}
SECTION("dstY out of bounds") {
hipPos invalid_pos = dst_pos;
invalid_pos.y = 1;
auto params = GetDrvMemcpy3DParms(dst_ptr, invalid_pos, src_ptr, src_pos, extent, kind);
HIP_CHECK_ERROR(hipDrvGraphAddMemcpyNode(&node, graph, nullptr, 0, &params, context),
hipErrorInvalidValue);
}
SECTION("srcY out of bounds") {
hipPos invalid_pos = src_pos;
invalid_pos.y = 1;
auto params = GetDrvMemcpy3DParms(dst_ptr, dst_pos, src_ptr, invalid_pos, extent, kind);
HIP_CHECK_ERROR(hipDrvGraphAddMemcpyNode(&node, graph, nullptr, 0, &params, context),
hipErrorInvalidValue);
}
SECTION("dstZ out of bounds") {
hipPos invalid_pos = dst_pos;
invalid_pos.z = 1;
auto params = GetDrvMemcpy3DParms(dst_ptr, invalid_pos, src_ptr, src_pos, extent, kind);
HIP_CHECK_ERROR(hipDrvGraphAddMemcpyNode(&node, graph, nullptr, 0, &params, context),
hipErrorInvalidValue);
}
SECTION("srcZ out of bounds") {
hipPos invalid_pos = src_pos;
invalid_pos.z = 1;
auto params = GetDrvMemcpy3DParms(dst_ptr, dst_pos, src_ptr, invalid_pos, extent, kind);
HIP_CHECK_ERROR(hipDrvGraphAddMemcpyNode(&node, graph, nullptr, 0, &params, context),
hipErrorInvalidValue);
}
HIP_CHECK(hipGraphDestroy(graph));
};
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, context);
}
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, context);
}
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, context);
}
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, context);
}
HIP_CHECK(hipCtxPopCurrent(&context));
HIP_CHECK(hipCtxDestroy(context));
}
@@ -0,0 +1,672 @@
/*
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 <functional>
#include <vector>
#include <hip_test_defgroups.hh>
#include <hip_test_common.hh>
#include <memcpy3d_tests_common.hh>
#include <resource_guards.hh>
#include <utils.hh>
#include "graph_memset_node_test_common.hh"
#include "graph_tests_common.hh"
#define SIZE 1024
static char memSetVal = 'a';
/**
* @addtogroup hipDrvGraphAddMemsetNode hipDrvGraphAddMemsetNode
* @{
* @ingroup GraphTest
* `hipDrvGraphAddMemsetNode(hipGraphNode_t* phGraphNode, hipGraph_t hGraph, const hipGraphNode_t*
* dependencies, size_t numDependencies, const HIP_MEMSET_NODE_PARAMS* memsetParams, hipCtx_t ctx)`
* - Creates a memset node and adds it to a graph
*/
/**
* Test Description
* ------------------------
* - Verify that all elements of destination memory are set to the correct value.
* The test is repeated for all valid element sizes(1, 2, 4), and several allocations of different
* height and width, both on host and device.
* Test source
* ------------------------
* - unit/graph/hipDrvGraphAddMemsetNode.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.0
*/
TEMPLATE_TEST_CASE("Unit_hipDrvGraphAddMemsetNode_Positive_Basic", "", uint8_t, uint16_t,
uint32_t) {
HIP_CHECK(hipInit(0));
hipDevice_t device;
hipCtx_t context;
HIP_CHECK(hipDeviceGet(&device, 0));
HIP_CHECK(hipCtxCreate(&context, 0, device));
CHECK_IMAGE_SUPPORT
const auto f = [&context](HIP_MEMSET_NODE_PARAMS* params) {
hipGraph_t graph = nullptr;
HIP_CHECK(hipGraphCreate(&graph, 0));
hipGraphNode_t node = nullptr;
HIP_CHECK(hipDrvGraphAddMemsetNode(&node, graph, nullptr, 0, params, context));
hipGraphExec_t graph_exec = nullptr;
HIP_CHECK(hipGraphInstantiate(&graph_exec, graph, nullptr, nullptr, 0));
HIP_CHECK(hipGraphLaunch(graph_exec, hipStreamPerThread));
HIP_CHECK(hipStreamSynchronize(hipStreamPerThread));
HIP_CHECK(hipGraphExecDestroy(graph_exec));
HIP_CHECK(hipGraphDestroy(graph));
return hipSuccess;
};
GraphMemsetNodeCommonPositive<TestType, HIP_MEMSET_NODE_PARAMS>(f);
HIP_CHECK(hipCtxPopCurrent(&context));
HIP_CHECK(hipCtxDestroy(context));
}
/**
* Test Description
* ------------------------
* - Verify API behaviour with invalid arguments:
* -# pGraphNode is nullptr
* -# graph is nullptr
* -# pDependencies is nullptr when numDependencies is not zero
* -# A node in pDependencies originates from a different graph
* -# numDependencies is invalid
* -# A node is duplicated in pDependencies
* -# pMemsetParams is nullptr
* -# pMemsetParams::dst is nullptr
* -# pMemsetParams::elementSize is different from 1, 2, and 4
* -# pMemsetParams::width is zero
* -# pMemsetParams::width is larger than the allocated memory region
* -# pMemsetParams::height is zero
* -# pMemsetParams::pitch is less than width when height is more than 1
* -# pMemsetParams::pitch * pMemsetParams::height is larger than the allocated memory region
* Test source
* ------------------------
* - unit/graph/hipDrvGraphAddMemsetNode.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.0
*/
TEST_CASE("Unit_hipDrvGraphAddMemsetNode_Negative_Parameters") {
using namespace std::placeholders;
HIP_CHECK(hipInit(0));
hipDevice_t device;
hipCtx_t context;
HIP_CHECK(hipDeviceGet(&device, 0));
HIP_CHECK(hipCtxCreate(&context, 0, device));
hipGraph_t graph = nullptr;
HIP_CHECK(hipGraphCreate(&graph, 0));
LinearAllocGuard<int> alloc(LinearAllocs::hipMalloc, 4 * sizeof(int));
HIP_MEMSET_NODE_PARAMS params = {};
params.dst = alloc.ptr();
params.elementSize = sizeof(*alloc.ptr());
params.width = 1;
params.height = 1;
params.value = 42;
GraphAddNodeCommonNegativeTests(
std::bind(hipDrvGraphAddMemsetNode, _1, _2, _3, _4, &params, context), graph);
hipGraphNode_t node = nullptr;
MemsetCommonNegative(std::bind(hipDrvGraphAddMemsetNode, &node, graph, nullptr, 0, _1, context),
params);
HIP_CHECK(hipGraphDestroy(graph));
HIP_CHECK(hipCtxPopCurrent(&context));
HIP_CHECK(hipCtxDestroy(context));
}
/**
* Test Description
* ------------------------
* - Allocate a 2D array using hipMallocPitch. Initialize the allocated memory using
* hipDrvGraphAddMemsetNode. Copy the values in device memory to host using
* hipDrvGraphAddMemcpyNode. Verify the results.
* Test source
* ------------------------
* - unit/graph/hipDrvGraphAddMemsetNode.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.0
*/
TEST_CASE("Unit_hipDrvGraphAddMemsetNode_hipMallocPitch_2D") {
HIP_CHECK(hipInit(0));
hipDevice_t device;
hipCtx_t context;
HIP_CHECK(hipDeviceGet(&device, 0));
HIP_CHECK(hipCtxCreate(&context, 0, device));
CHECK_IMAGE_SUPPORT
size_t width = SIZE * sizeof(char), numW{SIZE}, numH{SIZE}, pitch_A;
char* A_d;
hipGraph_t graph;
std::vector<hipGraphNode_t> nodeDependencies;
// Host memory.
char* A_h = new char[numW * numH];
for (size_t i = 0; i < numW; i++) {
for (size_t j = 0; j < numH; j++) {
*(A_h + i * numH + j) = ' ';
}
}
// 2D Memory allocation hipMallocPitch
HIP_CHECK(hipMallocPitch(reinterpret_cast<void**>(&A_d), &pitch_A, width, numH));
// Create Graph
HIP_CHECK(hipGraphCreate(&graph, 0));
hipGraphNode_t memsetNode, memcpyNode;
// Add MemSet Node
HIP_MEMSET_NODE_PARAMS memsetParams{};
memset(&memsetParams, 0, sizeof(memsetParams));
memsetParams.dst = reinterpret_cast<hipDeviceptr_t>(A_d);
memsetParams.value = memSetVal;
memsetParams.pitch = pitch_A;
memsetParams.elementSize = sizeof(char);
memsetParams.width = numW;
memsetParams.height = numH;
HIP_CHECK(hipDrvGraphAddMemsetNode(&memsetNode, graph, nullptr, 0, &memsetParams, context));
nodeDependencies.push_back(memsetNode);
// Add MemCpy Node
auto srcPos = make_hipPos(0, 0, 0);
auto dstPos = make_hipPos(0, 0, 0);
auto srcPtr = make_hipPitchedPtr(A_d, pitch_A, numW, numH);
auto dstPtr = make_hipPitchedPtr(A_h, width, numW, numH);
auto extent = make_hipExtent(width, numH, 1);
hipMemcpyKind kind = hipMemcpyDeviceToHost;
HIP_MEMCPY3D myparms = GetDrvMemcpy3DParms(dstPtr, dstPos, srcPtr, srcPos, extent, kind);
HIP_CHECK(hipDrvGraphAddMemcpyNode(&memcpyNode, graph, nodeDependencies.data(),
nodeDependencies.size(), &myparms, context));
nodeDependencies.clear();
// Create executable graph
hipStream_t streamForGraph;
hipGraphExec_t graphExec;
HIP_CHECK(hipStreamCreate(&streamForGraph));
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
HIP_CHECK(hipGraphLaunch(graphExec, streamForGraph));
HIP_CHECK(hipStreamSynchronize(streamForGraph));
// Verfication
for (size_t i = 0; i < numW; i++) {
for (size_t j = 0; j < numH; j++) {
REQUIRE(*(A_h + i * numH + j) == memSetVal);
}
}
HIP_CHECK(hipGraphExecDestroy(graphExec));
HIP_CHECK(hipGraphDestroy(graph));
HIP_CHECK(hipStreamDestroy(streamForGraph));
delete[] A_h;
HIP_CHECK(hipFree(A_d));
HIP_CHECK(hipCtxPopCurrent(&context));
HIP_CHECK(hipCtxDestroy(context));
}
/**
* Test Description
* ------------------------
* - Allocate a 1D array using hipMallocPitch. Initialize the allocated memory using
* hipDrvGraphAddMemsetNode. Copy the values in device memory to host using
* hipDrvGraphAddMemcpyNode. Verify the results.
* Test source
* ------------------------
* - unit/graph/hipDrvGraphAddMemsetNode.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.0
*/
TEST_CASE("Unit_hipDrvGraphAddMemsetNode_hipMallocPitch_1D") {
HIP_CHECK(hipInit(0));
hipDevice_t device;
hipCtx_t context;
HIP_CHECK(hipDeviceGet(&device, 0));
HIP_CHECK(hipCtxCreate(&context, 0, device));
CHECK_IMAGE_SUPPORT
size_t width = SIZE * sizeof(char), numW{SIZE}, pitch_A;
char* A_d;
// Initialize the host memory
std::vector<char> A_h(numW, ' ');
hipGraph_t graph;
std::vector<hipGraphNode_t> nodeDependencies;
// 1D Memory allocation hipMallocPitch
HIP_CHECK(hipMallocPitch(reinterpret_cast<void**>(&A_d), &pitch_A, width, 1));
// Create Graph
HIP_CHECK(hipGraphCreate(&graph, 0));
hipGraphNode_t memsetNode, memcpyNode;
// Add MemSet Node
HIP_MEMSET_NODE_PARAMS memsetParams{};
memset(&memsetParams, 0, sizeof(memsetParams));
memsetParams.dst = reinterpret_cast<hipDeviceptr_t>(A_d);
memsetParams.value = memSetVal;
memsetParams.pitch = pitch_A;
memsetParams.elementSize = sizeof(char);
memsetParams.width = numW;
memsetParams.height = 1;
HIP_CHECK(hipDrvGraphAddMemsetNode(&memsetNode, graph, nullptr, 0, &memsetParams, context));
nodeDependencies.push_back(memsetNode);
// Add MemCpy Node
auto srcPos = make_hipPos(0, 0, 0);
auto dstPos = make_hipPos(0, 0, 0);
auto srcPtr = make_hipPitchedPtr(A_d, pitch_A, numW, 1);
auto dstPtr = make_hipPitchedPtr(A_h.data(), width, numW, 1);
auto extent = make_hipExtent(width, 1, 1);
hipMemcpyKind kind = hipMemcpyDeviceToHost;
HIP_MEMCPY3D myparms = GetDrvMemcpy3DParms(dstPtr, dstPos, srcPtr, srcPos, extent, kind);
HIP_CHECK(hipDrvGraphAddMemcpyNode(&memcpyNode, graph, nodeDependencies.data(),
nodeDependencies.size(), &myparms, context));
nodeDependencies.clear();
// Create executable graph
hipStream_t streamForGraph;
hipGraphExec_t graphExec;
HIP_CHECK(hipStreamCreate(&streamForGraph));
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
HIP_CHECK(hipGraphLaunch(graphExec, streamForGraph));
HIP_CHECK(hipStreamSynchronize(streamForGraph));
// Verfication
for (size_t i = 0; i < numW; i++) {
REQUIRE(A_h[i] == memSetVal);
}
HIP_CHECK(hipGraphExecDestroy(graphExec));
HIP_CHECK(hipGraphDestroy(graph));
HIP_CHECK(hipStreamDestroy(streamForGraph));
HIP_CHECK(hipFree(A_d));
HIP_CHECK(hipCtxPopCurrent(&context));
HIP_CHECK(hipCtxDestroy(context));
}
/**
* Test Description
* ------------------------
* - Allocate a 2D array using hipMalloc3D. Initialize the allocated memory using
* hipDrvGraphAddMemsetNode. Copy the values in device memory to host using
* hipDrvGraphAddMemcpyNode. Verify the results.
* Test source
* ------------------------
* - unit/graph/hipDrvGraphAddMemsetNode.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.0
*/
TEST_CASE("Unit_hipDrvGraphAddMemsetNode_hipMalloc3D_2D") {
HIP_CHECK(hipInit(0));
hipDevice_t device;
hipCtx_t context;
HIP_CHECK(hipDeviceGet(&device, 0));
HIP_CHECK(hipCtxCreate(&context, 0, device));
CHECK_IMAGE_SUPPORT
size_t width = SIZE * sizeof(char);
size_t numW = SIZE, numH = SIZE;
// Host Memory
char* A_h = new char[numW * numH];
for (size_t i = 0; i < numW; i++) {
for (size_t j = 0; j < numH; j++) {
*(A_h + i * numH + j) = ' ';
}
}
hipGraph_t graph;
std::vector<hipGraphNode_t> nodeDependencies;
hipPitchedPtr A_d;
hipExtent extent3D = make_hipExtent(width, numH, 1);
// Allocate 3D memory.
HIPCHECK(hipMalloc3D(&A_d, extent3D));
// Create Graph
HIP_CHECK(hipGraphCreate(&graph, 0));
hipGraphNode_t memsetNode, memcpyNode;
// Add MemSet Node
HIP_MEMSET_NODE_PARAMS memsetParams{};
memset(&memsetParams, 0, sizeof(memsetParams));
memsetParams.dst = reinterpret_cast<hipDeviceptr_t>(A_d.ptr);
memsetParams.value = memSetVal;
memsetParams.pitch = A_d.pitch;
memsetParams.elementSize = sizeof(char);
memsetParams.width = numW;
memsetParams.height = numH;
HIP_CHECK(hipDrvGraphAddMemsetNode(&memsetNode, graph, nullptr, 0, &memsetParams, context));
nodeDependencies.push_back(memsetNode);
// Add MemCpy Node
auto srcPos = make_hipPos(0, 0, 0);
auto dstPos = make_hipPos(0, 0, 0);
auto srcPtr = A_d;
auto dstPtr = make_hipPitchedPtr(A_h, width, numW, numH);
auto extent = make_hipExtent(width, numH, 1);
hipMemcpyKind kind = hipMemcpyDeviceToHost;
HIP_MEMCPY3D myparms = GetDrvMemcpy3DParms(dstPtr, dstPos, srcPtr, srcPos, extent, kind);
HIP_CHECK(hipDrvGraphAddMemcpyNode(&memcpyNode, graph, nodeDependencies.data(),
nodeDependencies.size(), &myparms, context));
nodeDependencies.clear();
// Create executable graph
hipStream_t streamForGraph;
hipGraphExec_t graphExec;
HIP_CHECK(hipStreamCreate(&streamForGraph));
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
HIP_CHECK(hipGraphLaunch(graphExec, streamForGraph));
HIP_CHECK(hipStreamSynchronize(streamForGraph));
// Verfication
for (size_t i = 0; i < numW; i++) {
for (size_t j = 0; j < numH; j++) {
REQUIRE(*(A_h + i * numH + j) == memSetVal);
}
}
HIP_CHECK(hipGraphExecDestroy(graphExec));
HIP_CHECK(hipGraphDestroy(graph));
HIP_CHECK(hipStreamDestroy(streamForGraph));
delete[] A_h;
HIP_CHECK(hipFree(A_d.ptr));
HIP_CHECK(hipCtxPopCurrent(&context));
HIP_CHECK(hipCtxDestroy(context));
}
/**
* Test Description
* ------------------------
* - Allocate a 1D array using hipMalloc3D. Initialize the allocated memory using
* hipDrvGraphAddMemsetNode. Copy the values in device memory to host using
* hipDrvGraphAddMemcpyNode. Verify the results.
* Test source
* ------------------------
* - unit/graph/hipDrvGraphAddMemsetNode.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.0
*/
TEST_CASE("Unit_hipDrvGraphAddMemsetNode_hipMalloc3D_1D") {
HIP_CHECK(hipInit(0));
hipDevice_t device;
hipCtx_t context;
HIP_CHECK(hipDeviceGet(&device, 0));
HIP_CHECK(hipCtxCreate(&context, 0, device));
CHECK_IMAGE_SUPPORT
size_t width = SIZE * sizeof(char);
size_t numW = SIZE;
// Initialize the host memory
std::vector<char> A_h(numW, ' ');
hipGraph_t graph;
std::vector<hipGraphNode_t> nodeDependencies;
hipPitchedPtr A_d;
hipExtent extent1D = make_hipExtent(width, 1, 1);
// Allocate 3D memory.
HIPCHECK(hipMalloc3D(&A_d, extent1D));
// Create Graph
HIP_CHECK(hipGraphCreate(&graph, 0));
hipGraphNode_t memsetNode, memcpyNode;
// Add MemSet Node
HIP_MEMSET_NODE_PARAMS memsetParams{};
memset(&memsetParams, 0, sizeof(memsetParams));
memsetParams.dst = reinterpret_cast<hipDeviceptr_t>(A_d.ptr);
memsetParams.value = memSetVal;
memsetParams.pitch = A_d.pitch;
memsetParams.elementSize = sizeof(char);
memsetParams.width = numW;
memsetParams.height = 1;
HIP_CHECK(hipDrvGraphAddMemsetNode(&memsetNode, graph, nullptr, 0, &memsetParams, context));
nodeDependencies.push_back(memsetNode);
// Add MemCpy Node
auto srcPos = make_hipPos(0, 0, 0);
auto dstPos = make_hipPos(0, 0, 0);
auto srcPtr = A_d;
auto dstPtr = make_hipPitchedPtr(A_h.data(), width, numW, 1);
auto extent = make_hipExtent(width, 1, 1);
hipMemcpyKind kind = hipMemcpyDeviceToHost;
HIP_MEMCPY3D myparms = GetDrvMemcpy3DParms(dstPtr, dstPos, srcPtr, srcPos, extent, kind);
HIP_CHECK(hipDrvGraphAddMemcpyNode(&memcpyNode, graph, nodeDependencies.data(),
nodeDependencies.size(), &myparms, context));
nodeDependencies.clear();
// Create executable graph
hipStream_t streamForGraph;
hipGraphExec_t graphExec;
HIP_CHECK(hipStreamCreate(&streamForGraph));
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
HIP_CHECK(hipGraphLaunch(graphExec, streamForGraph));
HIP_CHECK(hipStreamSynchronize(streamForGraph));
// Verfication
for (size_t i = 0; i < numW; i++) {
REQUIRE(A_h[i] == memSetVal);
}
HIP_CHECK(hipGraphExecDestroy(graphExec));
HIP_CHECK(hipGraphDestroy(graph));
HIP_CHECK(hipStreamDestroy(streamForGraph))
HIP_CHECK(hipFree(A_d.ptr));
HIP_CHECK(hipCtxPopCurrent(&context));
HIP_CHECK(hipCtxDestroy(context));
}
/**
* Test Description
* ------------------------
* - Allocate a 1D array using hipMalloc. Initialize the allocated memory using
* hipDrvGraphAddMemsetNode. Copy the values in device memory to host using
* hipDrvGraphAddMemcpyNode. Verify the results.
* Test source
* ------------------------
* - unit/graph/hipDrvGraphAddMemsetNode.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.0
*/
TEST_CASE("Unit_hipDrvGraphAddMemsetNode_hipMalloc_1D") {
HIP_CHECK(hipInit(0));
hipDevice_t device;
hipCtx_t context;
HIP_CHECK(hipDeviceGet(&device, 0));
HIP_CHECK(hipCtxCreate(&context, 0, device));
char* A_d;
size_t NumW = SIZE;
size_t Nbytes1D = SIZE * sizeof(char);
// Initialize the host memory
std::vector<char> A_h(NumW, ' ');
// Allocate memory to Device pointer
HIP_CHECK(hipMalloc(reinterpret_cast<void**>(&A_d), Nbytes1D));
// Create the graph
hipGraph_t graph;
std::vector<hipGraphNode_t> nodeDependencies;
hipGraphNode_t memsetNode, memcpyNode;
HIP_CHECK(hipGraphCreate(&graph, 0));
// Add Memset node
HIP_MEMSET_NODE_PARAMS memsetParams{};
memset(&memsetParams, 0, sizeof(memsetParams));
memsetParams.dst = reinterpret_cast<hipDeviceptr_t>(A_d);
memsetParams.value = memSetVal;
memsetParams.pitch = Nbytes1D;
memsetParams.elementSize = sizeof(char);
memsetParams.width = NumW;
memsetParams.height = 1;
HIP_CHECK(hipDrvGraphAddMemsetNode(&memsetNode, graph, nullptr, 0, &memsetParams, context));
nodeDependencies.push_back(memsetNode);
// Add MemCpy Node
hipPitchedPtr devPitchedPtr{A_d, Nbytes1D, NumW, 0};
hipPitchedPtr hostPitchedPtr{A_h.data(), Nbytes1D, NumW, 0};
auto srcPos = make_hipPos(0, 0, 0);
auto dstPos = make_hipPos(0, 0, 0);
auto srcPtr = devPitchedPtr;
auto dstPtr = hostPitchedPtr;
auto extent = make_hipExtent(Nbytes1D, 1, 1);
hipMemcpyKind kind = hipMemcpyDeviceToHost;
HIP_MEMCPY3D myparms = GetDrvMemcpy3DParms(dstPtr, dstPos, srcPtr, srcPos, extent, kind);
HIP_CHECK(hipDrvGraphAddMemcpyNode(&memcpyNode, graph, nodeDependencies.data(),
nodeDependencies.size(), &myparms, context));
nodeDependencies.clear();
// Create executable graph
hipStream_t streamForGraph;
hipGraphExec_t graphExec;
HIP_CHECK(hipStreamCreate(&streamForGraph));
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
HIP_CHECK(hipGraphLaunch(graphExec, streamForGraph));
HIP_CHECK(hipStreamSynchronize(streamForGraph));
// Verfication
for (size_t i = 0; i < NumW; i++) {
REQUIRE(A_h[i] == memSetVal);
}
HIP_CHECK(hipGraphExecDestroy(graphExec));
HIP_CHECK(hipGraphDestroy(graph));
HIP_CHECK(hipStreamDestroy(streamForGraph));
HIP_CHECK(hipFree(A_d));
HIP_CHECK(hipCtxPopCurrent(&context));
HIP_CHECK(hipCtxDestroy(context));
}
/**
* Test Description
* ------------------------
* - Allocate a 1D array using hipMallocManaged. Initialize the allocated memory using
* hipDrvGraphAddMemsetNode. Copy the values in device memory to host using
* hipDrvGraphAddMemcpyNode. Verify the results.
* Test source
* ------------------------
* - unit/graph/hipDrvGraphAddMemsetNode.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.0
*/
TEST_CASE("Unit_hipDrvGraphAddMemsetNode_hipMallocManaged") {
HIP_CHECK(hipInit(0));
hipDevice_t device;
hipCtx_t context;
HIP_CHECK(hipDeviceGet(&device, 0));
HIP_CHECK(hipCtxCreate(&context, 0, device));
int managed = 0;
HIP_CHECK(hipDeviceGetAttribute(&managed, hipDeviceAttributeManagedMemory, 0));
INFO("hipDeviceAttributeManagedMemory: " << managed);
if (managed != 1) {
WARN(
"GPU 0 doesn't support hipDeviceAttributeManagedMemory attribute"
"so defaulting to system memory.");
}
size_t Nbytes1D = SIZE * sizeof(char);
char* A_d;
// Initialize the host memory
std::vector<char> A_h(SIZE, ' ');
// Device Memory
HIP_CHECK(hipMallocManaged(&A_d, SIZE * sizeof(char)));
// Create the graph
hipGraph_t graph;
std::vector<hipGraphNode_t> nodeDependencies;
hipGraphNode_t memsetNode, memcpyNode;
HIP_CHECK(hipGraphCreate(&graph, 0));
// Add Memset node
HIP_MEMSET_NODE_PARAMS memsetParams{};
memset(&memsetParams, 0, sizeof(memsetParams));
memsetParams.dst = reinterpret_cast<hipDeviceptr_t>(A_d);
memsetParams.value = memSetVal;
memsetParams.pitch = Nbytes1D;
memsetParams.elementSize = sizeof(char);
memsetParams.width = SIZE;
memsetParams.height = 1;
HIP_CHECK(hipDrvGraphAddMemsetNode(&memsetNode, graph, nullptr, 0, &memsetParams, context));
nodeDependencies.push_back(memsetNode);
// Add MemCpy Node
hipPitchedPtr devPitchedPtr{A_d, Nbytes1D, SIZE, 1};
hipPitchedPtr hostPitchedPtr{A_h.data(), Nbytes1D, SIZE, 1};
auto srcPos = make_hipPos(0, 0, 0);
auto dstPos = make_hipPos(0, 0, 0);
auto srcPtr = devPitchedPtr;
auto dstPtr = hostPitchedPtr;
auto extent = make_hipExtent(Nbytes1D, 1, 1);
hipMemcpyKind kind = hipMemcpyDeviceToHost;
HIP_MEMCPY3D myparms = GetDrvMemcpy3DParms(dstPtr, dstPos, srcPtr, srcPos, extent, kind);
HIP_CHECK(hipDrvGraphAddMemcpyNode(&memcpyNode, graph, nodeDependencies.data(),
nodeDependencies.size(), &myparms, context));
nodeDependencies.clear();
// Create executable graph
hipStream_t streamForGraph;
hipGraphExec_t graphExec;
HIP_CHECK(hipStreamCreate(&streamForGraph));
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
HIP_CHECK(hipGraphLaunch(graphExec, streamForGraph));
HIP_CHECK(hipStreamSynchronize(streamForGraph));
// Verfication
for (size_t i = 0; i < SIZE; i++) {
REQUIRE(A_h[i] == memSetVal);
}
HIP_CHECK(hipGraphExecDestroy(graphExec));
HIP_CHECK(hipGraphDestroy(graph));
HIP_CHECK(hipStreamDestroy(streamForGraph));
HIP_CHECK(hipFree(A_d));
HIP_CHECK(hipCtxPopCurrent(&context));
HIP_CHECK(hipCtxDestroy(context));
}
@@ -0,0 +1,94 @@
/*
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_defgroups.hh>
#include <hip_test_common.hh>
#include <memcpy3d_tests_common.hh>
// hipDrvGraphAddMemcpyNode API is yet to be implemented in HIP runtime.
#if 0
/**
* @addtogroup hipDrvGraphMemcpyNodeGetParams hipDrvGraphMemcpyNodeGetParams
* @{
* @ingroup GraphTest
* `hipDrvGraphMemcpyNodeGetParams(hipGraphNode_t hNode, HIP_MEMCPY3D* nodeParams)` -
* Gets a memcpy node's parameters
* ________________________
* Test cases from other APIs:
* - @ref Unit_hipDrvGraphMemcpyNodeSetParams_Positive_Basic
*/
/**
* Test Description
* ------------------------
* - Verify API behaviour with invalid arguments:
* -# node is nullptr
* -# pNodeParams is nullptr
* -# node is destroyed
* Test source
* ------------------------
* - unit/graph/hipDrvGraphMemcpyNodeGetParams.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.0
*/
TEST_CASE("Unit_hipDrvGraphMemcpyNodeGetParams_Negative_Parameters") {
HIP_CHECK(hipInit(0));
hipDevice_t device;
hipCtx_t context;
HIP_CHECK(hipDeviceGet(&device, 0));
HIP_CHECK(hipCtxCreate(&context, 0, device));
constexpr hipExtent extent{128 * sizeof(int), 128, 8};
LinearAllocGuard3D<int> src_alloc(extent);
LinearAllocGuard3D<int> dst_alloc(extent);
auto params =
GetDrvMemcpy3DParms(dst_alloc.pitched_ptr(), make_hipPos(0, 0, 0), src_alloc.pitched_ptr(),
make_hipPos(0, 0, 0), dst_alloc.extent(), hipMemcpyDeviceToDevice);
hipGraph_t graph = nullptr;
hipGraphNode_t node = nullptr;
SECTION("node == nullptr") {
HIP_CHECK_ERROR(hipDrvGraphMemcpyNodeGetParams(nullptr, &params), hipErrorInvalidValue);
}
SECTION("pNodeParams == nullptr") {
HIP_CHECK(hipGraphCreate(&graph, 0));
HIP_CHECK(hipDrvGraphAddMemcpyNode(&node, graph, nullptr, 0, &params, context));
HIP_CHECK_ERROR(hipDrvGraphMemcpyNodeGetParams(node, nullptr), hipErrorInvalidValue);
HIP_CHECK(hipGraphDestroy(graph));
}
SECTION("Node is destroyed") {
HIP_CHECK(hipGraphCreate(&graph, 0));
HIP_CHECK(hipDrvGraphAddMemcpyNode(&node, graph, nullptr, 0, &params, context));
HIP_CHECK(hipGraphDestroy(graph));
HIP_CHECK_ERROR(hipDrvGraphMemcpyNodeGetParams(node, &params), hipErrorInvalidValue);
}
HIP_CHECK(hipCtxPopCurrent(&context));
HIP_CHECK(hipCtxDestroy(context));
}
#endif // if 0
@@ -0,0 +1,317 @@
/*
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 <functional>
#include <hip_test_common.hh>
#include <hip_test_defgroups.hh>
#include <memcpy3d_tests_common.hh>
// hipDrvGraphMemcpyNodeSetParams API is is yet to be implemented in HIP runtime.
#if 0
/**
* @addtogroup hipDrvGraphMemcpyNodeSetParams hipDrvGraphMemcpyNodeSetParams
* @{
* @ingroup GraphTest
* `hipDrvGraphMemcpyNodeSetParams(hipGraphNode_t hNode, const HIP_MEMCPY3D* nodeParams)` - Sets a
* memcpy node's parameters
*/
/**
* Test Description
* ------------------------
* - Verify that node parameters get updated correctly by creating a node with valid but
* incorrect parameters, and then setting them to the correct values after which the graph is
* executed and the results of the memcpy verified.
* The test is run for all possible memcpy directions, with both the corresponding memcpy
* kind and hipMemcpyDefault, as well as half page and full page allocation sizes.
* Test source
* ------------------------
* - unit/graph/hipDrvGraphMemcpyNodeSetParams.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.0
*/
TEST_CASE("Unit_hipDrvGraphMemcpyNodeSetParams_Positive_Basic") {
using namespace std::placeholders;
constexpr bool async = false;
HIP_CHECK(hipInit(0));
hipDevice_t device;
hipCtx_t context;
HIP_CHECK(hipDeviceGet(&device, 0));
HIP_CHECK(hipCtxCreate(&context, 0, device));
SECTION("Device to host") {
Memcpy3DDeviceToHostShell<async>(
std::bind(DrvMemcpy3DGraphWrapper<true>, _1, _2, _3, _4, _5, _6, context, _7));
}
SECTION("Host to device") {
Memcpy3DHostToDeviceShell<async>(
std::bind(DrvMemcpy3DGraphWrapper<true>, _1, _2, _3, _4, _5, _6, context, _7));
}
SECTION("Host to host") {
Memcpy3DHostToHostShell<async>(
std::bind(DrvMemcpy3DGraphWrapper<true>, _1, _2, _3, _4, _5, _6, context, _7));
}
SECTION("Device to device") {
SECTION("Peer access enabled") {
Memcpy3DDeviceToDeviceShell<async, true>(
std::bind(DrvMemcpy3DGraphWrapper<true>, _1, _2, _3, _4, _5, _6, context, _7));
}
SECTION("Peer access disabled") {
Memcpy3DDeviceToDeviceShell<async, false>(
std::bind(DrvMemcpy3DGraphWrapper<true>, _1, _2, _3, _4, _5, _6, context, _7));
}
}
HIP_CHECK(hipCtxPopCurrent(&context));
HIP_CHECK(hipCtxDestroy(context));
}
TEST_CASE("Unit_hipDrvGraphMemcpyNodeSetParams_Positive_Array") {
CHECK_IMAGE_SUPPORT
using namespace std::placeholders;
constexpr bool async = false;
HIP_CHECK(hipInit(0));
hipDevice_t device;
hipCtx_t context;
HIP_CHECK(hipDeviceGet(&device, 0));
HIP_CHECK(hipCtxCreate(&context, 0, device));
SECTION("Array from/to Host") {
DrvMemcpy3DArrayHostShell<async>(
std::bind(DrvMemcpy3DGraphWrapper<true>, _1, _2, _3, _4, _5, _6, context, _7));
}
SECTION("Array from/to Device") {
DrvMemcpy3DArrayDeviceShell<async>(
std::bind(DrvMemcpy3DGraphWrapper<true>, _1, _2, _3, _4, _5, _6, context, _7));
}
HIP_CHECK(hipCtxPopCurrent(&context));
HIP_CHECK(hipCtxDestroy(context));
}
/**
* Test Description
* ------------------------
* - Verify API behaviour with invalid arguments:
* -# node is nullptr
* -# dst is nullptr
* -# src is nullptr
* -# dstPitch < width
* -# srcPitch < width
* -# dstPitch > max pitch
* -# srcPitch > max pitch
* -# WidthInBytes + dstXInBytes > dstPitch
* -# WidthInBytes + srcXInBytes > srcPitch
* -# dstY out of bounds
* -# srcY out of bounds
* -# dstZ out of bounds
* -# srcZ out of bounds
* Test source
* ------------------------
* - unit/graph/hipDrvGraphMemcpyNodeSetParams.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.0
*/
TEST_CASE("Unit_hipDrvGraphMemcpyNodeSetParams_Negative_Parameters") {
using namespace std::placeholders;
HIP_CHECK(hipInit(0));
hipDevice_t device;
hipCtx_t context;
HIP_CHECK(hipDeviceGet(&device, 0));
HIP_CHECK(hipCtxCreate(&context, 0, device));
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,
hipCtx_t context) {
hipGraph_t graph = nullptr;
HIP_CHECK(hipGraphCreate(&graph, 0));
hipGraphNode_t node = nullptr;
auto params = GetDrvMemcpy3DParms(dst_ptr, dst_pos, src_ptr, src_pos, extent, kind);
HIP_CHECK(hipDrvGraphAddMemcpyNode(&node, graph, nullptr, 0, &params, context));
SECTION("node == nullptr") {
HIP_CHECK_ERROR(hipDrvGraphMemcpyNodeSetParams(nullptr, &params), hipErrorInvalidValue);
}
SECTION("dst_ptr.ptr == nullptr") {
hipPitchedPtr invalid_ptr = dst_ptr;
invalid_ptr.ptr = nullptr;
auto invalid_params =
GetDrvMemcpy3DParms(invalid_ptr, dst_pos, src_ptr, src_pos, extent, kind);
HIP_CHECK_ERROR(hipDrvGraphMemcpyNodeSetParams(node, &invalid_params), hipErrorInvalidValue);
}
SECTION("src_ptr.ptr == nullptr") {
hipPitchedPtr invalid_ptr = src_ptr;
invalid_ptr.ptr = nullptr;
auto invalid_params =
GetDrvMemcpy3DParms(dst_ptr, dst_pos, invalid_ptr, src_pos, extent, kind);
HIP_CHECK_ERROR(hipDrvGraphMemcpyNodeSetParams(node, &invalid_params), hipErrorInvalidValue);
}
SECTION("dstPitch < width") {
hipPitchedPtr invalid_ptr = dst_ptr;
invalid_ptr.pitch = extent.width - 1;
auto invalid_params =
GetDrvMemcpy3DParms(invalid_ptr, dst_pos, src_ptr, src_pos, extent, kind);
HIP_CHECK_ERROR(hipDrvGraphMemcpyNodeSetParams(node, &invalid_params),
hipErrorInvalidPitchValue);
}
SECTION("srcPitch < width") {
hipPitchedPtr invalid_ptr = src_ptr;
invalid_ptr.pitch = extent.width - 1;
auto invalid_params =
GetDrvMemcpy3DParms(dst_ptr, dst_pos, invalid_ptr, src_pos, extent, kind);
HIP_CHECK_ERROR(hipDrvGraphMemcpyNodeSetParams(node, &invalid_params),
hipErrorInvalidPitchValue);
}
SECTION("dstPitch > max pitch") {
int attr = 0;
HIP_CHECK(hipDeviceGetAttribute(&attr, hipDeviceAttributeMaxPitch, 0));
hipPitchedPtr invalid_ptr = dst_ptr;
invalid_ptr.pitch = attr;
auto invalid_params =
GetDrvMemcpy3DParms(invalid_ptr, dst_pos, src_ptr, src_pos, extent, kind);
HIP_CHECK_ERROR(hipDrvGraphMemcpyNodeSetParams(node, &invalid_params), hipErrorInvalidValue);
}
SECTION("srcPitch > max pitch") {
int attr = 0;
HIP_CHECK(hipDeviceGetAttribute(&attr, hipDeviceAttributeMaxPitch, 0));
hipPitchedPtr invalid_ptr = src_ptr;
invalid_ptr.pitch = attr;
auto invalid_params =
GetDrvMemcpy3DParms(dst_ptr, dst_pos, invalid_ptr, src_pos, extent, kind);
HIP_CHECK_ERROR(hipDrvGraphMemcpyNodeSetParams(node, &invalid_params), hipErrorInvalidValue);
}
SECTION("WidthInBytes + dstXInBytes > dstPitch") {
hipPos invalid_pos = dst_pos;
invalid_pos.x = dst_ptr.pitch - extent.width + 1;
auto invalid_params =
GetDrvMemcpy3DParms(dst_ptr, invalid_pos, src_ptr, src_pos, extent, kind);
HIP_CHECK_ERROR(hipDrvGraphMemcpyNodeSetParams(node, &invalid_params), hipErrorInvalidValue);
}
SECTION("WidthInBytes + srcXInBytes > srcPitch") {
hipPos invalid_pos = src_pos;
invalid_pos.x = src_ptr.pitch - extent.width + 1;
auto invalid_params =
GetDrvMemcpy3DParms(dst_ptr, dst_pos, src_ptr, invalid_pos, extent, kind);
HIP_CHECK_ERROR(hipDrvGraphMemcpyNodeSetParams(node, &invalid_params), hipErrorInvalidValue);
}
SECTION("dstY out of bounds") {
hipPos invalid_pos = dst_pos;
invalid_pos.y = 1;
auto invalid_params =
GetDrvMemcpy3DParms(dst_ptr, invalid_pos, src_ptr, src_pos, extent, kind);
HIP_CHECK_ERROR(hipDrvGraphMemcpyNodeSetParams(node, &invalid_params), hipErrorInvalidValue);
}
SECTION("srcY out of bounds") {
hipPos invalid_pos = src_pos;
invalid_pos.y = 1;
auto invalid_params =
GetDrvMemcpy3DParms(dst_ptr, dst_pos, src_ptr, invalid_pos, extent, kind);
HIP_CHECK_ERROR(hipDrvGraphMemcpyNodeSetParams(node, &invalid_params), hipErrorInvalidValue);
}
SECTION("dstZ out of bounds") {
hipPos invalid_pos = dst_pos;
invalid_pos.z = 1;
auto invalid_params =
GetDrvMemcpy3DParms(dst_ptr, invalid_pos, src_ptr, src_pos, extent, kind);
HIP_CHECK_ERROR(hipDrvGraphMemcpyNodeSetParams(node, &invalid_params), hipErrorInvalidValue);
}
SECTION("srcZ out of bounds") {
hipPos invalid_pos = src_pos;
invalid_pos.z = 1;
auto invalid_params =
GetDrvMemcpy3DParms(dst_ptr, dst_pos, src_ptr, invalid_pos, extent, kind);
HIP_CHECK_ERROR(hipDrvGraphMemcpyNodeSetParams(node, &invalid_params), hipErrorInvalidValue);
}
HIP_CHECK(hipGraphDestroy(graph));
};
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, context);
}
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, context);
}
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, context);
}
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, context);
}
HIP_CHECK(hipCtxPopCurrent(&context));
HIP_CHECK(hipCtxDestroy(context));
}
#endif // if 0
+1 -1
View File
@@ -20,7 +20,7 @@ THE SOFTWARE.
#include <hip_test_common.hh>
#include <hip_test_checkers.hh>
#include <hip_test_kernels.hh>
#include <hip_test_defgroups.hh>
#include "graph_dependency_common.hh"
+1 -1
View File
@@ -21,7 +21,7 @@ THE SOFTWARE.
#include <hip_test_common.hh>
#include <hip_test_kernels.hh>
#include <hip_test_checkers.hh>
#include <hip_test_defgroups.hh>
#define CODEOBJ_FILE "add_Kernel.code"
#define KERNEL_NAME "Add"
@@ -22,7 +22,6 @@ THE SOFTWARE.
#include <functional>
#include <vector>
#include <hip_test_defgroups.hh>
#include <hip_test_common.hh>
#include <hip_test_checkers.hh>
@@ -75,7 +74,7 @@ void GraphMemcpyFromSymbolShell(void* symbol, size_t offset, const std::vector<T
* ------------------------
* - Verify that data is correctly copied from a symbol. A graph is constructed to which a
* MemcpyFromSymbol node is added. After graph execution, values in destination memory are compared
* against values known to be in symbol memory.
* against values known to be in symbol memory.
* The test is run for scalar, const scalar, array, and const array symbols of types char, int,
* float and double. For array symbols, the test is repeated for zero and non-zero offset values.
* Verification is performed for destination memory allocated on host and device.
@@ -106,7 +105,7 @@ TEST_CASE("Unit_hipGraphAddMemcpyNodeFromSymbol_Positive_Basic") {
/**
* Test Description
* ------------------------
* ------------------------
* - Verify API behavior with invalid arguments:
* -# pGraphNodes is nullptr
* -# graph is nullptr
@@ -122,12 +121,12 @@ TEST_CASE("Unit_hipGraphAddMemcpyNodeFromSymbol_Positive_Basic") {
* -# kind is illogical (hipMemcpyHostToDevice)
* -# kind is an invalid enum value
* Test source
* ------------------------
* ------------------------
* - unit/graph/hipGraphAddMemcpyNodeFromSymbol.cc
* Test requirements
* ------------------------
* ------------------------
* - HIP_VERSION >= 5.2
*/
*/
TEST_CASE("Unit_hipGraphAddMemcpyNodeFromSymbol_Negative_Parameters") {
using namespace std::placeholders;
hipGraph_t graph = nullptr;
@@ -23,7 +23,6 @@ THE SOFTWARE.
#include <functional>
#include <vector>
#include <hip_test_defgroups.hh>
#include <hip_test_common.hh>
#include <hip_test_checkers.hh>
@@ -78,7 +77,7 @@ void GraphMemcpyToSymbolShell(const void* symbol, size_t offset, const std::vect
* - Verify that data is correctly copied to a symbol. A graph is constructed to which a
* MemcpyToSymbol node is added. After graph execution, a MemcpyFromSymbol is performed and
* the copied values are compared against values known to have been copied to symbol memory
* previously.
* previously.
* The test is run for scalar, const scalar, array, and const array symbols of types char, int,
* float and double. For array symbols, the test is repeated for zero and non-zero offset values.
* Verification is performed for source memory allocated on host and device.
+41 -57
View File
@@ -22,7 +22,6 @@ THE SOFTWARE.
#include <functional>
#include <vector>
#include <hip_test_defgroups.hh>
#include <hip_test_common.hh>
#include <resource_guards.hh>
#include <utils.hh>
@@ -77,7 +76,7 @@ TEMPLATE_TEST_CASE("Unit_hipGraphAddMemsetNode_Positive_Basic", "", uint8_t, uin
return hipSuccess;
};
GraphMemsetNodeCommonPositive<TestType>(f);
GraphMemsetNodeCommonPositive<TestType, hipMemsetParams>(f);
}
/**
@@ -129,7 +128,7 @@ TEST_CASE("Unit_hipGraphAddMemsetNode_Negative_Parameters") {
* Allocate a 2D array using hipMallocPitch. Initialize the allocated memory
* using hipGraphAddMemsetNode. Copy the values in device memory to host using
* hipGraphAddMemcpyNode. Verify the results.
*/
*/
TEST_CASE("Unit_hipGraphAddMemsetNode_hipMallocPitch_2D") {
CHECK_IMAGE_SUPPORT
@@ -147,22 +146,20 @@ TEST_CASE("Unit_hipGraphAddMemsetNode_hipMallocPitch_2D") {
}
}
// 2D Memory allocation hipMallocPitch
HIP_CHECK(hipMallocPitch(reinterpret_cast<void**>(&A_d), &pitch_A, width,
numH));
HIP_CHECK(hipMallocPitch(reinterpret_cast<void**>(&A_d), &pitch_A, width, numH));
// Create Graph
HIP_CHECK(hipGraphCreate(&graph, 0));
hipGraphNode_t memsetNode, memcpyNode;
// Add MemSet Node
hipMemsetParams memsetParams{};
memset(&memsetParams, 0, sizeof(memsetParams));
memsetParams.dst = reinterpret_cast<void *>(A_d);
memsetParams.dst = reinterpret_cast<void*>(A_d);
memsetParams.value = memSetVal;
memsetParams.pitch = pitch_A;
memsetParams.elementSize = sizeof(char);
memsetParams.width = numW;
memsetParams.height = numH;
HIP_CHECK(hipGraphAddMemsetNode(&memsetNode, graph, nullptr, 0,
&memsetParams));
HIP_CHECK(hipGraphAddMemsetNode(&memsetNode, graph, nullptr, 0, &memsetParams));
nodeDependencies.push_back(memsetNode);
// Add MemCpy Node
hipMemcpy3DParms myparms{};
@@ -173,21 +170,20 @@ TEST_CASE("Unit_hipGraphAddMemsetNode_hipMallocPitch_2D") {
myparms.extent = make_hipExtent(width, numH, 1);
myparms.kind = hipMemcpyDeviceToHost;
HIP_CHECK(hipGraphAddMemcpyNode(&memcpyNode, graph, nodeDependencies.data(),
nodeDependencies.size(), &myparms));
nodeDependencies.size(), &myparms));
nodeDependencies.clear();
// Create executable graph
hipStream_t streamForGraph;
hipGraphExec_t graphExec;
HIP_CHECK(hipStreamCreate(&streamForGraph));
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr,
nullptr, 0));
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
HIP_CHECK(hipGraphLaunch(graphExec, streamForGraph));
HIP_CHECK(hipStreamSynchronize(streamForGraph));
// Verfication
for (size_t i = 0; i < numW; i++) {
for (size_t j = 0; j < numH; j++) {
REQUIRE(*(A_h + i*numH + j) == memSetVal);
REQUIRE(*(A_h + i * numH + j) == memSetVal);
}
}
HIP_CHECK(hipGraphExecDestroy(graphExec));
@@ -200,12 +196,12 @@ TEST_CASE("Unit_hipGraphAddMemsetNode_hipMallocPitch_2D") {
* Allocate a 1D array using hipMallocPitch. Initialize the allocated memory using
* hipGraphAddMemsetNode. Copy the values in device memory to host using
* hipGraphAddMemcpyNode. Verify the results.
*/
*/
TEST_CASE("Unit_hipGraphAddMemsetNode_hipMallocPitch_1D") {
CHECK_IMAGE_SUPPORT
size_t width = SIZE * sizeof(char), numW{SIZE}, pitch_A;
char *A_d;
char* A_d;
// Initialize the host memory
std::vector<char> A_h(numW, ' ');
@@ -213,22 +209,20 @@ TEST_CASE("Unit_hipGraphAddMemsetNode_hipMallocPitch_1D") {
hipGraph_t graph;
std::vector<hipGraphNode_t> nodeDependencies;
// 1D Memory allocation hipMallocPitch
HIP_CHECK(hipMallocPitch(reinterpret_cast<void**>(&A_d), &pitch_A, width,
1));
HIP_CHECK(hipMallocPitch(reinterpret_cast<void**>(&A_d), &pitch_A, width, 1));
// Create Graph
HIP_CHECK(hipGraphCreate(&graph, 0));
hipGraphNode_t memsetNode, memcpyNode;
// Add MemSet Node
hipMemsetParams memsetParams{};
memset(&memsetParams, 0, sizeof(memsetParams));
memsetParams.dst = reinterpret_cast<void *>(A_d);
memsetParams.dst = reinterpret_cast<void*>(A_d);
memsetParams.value = memSetVal;
memsetParams.pitch = pitch_A;
memsetParams.elementSize = sizeof(char);
memsetParams.width = numW;
memsetParams.height = 1;
HIP_CHECK(hipGraphAddMemsetNode(&memsetNode, graph, nullptr, 0,
&memsetParams));
HIP_CHECK(hipGraphAddMemsetNode(&memsetNode, graph, nullptr, 0, &memsetParams));
nodeDependencies.push_back(memsetNode);
// Add MemCpy Node
hipMemcpy3DParms myparms{};
@@ -239,15 +233,14 @@ TEST_CASE("Unit_hipGraphAddMemsetNode_hipMallocPitch_1D") {
myparms.extent = make_hipExtent(width, 1, 1);
myparms.kind = hipMemcpyDeviceToHost;
HIP_CHECK(hipGraphAddMemcpyNode(&memcpyNode, graph, nodeDependencies.data(),
nodeDependencies.size(), &myparms));
nodeDependencies.size(), &myparms));
nodeDependencies.clear();
// Create executable graph
hipStream_t streamForGraph;
hipGraphExec_t graphExec;
HIP_CHECK(hipStreamCreate(&streamForGraph));
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr,
nullptr, 0));
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
HIP_CHECK(hipGraphLaunch(graphExec, streamForGraph));
HIP_CHECK(hipStreamSynchronize(streamForGraph));
@@ -264,7 +257,7 @@ TEST_CASE("Unit_hipGraphAddMemsetNode_hipMallocPitch_1D") {
* Allocate a 2D array using hipMalloc3D. Initialize the allocated memory using
* hipGraphAddMemsetNode. Copy the values in device memory to host using
* hipGraphAddMemcpyNode. Verify the results.
*/
*/
TEST_CASE("Unit_hipGraphAddMemsetNode_hipMalloc3D_2D") {
CHECK_IMAGE_SUPPORT
@@ -300,8 +293,7 @@ TEST_CASE("Unit_hipGraphAddMemsetNode_hipMalloc3D_2D") {
memsetParams.elementSize = sizeof(char);
memsetParams.width = numW;
memsetParams.height = numH;
HIP_CHECK(hipGraphAddMemsetNode(&memsetNode, graph, nullptr, 0,
&memsetParams));
HIP_CHECK(hipGraphAddMemsetNode(&memsetNode, graph, nullptr, 0, &memsetParams));
nodeDependencies.push_back(memsetNode);
// MemCpy params
@@ -315,22 +307,21 @@ TEST_CASE("Unit_hipGraphAddMemsetNode_hipMalloc3D_2D") {
// Add MemCpy Node
HIP_CHECK(hipGraphAddMemcpyNode(&memcpyNode, graph, nodeDependencies.data(),
nodeDependencies.size(), &myparms));
nodeDependencies.size(), &myparms));
nodeDependencies.clear();
// Create executable graph
hipStream_t streamForGraph;
hipGraphExec_t graphExec;
HIP_CHECK(hipStreamCreate(&streamForGraph));
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr,
nullptr, 0));
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
HIP_CHECK(hipGraphLaunch(graphExec, streamForGraph));
HIP_CHECK(hipStreamSynchronize(streamForGraph));
// Verfication
for (size_t i = 0; i < numW; i++) {
for (size_t j = 0; j < numH; j++) {
REQUIRE(*(A_h + i*numH + j) == memSetVal);
REQUIRE(*(A_h + i * numH + j) == memSetVal);
}
}
HIP_CHECK(hipGraphExecDestroy(graphExec));
@@ -343,7 +334,7 @@ TEST_CASE("Unit_hipGraphAddMemsetNode_hipMalloc3D_2D") {
* Allocate a 1D array using hipMalloc3D. Initialize the allocated
* memory using hipGraphAddMemsetNode. Copy the values in device
* memory to host using hipGraphAddMemcpyNode. Verify the results.
*/
*/
TEST_CASE("Unit_hipGraphAddMemsetNode_hipMalloc3D_1D") {
CHECK_IMAGE_SUPPORT
@@ -375,8 +366,7 @@ TEST_CASE("Unit_hipGraphAddMemsetNode_hipMalloc3D_1D") {
memsetParams.elementSize = sizeof(char);
memsetParams.width = numW;
memsetParams.height = 1;
HIP_CHECK(hipGraphAddMemsetNode(&memsetNode, graph, nullptr, 0,
&memsetParams));
HIP_CHECK(hipGraphAddMemsetNode(&memsetNode, graph, nullptr, 0, &memsetParams));
nodeDependencies.push_back(memsetNode);
// MemCpy params
@@ -390,21 +380,20 @@ TEST_CASE("Unit_hipGraphAddMemsetNode_hipMalloc3D_1D") {
// Add MemCpy Node
HIP_CHECK(hipGraphAddMemcpyNode(&memcpyNode, graph, nodeDependencies.data(),
nodeDependencies.size(), &myparms));
nodeDependencies.size(), &myparms));
nodeDependencies.clear();
// Create executable graph
hipStream_t streamForGraph;
hipGraphExec_t graphExec;
HIP_CHECK(hipStreamCreate(&streamForGraph));
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr,
nullptr, 0));
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
HIP_CHECK(hipGraphLaunch(graphExec, streamForGraph));
HIP_CHECK(hipStreamSynchronize(streamForGraph));
// Verfication
for (size_t i = 0; i < numW; i++) {
REQUIRE(A_h[i] == memSetVal);
REQUIRE(A_h[i] == memSetVal);
}
HIP_CHECK(hipGraphExecDestroy(graphExec));
HIP_CHECK(hipGraphDestroy(graph));
@@ -415,9 +404,9 @@ TEST_CASE("Unit_hipGraphAddMemsetNode_hipMalloc3D_1D") {
* Allocate a 1D array using hipMalloc. Initialize the allocated memory using
* hipGraphAddMemsetNode. Copy the values in device memory to host using
* hipGraphAddMemcpyNode. Verify the results.
*/
*/
TEST_CASE("Unit_hipGraphAddMemsetNode_hipMalloc_1D") {
char *A_d;
char* A_d;
size_t NumW = SIZE;
size_t Nbytes1D = SIZE * sizeof(char);
@@ -436,14 +425,13 @@ TEST_CASE("Unit_hipGraphAddMemsetNode_hipMalloc_1D") {
// Add Memset node
hipMemsetParams memsetParams{};
memset(&memsetParams, 0, sizeof(memsetParams));
memsetParams.dst = reinterpret_cast<void *>(A_d);
memsetParams.dst = reinterpret_cast<void*>(A_d);
memsetParams.value = memSetVal;
memsetParams.pitch = Nbytes1D;
memsetParams.elementSize = sizeof(char);
memsetParams.width = NumW;
memsetParams.height = 1;
HIP_CHECK(hipGraphAddMemsetNode(&memsetNode, graph, nullptr, 0,
&memsetParams));
HIP_CHECK(hipGraphAddMemsetNode(&memsetNode, graph, nullptr, 0, &memsetParams));
nodeDependencies.push_back(memsetNode);
// Add MemCpy Node
hipPitchedPtr devPitchedPtr{A_d, Nbytes1D, NumW, 0};
@@ -456,20 +444,19 @@ TEST_CASE("Unit_hipGraphAddMemsetNode_hipMalloc_1D") {
myparms.extent = make_hipExtent(Nbytes1D, 1, 1);
myparms.kind = hipMemcpyDeviceToHost;
HIP_CHECK(hipGraphAddMemcpyNode(&memcpyNode, graph, nodeDependencies.data(),
nodeDependencies.size(), &myparms));
nodeDependencies.size(), &myparms));
nodeDependencies.clear();
// Create executable graph
hipStream_t streamForGraph;
hipGraphExec_t graphExec;
HIP_CHECK(hipStreamCreate(&streamForGraph));
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr,
nullptr, 0));
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
HIP_CHECK(hipGraphLaunch(graphExec, streamForGraph));
HIP_CHECK(hipStreamSynchronize(streamForGraph));
// Verfication
for (size_t i = 0; i < NumW; i++) {
REQUIRE(A_h[i] == memSetVal);
REQUIRE(A_h[i] == memSetVal);
}
HIP_CHECK(hipGraphExecDestroy(graphExec));
HIP_CHECK(hipGraphDestroy(graph));
@@ -479,16 +466,15 @@ TEST_CASE("Unit_hipGraphAddMemsetNode_hipMalloc_1D") {
TEST_CASE("Unit_hipGraphAddMemsetNode_hipMallocManaged") {
int managed = 0;
HIP_CHECK(hipDeviceGetAttribute(&managed,
hipDeviceAttributeManagedMemory, 0));
HIP_CHECK(hipDeviceGetAttribute(&managed, hipDeviceAttributeManagedMemory, 0));
INFO("hipDeviceAttributeManagedMemory: " << managed);
if (managed != 1) {
WARN(
"GPU 0 doesn't support hipDeviceAttributeManagedMemory attribute"
"so defaulting to system memory.");
"GPU 0 doesn't support hipDeviceAttributeManagedMemory attribute"
"so defaulting to system memory.");
}
size_t Nbytes1D = SIZE * sizeof(char);
char *A_d;
char* A_d;
// Initialize the host memory
std::vector<char> A_h(SIZE, ' ');
// Device Memory
@@ -502,14 +488,13 @@ TEST_CASE("Unit_hipGraphAddMemsetNode_hipMallocManaged") {
// Add Memset node
hipMemsetParams memsetParams{};
memset(&memsetParams, 0, sizeof(memsetParams));
memsetParams.dst = reinterpret_cast<void *>(A_d);
memsetParams.dst = reinterpret_cast<void*>(A_d);
memsetParams.value = memSetVal;
memsetParams.pitch = Nbytes1D;
memsetParams.elementSize = sizeof(char);
memsetParams.width = SIZE;
memsetParams.height = 1;
HIP_CHECK(hipGraphAddMemsetNode(&memsetNode, graph, nullptr, 0,
&memsetParams));
HIP_CHECK(hipGraphAddMemsetNode(&memsetNode, graph, nullptr, 0, &memsetParams));
nodeDependencies.push_back(memsetNode);
// Add MemCpy Node
@@ -524,21 +509,20 @@ TEST_CASE("Unit_hipGraphAddMemsetNode_hipMallocManaged") {
myparms.extent = make_hipExtent(Nbytes1D, 1, 1);
myparms.kind = hipMemcpyDeviceToHost;
HIP_CHECK(hipGraphAddMemcpyNode(&memcpyNode, graph, nodeDependencies.data(),
nodeDependencies.size(), &myparms));
nodeDependencies.size(), &myparms));
nodeDependencies.clear();
// Create executable graph
hipStream_t streamForGraph;
hipGraphExec_t graphExec;
HIP_CHECK(hipStreamCreate(&streamForGraph));
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr,
nullptr, 0));
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
HIP_CHECK(hipGraphLaunch(graphExec, streamForGraph));
HIP_CHECK(hipStreamSynchronize(streamForGraph));
// Verfication
for (size_t i = 0; i < SIZE; i++) {
REQUIRE(A_h[i] == memSetVal);
REQUIRE(A_h[i] == memSetVal);
}
HIP_CHECK(hipGraphExecDestroy(graphExec));
+552
View File
@@ -0,0 +1,552 @@
/*
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 <functional>
#include <vector>
#include <hip_test_defgroups.hh>
#include <hip_test_common.hh>
#include <hip_test_checkers.hh>
#include <memcpy3d_tests_common.hh>
#include <resource_guards.hh>
#include <utils.hh>
#include "graph_memset_node_test_common.hh"
#include "graph_tests_common.hh"
#pragma clang diagnostic ignored "-Wunused-parameter"
/**
* @addtogroup hipGraphAddNode hipGraphAddNode
* @{
* @ingroup GraphTest
* `hipGraphAddNode(hipGraphNode_t *pGraphNode, hipGraph_t graph, const hipGraphNode_t
* *pDependencies, size_t numDependencies, hipGraphNodeParams *nodeParams)` - Creates a node and
* adds it to a graph
*/
static constexpr size_t N = 1024;
static void callbackfunc(void* A_h) {
int* A = reinterpret_cast<int*>(A_h);
for (int i = 0; i < N; i++) {
A[i] = i;
}
}
static void __global__ vector_square(int* A_d) {
for (int i = 0; i < N; i++) {
A_d[i] = A_d[i] * A_d[i];
}
}
/**
* Test Description
* ------------------------
* - Verify that all elements of destination memory are set to the correct value.
* The test is repeated for all valid element sizes(1, 2, 4), and several allocations of different
* height and width, both on host and device.
* Test source
* ------------------------
* - unit/graph/hipGraphAddNode.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.0
*/
TEMPLATE_TEST_CASE("Unit_hipGraphAddNodeTypeMemset_Positive_Basic", "", uint8_t, uint16_t,
uint32_t) {
const auto f = [](hipMemsetParams* params) {
hipGraph_t graph = nullptr;
HIP_CHECK(hipGraphCreate(&graph, 0));
hipGraphNode_t node = nullptr;
hipGraphNodeParams node_params = {};
node_params.type = hipGraphNodeTypeMemset;
node_params.memset.dst = params->dst;
node_params.memset.elementSize = params->elementSize;
node_params.memset.width = params->width;
node_params.memset.height = params->height;
node_params.memset.pitch = params->pitch;
node_params.memset.value = params->value;
HIP_CHECK(hipGraphAddNode(&node, graph, nullptr, 0, &node_params));
hipGraphExec_t graph_exec = nullptr;
HIP_CHECK(hipGraphInstantiate(&graph_exec, graph, nullptr, nullptr, 0));
HIP_CHECK(hipGraphLaunch(graph_exec, hipStreamPerThread));
HIP_CHECK(hipStreamSynchronize(hipStreamPerThread));
HIP_CHECK(hipGraphExecDestroy(graph_exec));
HIP_CHECK(hipGraphDestroy(graph));
return hipSuccess;
};
GraphMemsetNodeCommonPositive<TestType, hipMemsetParams>(f);
}
/**
* Test Description
* ------------------------
* - Verify that kernel node added with hipGraphAddNode executes correctly and does the square of
* values in the device array. The result is copied to host and verified.
* Test source
* ------------------------
* - unit/graph/hipGraphAddNode.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.0
*/
TEST_CASE("Unit_hipGraphAddNodeTypeKernel_Positive_Basic") {
constexpr size_t allocation_size = N * sizeof(int);
hipGraph_t graph;
hipGraphExec_t graphExec;
int* A_d{nullptr};
int *A_h{nullptr}, *B_h{nullptr};
HipTest::initArrays<int>(&A_d, nullptr, nullptr, &A_h, &B_h, nullptr, N, false);
HIP_CHECK(hipGraphCreate(&graph, 0));
hipGraphNode_t memcpyH2D_A, memcpyD2H_B;
hipStream_t streamForGraph;
HIP_CHECK(hipStreamCreate(&streamForGraph));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_A, graph, nullptr, 0, A_d, A_h, allocation_size,
hipMemcpyHostToDevice));
hipGraphNode_t node;
hipGraphNodeParams node_params = {};
node_params.type = hipGraphNodeTypeKernel;
void* kernel_args[] = {&A_d};
node_params.kernel.func = reinterpret_cast<void*>(vector_square);
node_params.kernel.gridDim = dim3(1);
node_params.kernel.blockDim = dim3(1);
node_params.kernel.sharedMemBytes = 0;
node_params.kernel.kernelParams = reinterpret_cast<void**>(kernel_args);
node_params.kernel.extra = nullptr;
HIP_CHECK(hipGraphAddNode(&node, graph, nullptr, 0, &node_params));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyD2H_B, graph, nullptr, 0, B_h, A_d, allocation_size,
hipMemcpyDeviceToHost));
HIP_CHECK(hipGraphAddDependencies(graph, &memcpyH2D_A, &node, 1));
HIP_CHECK(hipGraphAddDependencies(graph, &node, &memcpyD2H_B, 1));
// 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
for (size_t i = 0; i < N; i++) {
if (B_h[i] != (A_h[i] * A_h[i])) {
REQUIRE(false);
}
}
HipTest::freeArrays<int>(A_d, nullptr, nullptr, A_h, B_h, nullptr, false);
HIP_CHECK(hipGraphExecDestroy(graphExec));
HIP_CHECK(hipGraphDestroy(graph));
HIP_CHECK(hipStreamDestroy(streamForGraph));
}
/**
* Test Description
* ------------------------
* - Verify that host node added with hipGraphAddNode executes correctly and sets values of host
* array. The result is verified.
* Test source
* ------------------------
* - unit/graph/hipGraphAddNode.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.0
*/
TEST_CASE("Unit_hipGraphAddNodeTypeHost_Positive_Basic") {
constexpr size_t allocation_size = N * sizeof(int);
hipGraph_t graph;
hipGraphExec_t graphExec;
int* A_h = (int*)malloc(allocation_size);
std::fill_n(A_h, N, 0);
HIP_CHECK(hipGraphCreate(&graph, 0));
hipStream_t streamForGraph;
HIP_CHECK(hipStreamCreate(&streamForGraph));
hipGraphNode_t node;
hipGraphNodeParams node_params = {};
node_params.type = hipGraphNodeTypeHost;
node_params.host.fn = callbackfunc;
node_params.host.userData = A_h;
HIP_CHECK(hipGraphAddNode(&node, graph, nullptr, 0, &node_params));
// 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
for (size_t i = 0; i < N; i++) {
if (A_h[i] != static_cast<int>(i)) {
REQUIRE(false);
}
}
free(A_h);
HIP_CHECK(hipGraphExecDestroy(graphExec));
HIP_CHECK(hipGraphDestroy(graph));
HIP_CHECK(hipStreamDestroy(streamForGraph));
}
/**
* Test Description
* ------------------------
* - Verify that when graph is created and childgraph node is added with hipGraphAddNode, the
* childgraph executes correctly.
* Test source
* ------------------------
* - unit/graph/hipGraphAddNode.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.0
*/
TEST_CASE("Unit_hipGraphAddNodeTypeChildGraph_Positive_Basic") {
constexpr size_t allocation_size = N * sizeof(int);
hipGraph_t graph, childgraph;
hipGraphExec_t graphExec;
int *A_d{nullptr}, *B_d{nullptr}, *C_d{nullptr};
int *A_h{nullptr}, *B_h{nullptr}, *C_h{nullptr};
HipTest::initArrays<int>(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, N, false);
HIP_CHECK(hipGraphCreate(&graph, 0));
for (size_t i = 0; i < N; i++) {
B_h[i] = i;
}
hipGraphNode_t memcpyH2D_A, memcpyH2D_B, childGraphNode1, memcpyH2D_C;
hipStream_t streamForGraph;
HIP_CHECK(hipStreamCreate(&streamForGraph));
HIP_CHECK(hipGraphCreate(&childgraph, 0));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_B, childgraph, nullptr, 0, B_d, B_h, allocation_size,
hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_A, childgraph, nullptr, 0, A_h, B_d, allocation_size,
hipMemcpyDeviceToHost));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_C, graph, nullptr, 0, C_d, C_h, allocation_size,
hipMemcpyHostToDevice));
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyH2D_C, graph, nullptr, 0, A_h, C_d, allocation_size,
hipMemcpyDeviceToHost));
hipGraphNodeParams node_params = {};
node_params.type = hipGraphNodeTypeGraph;
node_params.graph.graph = childgraph;
HIP_CHECK(hipGraphAddNode(&childGraphNode1, graph, nullptr, 0, &node_params));
HIP_CHECK(hipGraphAddDependencies(childgraph, &memcpyH2D_B, &memcpyH2D_A, 1));
// Instantiate and launch the childgraph
HIP_CHECK(hipGraphInstantiate(&graphExec, childgraph, nullptr, nullptr, 0));
HIP_CHECK(hipGraphLaunch(graphExec, streamForGraph));
HIP_CHECK(hipStreamSynchronize(streamForGraph));
// Verify execution result
for (size_t i = 0; i < N; i++) {
if (B_h[i] != A_h[i]) {
REQUIRE(false);
}
}
HipTest::freeArrays<int>(A_d, B_d, C_d, A_h, B_h, C_h, false);
HIP_CHECK(hipGraphExecDestroy(graphExec));
HIP_CHECK(hipGraphDestroy(childgraph));
HIP_CHECK(hipGraphDestroy(graph));
HIP_CHECK(hipStreamDestroy(streamForGraph));
}
static hipError_t MemcpyType3DWrapper(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);
hipGraph_t graph = nullptr;
HIP_CHECK(hipGraphCreate(&graph, 0));
hipGraphNode_t node = nullptr;
hipGraphNodeParams node_params = {};
node_params.type = hipGraphNodeTypeMemcpy;
memset(&node_params.memcpy, 0, sizeof(hipMemcpyNodeParams));
node_params.memcpy.copyParams = parms;
HIP_CHECK(hipGraphAddNode(&node, graph, nullptr, 0, &node_params));
hipGraphExec_t graph_exec = nullptr;
HIP_CHECK(hipGraphInstantiate(&graph_exec, graph, nullptr, nullptr, 0));
HIP_CHECK(hipGraphLaunch(graph_exec, hipStreamPerThread));
HIP_CHECK(hipStreamSynchronize(hipStreamPerThread));
HIP_CHECK(hipGraphExecDestroy(graph_exec));
HIP_CHECK(hipGraphDestroy(graph));
return hipSuccess;
}
/**
* Test Description
* ------------------------
* - Verify basic API behavior. A Memcpy node is created using hipGraphAddNode with parameters
* set according to the test run, after which the graph is run and the memcpy results are verified.
* The test is run for all possible memcpy directions, with both the corresponding memcpy
* kind and hipMemcpyDefault, as well as half page and full page allocation sizes.
* Test source
* ------------------------
* - unit/graph/hipGraphAddNode.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.0
*/
TEST_CASE("Unit_hipGraphAddNodeTypeMemcpy_Positive_Basic") {
constexpr bool async = false;
SECTION("Device to host") { Memcpy3DDeviceToHostShell<async>(MemcpyType3DWrapper); }
SECTION("Device to host with default kind") {
Memcpy3DDeviceToHostShell<async>(MemcpyType3DWrapper);
}
SECTION("Host to device") { Memcpy3DHostToDeviceShell<async>(MemcpyType3DWrapper); }
SECTION("Host to device with default kind") {
Memcpy3DHostToDeviceShell<async>(MemcpyType3DWrapper);
}
SECTION("Host to host") { Memcpy3DHostToHostShell<async>(MemcpyType3DWrapper); }
SECTION("Host to host with default kind") { Memcpy3DHostToHostShell<async>(MemcpyType3DWrapper); }
SECTION("Device to device") {
SECTION("Peer access enabled") {
Memcpy3DDeviceToDeviceShell<async, true>(MemcpyType3DWrapper);
}
SECTION("Peer access disabled") {
Memcpy3DDeviceToDeviceShell<async, false>(MemcpyType3DWrapper);
}
}
SECTION("Device to device with default kind") {
SECTION("Peer access enabled") {
Memcpy3DDeviceToDeviceShell<async, true>(MemcpyType3DWrapper);
}
SECTION("Peer access disabled") {
Memcpy3DDeviceToDeviceShell<async, false>(MemcpyType3DWrapper);
}
}
SECTION("Array from/to Host") { Memcpy3DArrayHostShell<async>(MemcpyType3DWrapper); }
#if HT_NVIDIA // Disabled on AMD due to defect - EXSWHTEC-220
SECTION("Array from/to Device") { Memcpy3DArrayDeviceShell<async>(MemcpyType3DWrapper); }
#endif
}
/**
* Test Description
* ------------------------
* - Verify basic API functionality where one event record node is added to graph with
* hipGraphAddNode and its correct behavior is verified.
* Test source
* ------------------------
* - unit/graph/hipGraphAddNode.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.0
*/
TEST_CASE("Unit_hipGraphAddNodeTypeEventRecord_Positive_Basic") {
hipGraph_t graph;
hipStream_t streamForGraph;
hipGraphExec_t graphExec;
hipGraphNode_t node;
HIP_CHECK(hipStreamCreate(&streamForGraph));
HIP_CHECK(hipGraphCreate(&graph, 0));
hipEvent_t event;
HIP_CHECK(hipEventCreate(&event));
hipGraphNodeParams node_params = {};
node_params.type = hipGraphNodeTypeEventRecord;
node_params.eventRecord.event = event;
HIP_CHECK(hipGraphAddNode(&node, graph, nullptr, 0, &node_params));
// Instantiate and launch the graph
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
HIP_CHECK(hipGraphLaunch(graphExec, streamForGraph));
// Wait for event
HIP_CHECK(hipEventSynchronize(event));
HIP_CHECK(hipGraphExecDestroy(graphExec));
HIP_CHECK(hipGraphDestroy(graph));
HIP_CHECK(hipEventDestroy(event));
HIP_CHECK(hipStreamDestroy(streamForGraph));
}
/**
* Test Description
* ------------------------
* - Verify basic API functionality where one event record and one event wait nodes are added to
* graph with hipGraphAddNode and their correct behavior is verified.
* Test source
* ------------------------
* - unit/graph/hipGraphAddNode.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.0
*/
TEST_CASE("Unit_hipGraphAddNodeTypeEventWait_Positive_Basic") {
hipGraph_t graph;
hipStream_t streamForGraph;
hipGraphExec_t graphExec;
HIP_CHECK(hipStreamCreate(&streamForGraph));
HIP_CHECK(hipGraphCreate(&graph, 0));
hipEvent_t event;
HIP_CHECK(hipEventCreate(&event));
hipGraphNode_t event_rec_node, event_wait_node;
// Create a event record node in graph
hipGraphNodeParams rec_node_params = {};
rec_node_params.type = hipGraphNodeTypeEventRecord;
rec_node_params.eventRecord.event = event;
HIP_CHECK(hipGraphAddNode(&event_rec_node, graph, nullptr, 0, &rec_node_params));
// Create a event wait node in graph
hipGraphNodeParams wait_node_params = {};
rec_node_params.type = hipGraphNodeTypeWaitEvent;
rec_node_params.eventWait.event = event;
HIP_CHECK(hipGraphAddNode(&event_wait_node, graph, &event_rec_node, 1, &wait_node_params));
// Instantiate and launch the graph
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
HIP_CHECK(hipGraphLaunch(graphExec, streamForGraph));
HIP_CHECK(hipStreamSynchronize(streamForGraph));
HIP_CHECK(hipGraphExecDestroy(graphExec));
HIP_CHECK(hipGraphDestroy(graph));
HIP_CHECK(hipEventDestroy(event));
HIP_CHECK(hipStreamDestroy(streamForGraph));
}
/**
* Test Description
* ------------------------
* - Test to verify basic API functionality when memalloc and memfree nodes are added with
* hipGraphAddNode. Verify that memory is allocated correctly and graph behaves as expected when
* free node is added to the same graph.
* Test source
* ------------------------
* - /unit/graph/hipGraphAddNode.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.0
*/
TEST_CASE("Unit_hipGraphAddNodeTypeMemAlloc_Positive_Basic") {
constexpr size_t allocation_size = N * sizeof(int);
hipGraph_t graph;
hipStream_t streamForGraph;
hipGraphExec_t graphExec;
HIP_CHECK(hipStreamCreate(&streamForGraph));
HIP_CHECK(hipGraphCreate(&graph, 0));
hipGraphNode_t alloc_node;
hipGraphNodeParams alloc_node_params = {};
alloc_node_params.type = hipGraphNodeTypeMemAlloc;
memset(&alloc_node_params.alloc, 0, sizeof(hipMemAllocNodeParams));
alloc_node_params.alloc.bytesize = allocation_size;
alloc_node_params.alloc.poolProps.allocType = hipMemAllocationTypePinned;
alloc_node_params.alloc.poolProps.location.id = 0;
alloc_node_params.alloc.poolProps.location.type = hipMemLocationTypeDevice;
HIP_CHECK(hipGraphAddNode(&alloc_node, graph, nullptr, 0, &alloc_node_params));
REQUIRE(alloc_node_params.alloc.dptr != nullptr);
int* A_d = reinterpret_cast<int*>(alloc_node_params.alloc.dptr);
hipGraphNode_t free_node;
hipGraphNodeParams free_node_params = {};
free_node_params.type = hipGraphNodeTypeMemFree;
free_node_params.free.dptr = A_d;
HIP_CHECK(hipGraphAddNode(&free_node, graph, &alloc_node, 1, &free_node_params));
// Instantiate and launch the graph
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
HIP_CHECK(hipGraphLaunch(graphExec, streamForGraph));
HIP_CHECK(hipStreamSynchronize(streamForGraph));
HIP_CHECK(hipGraphExecDestroy(graphExec));
HIP_CHECK(hipGraphDestroy(graph));
HIP_CHECK(hipStreamDestroy(streamForGraph));
HIP_CHECK(hipDeviceGraphMemTrim(0));
}
/**
* Test Description
* ------------------------
* - Test to verify hipGraphAddNode behavior with invalid arguments:
* -# Nullptr graph
* -# Nullptr graph node
* -# Invalid numDependencies for null list of dependencies
* -# Node in dependency is from different graph
* -# Invalid numNodes
* -# Duplicate node in dependencies
* -# Nullptr params
* -# params type is invalid
* Test source
* ------------------------
* - /unit/graph/hipGraphAddNode.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 6.0
*/
TEST_CASE("Unit_hipGraphAddNode_Negative_Parameters") {
using namespace std::placeholders;
hipGraph_t graph = nullptr;
HIP_CHECK(hipGraphCreate(&graph, 0));
hipEvent_t event;
HIP_CHECK(hipEventCreate(&event));
hipGraphNode_t node;
hipGraphNodeParams node_params = {};
node_params.type = hipGraphNodeTypeEventRecord;
node_params.eventRecord.event = event;
GraphAddNodeCommonNegativeTests(std::bind(hipGraphAddNode, _1, _2, _3, _4, &node_params), graph);
SECTION("params == nullptr") {
HIP_CHECK_ERROR(hipGraphAddNode(&node, graph, nullptr, 0, nullptr), hipErrorInvalidValue);
}
SECTION("params type is invalid") {
node_params.type = static_cast<hipGraphNodeType>(0x20);
HIP_CHECK_ERROR(hipGraphAddNode(&node, graph, nullptr, 0, &node_params), hipErrorInvalidValue);
}
HIP_CHECK(hipGraphDestroy(graph));
HIP_CHECK(hipEventDestroy(event));
}
@@ -22,7 +22,6 @@ THE SOFTWARE.
#include <functional>
#include <vector>
#include <hip_test_defgroups.hh>
#include <hip_test_common.hh>
#include <hip_test_checkers.hh>
@@ -86,7 +85,7 @@ void GraphExecMemcpyToSymbolSetParamsShell(const void* symbol, const void* alt_s
* node addition. A graph is constructed to which a MemcpyToSymbol node is added with valid but
* incorrect parameters. After the graph is instantiated the parameters are updated to correct
* values and the graph executed. After graph execution, a MemcpyFromSymbol is performed and the
* copied values are compared against values known to have been copied to symbol memory previously.
* copied values are compared against values known to have been copied to symbol memory previously.
* The test is run for scalar, const scalar, array, and const array symbols of types char, int,
* float and double. For array symbols, the test is repeated for zero and non-zero offset values.
* Verification is performed for destination memory allocated on host and device.
@@ -21,7 +21,6 @@ THE SOFTWARE.
#include <functional>
#include <hip_test_defgroups.hh>
#include <hip_test_common.hh>
#include "graph_memset_node_test_common.hh"
@@ -46,7 +45,7 @@ THE SOFTWARE.
* which also constitutes a test for said API.
* The test is repeated for all valid element sizes(1,
* 2, 4), and several allocations of different width(height is always 1 because only 1D memset nodes
* can be updated), both on host and device
* can be updated), both on host and device
* Test source
* ------------------------
* - unit/graph/hipGraphExecMemsetNodeSetParams.cc
+1 -1
View File
@@ -20,7 +20,7 @@ THE SOFTWARE.
#include <hip_test_common.hh>
#include <hip_test_checkers.hh>
#include <hip_test_kernels.hh>
#include <hip_test_defgroups.hh>
#include "graph_dependency_common.hh"
+1 -1
View File
@@ -22,7 +22,7 @@ THE SOFTWARE.
#include <hip_test_common.hh>
#include <hip_test_checkers.hh>
#include <hip_test_kernels.hh>
#include <hip_test_defgroups.hh>
#include "graph_dependency_common.hh"
+1 -1
View File
@@ -22,7 +22,7 @@ THE SOFTWARE.
#include <hip_test_common.hh>
#include <hip_test_checkers.hh>
#include <hip_test_kernels.hh>
#include <hip_test_defgroups.hh>
#include "graph_dependency_common.hh"
@@ -22,7 +22,6 @@ THE SOFTWARE.
#include <functional>
#include <vector>
#include <hip_test_defgroups.hh>
#include <hip_test_common.hh>
#include <hip_test_checkers.hh>
@@ -85,7 +84,7 @@ void GraphMemcpyFromSymbolSetParamsShell(const void* symbol, const void* alt_sym
* - Verify that data is correctly copied from a symbol after node parameters are set following
* node addition. A graph is constructed to which a MemcpyFromSymbol node is added with valid but
* incorrect parameters. The parameters are then updated to correct values and the graph executed.
* Values in destination memory are compared against values known to be in symbol memory.
* Values in destination memory are compared against values known to be in symbol memory.
* The test is run for scalar, const scalar, array, and const array symbols of types char, int,
* float and double. For array symbols, the test is repeated for zero and non-zero offset values.
* Verification is performed for destination memory allocated on host and device.
@@ -22,7 +22,6 @@ THE SOFTWARE.
#include <functional>
#include <vector>
#include <hip_test_defgroups.hh>
#include <hip_test_common.hh>
#include <hip_test_checkers.hh>
@@ -86,7 +85,7 @@ void GraphMemcpyToSymbolSetParamsShell(const void* symbol, const void* alt_symbo
* node addition. A graph is constructed to which a MemcpyToSymbol node is added with valid but
* incorrect parameters. The parameters are then updated to correct values and the graph executed.
* After graph execution, a MemcpyFromSymbol is performed and the copied values are compared against
* values known to have been copied to symbol memory previously.
* values known to have been copied to symbol memory previously.
* The test is run for scalar, const scalar, array, and const array symbols of types char, int,
* float and double. For array symbols, the test is repeated for zero and non-zero offset values.
* Verification is performed for destination memory allocated on host and device.
@@ -19,7 +19,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include <hip_test_defgroups.hh>
#include <hip_test_common.hh>
#include <resource_guards.hh>
@@ -21,7 +21,6 @@ THE SOFTWARE.
#include <functional>
#include <hip_test_defgroups.hh>
#include <hip_test_common.hh>
#include "graph_memset_node_test_common.hh"
@@ -44,7 +43,7 @@ THE SOFTWARE.
* The parameters are also verified via hipGraphMemsetNodeGetParams, which also constitutes a test
* for said API.
* The test is repeated for all valid element sizes(1, 2, 4), and several allocations of different
* height and width both on host and device
* height and width both on host and device
* Test source
* ------------------------
* - unit/graph/hipGraphMemsetNodeSetParams.cc
@@ -100,7 +99,7 @@ TEMPLATE_TEST_CASE("Unit_hipGraphMemsetNodeSetParams_Positive_Basic", "", uint8_
return hipSuccess;
};
GraphMemsetNodeCommonPositive<TestType>(f);
GraphMemsetNodeCommonPositive<TestType, hipMemsetParams>(f);
}
/**
@@ -22,7 +22,7 @@ THE SOFTWARE.
#include <hip_test_common.hh>
#include <hip_test_checkers.hh>
#include <hip_test_kernels.hh>
#include <hip_test_defgroups.hh>
#include "graph_dependency_common.hh"
@@ -22,7 +22,7 @@ THE SOFTWARE.
#include <hip_test_common.hh>
#include <hip_test_checkers.hh>
#include <hip_test_kernels.hh>
#include <hip_test_defgroups.hh>
#include "graph_dependency_common.hh"
@@ -20,7 +20,7 @@ THE SOFTWARE.
#include <hip_test_common.hh>
#include <hip_test_checkers.hh>
#include <hip_test_kernels.hh>
#include <hip_test_defgroups.hh>
#include "graph_dependency_common.hh"
-1
View File
@@ -18,7 +18,6 @@ THE SOFTWARE.
*/
#include <hip_test_common.hh>
#include <hip_test_kernels.hh>
#include <hip_test_defgroups.hh>
#include "stream_capture_common.hh"
+135 -198
View File
@@ -19,7 +19,7 @@ THE SOFTWARE.
#include <hip_test_common.hh>
#include <hip_test_kernels.hh>
#include <hip_test_defgroups.hh>
#include "stream_capture_common.hh" // NOLINT
#pragma clang diagnostic ignored "-Wunused-variable"
@@ -56,8 +56,7 @@ static void hostNodeCallback(void* data) {
}
template <typename T, typename F>
void captureStreamAndLaunchGraph(F graphFunc, hipStreamCaptureMode mode,
hipStream_t stream) {
void captureStreamAndLaunchGraph(F graphFunc, hipStreamCaptureMode mode, hipStream_t stream) {
constexpr size_t N = 1000000;
size_t Nbytes = N * sizeof(T);
@@ -89,8 +88,7 @@ void captureStreamAndLaunchGraph(F graphFunc, hipStreamCaptureMode mode,
std::fill_n(A_h.host_ptr(), N, static_cast<float>(i));
HIP_CHECK(hipGraphLaunch(graphExec, stream));
HIP_CHECK(hipStreamSynchronize(stream));
ArrayFindIfNot(B_h.host_ptr(),
static_cast<float>(i) * static_cast<float>(i), N);
ArrayFindIfNot(B_h.host_ptr(), static_cast<float>(i) * static_cast<float>(i), N);
}
HIP_CHECK(hipGraphExecDestroy(graphExec))
@@ -117,16 +115,15 @@ TEST_CASE("Unit_hipStreamBeginCapture_Positive_Functional") {
StreamGuard stream_guard(stream_type);
hipStream_t stream = stream_guard.stream();
const hipStreamCaptureMode captureMode = GENERATE(hipStreamCaptureModeGlobal,
hipStreamCaptureModeThreadLocal, hipStreamCaptureModeRelaxed);
const hipStreamCaptureMode captureMode = GENERATE(
hipStreamCaptureModeGlobal, hipStreamCaptureModeThreadLocal, hipStreamCaptureModeRelaxed);
EventsGuard events_guard(3);
StreamsGuard streams_guard(2);
SECTION("Linear graph capture") {
captureStreamAndLaunchGraph<float>(
[](float* A_h, float* A_d, float* B_h, float* B_d, size_t N,
hipStream_t stream) {
[](float* A_h, float* A_d, float* B_h, float* B_d, size_t N, hipStream_t stream) {
return captureSequenceLinear(A_h, A_d, B_h, B_d, N, stream);
},
captureMode, stream);
@@ -134,10 +131,10 @@ TEST_CASE("Unit_hipStreamBeginCapture_Positive_Functional") {
SECTION("Branched graph capture") {
captureStreamAndLaunchGraph<float>(
[&streams_guard, &events_guard](float* A_h, float* A_d, float* B_h,
float* B_d, size_t N, hipStream_t stream) {
captureSequenceBranched(A_h, A_d, B_h, B_d, N, stream,
streams_guard.stream_list(), events_guard.event_list());
[&streams_guard, &events_guard](float* A_h, float* A_d, float* B_h, float* B_d, size_t N,
hipStream_t stream) {
captureSequenceBranched(A_h, A_d, B_h, B_d, N, stream, streams_guard.stream_list(),
events_guard.event_list());
},
captureMode, stream);
}
@@ -173,8 +170,7 @@ TEST_CASE("Unit_hipStreamBeginCapture_Negative_Parameters") {
hipErrorIllegalState);
}
SECTION("Creating hipStream with invalid mode") {
HIP_CHECK_ERROR(hipStreamBeginCapture(stream, hipStreamCaptureMode(-1)),
hipErrorInvalidValue);
HIP_CHECK_ERROR(hipStreamBeginCapture(stream, hipStreamCaptureMode(-1)), hipErrorInvalidValue);
}
#if HT_NVIDIA // EXSWHTEC-216
SECTION("Stream capture on uninitialized stream returns error code.") {
@@ -182,8 +178,7 @@ TEST_CASE("Unit_hipStreamBeginCapture_Negative_Parameters") {
StreamGuard sg(Streams::created);
return sg.stream();
};
HIP_CHECK_ERROR(hipStreamBeginCapture(InvalidStream(),
hipStreamCaptureModeGlobal),
HIP_CHECK_ERROR(hipStreamBeginCapture(InvalidStream(), hipStreamCaptureModeGlobal),
hipErrorContextIsDestroyed);
}
#endif
@@ -207,8 +202,8 @@ TEST_CASE("Unit_hipStreamBeginCapture_Positive_Basic") {
StreamGuard stream_guard(stream_type);
hipStream_t s = stream_guard.stream();
const hipStreamCaptureMode captureMode = GENERATE(hipStreamCaptureModeGlobal,
hipStreamCaptureModeThreadLocal, hipStreamCaptureModeRelaxed);
const hipStreamCaptureMode captureMode = GENERATE(
hipStreamCaptureModeGlobal, hipStreamCaptureModeThreadLocal, hipStreamCaptureModeRelaxed);
HIP_CHECK(hipStreamBeginCapture(s, captureMode));
@@ -218,8 +213,7 @@ TEST_CASE("Unit_hipStreamBeginCapture_Positive_Basic") {
/* Local function for inter stream event synchronization
*/
static void interStrmEventSyncCapture(const hipStream_t& stream1,
const hipStream_t& stream2) {
static void interStrmEventSyncCapture(const hipStream_t& stream1, const hipStream_t& stream2) {
hipGraph_t graph1{nullptr}, graph2{nullptr};
hipGraphExec_t graphExec1{nullptr}, graphExec2{nullptr};
@@ -266,8 +260,7 @@ static void interStrmEventSyncCapture(const hipStream_t& stream1,
/* Local function for colligated stream capture
*/
static void colligatedStrmCapture(const hipStream_t& stream1,
const hipStream_t& stream2) {
static void colligatedStrmCapture(const hipStream_t& stream1, const hipStream_t& stream2) {
hipGraph_t graph1{nullptr}, graph2{nullptr};
hipGraphExec_t graphExec1{nullptr}, graphExec2{nullptr};
@@ -310,8 +303,7 @@ static void colligatedStrmCapture(const hipStream_t& stream1,
/* Local function for colligated stream capture functionality
*/
static void colligatedStrmCaptureFunc(const hipStream_t& stream1,
const hipStream_t& stream2) {
static void colligatedStrmCaptureFunc(const hipStream_t& stream1, const hipStream_t& stream2) {
constexpr size_t N = 1000000;
size_t Nbytes = N * sizeof(int);
@@ -331,10 +323,8 @@ static void colligatedStrmCaptureFunc(const hipStream_t& stream1,
// Capture 2 streams
HIP_CHECK(hipStreamBeginCapture(stream1, hipStreamCaptureModeGlobal));
HIP_CHECK(hipStreamBeginCapture(stream2, hipStreamCaptureModeGlobal));
captureSequenceLinear(A_h.host_ptr(), A_d.ptr(), B_h.host_ptr(), B_d.ptr(),
N, stream1);
captureSequenceLinear(C_h.host_ptr(), C_d.ptr(), D_h.host_ptr(), D_d.ptr(),
N, stream2);
captureSequenceLinear(A_h.host_ptr(), A_d.ptr(), B_h.host_ptr(), B_d.ptr(), N, stream1);
captureSequenceLinear(C_h.host_ptr(), C_d.ptr(), D_h.host_ptr(), D_d.ptr(), N, stream2);
captureSequenceCompute(A_d.ptr(), B_h.host_ptr(), B_d.ptr(), N, stream1);
captureSequenceCompute(C_d.ptr(), D_h.host_ptr(), D_d.ptr(), N, stream2);
HIP_CHECK(hipStreamEndCapture(stream1, &graph1));
@@ -370,9 +360,8 @@ static void colligatedStrmCaptureFunc(const hipStream_t& stream1,
/* Stream Capture thread function
*/
static void threadStrmCaptureFunc(hipStream_t stream, int* A_h, int* A_d,
int* B_h, int* B_d, hipGraph_t* graph,
size_t N, hipStreamCaptureMode mode) {
static void threadStrmCaptureFunc(hipStream_t stream, int* A_h, int* A_d, int* B_h, int* B_d,
hipGraph_t* graph, size_t N, hipStreamCaptureMode mode) {
// Capture stream
HIP_CHECK(hipStreamBeginCapture(stream, mode));
captureSequenceLinear(A_h, A_d, B_h, B_d, N, stream);
@@ -404,10 +393,10 @@ static void multithreadedTest(hipStreamCaptureMode mode) {
LinearAllocGuard<int> D_d(LinearAllocs::hipMalloc, Nbytes);
// Launch 2 threads to capture the 2 streams into graphs
std::thread t1(threadStrmCaptureFunc, stream1, A_h.host_ptr(), A_d.ptr(),
B_h.host_ptr(), B_d.ptr(), &graph1, N, mode);
std::thread t2(threadStrmCaptureFunc, stream2, C_h.host_ptr(), C_d.ptr(),
D_h.host_ptr(), D_d.ptr(), &graph2, N, mode);
std::thread t1(threadStrmCaptureFunc, stream1, A_h.host_ptr(), A_d.ptr(), B_h.host_ptr(),
B_d.ptr(), &graph1, N, mode);
std::thread t2(threadStrmCaptureFunc, stream2, C_h.host_ptr(), C_d.ptr(), D_h.host_ptr(),
D_d.ptr(), &graph2, N, mode);
t1.join();
t2.join();
@@ -480,11 +469,9 @@ TEST_CASE("Unit_hipStreamBeginCapture_Positive_InterStrmEventSync_Flags") {
TEST_CASE("Unit_hipStreamBeginCapture_Positive_InterStrmEventSync_Priority") {
int minPriority = 0, maxPriority = 0;
HIP_CHECK(hipDeviceGetStreamPriorityRange(&minPriority, &maxPriority));
StreamGuard stream_guard1(Streams::withPriority, hipStreamDefault,
minPriority);
StreamGuard stream_guard1(Streams::withPriority, hipStreamDefault, minPriority);
hipStream_t stream1 = stream_guard1.stream();
StreamGuard stream_guard2(Streams::withPriority, hipStreamDefault,
maxPriority);
StreamGuard stream_guard2(Streams::withPriority, hipStreamDefault, maxPriority);
hipStream_t stream2 = stream_guard2.stream();
interStrmEventSyncCapture(stream1, stream2);
}
@@ -533,11 +520,9 @@ TEST_CASE("Unit_hipStreamBeginCapture_Positive_ColligatedStrmCapture_Flags") {
TEST_CASE("Unit_hipStreamBeginCapture_Positive_ColligatedStrmCapture_Prio") {
int minPriority = 0, maxPriority = 0;
HIP_CHECK(hipDeviceGetStreamPriorityRange(&minPriority, &maxPriority));
StreamGuard stream_guard1(Streams::withPriority, hipStreamDefault,
minPriority);
StreamGuard stream_guard1(Streams::withPriority, hipStreamDefault, minPriority);
hipStream_t stream1 = stream_guard1.stream();
StreamGuard stream_guard2(Streams::withPriority, hipStreamDefault,
maxPriority);
StreamGuard stream_guard2(Streams::withPriority, hipStreamDefault, maxPriority);
hipStream_t stream2 = stream_guard2.stream();
colligatedStrmCapture(stream1, stream2);
}
@@ -578,8 +563,8 @@ TEST_CASE("Unit_hipStreamBeginCapture_Positive_ColligatedStrmCaptureFunc") {
* - HIP_VERSION >= 5.2
*/
TEST_CASE("Unit_hipStreamBeginCapture_Positive_Multithreaded") {
const hipStreamCaptureMode captureMode = GENERATE(hipStreamCaptureModeGlobal,
hipStreamCaptureModeThreadLocal, hipStreamCaptureModeRelaxed);
const hipStreamCaptureMode captureMode = GENERATE(
hipStreamCaptureModeGlobal, hipStreamCaptureModeThreadLocal, hipStreamCaptureModeRelaxed);
multithreadedTest(captureMode);
}
@@ -708,8 +693,7 @@ TEST_CASE("Unit_hipStreamBeginCapture_Positive_CapturingFromWithinStrms") {
HIP_CHECK(hipEventRecord(events[2], streams[2]));
HIP_CHECK(hipStreamWaitEvent(streams[0], events[1], 0));
HIP_CHECK(hipStreamWaitEvent(streams[0], events[2], 0));
HIP_CHECK(hipMemcpyAsync(hostMem, devMem, sizeof(int), hipMemcpyDefault,
streams[0]));
HIP_CHECK(hipMemcpyAsync(hostMem, devMem, sizeof(int), hipMemcpyDefault, streams[0]));
HIP_CHECK(hipStreamEndCapture(streams[0], &graph)); // End Capture
// Reset device memory
HIP_CHECK(hipMemset(devMem, 0, sizeof(int)));
@@ -751,8 +735,7 @@ TEST_CASE("Unit_hipStreamBeginCapture_Negative_DetectingInvalidCapture") {
dummyKernel<<<1, 1, 0, streams[0]>>>();
// Since stream[1] is already in capture mode due to event wait
// hipStreamBeginCapture on stream[1] is expected to return error.
HIP_CHECK_ERROR(hipStreamBeginCapture(streams[1],
hipStreamCaptureModeGlobal),
HIP_CHECK_ERROR(hipStreamBeginCapture(streams[1], hipStreamCaptureModeGlobal),
hipErrorIllegalState);
}
@@ -785,8 +768,7 @@ TEST_CASE("Unit_hipStreamBeginCapture_Positive_CapturingMultGraphsFrom1Strm") {
for (int i = 0; i < 3; i++) {
HIP_CHECK(hipStreamBeginCapture(stream1, hipStreamCaptureModeGlobal));
for (int j = 0; j <= i; j++) incrementKernel<<<1, 1, 0, stream1>>>(devMem);
HIP_CHECK(hipMemcpyAsync(hostMem, devMem, sizeof(int), hipMemcpyDefault,
stream1));
HIP_CHECK(hipMemcpyAsync(hostMem, devMem, sizeof(int), hipMemcpyDefault, stream1));
HIP_CHECK(hipStreamEndCapture(stream1, &graphs[i]));
}
// Instantiate and execute all graphs
@@ -825,22 +807,19 @@ TEST_CASE("Unit_hipStreamBeginCapture_Negative_CheckingSyncDuringCapture") {
EventsGuard events_guard(1);
hipEvent_t e = events_guard[0];
const hipStreamCaptureMode captureMode = GENERATE(hipStreamCaptureModeGlobal,
hipStreamCaptureModeThreadLocal, hipStreamCaptureModeRelaxed);
const hipStreamCaptureMode captureMode = GENERATE(
hipStreamCaptureModeGlobal, hipStreamCaptureModeThreadLocal, hipStreamCaptureModeRelaxed);
HIP_CHECK(hipStreamBeginCapture(stream, captureMode));
SECTION("Synchronize stream during capture") {
HIP_CHECK_ERROR(hipStreamSynchronize(stream),
hipErrorStreamCaptureUnsupported);
HIP_CHECK_ERROR(hipStreamSynchronize(stream), hipErrorStreamCaptureUnsupported);
}
SECTION("Query stream during capture") {
HIP_CHECK_ERROR(hipStreamQuery(stream),
hipErrorStreamCaptureUnsupported);
HIP_CHECK_ERROR(hipStreamQuery(stream), hipErrorStreamCaptureUnsupported);
}
#if HT_NVIDIA
SECTION("Synchronize device during capture") {
HIP_CHECK_ERROR(hipDeviceSynchronize(),
hipErrorStreamCaptureUnsupported);
HIP_CHECK_ERROR(hipDeviceSynchronize(), hipErrorStreamCaptureUnsupported);
}
SECTION("Synchronize event during capture") {
HIP_CHECK(hipEventRecord(e, stream));
@@ -884,17 +863,14 @@ TEST_CASE("Unit_hipStreamBeginCapture_Negative_UnsafeCallsDuringCapture") {
HIP_CHECK(hipStreamBeginCapture(stream, captureMode));
SECTION("hipMalloc during capture") {
HIP_CHECK_ERROR(hipMalloc(&devMem2, sizeof(int)),
hipErrorStreamCaptureUnsupported);
HIP_CHECK_ERROR(hipMalloc(&devMem2, sizeof(int)), hipErrorStreamCaptureUnsupported);
}
SECTION("hipMemcpy during capture") {
HIP_CHECK_ERROR(hipMemcpy(devMem.ptr(), hostMem.host_ptr(), sizeof(int),
hipMemcpyHostToDevice),
HIP_CHECK_ERROR(hipMemcpy(devMem.ptr(), hostMem.host_ptr(), sizeof(int), hipMemcpyHostToDevice),
hipErrorStreamCaptureImplicit);
}
SECTION("hipMemset during capture") {
HIP_CHECK_ERROR(hipMemset(devMem.ptr(), 0, sizeof(int)),
hipErrorStreamCaptureImplicit);
HIP_CHECK_ERROR(hipMemset(devMem.ptr(), 0, sizeof(int)), hipErrorStreamCaptureImplicit);
}
}
#endif
@@ -931,8 +907,7 @@ TEST_CASE("Unit_hipStreamBeginCapture_Negative_EndingCapwhenCapInProg") {
HIP_CHECK(hipEventRecord(e, stream1));
HIP_CHECK(hipStreamWaitEvent(stream2, e, 0));
dummyKernel<<<1, 1, 0, stream2>>>();
HIP_CHECK_ERROR(hipStreamEndCapture(stream1, &graph),
hipErrorStreamCaptureUnjoined);
HIP_CHECK_ERROR(hipStreamEndCapture(stream1, &graph), hipErrorStreamCaptureUnjoined);
}
SECTION("End strm capture when forked strm still has operations") {
EventsGuard events_guard(2);
@@ -946,8 +921,7 @@ TEST_CASE("Unit_hipStreamBeginCapture_Negative_EndingCapwhenCapInProg") {
HIP_CHECK(hipEventRecord(e2, stream2));
HIP_CHECK(hipStreamWaitEvent(stream1, e2, 0));
dummyKernel<<<1, 1, 0, stream2>>>();
HIP_CHECK_ERROR(hipStreamEndCapture(stream1, &graph),
hipErrorStreamCaptureUnjoined);
HIP_CHECK_ERROR(hipStreamEndCapture(stream1, &graph), hipErrorStreamCaptureUnjoined);
}
}
/**
@@ -970,19 +944,17 @@ TEST_CASE("Unit_hipStreamBeginCapture_Positive_MultiGPU") {
SUCCEED("skipping the testcases as numDevices < 2");
return;
}
hipStream_t* stream = reinterpret_cast<hipStream_t*>
(malloc(devcount * sizeof(hipStream_t)));
hipStream_t* stream = reinterpret_cast<hipStream_t*>(malloc(devcount * sizeof(hipStream_t)));
REQUIRE(stream != nullptr);
hipGraph_t* graph = reinterpret_cast<hipGraph_t*>
(malloc(devcount * sizeof(hipGraph_t)));
hipGraph_t* graph = reinterpret_cast<hipGraph_t*>(malloc(devcount * sizeof(hipGraph_t)));
REQUIRE(graph != nullptr);
int **devMem{nullptr}, **hostMem{nullptr};
hostMem = reinterpret_cast<int**>(malloc(sizeof(int*) * devcount));
REQUIRE(hostMem != nullptr);
devMem = reinterpret_cast<int**>(malloc(sizeof(int*) * devcount));
REQUIRE(devMem != nullptr);
hipGraphExec_t* graphExec = reinterpret_cast<hipGraphExec_t*>
(malloc(devcount * sizeof(hipGraphExec_t)));
hipGraphExec_t* graphExec =
reinterpret_cast<hipGraphExec_t*>(malloc(devcount * sizeof(hipGraphExec_t)));
// Capture stream in each device
for (int dev = 0; dev < devcount; dev++) {
HIP_CHECK(hipSetDevice(dev));
@@ -994,15 +966,14 @@ TEST_CASE("Unit_hipStreamBeginCapture_Positive_MultiGPU") {
for (int i = 0; i < (dev + 1); i++) {
incrementKernel<<<1, 1, 0, stream[dev]>>>(devMem[dev]);
}
HIP_CHECK(hipMemcpyAsync(hostMem[dev], devMem[dev], sizeof(int),
hipMemcpyDefault, stream[dev]));
HIP_CHECK(
hipMemcpyAsync(hostMem[dev], devMem[dev], sizeof(int), hipMemcpyDefault, stream[dev]));
HIP_CHECK(hipStreamEndCapture(stream[dev], &graph[dev]));
}
// Launch the captured graphs in the respective device
for (int dev = 0; dev < devcount; dev++) {
HIP_CHECK(hipSetDevice(dev));
HIP_CHECK(hipGraphInstantiate(&graphExec[dev], graph[dev], nullptr,
nullptr, 0));
HIP_CHECK(hipGraphInstantiate(&graphExec[dev], graph[dev], nullptr, nullptr, 0));
HIP_CHECK(hipGraphLaunch(graphExec[dev], stream[dev]));
}
// Validate output
@@ -1069,8 +1040,8 @@ TEST_CASE("Unit_hipStreamBeginCapture_Positive_nestedStreamCapture") {
HIP_CHECK(hipEventRecord(events[3], streams[2]));
HIP_CHECK(hipStreamWaitEvent(streams[0], events[3], 0));
HIP_CHECK(hipStreamWaitEvent(streams[0], events[2], 0));
HIP_CHECK(hipMemcpyAsync(hostMem_g.host_ptr(), devMem_g.ptr(), sizeof(int),
hipMemcpyDefault, streams[0]));
HIP_CHECK(hipMemcpyAsync(hostMem_g.host_ptr(), devMem_g.ptr(), sizeof(int), hipMemcpyDefault,
streams[0]));
HIP_CHECK(hipStreamEndCapture(streams[0], &graph)); // End Capture
// Reset device memory
HIP_CHECK(hipMemset(devMem_g.ptr(), 0, sizeof(int)));
@@ -1108,23 +1079,15 @@ TEST_CASE("Unit_hipStreamBeginCapture_Positive_streamReuse") {
hipGraph_t graphs[3];
StreamsGuard streams(3);
EventsGuard events(4);
LinearAllocGuard<int> hostMem_g1 = LinearAllocGuard<int>
(LinearAllocs::malloc, sizeof(int));
LinearAllocGuard<int> hostMem_g2 = LinearAllocGuard<int>
(LinearAllocs::malloc, sizeof(int));
LinearAllocGuard<int> hostMem_g3 = LinearAllocGuard<int>
(LinearAllocs::malloc, sizeof(int));
LinearAllocGuard<int> devMem_g1 = LinearAllocGuard<int>
(LinearAllocs::hipMalloc, sizeof(int));
LinearAllocGuard<int> devMem_g2 = LinearAllocGuard<int>
(LinearAllocs::hipMalloc, sizeof(int));
LinearAllocGuard<int> devMem_g3 = LinearAllocGuard<int>
(LinearAllocs::hipMalloc, sizeof(int));
LinearAllocGuard<int> hostMem_g1 = LinearAllocGuard<int>(LinearAllocs::malloc, sizeof(int));
LinearAllocGuard<int> hostMem_g2 = LinearAllocGuard<int>(LinearAllocs::malloc, sizeof(int));
LinearAllocGuard<int> hostMem_g3 = LinearAllocGuard<int>(LinearAllocs::malloc, sizeof(int));
LinearAllocGuard<int> devMem_g1 = LinearAllocGuard<int>(LinearAllocs::hipMalloc, sizeof(int));
LinearAllocGuard<int> devMem_g2 = LinearAllocGuard<int>(LinearAllocs::hipMalloc, sizeof(int));
LinearAllocGuard<int> devMem_g3 = LinearAllocGuard<int>(LinearAllocs::hipMalloc, sizeof(int));
std::vector<int*> hostMem = {hostMem_g1.host_ptr(), hostMem_g2.host_ptr(),
hostMem_g3.host_ptr()};
std::vector<int*> devMem = {devMem_g1.ptr(), devMem_g2.ptr(),
devMem_g3.ptr()};
std::vector<int*> hostMem = {hostMem_g1.host_ptr(), hostMem_g2.host_ptr(), hostMem_g3.host_ptr()};
std::vector<int*> devMem = {devMem_g1.ptr(), devMem_g2.ptr(), devMem_g3.ptr()};
// Create a device memory of size int and initialize it to 0
for (int i = 0; i < 3; i++) {
memset(hostMem[i], 0, sizeof(int));
@@ -1148,16 +1111,14 @@ TEST_CASE("Unit_hipStreamBeginCapture_Positive_streamReuse") {
HIP_CHECK(hipEventRecord(events[3], streams[2]));
HIP_CHECK(hipStreamWaitEvent(streams[0], events[3], 0));
HIP_CHECK(hipStreamWaitEvent(streams[0], events[2], 0));
HIP_CHECK(hipMemcpyAsync(hostMem[0], devMem[0], sizeof(int),
hipMemcpyDefault, streams[0]));
HIP_CHECK(hipMemcpyAsync(hostMem[0], devMem[0], sizeof(int), hipMemcpyDefault, streams[0]));
HIP_CHECK(hipStreamEndCapture(streams[0], &graphs[0])); // End Capture
// Start capturing graph2 from stream 2
HIP_CHECK(hipStreamBeginCapture(streams[1], hipStreamCaptureModeGlobal));
incrementKernel<<<1, 1, 0, streams[1]>>>(devMem[1]);
incrementKernel<<<1, 1, 0, streams[1]>>>(devMem[1]);
incrementKernel<<<1, 1, 0, streams[1]>>>(devMem[1]);
HIP_CHECK(hipMemcpyAsync(hostMem[1], devMem[1], sizeof(int),
hipMemcpyDefault, streams[1]));
HIP_CHECK(hipMemcpyAsync(hostMem[1], devMem[1], sizeof(int), hipMemcpyDefault, streams[1]));
HIP_CHECK(hipStreamEndCapture(streams[1], &graphs[1])); // End Capture
// Start capturing graph3 from stream 3
HIP_CHECK(hipStreamBeginCapture(streams[2], hipStreamCaptureModeGlobal));
@@ -1166,8 +1127,7 @@ TEST_CASE("Unit_hipStreamBeginCapture_Positive_streamReuse") {
incrementKernel<<<1, 1, 0, streams[2]>>>(devMem[2]);
incrementKernel<<<1, 1, 0, streams[2]>>>(devMem[2]);
incrementKernel<<<1, 1, 0, streams[2]>>>(devMem[2]);
HIP_CHECK(hipMemcpyAsync(hostMem[2], devMem[2], sizeof(int),
hipMemcpyDefault, streams[2]));
HIP_CHECK(hipMemcpyAsync(hostMem[2], devMem[2], sizeof(int), hipMemcpyDefault, streams[2]));
HIP_CHECK(hipStreamEndCapture(streams[2], &graphs[2])); // End Capture
// Reset device memory
HIP_CHECK(hipMemset(devMem[0], 0, sizeof(int)));
@@ -1211,40 +1171,32 @@ TEST_CASE("Unit_hipStreamBeginCapture_Positive_captureComplexGraph") {
EventsGuard events(7);
// Allocate Device memory and Host memory
size_t N = GRIDSIZE * BLOCKSIZE;
LinearAllocGuard<int> Ah = LinearAllocGuard<int>
(LinearAllocs::malloc, N * sizeof(int));
LinearAllocGuard<int> Bh = LinearAllocGuard<int>
(LinearAllocs::malloc, N * sizeof(int));
LinearAllocGuard<int> Ch = LinearAllocGuard<int>
(LinearAllocs::malloc, N * sizeof(int));
LinearAllocGuard<int> Ad = LinearAllocGuard<int>
(LinearAllocs::hipMalloc, N * sizeof(int));
LinearAllocGuard<int> Bd = LinearAllocGuard<int>
(LinearAllocs::hipMalloc, N * sizeof(int));
LinearAllocGuard<int> Ah = LinearAllocGuard<int>(LinearAllocs::malloc, N * sizeof(int));
LinearAllocGuard<int> Bh = LinearAllocGuard<int>(LinearAllocs::malloc, N * sizeof(int));
LinearAllocGuard<int> Ch = LinearAllocGuard<int>(LinearAllocs::malloc, N * sizeof(int));
LinearAllocGuard<int> Ad = LinearAllocGuard<int>(LinearAllocs::hipMalloc, N * sizeof(int));
LinearAllocGuard<int> Bd = LinearAllocGuard<int>(LinearAllocs::hipMalloc, N * sizeof(int));
// Capture streams into graph
HIP_CHECK(hipStreamBeginCapture(streams[0], hipStreamCaptureModeGlobal));
HIP_CHECK(hipEventRecord(events[0], streams[0]));
HIP_CHECK(hipStreamWaitEvent(streams[3], events[0], 0));
HIP_CHECK(hipStreamWaitEvent(streams[4], events[0], 0));
HIP_CHECK(hipMemcpyAsync(Ad.ptr(), Ah.host_ptr(), (N * sizeof(int)),
hipMemcpyDefault, streams[0]));
HIP_CHECK(hipMemcpyAsync(Bd.ptr(), Bh.host_ptr(), (N * sizeof(int)),
hipMemcpyDefault, streams[4]));
HIP_CHECK(
hipMemcpyAsync(Ad.ptr(), Ah.host_ptr(), (N * sizeof(int)), hipMemcpyDefault, streams[0]));
HIP_CHECK(
hipMemcpyAsync(Bd.ptr(), Bh.host_ptr(), (N * sizeof(int)), hipMemcpyDefault, streams[4]));
hipHostFn_t fn = hostNodeCallback;
HIPCHECK(hipLaunchHostFunc(streams[3], fn, nullptr));
HIP_CHECK(hipEventRecord(events[1], streams[0]));
HIP_CHECK(hipStreamWaitEvent(streams[1], events[1], 0));
int* Ad_2nd_half = Ad.ptr() + N / 2;
int* Ad_1st_half = Ad.ptr();
mymul<<<GRIDSIZE / 2, BLOCKSIZE, 0, streams[0]>>>(Ad_2nd_half,
CONST_KER2_VAL);
mymul<<<GRIDSIZE / 2, BLOCKSIZE, 0, streams[1]>>>(Ad_1st_half,
CONST_KER1_VAL);
mymul<<<GRIDSIZE / 2, BLOCKSIZE, 0, streams[0]>>>(Ad_2nd_half, CONST_KER2_VAL);
mymul<<<GRIDSIZE / 2, BLOCKSIZE, 0, streams[1]>>>(Ad_1st_half, CONST_KER1_VAL);
HIP_CHECK(hipEventRecord(events[2], streams[1]));
HIP_CHECK(hipStreamWaitEvent(streams[2], events[2], 0));
mymul<<<GRIDSIZE / 2, BLOCKSIZE, 0, streams[1]>>>(Ad_1st_half,
CONST_KER3_VAL);
mymul<<<GRIDSIZE / 2, BLOCKSIZE, 0, streams[1]>>>(Ad_1st_half, CONST_KER3_VAL);
HIPCHECK(hipLaunchHostFunc(streams[2], fn, nullptr));
HIP_CHECK(hipEventRecord(events[6], streams[1]));
HIP_CHECK(hipStreamWaitEvent(streams[0], events[6], 0));
@@ -1255,8 +1207,8 @@ TEST_CASE("Unit_hipStreamBeginCapture_Positive_captureComplexGraph") {
HIP_CHECK(hipStreamWaitEvent(streams[0], events[3], 0));
HIP_CHECK(hipEventRecord(events[4], streams[3]));
HIP_CHECK(hipStreamWaitEvent(streams[0], events[4], 0));
HIP_CHECK(hipMemcpyAsync(Ch.host_ptr(), Ad.ptr(), (N * sizeof(int)),
hipMemcpyDefault, streams[0]));
HIP_CHECK(
hipMemcpyAsync(Ch.host_ptr(), Ad.ptr(), (N * sizeof(int)), hipMemcpyDefault, streams[0]));
HIP_CHECK(hipStreamEndCapture(streams[0], &graph)); // End Capture
// Execute and test the graph
hipGraphExec_t graphExec{nullptr};
@@ -1269,11 +1221,10 @@ TEST_CASE("Unit_hipStreamBeginCapture_Positive_captureComplexGraph") {
HIP_CHECK(hipStreamSynchronize(streams[0]));
for (size_t i = 0; i < N; i++) {
if (i > (N / 2 - 1)) {
REQUIRE(Ch.host_ptr()[i] == (Bh.host_ptr()[i] +
Ah.host_ptr()[i] * CONST_KER2_VAL));
REQUIRE(Ch.host_ptr()[i] == (Bh.host_ptr()[i] + Ah.host_ptr()[i] * CONST_KER2_VAL));
} else {
REQUIRE(Ch.host_ptr()[i] == (Bh.host_ptr()[i] +
Ah.host_ptr()[i] * CONST_KER1_VAL * CONST_KER3_VAL));
REQUIRE(Ch.host_ptr()[i] ==
(Bh.host_ptr()[i] + Ah.host_ptr()[i] * CONST_KER1_VAL * CONST_KER3_VAL));
}
}
}
@@ -1340,14 +1291,12 @@ TEST_CASE("Unit_hipStreamBeginCapture_StreamSync_OngoingCapture") {
hipGraph_t graph{nullptr};
hipGraphExec_t graphExec{nullptr};
// Allocate device memory
LinearAllocGuard<int> Ah = LinearAllocGuard<int>(LinearAllocs::malloc,
BLOCKSIZE * sizeof(int));
LinearAllocGuard<int> Ad = LinearAllocGuard<int>(LinearAllocs::hipMalloc,
BLOCKSIZE * sizeof(int));
LinearAllocGuard<int> Bh = LinearAllocGuard<int>(LinearAllocs::malloc,
BLOCKSIZE * sizeof(int));
LinearAllocGuard<int> Bd = LinearAllocGuard<int>(LinearAllocs::hipMalloc,
BLOCKSIZE * sizeof(int));
LinearAllocGuard<int> Ah = LinearAllocGuard<int>(LinearAllocs::malloc, BLOCKSIZE * sizeof(int));
LinearAllocGuard<int> Ad =
LinearAllocGuard<int>(LinearAllocs::hipMalloc, BLOCKSIZE * sizeof(int));
LinearAllocGuard<int> Bh = LinearAllocGuard<int>(LinearAllocs::malloc, BLOCKSIZE * sizeof(int));
LinearAllocGuard<int> Bd =
LinearAllocGuard<int>(LinearAllocs::hipMalloc, BLOCKSIZE * sizeof(int));
// Fill input data
std::fill_n(Ah.host_ptr(), BLOCKSIZE, VALUE1);
std::fill_n(Bh.host_ptr(), BLOCKSIZE, VALUE2);
@@ -1357,10 +1306,10 @@ TEST_CASE("Unit_hipStreamBeginCapture_StreamSync_OngoingCapture") {
SECTION("Stream Creation Before Capture") {
StreamsGuard stream1(1);
HIP_CHECK(hipStreamBeginCapture(stream0[0], flag));
HIP_CHECK(hipMemcpyAsync(Ad.ptr(), Ah.host_ptr(), BLOCKSIZE * sizeof(int),
hipMemcpyDefault, stream1[0]));
HIP_CHECK(hipMemcpyAsync(Bd.ptr(), Bh.host_ptr(), BLOCKSIZE * sizeof(int),
hipMemcpyDefault, stream1[0]));
HIP_CHECK(hipMemcpyAsync(Ad.ptr(), Ah.host_ptr(), BLOCKSIZE * sizeof(int), hipMemcpyDefault,
stream1[0]));
HIP_CHECK(hipMemcpyAsync(Bd.ptr(), Bh.host_ptr(), BLOCKSIZE * sizeof(int), hipMemcpyDefault,
stream1[0]));
HIP_CHECK(hipStreamSynchronize(stream1[0]));
myadd<<<GRIDSIZE, BLOCKSIZE, 0, stream0[0]>>>(Ad.ptr(), Bd.ptr());
HIP_CHECK(hipStreamEndCapture(stream0[0], &graph)); // End Capture
@@ -1368,10 +1317,10 @@ TEST_CASE("Unit_hipStreamBeginCapture_StreamSync_OngoingCapture") {
SECTION("Synchronizing multiple streams during Capture") {
StreamsGuard stream1(1), stream2(1);
HIP_CHECK(hipStreamBeginCapture(stream0[0], flag));
HIP_CHECK(hipMemcpyAsync(Ad.ptr(), Ah.host_ptr(), BLOCKSIZE * sizeof(int),
hipMemcpyDefault, stream1[0]));
HIP_CHECK(hipMemcpyAsync(Bd.ptr(), Bh.host_ptr(), BLOCKSIZE * sizeof(int),
hipMemcpyDefault, stream2[0]));
HIP_CHECK(hipMemcpyAsync(Ad.ptr(), Ah.host_ptr(), BLOCKSIZE * sizeof(int), hipMemcpyDefault,
stream1[0]));
HIP_CHECK(hipMemcpyAsync(Bd.ptr(), Bh.host_ptr(), BLOCKSIZE * sizeof(int), hipMemcpyDefault,
stream2[0]));
HIP_CHECK(hipStreamSynchronize(stream1[0]));
HIP_CHECK(hipStreamSynchronize(stream2[0]));
myadd<<<GRIDSIZE, BLOCKSIZE, 0, stream0[0]>>>(Ad.ptr(), Bd.ptr());
@@ -1380,20 +1329,20 @@ TEST_CASE("Unit_hipStreamBeginCapture_StreamSync_OngoingCapture") {
SECTION("Stream Creation After Capture") {
HIP_CHECK(hipStreamBeginCapture(stream0[0], flag));
StreamsGuard stream1(1);
HIP_CHECK(hipMemcpyAsync(Ad.ptr(), Ah.host_ptr(), BLOCKSIZE * sizeof(int),
hipMemcpyDefault, stream1[0]));
HIP_CHECK(hipMemcpyAsync(Bd.ptr(), Bh.host_ptr(), BLOCKSIZE * sizeof(int),
hipMemcpyDefault, stream1[0]));
HIP_CHECK(hipMemcpyAsync(Ad.ptr(), Ah.host_ptr(), BLOCKSIZE * sizeof(int), hipMemcpyDefault,
stream1[0]));
HIP_CHECK(hipMemcpyAsync(Bd.ptr(), Bh.host_ptr(), BLOCKSIZE * sizeof(int), hipMemcpyDefault,
stream1[0]));
HIP_CHECK(hipStreamSynchronize(stream1[0]));
myadd<<<GRIDSIZE, BLOCKSIZE, 0, stream0[0]>>>(Ad.ptr(), Bd.ptr());
HIP_CHECK(hipStreamEndCapture(stream0[0], &graph)); // End Capture
}
SECTION("Stream Synchronize Before Capture") {
StreamsGuard stream1(1);
HIP_CHECK(hipMemcpyAsync(Ad.ptr(), Ah.host_ptr(), BLOCKSIZE * sizeof(int),
hipMemcpyDefault, stream1[0]));
HIP_CHECK(hipMemcpyAsync(Bd.ptr(), Bh.host_ptr(), BLOCKSIZE * sizeof(int),
hipMemcpyDefault, stream1[0]));
HIP_CHECK(hipMemcpyAsync(Ad.ptr(), Ah.host_ptr(), BLOCKSIZE * sizeof(int), hipMemcpyDefault,
stream1[0]));
HIP_CHECK(hipMemcpyAsync(Bd.ptr(), Bh.host_ptr(), BLOCKSIZE * sizeof(int), hipMemcpyDefault,
stream1[0]));
HIP_CHECK(hipStreamSynchronize(stream1[0]));
HIP_CHECK(hipStreamBeginCapture(stream0[0], flag));
myadd<<<GRIDSIZE, BLOCKSIZE, 0, stream0[0]>>>(Ad.ptr(), Bd.ptr());
@@ -1404,10 +1353,10 @@ TEST_CASE("Unit_hipStreamBeginCapture_StreamSync_OngoingCapture") {
myadd<<<GRIDSIZE, BLOCKSIZE, 0, stream0[0]>>>(Ad.ptr(), Bd.ptr());
HIP_CHECK(hipStreamEndCapture(stream0[0], &graph)); // End Capture
StreamsGuard stream1(1);
HIP_CHECK(hipMemcpyAsync(Ad.ptr(), Ah.host_ptr(), BLOCKSIZE * sizeof(int),
hipMemcpyDefault, stream1[0]));
HIP_CHECK(hipMemcpyAsync(Bd.ptr(), Bh.host_ptr(), BLOCKSIZE * sizeof(int),
hipMemcpyDefault, stream1[0]));
HIP_CHECK(hipMemcpyAsync(Ad.ptr(), Ah.host_ptr(), BLOCKSIZE * sizeof(int), hipMemcpyDefault,
stream1[0]));
HIP_CHECK(hipMemcpyAsync(Bd.ptr(), Bh.host_ptr(), BLOCKSIZE * sizeof(int), hipMemcpyDefault,
stream1[0]));
HIP_CHECK(hipStreamSynchronize(stream1[0]));
}
// Execute and test the graph
@@ -1415,8 +1364,7 @@ TEST_CASE("Unit_hipStreamBeginCapture_StreamSync_OngoingCapture") {
HIP_CHECK(hipGraphLaunch(graphExec, stream0[0]));
HIP_CHECK(hipStreamSynchronize(stream0[0]));
// Check output
HIP_CHECK(hipMemcpy(Ah.host_ptr(), Ad.ptr(), BLOCKSIZE * sizeof(int),
hipMemcpyDeviceToHost));
HIP_CHECK(hipMemcpy(Ah.host_ptr(), Ad.ptr(), BLOCKSIZE * sizeof(int), hipMemcpyDeviceToHost));
for (int idx = 0; idx < BLOCKSIZE; idx++) {
REQUIRE(Ah.host_ptr()[idx] == (VALUE1 + VALUE2));
}
@@ -1437,20 +1385,16 @@ TEST_CASE("Unit_hipStreamBeginCapture_StreamSync_OngoingCapture") {
* - HIP_VERSION >= 5.6
*/
// Local function executed as thread
static void strmSyncThread(int *Ah, int *Ad, int *Bh, int *Bd,
int BLOCKSIZE, hipError_t *error) {
static void strmSyncThread(int* Ah, int* Ad, int* Bh, int* Bd, int BLOCKSIZE, hipError_t* error) {
StreamsGuard stream(1);
HIP_CHECK(hipMemcpyAsync(Ad, Ah, BLOCKSIZE * sizeof(int),
hipMemcpyDefault, stream[0]));
HIP_CHECK(hipMemcpyAsync(Bd, Bh, BLOCKSIZE * sizeof(int),
hipMemcpyDefault, stream[0]));
HIP_CHECK(hipMemcpyAsync(Ad, Ah, BLOCKSIZE * sizeof(int), hipMemcpyDefault, stream[0]));
HIP_CHECK(hipMemcpyAsync(Bd, Bh, BLOCKSIZE * sizeof(int), hipMemcpyDefault, stream[0]));
*error = hipStreamSynchronize(stream[0]);
}
// Local function executed as thread
static void captureStrmThread(hipGraph_t *graph, int *Ah, int *Ad,
int *Bh, int *Bd, int BLOCKSIZE, int GRIDSIZE,
hipStreamCaptureMode flag, hipError_t *error) {
static void captureStrmThread(hipGraph_t* graph, int* Ah, int* Ad, int* Bh, int* Bd, int BLOCKSIZE,
int GRIDSIZE, hipStreamCaptureMode flag, hipError_t* error) {
StreamsGuard stream(1);
// Capture streams into graph
HIP_CHECK(hipStreamBeginCapture(stream[0], flag));
@@ -1466,14 +1410,12 @@ TEST_CASE("Unit_hipStreamBeginCapture_StreamSync_OngoingCapture_MThread") {
constexpr int VALUE1 = 7, VALUE2 = 11;
hipGraph_t graph{nullptr};
// Allocate device memory
LinearAllocGuard<int> Ah = LinearAllocGuard<int>(LinearAllocs::malloc,
BLOCKSIZE * sizeof(int));
LinearAllocGuard<int> Ad = LinearAllocGuard<int>(LinearAllocs::hipMalloc,
BLOCKSIZE * sizeof(int));
LinearAllocGuard<int> Bh = LinearAllocGuard<int>(LinearAllocs::malloc,
BLOCKSIZE * sizeof(int));
LinearAllocGuard<int> Bd = LinearAllocGuard<int>(LinearAllocs::hipMalloc,
BLOCKSIZE * sizeof(int));
LinearAllocGuard<int> Ah = LinearAllocGuard<int>(LinearAllocs::malloc, BLOCKSIZE * sizeof(int));
LinearAllocGuard<int> Ad =
LinearAllocGuard<int>(LinearAllocs::hipMalloc, BLOCKSIZE * sizeof(int));
LinearAllocGuard<int> Bh = LinearAllocGuard<int>(LinearAllocs::malloc, BLOCKSIZE * sizeof(int));
LinearAllocGuard<int> Bd =
LinearAllocGuard<int>(LinearAllocs::hipMalloc, BLOCKSIZE * sizeof(int));
// Fill input data
std::fill_n(Ah.host_ptr(), BLOCKSIZE, VALUE1);
std::fill_n(Bh.host_ptr(), BLOCKSIZE, VALUE2);
@@ -1483,10 +1425,10 @@ TEST_CASE("Unit_hipStreamBeginCapture_StreamSync_OngoingCapture_MThread") {
StreamsGuard stream(2);
// Capture streams into graph
HIP_CHECK(hipStreamBeginCapture(stream[0], hipStreamCaptureModeGlobal));
HIP_CHECK(hipMemcpyAsync(Ad.ptr(), Ah.host_ptr(),
BLOCKSIZE * sizeof(int), hipMemcpyDefault, stream[1]));
HIP_CHECK(hipMemcpyAsync(Bd.ptr(), Bh.host_ptr(),
BLOCKSIZE * sizeof(int), hipMemcpyDefault, stream[1]));
HIP_CHECK(hipMemcpyAsync(Ad.ptr(), Ah.host_ptr(), BLOCKSIZE * sizeof(int), hipMemcpyDefault,
stream[1]));
HIP_CHECK(hipMemcpyAsync(Bd.ptr(), Bh.host_ptr(), BLOCKSIZE * sizeof(int), hipMemcpyDefault,
stream[1]));
error = hipStreamSynchronize(stream[1]);
REQUIRE(error == hipErrorStreamCaptureUnsupported);
}
@@ -1494,34 +1436,30 @@ TEST_CASE("Unit_hipStreamBeginCapture_StreamSync_OngoingCapture_MThread") {
SECTION("Capture Flag = hipStreamCaptureModeThreadLocal Single Threaded") {
StreamsGuard stream(2);
// Capture streams into graph
HIP_CHECK(hipStreamBeginCapture(stream[0],
hipStreamCaptureModeThreadLocal));
HIP_CHECK(hipMemcpyAsync(Ad.ptr(), Ah.host_ptr(),
BLOCKSIZE * sizeof(int), hipMemcpyDefault, stream[1]));
HIP_CHECK(hipMemcpyAsync(Bd.ptr(), Bh.host_ptr(),
BLOCKSIZE * sizeof(int), hipMemcpyDefault, stream[1]));
HIP_CHECK(hipStreamBeginCapture(stream[0], hipStreamCaptureModeThreadLocal));
HIP_CHECK(hipMemcpyAsync(Ad.ptr(), Ah.host_ptr(), BLOCKSIZE * sizeof(int), hipMemcpyDefault,
stream[1]));
HIP_CHECK(hipMemcpyAsync(Bd.ptr(), Bh.host_ptr(), BLOCKSIZE * sizeof(int), hipMemcpyDefault,
stream[1]));
error = hipStreamSynchronize(stream[1]);
REQUIRE(error == hipErrorStreamCaptureUnsupported);
}
#endif
#if HT_AMD
SECTION("Capture Flag = hipStreamCaptureModeGlobal Multithreaded") {
captureStrmThread(&graph, Ah.host_ptr(), Ad.ptr(),
Bh.host_ptr(), Bd.ptr(), BLOCKSIZE, GRIDSIZE,
hipStreamCaptureModeGlobal, &error);
captureStrmThread(&graph, Ah.host_ptr(), Ad.ptr(), Bh.host_ptr(), Bd.ptr(), BLOCKSIZE, GRIDSIZE,
hipStreamCaptureModeGlobal, &error);
REQUIRE(error == hipErrorStreamCaptureUnsupported);
}
#endif
SECTION("Capture Flag = hipStreamCaptureModeThreadLocal Multithreaded") {
captureStrmThread(&graph, Ah.host_ptr(), Ad.ptr(),
Bh.host_ptr(), Bd.ptr(), BLOCKSIZE, GRIDSIZE,
hipStreamCaptureModeThreadLocal, &error);
captureStrmThread(&graph, Ah.host_ptr(), Ad.ptr(), Bh.host_ptr(), Bd.ptr(), BLOCKSIZE, GRIDSIZE,
hipStreamCaptureModeThreadLocal, &error);
REQUIRE(error == hipSuccess);
}
SECTION("Capture Flag = hipStreamCaptureModeRelaxed Multithreaded") {
captureStrmThread(&graph, Ah.host_ptr(), Ad.ptr(),
Bh.host_ptr(), Bd.ptr(), BLOCKSIZE, GRIDSIZE,
hipStreamCaptureModeRelaxed, &error);
captureStrmThread(&graph, Ah.host_ptr(), Ad.ptr(), Bh.host_ptr(), Bd.ptr(), BLOCKSIZE, GRIDSIZE,
hipStreamCaptureModeRelaxed, &error);
REQUIRE(error == hipSuccess);
}
if (graph != nullptr) {
@@ -1532,8 +1470,7 @@ TEST_CASE("Unit_hipStreamBeginCapture_StreamSync_OngoingCapture_MThread") {
HIP_CHECK(hipGraphLaunch(graphExec, stream[0]));
HIP_CHECK(hipStreamSynchronize(stream[0]));
// Check output
HIP_CHECK(hipMemcpy(Ah.host_ptr(), Ad.ptr(), BLOCKSIZE * sizeof(int),
hipMemcpyDeviceToHost));
HIP_CHECK(hipMemcpy(Ah.host_ptr(), Ad.ptr(), BLOCKSIZE * sizeof(int), hipMemcpyDeviceToHost));
for (int idx = 0; idx < BLOCKSIZE; idx++) {
REQUIRE(Ah.host_ptr()[idx] == (VALUE1 + VALUE2));
}
-1
View File
@@ -19,7 +19,6 @@ THE SOFTWARE.
#include <hip_test_common.hh>
#include <hip_test_kernels.hh>
#include <hip_test_defgroups.hh>
#include "stream_capture_common.hh"
@@ -18,7 +18,6 @@ THE SOFTWARE.
*/
#include <hip_test_checkers.hh>
#include <hip_test_defgroups.hh>
#include <hip_test_kernels.hh>
#include "stream_capture_common.hh"
@@ -19,7 +19,6 @@ THE SOFTWARE.
#include <hip_test_checkers.hh>
#include <hip_test_kernels.hh>
#include <hip_test_defgroups.hh>
#include "stream_capture_common.hh"
-1
View File
@@ -18,7 +18,6 @@ THE SOFTWARE.
*/
#include <hip_test_common.hh>
#include <hip_test_defgroups.hh>
#include <hip_test_kernels.hh>
#include "stream_capture_common.hh"
@@ -20,7 +20,6 @@ THE SOFTWARE.
#include <hip_test_checkers.hh>
#include <hip_test_common.hh>
#include <hip_test_kernels.hh>
#include <hip_test_defgroups.hh>
#include "stream_capture_common.hh"
@@ -367,7 +366,7 @@ TEST_CASE("Unit_hipStreamUpdateCaptureDependencies_Positive_Parameters") {
const hipStreamUpdateCaptureDependenciesFlags flag =
GENERATE(hipStreamAddCaptureDependencies, hipStreamSetCaptureDependencies);
HIP_CHECK(hipStreamBeginCapture(stream, captureMode)); //hipStreamCaptureModeGlobal));
HIP_CHECK(hipStreamBeginCapture(stream, captureMode)); // hipStreamCaptureModeGlobal));
HIP_CHECK(hipStreamUpdateCaptureDependencies(stream, nullptr, 0, flag));
@@ -20,7 +20,6 @@ THE SOFTWARE.
#include <hip_test_checkers.hh>
#include <hip_test_common.hh>
#include <hip_test_kernels.hh>
#include <hip_test_defgroups.hh>
#include "stream_capture_common.hh"