/* * Copyright (c) Advanced Micro Devices, Inc., or its affiliates. * * SPDX-License-Identifier: MIT */ #include #include #include #include #include "graph_tests_common.hh" /** * @addtogroup hipGraphMemcpyNodeSetParams hipGraphMemcpyNodeSetParams * @{ * @ingroup GraphTest * `hipGraphMemcpyNodeSetParams (hipGraphNode_t node, const hipMemcpy3DParms *pNodeParams)` - 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 the 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/hipGraphMemcpyNodeSetParams.cc * Test requirements * ------------------------ * - HIP_VERSION >= 5.2 */ HIP_TEST_CASE(Unit_hipGraphMemcpyNodeSetParams_Positive_Basic) { CHECK_IMAGE_SUPPORT constexpr bool async = false; SECTION("Device to host") { Memcpy3DDeviceToHostShell(Memcpy3DWrapper); } SECTION("Device to host with default kind") { Memcpy3DDeviceToHostShell(Memcpy3DWrapper); } SECTION("Host to device") { Memcpy3DHostToDeviceShell(Memcpy3DWrapper); } SECTION("Host to device with default kind") { Memcpy3DHostToDeviceShell(Memcpy3DWrapper); } SECTION("Host to host") { Memcpy3DHostToHostShell(Memcpy3DWrapper); } SECTION("Host to host with default kind") { Memcpy3DHostToHostShell(Memcpy3DWrapper); } SECTION("Device to device") { SECTION("Peer access enabled") { Memcpy3DDeviceToDeviceShell(Memcpy3DWrapper); } SECTION("Peer access disabled") { Memcpy3DDeviceToDeviceShell(Memcpy3DWrapper); } } SECTION("Device to device with default kind") { SECTION("Peer access enabled") { Memcpy3DDeviceToDeviceShell(Memcpy3DWrapper); } SECTION("Peer access disabled") { Memcpy3DDeviceToDeviceShell(Memcpy3DWrapper); } } SECTION("Array from/to Host") { Memcpy3DArrayHostShell(Memcpy3DWrapper); } #if HT_NVIDIA // Disabled on AMD due to defect - EXSWHTEC-220 SECTION("Array from/to Device") { Memcpy3DArrayDeviceShell(Memcpy3DWrapper); } #endif } /** * Test Description * ------------------------ * - Verify API behaviour with invalid arguments: * -# node is nullptr * -# pNodeParams is nullptr * -# node is uninitialized * -# dst is nullptr * -# src is nullptr * -# dst pitch is less than width * -# src pitch is less than width * -# dst pitch exceeds max pitch * -# src pitch exceeds max pitch * -# extent width + dst position exceeds dst pitch * -# extent width + src position exceeds src pitch * -# dst position y is out of bounds * -# src position y is out of bounds * -# dst position z is out of bounds * -# src position z is out of bounds * -# kind is an invalid enum value * Test source * ------------------------ * - unit/graph/hipGraphAddMemcpyNode.cc * Test requirements * ------------------------ * - HIP_VERSION >= 5.2 */ HIP_TEST_CASE(Unit_hipGraphMemcpyNodeSetParams_Negative_Parameters) { using namespace std::placeholders; 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) { hipGraph_t graph = nullptr; HIP_CHECK(hipGraphCreate(&graph, 0)); hipGraphNode_t node = nullptr; auto params = GetMemcpy3DParms(dst_ptr, dst_pos, src_ptr, src_pos, extent, kind); HIP_CHECK(hipGraphAddMemcpyNode(&node, graph, nullptr, 0, ¶ms)); SECTION("node == nullptr") { params = GetMemcpy3DParms(dst_ptr, dst_pos, src_ptr, src_pos, extent, kind); HIP_CHECK_ERROR(hipGraphMemcpyNodeSetParams(nullptr, ¶ms), hipErrorInvalidValue); } SECTION("pNodeParams == nullptr") { HIP_CHECK_ERROR(hipGraphMemcpyNodeSetParams(node, nullptr), hipErrorInvalidValue); } SECTION("Uninitialized node") { hipGraphNode_t node_uninit{}; params = GetMemcpy3DParms(dst_ptr, dst_pos, src_ptr, src_pos, extent, kind); HIP_CHECK_ERROR(hipGraphMemcpyNodeSetParams(node_uninit, ¶ms), hipErrorInvalidValue); } SECTION("dst_ptr.ptr == nullptr") { hipPitchedPtr invalid_ptr = dst_ptr; invalid_ptr.ptr = nullptr; params = GetMemcpy3DParms(invalid_ptr, dst_pos, src_ptr, src_pos, extent, kind); HIP_CHECK_ERROR(hipGraphMemcpyNodeSetParams(node, ¶ms), hipErrorInvalidValue); } SECTION("src_ptr.ptr == nullptr") { hipPitchedPtr invalid_ptr = src_ptr; invalid_ptr.ptr = nullptr; params = GetMemcpy3DParms(dst_ptr, dst_pos, invalid_ptr, src_pos, extent, kind); HIP_CHECK_ERROR(hipGraphMemcpyNodeSetParams(node, ¶ms), hipErrorInvalidValue); } SECTION("dst_ptr.pitch < width") { hipPitchedPtr invalid_ptr = dst_ptr; invalid_ptr.pitch = extent.width - 1; params = GetMemcpy3DParms(invalid_ptr, dst_pos, src_ptr, src_pos, extent, kind); HIP_CHECK_ERROR(hipGraphMemcpyNodeSetParams(node, ¶ms), hipErrorInvalidPitchValue); } SECTION("src_ptr.pitch < width") { hipPitchedPtr invalid_ptr = src_ptr; invalid_ptr.pitch = extent.width - 1; params = GetMemcpy3DParms(dst_ptr, dst_pos, invalid_ptr, src_pos, extent, kind); HIP_CHECK_ERROR(hipGraphMemcpyNodeSetParams(node, ¶ms), hipErrorInvalidPitchValue); } SECTION("dst_ptr.pitch > max pitch") { int attr = 0; HIP_CHECK(hipDeviceGetAttribute(&attr, hipDeviceAttributeMaxPitch, 0)); hipPitchedPtr invalid_ptr = dst_ptr; invalid_ptr.pitch = attr; params = GetMemcpy3DParms(invalid_ptr, dst_pos, src_ptr, src_pos, extent, kind); HIP_CHECK_ERROR(hipGraphMemcpyNodeSetParams(node, ¶ms), hipErrorInvalidValue); } SECTION("src_ptr.pitch > max pitch") { int attr = 0; HIP_CHECK(hipDeviceGetAttribute(&attr, hipDeviceAttributeMaxPitch, 0)); hipPitchedPtr invalid_ptr = src_ptr; invalid_ptr.pitch = attr; params = GetMemcpy3DParms(dst_ptr, dst_pos, invalid_ptr, src_pos, extent, kind); HIP_CHECK_ERROR(hipGraphMemcpyNodeSetParams(node, ¶ms), hipErrorInvalidValue); } SECTION("extent.width + dst_pos.x > dst_ptr.pitch") { hipPos invalid_pos = dst_pos; invalid_pos.x = dst_ptr.pitch - extent.width + 1; params = GetMemcpy3DParms(dst_ptr, invalid_pos, src_ptr, src_pos, extent, kind); HIP_CHECK_ERROR(hipGraphMemcpyNodeSetParams(node, ¶ms), hipErrorInvalidValue); } SECTION("extent.width + src_pos.x > src_ptr.pitch") { hipPos invalid_pos = src_pos; invalid_pos.x = src_ptr.pitch - extent.width + 1; params = GetMemcpy3DParms(dst_ptr, dst_pos, src_ptr, invalid_pos, extent, kind); HIP_CHECK_ERROR(hipGraphMemcpyNodeSetParams(node, ¶ms), hipErrorInvalidValue); } SECTION("dst_pos.y out of bounds") { hipPos invalid_pos = dst_pos; invalid_pos.y = 1; params = GetMemcpy3DParms(dst_ptr, invalid_pos, src_ptr, src_pos, extent, kind); HIP_CHECK_ERROR(hipGraphMemcpyNodeSetParams(node, ¶ms), hipErrorInvalidValue); } SECTION("src_pos.y out of bounds") { hipPos invalid_pos = src_pos; invalid_pos.y = 1; params = GetMemcpy3DParms(dst_ptr, dst_pos, src_ptr, invalid_pos, extent, kind); HIP_CHECK_ERROR(hipGraphMemcpyNodeSetParams(node, ¶ms), hipErrorInvalidValue); } SECTION("dst_pos.z out of bounds") { hipPos invalid_pos = dst_pos; invalid_pos.z = 1; params = GetMemcpy3DParms(dst_ptr, invalid_pos, src_ptr, src_pos, extent, kind); HIP_CHECK_ERROR(hipGraphMemcpyNodeSetParams(node, ¶ms), hipErrorInvalidValue); } SECTION("src_pos.z out of bounds") { hipPos invalid_pos = src_pos; invalid_pos.z = 1; params = GetMemcpy3DParms(dst_ptr, dst_pos, src_ptr, invalid_pos, extent, kind); HIP_CHECK_ERROR(hipGraphMemcpyNodeSetParams(node, ¶ms), hipErrorInvalidValue); } SECTION("Invalid MemcpyKind") { params = GetMemcpy3DParms(dst_ptr, dst_pos, src_ptr, src_pos, extent, static_cast(-1)); HIP_CHECK_ERROR(hipGraphMemcpyNodeSetParams(node, ¶ms), hipErrorInvalidMemcpyDirection); } HIP_CHECK(hipGraphDestroy(graph)); }; SECTION("Host to Device") { LinearAllocGuard3D device_alloc(extent); LinearAllocGuard host_alloc( LinearAllocs::hipHostMalloc, device_alloc.pitch() * device_alloc.height() * device_alloc.depth()); NegativeTests(device_alloc.pitched_ptr(), make_hipPos(0, 0, 0), make_hipPitchedPtr(host_alloc.ptr(), device_alloc.pitch(), device_alloc.width(), device_alloc.height()), make_hipPos(0, 0, 0), extent, hipMemcpyHostToDevice); } SECTION("Device to Host") { LinearAllocGuard3D device_alloc(extent); LinearAllocGuard host_alloc( LinearAllocs::hipHostMalloc, device_alloc.pitch() * device_alloc.height() * device_alloc.depth()); NegativeTests(make_hipPitchedPtr(host_alloc.ptr(), device_alloc.pitch(), device_alloc.width(), device_alloc.height()), make_hipPos(0, 0, 0), device_alloc.pitched_ptr(), make_hipPos(0, 0, 0), extent, hipMemcpyDeviceToHost); } SECTION("Host to Host") { LinearAllocGuard src_alloc(LinearAllocs::hipHostMalloc, extent.width * extent.height * extent.depth); LinearAllocGuard dst_alloc(LinearAllocs::hipHostMalloc, extent.width * extent.height * extent.depth); NegativeTests(make_hipPitchedPtr(dst_alloc.ptr(), extent.width, extent.width, extent.height), make_hipPos(0, 0, 0), make_hipPitchedPtr(src_alloc.ptr(), extent.width, extent.width, extent.height), make_hipPos(0, 0, 0), extent, hipMemcpyHostToHost); } SECTION("Device to Device") { LinearAllocGuard3D src_alloc(extent); LinearAllocGuard3D dst_alloc(extent); NegativeTests(dst_alloc.pitched_ptr(), make_hipPos(0, 0, 0), src_alloc.pitched_ptr(), make_hipPos(0, 0, 0), extent, hipMemcpyDeviceToDevice); } } /** * End doxygen group GraphTest. * @} */