/* * Copyright (c) Advanced Micro Devices, Inc., or its affiliates. * * SPDX-License-Identifier: MIT */ /* Testcase Scenarios : Unit_hipMemcpy2DFromArray_Positive_Default - Test basic memcpy between 2D array and host/device with hipMemcpy2DFromArray api Unit_hipMemcpy2DFromArray_Positive_Synchronization_Behavior - Test synchronization behavior for hipMemcpy2DFromArray api Unit_hipMemcpy2DFromArray_Positive_ZeroWidthHeight - Test that no data is copied when width/height is set to 0 Unit_hipMemcpy2DFromArray_Negative_Parameters - Test unsuccessful execution of hipMemcpy2DFromArray api when parameters are invalid */ #include "array_memcpy_tests_common.hh" #include #include #include #include HIP_TEST_CASE(Unit_hipMemcpy2DFromArray_Positive_Default) { CHECK_IMAGE_SUPPORT using namespace std::placeholders; const auto width = GENERATE(16, 32, 48); const auto height = GENERATE(1, 16, 32, 48); SECTION("Array to host") { Memcpy2DHostFromAShell( std::bind(hipMemcpy2DFromArray, _1, _2, _3, 0, 0, width * sizeof(int), height, hipMemcpyDeviceToHost), width, height); } SECTION("Array to host with default kind") { Memcpy2DHostFromAShell(std::bind(hipMemcpy2DFromArray, _1, _2, _3, 0, 0, width * sizeof(int), height, hipMemcpyDefault), width, height); } #if HT_NVIDIA // EXSWHTEC-120 SECTION("Array to device") { SECTION("Peer access disabled") { Memcpy2DDeviceFromAShell( std::bind(hipMemcpy2DFromArray, _1, _2, _3, 0, 0, width * sizeof(int), height, hipMemcpyDeviceToDevice), width, height); } SECTION("Peer access enabled") { Memcpy2DDeviceFromAShell( std::bind(hipMemcpy2DFromArray, _1, _2, _3, 0, 0, width * sizeof(int), height, hipMemcpyDeviceToDevice), width, height); } } SECTION("Array to device with default kind") { SECTION("Peer access disabled") { Memcpy2DDeviceFromAShell( std::bind(hipMemcpy2DFromArray, _1, _2, _3, 0, 0, width * sizeof(int), height, hipMemcpyDefault), width, height); } SECTION("Peer access enabled") { Memcpy2DDeviceFromAShell( std::bind(hipMemcpy2DFromArray, _1, _2, _3, 0, 0, width * sizeof(int), height, hipMemcpyDefault), width, height); } } #endif } HIP_TEST_CASE(Unit_hipMemcpy2DFromArray_Positive_Synchronization_Behavior) { CHECK_IMAGE_SUPPORT using namespace std::placeholders; HIP_CHECK(hipDeviceSynchronize()); SECTION("Array to host") { const auto width = GENERATE(16, 32, 48); const auto height = GENERATE(16, 32, 48); MemcpyAtoHPageableSyncBehavior(std::bind(hipMemcpy2DFromArray, _1, width * sizeof(int), _2, 0, 0, width * sizeof(int), height, hipMemcpyDeviceToHost), width, height, true); MemcpyAtoHPinnedSyncBehavior(std::bind(hipMemcpy2DFromArray, _1, width * sizeof(int), _2, 0, 0, width * sizeof(int), height, hipMemcpyDeviceToHost), width, height, true); } #if HT_NVIDIA // EXSWHTEC-214 SECTION("Array to device") { const auto width = GENERATE(16, 32, 48); const auto height = GENERATE(16, 32, 48); MemcpyAtoDSyncBehavior(std::bind(hipMemcpy2DFromArray, _1, _2, _3, 0, 0, width * sizeof(int), height, hipMemcpyDeviceToDevice), width, height, false); } #endif } HIP_TEST_CASE(Unit_hipMemcpy2DFromArray_Positive_ZeroWidthHeight) { CHECK_IMAGE_SUPPORT using namespace std::placeholders; const auto width = 16; const auto height = 16; SECTION("Array to host") { SECTION("Height is 0") { Memcpy2DFromArrayZeroWidthHeight( std::bind(hipMemcpy2DFromArray, _1, _2, _3, 0, 0, width * sizeof(int), 0, hipMemcpyDeviceToHost), width, height); } SECTION("Width is 0") { Memcpy2DFromArrayZeroWidthHeight( std::bind(hipMemcpy2DFromArray, _1, _2, _3, 0, 0, 0, height, hipMemcpyDeviceToHost), width, height); } } SECTION("Array to device") { SECTION("Height is 0") { Memcpy2DFromArrayZeroWidthHeight( std::bind(hipMemcpy2DFromArray, _1, _2, _3, 0, 0, width * sizeof(int), 0, hipMemcpyDeviceToDevice), width, height); } SECTION("Width is 0") { Memcpy2DFromArrayZeroWidthHeight( std::bind(hipMemcpy2DFromArray, _1, _2, _3, 0, 0, 0, height, hipMemcpyDeviceToDevice), width, height); } } } HIP_TEST_CASE(Unit_hipMemcpy2DFromArray_Negative_Parameters) { CHECK_IMAGE_SUPPORT using namespace std::placeholders; const auto width = 32; const auto height = 32; const auto allocation_size = 2 * width * height * sizeof(int); const unsigned int flag = hipArrayDefault; ArrayAllocGuard array_alloc(make_hipExtent(width, height, 0), flag); LinearAllocGuard2D device_alloc(width, height); LinearAllocGuard host_alloc(LinearAllocs::hipHostMalloc, allocation_size); SECTION("Array to host") { SECTION("dst == nullptr") { HIP_CHECK_ERROR(hipMemcpy2DFromArray(nullptr, 2 * width * sizeof(int), array_alloc.ptr(), 0, 0, width * sizeof(int), height, hipMemcpyDeviceToHost), hipErrorInvalidValue); } SECTION("src == nullptr") { HIP_CHECK_ERROR(hipMemcpy2DFromArray(host_alloc.ptr(), 2 * width * sizeof(int), nullptr, 0, 0, width * sizeof(int), height, hipMemcpyDeviceToHost), hipErrorInvalidHandle); } #if HT_NVIDIA // EXSWHTEC-119 SECTION("dpitch < width") { HIP_CHECK_ERROR( hipMemcpy2DFromArray(host_alloc.ptr(), width * sizeof(int) - 10, array_alloc.ptr(), 0, 0, width * sizeof(int), height, hipMemcpyDeviceToHost), hipErrorInvalidPitchValue); } SECTION("Offset + width/height overflows") { HIP_CHECK_ERROR( hipMemcpy2DFromArray(host_alloc.ptr(), 2 * width * sizeof(int), array_alloc.ptr(), 1, 0, width * sizeof(int), height, hipMemcpyDeviceToHost), hipErrorInvalidValue); HIP_CHECK_ERROR( hipMemcpy2DFromArray(host_alloc.ptr(), 2 * width * sizeof(int), array_alloc.ptr(), 0, 1, width * sizeof(int), height, hipMemcpyDeviceToHost), hipErrorInvalidValue); } SECTION("Width/height overflows") { HIP_CHECK_ERROR( hipMemcpy2DFromArray(host_alloc.ptr(), 2 * width * sizeof(int), array_alloc.ptr(), 0, 0, width * sizeof(int) + 1, height, hipMemcpyDeviceToHost), hipErrorInvalidValue); HIP_CHECK_ERROR( hipMemcpy2DFromArray(host_alloc.ptr(), 2 * width * sizeof(int), array_alloc.ptr(), 0, 0, width * sizeof(int), height + 1, hipMemcpyDeviceToHost), hipErrorInvalidValue); } SECTION("Memcpy kind is invalid") { HIP_CHECK_ERROR( hipMemcpy2DFromArray(host_alloc.ptr(), 2 * width * sizeof(int), array_alloc.ptr(), 0, 0, width * sizeof(int), height, static_cast(-1)), hipErrorInvalidMemcpyDirection); } #endif } SECTION("Array to device") { SECTION("dst == nullptr") { HIP_CHECK_ERROR(hipMemcpy2DFromArray(nullptr, device_alloc.pitch(), array_alloc.ptr(), 0, 0, width * sizeof(int), height, hipMemcpyDeviceToDevice), hipErrorInvalidValue); } SECTION("src == nullptr") { HIP_CHECK_ERROR(hipMemcpy2DFromArray(device_alloc.ptr(), device_alloc.pitch(), nullptr, 0, 0, width * sizeof(int), height, hipMemcpyDeviceToDevice), hipErrorInvalidHandle); } #if HT_NVIDIA // EXSWHTEC-119 SECTION("dpitch < width") { HIP_CHECK_ERROR( hipMemcpy2DFromArray(device_alloc.ptr(), width * sizeof(int) - 10, array_alloc.ptr(), 0, 0, width * sizeof(int), height, hipMemcpyDeviceToDevice), hipErrorInvalidPitchValue); } SECTION("Offset + width/height overflows") { HIP_CHECK_ERROR( hipMemcpy2DFromArray(device_alloc.ptr(), device_alloc.pitch(), array_alloc.ptr(), 1, 0, width * sizeof(int), height, hipMemcpyDeviceToDevice), hipErrorInvalidValue); HIP_CHECK_ERROR( hipMemcpy2DFromArray(device_alloc.ptr(), device_alloc.pitch(), array_alloc.ptr(), 0, 1, width * sizeof(int), height, hipMemcpyDeviceToDevice), hipErrorInvalidValue); } SECTION("Width/height overflows") { HIP_CHECK_ERROR( hipMemcpy2DFromArray(device_alloc.ptr(), device_alloc.pitch(), array_alloc.ptr(), 0, 0, width * sizeof(int) + 1, height, hipMemcpyDeviceToDevice), hipErrorInvalidValue); HIP_CHECK_ERROR( hipMemcpy2DFromArray(device_alloc.ptr(), device_alloc.pitch(), array_alloc.ptr(), 0, 0, width * sizeof(int), height + 1, hipMemcpyDeviceToDevice), hipErrorInvalidValue); } SECTION("Memcpy kind is invalid") { HIP_CHECK_ERROR( hipMemcpy2DFromArray(device_alloc.ptr(), device_alloc.pitch(), array_alloc.ptr(), 0, 0, width * sizeof(int), height, static_cast(-1)), hipErrorInvalidMemcpyDirection); } #endif } } HIP_TEST_CASE(Unit_hipMemcpy2DFromArray_Capture) { CHECK_IMAGE_SUPPORT const auto width = 16; const auto height = 16; const auto size = width * height * sizeof(int); ArrayAllocGuard A_d(make_hipExtent(width, height, 0), hipArrayDefault); LinearAllocGuard A_h(LinearAllocs::hipHostMalloc, size); LinearAllocGuard B_h(LinearAllocs::hipHostMalloc, size); HIP_CHECK(hipMemcpy2DToArray(A_d.ptr(), 0, 0, A_h.ptr(), width * sizeof(int), width * sizeof(int), height, hipMemcpyHostToDevice)); hipError_t memcpy_err = hipSuccess; BEGIN_CAPTURE_SYNC(memcpy_err, false); HIP_CHECK_ERROR(hipMemcpy2DFromArray(B_h.host_ptr(), width * sizeof(int), A_d.ptr(), 0, 0, width * sizeof(int), height, hipMemcpyDeviceToHost), memcpy_err); END_CAPTURE_SYNC(memcpy_err); }