diff --git a/catch/DoxyfileTests b/catch/DoxyfileTests index 6fe1167e4..28dbc095c 100644 --- a/catch/DoxyfileTests +++ b/catch/DoxyfileTests @@ -616,7 +616,7 @@ SORT_MEMBER_DOCS = YES # this will also influence the order of the classes in the class list. # The default value is: NO. -SORT_BRIEF_DOCS = NO +SORT_BRIEF_DOCS = YES # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the # (brief and detailed) documentation of class members so that constructors and @@ -635,7 +635,7 @@ SORT_MEMBERS_CTORS_1ST = NO # appear in their defined order. # The default value is: NO. -SORT_GROUP_NAMES = NO +SORT_GROUP_NAMES = YES # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by # fully-qualified names, including namespaces. If set to NO, the class list will diff --git a/catch/include/hip_test_defgroups.hh b/catch/include/hip_test_defgroups.hh index 680dfa8a0..484763bfb 100644 --- a/catch/include/hip_test_defgroups.hh +++ b/catch/include/hip_test_defgroups.hh @@ -131,6 +131,214 @@ THE SOFTWARE. * @} */ +/** + * @defgroup MemoryTest Memory Management + * @{ + * This section describes tests for the memory management functions of HIP runtime API. + */ + +/** + * @addtogroup hipMemset hipMemset + * @{ + * @ingroup MemoryTest + */ +/** + * Test Description + * ------------------------ + * - Validates the case when zero value is set. + * Test source + * ------------------------ + * - unit/memory/hipMemsetFunctional.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipMemsetFunctional_ZeroValue_hipMemset") {} + +/** + * Test Description + * ------------------------ + * - Validates the case when small size is set. + * Test source + * ------------------------ + * - unit/memory/hipMemsetFunctional.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipMemsetFunctional_SmallSize_hipMemset") {} + +/** + * Test Description + * ------------------------ + * - Validates the case when zero size is set. + * Test source + * ------------------------ + * - unit/memory/hipMemsetFunctional.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipMemsetFunctional_ZeroSize_hipMemset") {} +/** + * End doxygen group hipMemset. + * @} + */ + +/** + * @addtogroup hipMemsetD32 hipMemsetD32 + * @{ + * @ingroup MemoryTest + */ +/** + * Test Description + * ------------------------ + * - Validates the case when zero value is set. + * Test source + * ------------------------ + * - unit/memory/hipMemsetFunctional.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipMemsetFunctional_ZeroValue_hipMemsetD32") {} + +/** + * Test Description + * ------------------------ + * - Validates the case when small size is set. + * Test source + * ------------------------ + * - unit/memory/hipMemsetFunctional.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipMemsetFunctional_SmallSize_hipMemsetD32") {} + +/** + * Test Description + * ------------------------ + * - Validates the case when zero size is set. + * Test source + * ------------------------ + * - unit/memory/hipMemsetFunctional.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipMemsetFunctional_ZeroSize_hipMemsetD32") {} +/** + * End doxygen group hipMemsetD32. + * @} + */ + +/** + * @addtogroup hipMemsetD16 hipMemsetD16 + * @{ + * @ingroup MemoryTest + */ +/** + * Test Description + * ------------------------ + * - Validates the case when zero value is set. + * Test source + * ------------------------ + * - unit/memory/hipMemsetFunctional.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipMemsetFunctional_ZeroValue_hipMemsetD16") {} + +/** + * Test Description + * ------------------------ + * - Validates the case when small size is set. + * Test source + * ------------------------ + * - unit/memory/hipMemsetFunctional.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipMemsetFunctional_SmallSize_hipMemsetD16") {} + +/** + * Test Description + * ------------------------ + * - Validates the case when zero size is set. + * Test source + * ------------------------ + * - unit/memory/hipMemsetFunctional.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipMemsetFunctional_ZeroSize_hipMemsetD16") {} +/** + * End doxygen group hipMemsetD16. + * @} + */ + +/** + * @addtogroup hipMemsetD8 hipMemsetD8 + * @{ + * @ingroup MemoryTest + */ +/** + * Test Description + * ------------------------ + * - Validates the case when zero value is set. + * Test source + * ------------------------ + * - unit/memory/hipMemsetFunctional.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipMemsetFunctional_ZeroValue_hipMemsetD8") {} + +/** + * Test Description + * ------------------------ + * - Validates the case when small size is set. + * Test source + * ------------------------ + * - unit/memory/hipMemsetFunctional.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipMemsetFunctional_SmallSize_hipMemsetD8") {} + +/** + * Test Description + * ------------------------ + * - Validates the case when zero size is set. + * Test source + * ------------------------ + * - unit/memory/hipMemsetFunctional.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipMemsetFunctional_ZeroSize_hipMemsetD8") {} /** + * End doxygen group hipMemsetD8. + * @} + */ + +/** + * End doxygen group MemoryTest. + * @} + */ + +/** + * @defgroup MemoryMTest Managed Memory + * @{ + * This section describes tests for the managed memory management functions of HIP runtime API. + */ + /** * @defgroup ShflTest warp shuffle function Management * @{ @@ -154,7 +362,7 @@ THE SOFTWARE. /** * @defgroup StreamTest Stream Management * @{ - * This section describes the stream management types & functions of HIP runtime API. + *This section describes the stream management types& functions of HIP runtime API. * @} */ diff --git a/catch/include/memcpy1d_tests_common.hh b/catch/include/memcpy1d_tests_common.hh index ec8f991fa..a9e5c3640 100644 --- a/catch/include/memcpy1d_tests_common.hh +++ b/catch/include/memcpy1d_tests_common.hh @@ -142,7 +142,7 @@ void MemcpyDeviceToDeviceShell(F memcpy_func, const hipStream_t kernel_stream = HIP_CHECK(hipDeviceCanAccessPeer(&can_access_peer, src_device, dst_device)); if (!can_access_peer) { INFO("Peer access cannot be enabled between devices " << src_device << " " << dst_device); - return; + REQUIRE(can_access_peer); } HIP_CHECK(hipDeviceEnablePeerAccess(dst_device, 0)); } diff --git a/catch/unit/device/hipDeviceEnableDisablePeerAccess.cc b/catch/unit/device/hipDeviceEnableDisablePeerAccess.cc index bf85cbe0e..5cacfbd07 100644 --- a/catch/unit/device/hipDeviceEnableDisablePeerAccess.cc +++ b/catch/unit/device/hipDeviceEnableDisablePeerAccess.cc @@ -125,9 +125,9 @@ TEST_CASE("Unit_hipDeviceEnablePeerAccess_negative") { * @addtogroup hipDeviceDisablePeerAccess hipDeviceDisablePeerAccess * @{ * @ingroup PeerToPeerTest - * hipDeviceDisablePeerAccess(int peerDeviceId)` - - * Disable direct access from current device's virtual address space - * to memory allocations physically located on a peer device. + * `hipDeviceDisablePeerAccess(int peerDeviceId)` - + * Disable direct access from current device's virtual address space to memory allocations + * physically located on a peer device. * ________________________ * Test cases from other modules: * - @ref Unit_hipDeviceEnableDisablePeerAccess_positive diff --git a/catch/unit/memory/CMakeLists.txt b/catch/unit/memory/CMakeLists.txt index fda74f5b2..0a596b525 100644 --- a/catch/unit/memory/CMakeLists.txt +++ b/catch/unit/memory/CMakeLists.txt @@ -120,8 +120,8 @@ set(TEST_SRC hipMemcpyPeer.cc hipMemcpyPeer_old.cc hipMemcpyPeerAsync.cc - hipMemcpyPeerAsync_old.cc hipMemcpyWithStream_old.cc + hipMemcpyPeerAsync_old.cc hipMemcpyWithStream.cc hipMemcpyWithStreamMultiThread.cc hipMemsetAsyncAndKernel.cc @@ -132,11 +132,12 @@ set(TEST_SRC hipHostMalloc.cc hipMemcpy_old.cc hipMemcpy_derivatives.cc - hipMemcpyAsync.cc hipMemcpyAsync_old.cc + hipMemcpyAsync.cc hipMemcpyAsync_derivatives.cc hipMemsetFunctional.cc hipMalloc.cc + hipExtMallocWithFlags.cc hipMallocPitch.cc hipMalloc3D.cc hipMalloc3DArray.cc diff --git a/catch/unit/memory/hipArray.cc b/catch/unit/memory/hipArray.cc index 2f9ce4056..555760557 100644 --- a/catch/unit/memory/hipArray.cc +++ b/catch/unit/memory/hipArray.cc @@ -16,7 +16,15 @@ 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 + +/** + * @addtogroup hipArrayDestroy hipArrayDestroy + * @{ + * @ingroup MemoryTest + */ + TEST_CASE("Unit_hipArray_Valid") { CHECK_IMAGE_SUPPORT @@ -38,12 +46,14 @@ TEST_CASE("Unit_hipArray_Invalid") { REQUIRE(hipFreeArray(arrayPtr) == hipErrorContextIsDestroyed); free(data); } + TEST_CASE("Unit_hipArray_Nullptr") { CHECK_IMAGE_SUPPORT hipArray_t array = nullptr; REQUIRE(hipFreeArray(array) == hipErrorInvalidValue); } + TEST_CASE("Unit_hipArray_DoubleFree") { CHECK_IMAGE_SUPPORT @@ -57,6 +67,19 @@ TEST_CASE("Unit_hipArray_DoubleFree") { HIP_CHECK(hipFreeArray(array)); REQUIRE(hipFreeArray(array) == hipErrorContextIsDestroyed); } + +/** + * Test Description + * ------------------------ + * - Validates handling when array destroy is called three times: + * - Expected output: return `hipErrorContextIsDestroyed` + * Test source + * ------------------------ + * - unit/memory/hipArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipArray_TrippleDestroy") { CHECK_IMAGE_SUPPORT @@ -71,6 +94,120 @@ TEST_CASE("Unit_hipArray_TrippleDestroy") { REQUIRE(hipArrayDestroy(array) == hipErrorContextIsDestroyed); REQUIRE(hipArrayDestroy(array) == hipErrorContextIsDestroyed); } + +/** + * End doxygen group hipArrayDestroy. + * @} + */ + +/** + * @addtogroup hipFreeArray hipFreeArray + * @{ + * @ingroup MemoryTest + * `hipFreeArray(hipArray* array)` - + * Frees an array on the device. + * ________________________ + * Test cases from other modules: + * - @ref Unit_hipFreeImplicitSyncArray + * - @ref Unit_hipFreeMultiTArray + * - @ref Unit_hipFreeNegativeArray + * - @ref Unit_hipFreeDoubleArray + */ + +/** + * Test Description + * ------------------------ + * - Successfully frees a created array. + * Test source + * ------------------------ + * - unit/memory/hipArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipArray_Valid") { + hipArray* array = nullptr; + HIP_ARRAY_DESCRIPTOR desc; + desc.Format = HIP_AD_FORMAT_FLOAT; + desc.NumChannels = 1; + desc.Width = 1024; + desc.Height = 1024; + HIP_CHECK(hipArrayCreate(&array, &desc)); + HIP_CHECK(hipFreeArray(array)); +} + +/** + * Test Description + * ------------------------ + * - Validates handling when array is not initialized + * - Expected output: return `hipErrorContextIsDestroyed` + * Test source + * ------------------------ + * - unit/memory/hipArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipArray_Invalid") { + void* data = malloc(sizeof(char)); + hipArray_t arrayPtr = static_cast(data); + REQUIRE(hipFreeArray(arrayPtr) == hipErrorContextIsDestroyed); + free(data); +} + +/** + * Test Description + * ------------------------ + * - Validates handling when array is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipArray_Nullptr") { + hipArray* array = nullptr; + REQUIRE(hipFreeArray(array) == hipErrorInvalidValue); +} + +/** + * Test Description + * ------------------------ + * - Validates handling when the array is freed twice: + * - Expected output: return `hipErrorContextIsDestroyed` + * Test source + * ------------------------ + * - unit/memory/hipArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipArray_DoubleFree") { + hipArray* array = nullptr; + HIP_ARRAY_DESCRIPTOR desc; + desc.Format = HIP_AD_FORMAT_FLOAT; + desc.NumChannels = 1; + desc.Width = 1024; + desc.Height = 1024; + HIP_CHECK(hipArrayCreate(&array, &desc)); + HIP_CHECK(hipFreeArray(array)); + REQUIRE(hipFreeArray(array) == hipErrorContextIsDestroyed); +} + +/** + * Test Description + * ------------------------ + * - Validates handling when `nullptr` array is freed twice: + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipArray_DoubleNullptr") { CHECK_IMAGE_SUPPORT @@ -78,6 +215,19 @@ TEST_CASE("Unit_hipArray_DoubleNullptr") { REQUIRE(hipFreeArray(array) == hipErrorInvalidValue); REQUIRE(hipFreeArray(array) == hipErrorInvalidValue); } + +/** + * Test Description + * ------------------------ + * - Validates handling when the uninitialized array is freed twice: + * - Expected output: return `hipErrorContextIsDestroyed` + * Test source + * ------------------------ + * - unit/memory/hipArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipArray_DoubleInvalid") { CHECK_IMAGE_SUPPORT diff --git a/catch/unit/memory/hipArray3DCreate.cc b/catch/unit/memory/hipArray3DCreate.cc index a5d3a4bca..034649290 100644 --- a/catch/unit/memory/hipArray3DCreate.cc +++ b/catch/unit/memory/hipArray3DCreate.cc @@ -23,6 +23,14 @@ THE SOFTWARE. #include "hip_array_common.hh" #include "hip_test_common.hh" +/** + * @addtogroup hipArray3DCreate hipArray3DCreate + * @{ + * @ingroup MemoryTest + * `hipArray3DCreate(hipArray** array, const HIP_ARRAY3D_DESCRIPTOR* pAllocateArray)` - + * Create a 3D array. + */ + namespace { void checkArrayIsExpected(const hipArray_t array, const HIP_ARRAY3D_DESCRIPTOR& expected_desc) { // hipArray3DGetDescriptor doesn't currently exist (EXSWCPHIPT-87) @@ -48,6 +56,18 @@ void testInvalidDescription(HIP_ARRAY3D_DESCRIPTOR desc) { } } // namespace +/** + * Test Description + * ------------------------ + * - Validates handling that 3D array is created successfully for + * different types of data and supported flags. + * Test source + * ------------------------ + * - unit/memory/hipArray3DCreate.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEMPLATE_TEST_CASE("Unit_hipArray3DCreate_happy", "", char, uchar2, uint2, int4, short4, float, float2, float4) { CHECK_IMAGE_SUPPORT @@ -88,6 +108,20 @@ TEMPLATE_TEST_CASE("Unit_hipArray3DCreate_happy", "", char, uchar2, uint2, int4, } } +/** + * Test Description + * ------------------------ + * - Validate that array 3D is created successfully for different + * types of data when its width/height/depth are set to maximal size. + * - Maximal size corresponds to maximal texture width/height/width. + * - Test can fail with `hipErrorOutMemory` + * Test source + * ------------------------ + * - unit/memory/hipArray3DCreate.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEMPLATE_TEST_CASE("Unit_hipArray3DCreate_MaxTexture", "", int, uint4, short, ushort2, unsigned char, float, float4) { CHECK_IMAGE_SUPPORT @@ -209,7 +243,18 @@ constexpr HIP_ARRAY3D_DESCRIPTOR defaultDescriptor(unsigned int flags, size_t si return desc; } -// Providing the array pointer as nullptr should return an error +/** + * Test Description + * ------------------------ + * - Validates handling when the array is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipArray3DCreate.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipArray3DCreate_Negative_NullArrayPtr") { CHECK_IMAGE_SUPPORT @@ -219,7 +264,18 @@ TEST_CASE("Unit_hipArray3DCreate_Negative_NullArrayPtr") { HIP_CHECK_ERROR(hipArray3DCreate(nullptr, &desc), hipErrorInvalidValue); } -// Providing the description pointer as nullptr should return an error +/** + * Test Description + * ------------------------ + * - Validates handling when array descriptor is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipArray3DCreate.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipArray3DCreate_Negative_NullDescPtr") { CHECK_IMAGE_SUPPORT @@ -228,8 +284,18 @@ TEST_CASE("Unit_hipArray3DCreate_Negative_NullDescPtr") { HIP_CHECK_ERROR(hipArray3DCreate(&array, nullptr), hipErrorInvalidValue); } - -// Zero width arrays are not allowed +/** + * Test Description + * ------------------------ + * - Validates handling when width is zero + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipArray3DCreate.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipArray3DCreate_Negative_ZeroWidth") { CHECK_IMAGE_SUPPORT @@ -243,7 +309,18 @@ TEST_CASE("Unit_hipArray3DCreate_Negative_ZeroWidth") { testInvalidDescription(desc); } -// Zero height arrays are only allowed for 1D arrays and layered arrays +/** + * Test Description + * ------------------------ + * - Validates handling when height is zero + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipArray3DCreate.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipArray3DCreate_Negative_ZeroHeight") { CHECK_IMAGE_SUPPORT @@ -265,7 +342,18 @@ TEST_CASE("Unit_hipArray3DCreate_Negative_ZeroHeight") { } } -// Arrays must be created with a valid data format +/** + * Test Description + * ------------------------ + * - Validates handling when channel descriptor format is not valid + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipArray3DCreate.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipArray3DCreate_Negative_InvalidFormat") { CHECK_IMAGE_SUPPORT @@ -281,7 +369,18 @@ TEST_CASE("Unit_hipArray3DCreate_Negative_InvalidFormat") { testInvalidDescription(desc); } -// An array must have either 1,2, or 4 channels +/** + * Test Description + * ------------------------ + * - Validates handling when channel number in descriptor is not valid + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipArray3DCreate.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipArray3DCreate_Negative_NumChannels") { CHECK_IMAGE_SUPPORT @@ -293,7 +392,18 @@ TEST_CASE("Unit_hipArray3DCreate_Negative_NumChannels") { testInvalidDescription(desc); } -// Using invalid flags should result in an error +/** + * Test Description + * ------------------------ + * - Validates handling when flag values in descriptor are not valid: + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipArray3DCreate.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipArray3DCreate_Negative_InvalidFlags") { CHECK_IMAGE_SUPPORT @@ -319,8 +429,19 @@ TEST_CASE("Unit_hipArray3DCreate_Negative_InvalidFlags") { testInvalidDescription(desc); } - -// hipArray3DCreate should handle the max numeric value gracefully. +/** + * Test Description + * ------------------------ + * - Validates handling when height/width/depth values are set to maximal + * numerical values + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipArray3DCreate.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipArray3DCreate_Negative_NumericLimit") { CHECK_IMAGE_SUPPORT @@ -332,7 +453,20 @@ TEST_CASE("Unit_hipArray3DCreate_Negative_NumericLimit") { testInvalidDescription(desc); } -// texture gather arrays may only be 2D +/** + * Test Description + * ------------------------ + * - Validates handling when descriptor for array with flag set to texture gather + * is set to represent 1D or 3D array for various types, which is not valid. + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipArray3DCreate.cc + * Test requirements + * ------------------------ + * - Platform specific (AMD) + * - HIP_VERSION >= 5.2 + */ TEMPLATE_TEST_CASE("Unit_hipArray3DCreate_Negative_Non2DTextureGather", "", char, uint2, int4, float2, float4) { CHECK_IMAGE_SUPPORT diff --git a/catch/unit/memory/hipArrayCreate.cc b/catch/unit/memory/hipArrayCreate.cc index 29686b2ab..6cd93f0f3 100644 --- a/catch/unit/memory/hipArrayCreate.cc +++ b/catch/unit/memory/hipArrayCreate.cc @@ -17,13 +17,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* -hipArrayCreate API test scenarios -1. Negative Scenarios -2. Allocating Small and big chunk data -3. Multithreaded scenario -*/ - #include #include #include @@ -31,6 +24,14 @@ hipArrayCreate API test scenarios #include "hipArrayCommon.hh" #include "DriverContext.hh" +/** + * @addtogroup hipArrayCreate hipArrayCreate + * @{ + * @ingroup MemoryTest + * `hipArrayCreate(hipArray** pHandle, const HIP_ARRAY_DESCRIPTOR* pAllocateArray)` - + * Creates a 1D or 2D array. + */ + static constexpr size_t NUM_W{4}; static constexpr size_t BIGNUM_W{100}; static constexpr size_t NUM_H{4}; @@ -47,7 +48,6 @@ static constexpr auto ARRAY_LOOP{100}; * releases the memory. * */ - static void ArrayCreate_DiffSizes(int gpu) { HIP_CHECK_THREAD(hipSetDevice(gpu)); //Use of GENERATE in thead function causes random failures with multithread condition. @@ -71,7 +71,18 @@ static void ArrayCreate_DiffSizes(int gpu) { } } -/* This testcase verifies hipArrayCreate API for small and big chunks data*/ +/** + * Test Description + * ------------------------ + * - Validates that array can be created correctly when multiple arrays + * of small and big chunks of float data are allocated. + * Test source + * ------------------------ + * - unit/memory/hipArrayCreate.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipArrayCreate_DiffSizes") { CHECK_IMAGE_SUPPORT @@ -79,11 +90,19 @@ TEST_CASE("Unit_hipArrayCreate_DiffSizes") { HIP_CHECK_THREAD_FINALIZE(); } -/* -This testcase verifies the hipArrayCreate API in multithreaded -scenario by launching threads in parallel on multiple GPUs -and verifies the hipArrayCreate API with small and big chunks data -*/ +/** + * Test Description + * ------------------------ + * - Validates that array can be created correctly when multiple arrays + * of small and big chunks of float data are allocated in multiple threads + * on separate devices. + * Test source + * ------------------------ + * - unit/memory/hipArrayCreate.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipArrayCreate_MultiThread") { CHECK_IMAGE_SUPPORT @@ -197,8 +216,18 @@ void testArrayAsTexture(hipArray_t array, const size_t width, const size_t heigh HIP_CHECK(hipFree(device_data)); } -// Selection of types chosen since trying all types would be slow to compile -// Test the happy path of the hipArrayCreate +/** + * Test Description + * ------------------------ + * - Validates that array can be created correctly for different types + * of data when texture is generated from it and reading from texture is successful. + * Test source + * ------------------------ + * - unit/memory/hipArrayCreate.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEMPLATE_TEST_CASE("Unit_hipArrayCreate_happy", "", uint, int, int4, ushort, short2, char, uchar2, char4, float, float2, float4) { CHECK_IMAGE_SUPPORT @@ -222,8 +251,20 @@ TEMPLATE_TEST_CASE("Unit_hipArrayCreate_happy", "", uint, int, int4, ushort, sho HIP_CHECK(hipArrayDestroy(array)); } - -// Only widths and Heights up to the maxTexture size is supported +/** + * Test Description + * ------------------------ + * - Validates that array can be created correctly for different types of data + * when its width/height are set to maximal size. + * - Maximal size corresponds to maximal texture width/height. + * - This test can fail with `hipErrorOutOfMemory` + * Test source + * ------------------------ + * - unit/memory/hipArrayCreate.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEMPLATE_TEST_CASE("Unit_hipArrayCreate_maxTexture", "", uint, int, int4, ushort, short2, char, uchar2, char4, float, float2, float4) { CHECK_IMAGE_SUPPORT @@ -284,7 +325,18 @@ TEMPLATE_TEST_CASE("Unit_hipArrayCreate_maxTexture", "", uint, int, int4, ushort } } -// zero-width array is not supported +/** + * Test Description + * ------------------------ + * - Validates handling when array width is zero: + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipArrayCreate.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipArrayCreate_ZeroWidth") { CHECK_IMAGE_SUPPORT @@ -300,7 +352,21 @@ TEST_CASE("Unit_hipArrayCreate_ZeroWidth") { HIP_CHECK_ERROR(hipArrayCreate(&array, &desc), hipErrorInvalidValue); } -// HipArrayCreate will return an error when nullptr is used as the array argument +/** + * Test Description + * ------------------------ + * - Validates handling of passing `nullptr` arguments: + * -# When output pointer to the array is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When pointer to the array descriptor is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipArrayCreate.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipArrayCreate_Nullptr") { CHECK_IMAGE_SUPPORT @@ -320,7 +386,19 @@ TEST_CASE("Unit_hipArrayCreate_Nullptr") { } } -// Only elements with 1,2, or 4 channels is supported +/** + * Test Description + * ------------------------ + * - Validates handling when channel number in descriptor + * is not valid + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipArrayCreate.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipArrayCreate_BadNumberChannelElement") { CHECK_IMAGE_SUPPORT @@ -338,7 +416,18 @@ TEST_CASE("Unit_hipArrayCreate_BadNumberChannelElement") { HIP_CHECK_ERROR(hipArrayCreate(&array, &desc), hipErrorInvalidValue); } -// Only certain channel formats are acceptable. +/** + * Test Description + * ------------------------ + * - Validates handling when channel format in descriptor is not valid + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipArrayCreate.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipArrayCreate_BadChannelFormat") { CHECK_IMAGE_SUPPORT diff --git a/catch/unit/memory/hipDrvMemcpy3D.cc b/catch/unit/memory/hipDrvMemcpy3D.cc index 6e33de8c0..4ea2bf195 100644 --- a/catch/unit/memory/hipDrvMemcpy3D.cc +++ b/catch/unit/memory/hipDrvMemcpy3D.cc @@ -28,6 +28,35 @@ THE SOFTWARE. #include #include +/** + * @addtogroup hipDrvMemcpy3D hipDrvMemcpy3D + * @{ + * @ingroup MemoryTest + * `hipDrvMemcpy3D(const HIP_MEMCPY3D* pCopy)` - + * Copies data between host and device. + */ + +/** + * Test Description + * ------------------------ + * - Verifies basic test cases for copying 3D memory between + * device and host. + * - Validates following memcpy directions: + * -# Device to host + * - Platform specific (NVIDIA) + * -# Device to device + * - Peer access disabled + * - Peer access enabled + * -# Host to device + * -# Host to host + * - Platform specific (NVIDIA) + * Test source + * ------------------------ + * - unit/memory/hipDrvMemcpy3D.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipDrvMemcpy3D_Positive_Basic") { CHECK_IMAGE_SUPPORT @@ -53,6 +82,27 @@ TEST_CASE("Unit_hipDrvMemcpy3D_Positive_Basic") { #endif } +/** + * Test Description + * ------------------------ + * - Validates that API synchronizes regarding to host when copying from + * device memory to the pageable or pinned host memory. + * - Validates following memcpy directions: + * -# Host to device + * -# Device to pageable host + * -# Device to pinned host + * - Platform specific (NVIDIA) + * -# Device to device + * - Platform specific (NVIDIA) + * -# Host to host + * - Platform specific (NVIDIA) + * Test source + * ------------------------ + * - unit/memory/hipDrvMemcpy3D.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipDrvMemcpy3D_Positive_Synchronization_Behavior") { CHECK_IMAGE_SUPPORT @@ -81,6 +131,22 @@ TEST_CASE("Unit_hipDrvMemcpy3D_Positive_Synchronization_Behavior") { #endif } +/** + * Test Description + * ------------------------ + * - Validates that nothing will be copied if width, height or depth are set to zero. + * - Validates following memcpy directions: + * -# Device to host + * -# Device to device + * -# Host to device + * -# Host to host + * Test source + * ------------------------ + * - unit/memory/hipDrvMemcpy3D.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipDrvMemcpy3D_Positive_Parameters") { CHECK_IMAGE_SUPPORT @@ -88,7 +154,22 @@ TEST_CASE("Unit_hipDrvMemcpy3D_Positive_Parameters") { Memcpy3DZeroWidthHeightDepth(DrvMemcpy3DWrapper); } -// Disabled on AMD due to defect - EXSWHTEC-238 +/** + * Test Description + * ------------------------ + * - Validates that an array is successfully copied. + * - Validates following memcpy directions: + * -# Device to host + * -# Host to host + * -# Device to device + * -# Host to device + * Test source + * ------------------------ + * - unit/memory/hipDrvMemcpy3D.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipDrvMemcpy3D_Positive_Array") { CHECK_IMAGE_SUPPORT @@ -97,6 +178,55 @@ TEST_CASE("Unit_hipDrvMemcpy3D_Positive_Array") { SECTION("Array from/to Device") { DrvMemcpy3DArrayDeviceShell(DrvMemcpy3DWrapper); } } +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When destination pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When source pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When destination pitch is less than width + * - Expected output: return `hipErrorInvalidPitchValue` + * -# When source pitch is less than width + * - Expected output: return `hipErrorInvalidPitchValue` + * -# When destination pitch is larger than maximum pitch + * - Expected output: return `hipErrorInvalidValue` + * -# When source pitch is larger than maximum pitch + * - Expected output: return `hipErrorInvalidValue` + * -# When extent.width + dst_pos.x > dst_ptr.pitch + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When extent.width + src_pos.x > src_ptr.pitch + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When dst_pos.y out of bounds + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When src_pos.y out of bounds + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When dst_pos.z out of bounds + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When src_pos.z out of bounds + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When memcpy kind is not valid (-1) + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * - All cases are executed for following memcpy directions: + * -# Host to device + * -# Device to host + * -# Host to host + * -# Device to device + * Test source + * ------------------------ + * - unit/memory/hipDrvMemcpy3D.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipDrvMemcpy3D_Negative_Parameters") { CHECK_IMAGE_SUPPORT @@ -234,4 +364,4 @@ TEST_CASE("Unit_hipDrvMemcpy3D_Negative_Parameters") { NegativeTests(dst_alloc.pitched_ptr(), make_hipPos(0, 0, 0), src_alloc.pitched_ptr(), make_hipPos(0, 0, 0), extent, hipMemcpyDeviceToDevice); } -} \ No newline at end of file +} diff --git a/catch/unit/memory/hipDrvMemcpy3DAsync.cc b/catch/unit/memory/hipDrvMemcpy3DAsync.cc index 4b6e29133..a9c48244f 100644 --- a/catch/unit/memory/hipDrvMemcpy3DAsync.cc +++ b/catch/unit/memory/hipDrvMemcpy3DAsync.cc @@ -28,6 +28,35 @@ THE SOFTWARE. #include #include +/** + * @addtogroup hipDrvMemcpy3DAsync hipDrvMemcpy3DAsync + * @{ + * @ingroup MemoryTest + * `hipDrvMemcpy3DAsync(const HIP_MEMCPY3D* pCopy, hipStream_t stream)` - + * Copies data between host and device asynchronously. + */ + +/** + * Test Description + * ------------------------ + * - Verifies basic test cases for copying 3D memory between + * device and host asynchronously. + * - Validates following memcpy directions: + * -# Device to host + * - Platform specific (NVIDIA) + * -# Device to device + * - Peer access disabled + * - Peer access enabled + * -# Host to device + * -# Host to host + * - Platform specific (NVIDIA) + * Test source + * ------------------------ + * - unit/memory/hipDrvMemcpy3DAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipDrvMemcpy3DAsync_Positive_Basic") { CHECK_IMAGE_SUPPORT @@ -57,6 +86,27 @@ TEST_CASE("Unit_hipDrvMemcpy3DAsync_Positive_Basic") { #endif } +/** + * Test Description + * ------------------------ + * - Validates that API synchronizes regarding to host when copying from + * device memory to the pageable or pinned host memory. + * - Validates following memcpy directions: + * -# Host to device + * -# Device to pageable host + * - Platform specific (NVIDIA) + * -# Device to pinned host + * - Platform specific (NVIDIA) + * -# Device to device + * -# Host to host + * - Platform specific (NVIDIA) + * Test source + * ------------------------ + * - unit/memory/hipDrvMemcpy3DAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipDrvMemcpy3DAsync_Positive_Synchronization_Behavior") { CHECK_IMAGE_SUPPORT @@ -85,6 +135,22 @@ TEST_CASE("Unit_hipDrvMemcpy3DAsync_Positive_Synchronization_Behavior") { #endif } +/** + * Test Description + * ------------------------ + * - Validates that nothing will be copied if width, height or depth are set to zero. + * - Validates following memcpy directions: + * -# Device to host + * -# Device to device + * -# Host to device + * -# Host to host + * Test source + * ------------------------ + * - unit/memory/hipDrvMemcpy3DAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipDrvMemcpy3DAsync_Positive_Parameters") { CHECK_IMAGE_SUPPORT @@ -92,7 +158,24 @@ TEST_CASE("Unit_hipDrvMemcpy3DAsync_Positive_Parameters") { Memcpy3DZeroWidthHeightDepth(DrvMemcpy3DWrapper); } -// Disabled on AMD due to defect - EXSWHTEC-238 +/** + * Test Description + * ------------------------ + * - Validates that an array is successfully copied. + * - Validates following memcpy directions: + * -# Device to host + * -# Host to host + * -# Device to device + * - Plaform specific (NVIDIA) + * -# Host to device + * - Plaform specific (NVIDIA) + * Test source + * ------------------------ + * - unit/memory/hipDrvMemcpy3DAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipDrvMemcpy3DAsync_Positive_Array") { CHECK_IMAGE_SUPPORT @@ -101,6 +184,58 @@ TEST_CASE("Unit_hipDrvMemcpy3DAsync_Positive_Array") { SECTION("Array from/to Device") { DrvMemcpy3DArrayDeviceShell(DrvMemcpy3DWrapper); } } +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When destination pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When source pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When destination pitch is less than width + * - Expected output: return `hipErrorInvalidPitchValue` + * -# When source pitch is less than width + * - Expected output: return `hipErrorInvalidPitchValue` + * -# When destination pitch is larger than maximum pitch + * - Expected output: return `hipErrorInvalidValue` + * -# When source pitch is larger than maximum pitch + * - Expected output: return `hipErrorInvalidValue` + * -# When extent.width + dst_pos.x > dst_ptr.pitch + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When extent.width + src_pos.x > src_ptr.pitch + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When dst_pos.y out of bounds + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When src_pos.y out of bounds + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When dst_pos.z out of bounds + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When src_pos.z out of bounds + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When memcpy kind is not valid (-1) + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When stream is not valid + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorContextIsDestroyed` + * - All cases are executed for following memcpy directions: + * -# Host to device + * -# Device to host + * -# Host to host + * -# Device to device + * Test source + * ------------------------ + * - unit/memory/hipDrvMemcpy3DAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipDrvMemcpy3DAsync_Negative_Parameters") { CHECK_IMAGE_SUPPORT @@ -261,4 +396,4 @@ TEST_CASE("Unit_hipDrvMemcpy3DAsync_Negative_Parameters") { NegativeTests(dst_alloc.pitched_ptr(), make_hipPos(0, 0, 0), src_alloc.pitched_ptr(), make_hipPos(0, 0, 0), extent, hipMemcpyDeviceToDevice); } -} \ No newline at end of file +} diff --git a/catch/unit/memory/hipDrvPtrGetAttributes.cc b/catch/unit/memory/hipDrvPtrGetAttributes.cc index 8aeb9b37b..bef8304af 100644 --- a/catch/unit/memory/hipDrvPtrGetAttributes.cc +++ b/catch/unit/memory/hipDrvPtrGetAttributes.cc @@ -20,27 +20,41 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* - * Tests for hipDrvPointerGetAttributes API - Functional Tests: - 1. Pass multiple device related attributes in the attributes of hipDrvPointerGetAttributes API - for the device pointer and check the behaviour - 2. Pass device and host attributes in the attributes of hipDrvPointerGetAttributes API and validate the behaviour - 3. Pass invalid pointer to hipDrvPointerGetAttributes API and validate the behaviour. - - Negative Tests: - 1. Pass invalid numAttributes - 2. Pass nullptr to attributes - 3. Pass nullptr to data - 4. Pass nullptr to device pointer -*/ #include +/** + * @addtogroup hipDrvPointerGetAttributes hipDrvPointerGetAttributes + * @{ + * @ingroup MemoryTest + * `hipDrvPointerGetAttributes(unsigned int numAttributes, hipPointer_attribute* attributes, + * void** data, hipDeviceptr_t ptr)` - + * Returns information about the specified pointer.[BETA] + */ + static size_t Nbytes = 0; constexpr size_t N {1000000}; -/* This testcase verifies Negative Scenarios of - * hipDrvPointerGetAttributes API */ +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When pointer to the attributes to query for is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When output pointer to the data array is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When device pointer is `nullptr` + * - Platform specific (AMD) + * - Expected output: return `hipErrorInvalidValue` + * -# When dependencies are not valid + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipDrvPtrGetAttributes.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipDrvPtrGetAttributes_Negative") { HIP_CHECK(hipSetDevice(0)); Nbytes = N * sizeof(int); @@ -89,7 +103,21 @@ TEST_CASE("Unit_hipDrvPtrGetAttributes_Negative") { #endif } -// Testcase verifies functional scenarios of hipDrvPointerGetAttributes API +/** + * Test Description + * ------------------------ + * - Verifies functional scenarios: + * -# Pass multiple device related attributes in the attributes for the + * device pointer and check the behaviour. + * -# Pass device and host attributes in the attributes and validate the behaviour. + * -# Pass host pointer to host pointer and validate the behaviour. + * Test source + * ------------------------ + * - unit/memory/hipDrvPtrGetAttributes.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipDrvPtrGetAttributes_Functional") { HIP_CHECK(hipSetDevice(0)); Nbytes = N * sizeof(int); diff --git a/catch/unit/memory/hipExtMallocWithFlags.cc b/catch/unit/memory/hipExtMallocWithFlags.cc index 874325428..1cfef4f15 100644 --- a/catch/unit/memory/hipExtMallocWithFlags.cc +++ b/catch/unit/memory/hipExtMallocWithFlags.cc @@ -24,6 +24,31 @@ THE SOFTWARE. #include #include +/** + * @addtogroup hipExtMallocWithFlags hipExtMallocWithFlags + * @{ + * @ingroup MemoryTest + * `hipExtMallocWithFlags(void** ptr, size_t sizeBytes, unsigned int flags)` - + * Allocate memory on the default accelerator. + */ + +/** + * Test Description + * ------------------------ + * - Validate basic scenarios: + * -# When flag is `hipDeviceMallocDefault` + * - Expected output: return `hipSuccess` + * -# When flag is `hipDeviceMallocFinegrained` + * -Expected output: return `hipSuccess` + * -# When flag is `hipMallocSignalMemory` + * - Expected output: return `hipSuccess` + * Test source + * ------------------------ + * - unit/memory/hipExtMallocWithFlags.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipExtMallocWithFlags_Positive_Basic") { void* ptr = nullptr; @@ -56,6 +81,18 @@ TEST_CASE("Unit_hipExtMallocWithFlags_Positive_Basic") { } } +/** + * Test Description + * ------------------------ + * - Validates allocation with zero size. + * - Output address pointer is expected to be `nullptr` + * Test source + * ------------------------ + * - unit/memory/hipExtMallocWithFlags.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipExtMallocWithFlags_Positive_Zero_Size") { void* ptr = reinterpret_cast(0x1); const auto flag = GENERATE(hipDeviceMallocDefault, hipDeviceMallocFinegrained); @@ -63,6 +100,17 @@ TEST_CASE("Unit_hipExtMallocWithFlags_Positive_Zero_Size") { REQUIRE(ptr == nullptr); } +/** + * Test Description + * ------------------------ + * - Validates alignment of the allocated memory. + * Test source + * ------------------------ + * - unit/memory/hipExtMallocWithFlags.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipExtMallocWithFlags_Positive_Alignment") { void *ptr1 = nullptr, *ptr2 = nullptr; const auto flag = GENERATE(hipDeviceMallocDefault, hipDeviceMallocFinegrained); @@ -79,6 +127,35 @@ TEST_CASE("Unit_hipExtMallocWithFlags_Positive_Alignment") { HIP_CHECK(hipFree(ptr2)); } +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When flags are not valid + * - Expected output: return `hipErrorInvalidValue` + * -# When flag is `hipDeviceMallocDefault` and output pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When flag is `hipDeviceMallocDefault` and allocation size is + * `size_t` maximum + * - Expected output: return `hipErrorInvalidValue` + * -# When flag is `hipDeviceMallocFinegrained` and output pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When flag is `hipDeviceMallocFinegrained` and allocation size is + * `size_t` maximum + * - Expected output: return `hipErrorInvalidValue` + * -# When flag is `hipMallocSignalMemory` and output pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When flag is `hipMallocSignalMemory` and allocation size is zero + * - Expected output: return `hipErrorInvalidValue` + * -# When flag is `hipMallocSignalMemory` and allocation size is not 8 + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipExtMallocWithFlags.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipExtMallocWithFlags_Negative_Parameters") { SECTION("Invalid flags") { void* ptr = nullptr; @@ -131,4 +208,4 @@ TEST_CASE("Unit_hipExtMallocWithFlags_Negative_Parameters") { HIP_CHECK_ERROR(hipExtMallocWithFlags(&ptr, 16, hipMallocSignalMemory), hipErrorInvalidValue); } } -} \ No newline at end of file +} diff --git a/catch/unit/memory/hipFree.cc b/catch/unit/memory/hipFree.cc index 23b45d513..e92697556 100644 --- a/catch/unit/memory/hipFree.cc +++ b/catch/unit/memory/hipFree.cc @@ -20,27 +20,19 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - #include #include #include "hipArrayCommon.hh" #include "DriverContext.hh" #include -/* - * This testcase verifies [ hipFree || hipFreeArray || hipFreeType::ArrayDestroy || - * hipFreeType::HostFree with hipHostMalloc ] - * 1. Check that hipFree implicitly synchronises the device. - * 2. Perform multiple allocations and then call hipFree on each pointer concurrently (from unique - * threads) for different memory types and different allocation sizes. - * 3. Pass nullptr as argument and check that no operation is performed and hipSuccess is returned. - * 4. Pass an invalid ptr and check that hipErrorInvalidValue is returned. - * 5. Call hipFree twice on the same pointer and check that the implementation handles the second - * call correctly. - * 6. HipFreeType::HostFree only: - * Try to free memory that has been registered with hipHostRegister and check that - * hipErrorInvalidValue is returned. - */ +/** + * @addtogroup hipFree hipFree + * @{ + * @ingroup MemoryTest + * `hipFree(void* ptr)` - + * Free memory allocated by the hcc hip memory allocation API. + */ enum class FreeType { DevFree, ArrayFree, ArrayDestroy, HostFree }; @@ -48,6 +40,19 @@ enum class FreeType { DevFree, ArrayFree, ArrayDestroy, HostFree }; using namespace std::chrono_literals; constexpr size_t numAllocs = 10; +/** + * Test Description + * ------------------------ + * - Validate that memory freeing causes device synchronization. + * - Uses query on the null stream to check device state. + * - The test is run for various allocation sizes. + * Test source + * ------------------------ + * - unit/memory/hipFree.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipFreeImplicitSyncDev") { int* devPtr{}; size_t size_mult = GENERATE(1, 32, 64, 128, 256); @@ -65,6 +70,32 @@ TEST_CASE("Unit_hipFreeImplicitSyncDev") { HIP_CHECK(hipStreamQuery(nullptr)); } +/** + * End doxygen group hipFree. + * @} + */ + +/** + * @addtogroup hipHostFree hipHostFree + * @{ + * @ingroup MemoryTest + * `hipHostFree(void* ptr)` - + * Free memory allocated by the hcc hip host memory allocation API. + */ + +/** + * Test Description + * ------------------------ + * - Validate that API call causes device synchronization. + * - Run kernel that executes for a couple tens of ms. + * - Query null stream to check the synchronization state. + * Test source + * ------------------------ + * - unit/memory/hipFree.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipFreeImplicitSyncHost") { int* hostPtr{}; size_t size_mult = GENERATE(1, 32, 64, 128, 256); @@ -83,7 +114,35 @@ TEST_CASE("Unit_hipFreeImplicitSyncHost") { HIP_CHECK(hipStreamQuery(nullptr)); } +/** + * End doxygen group hipHostFree. + * @} + */ + +/** + * @addtogroup hipArrayDestroy hipArrayDestroy + * @{ + * @ingroup MemoryTest + * `hipArrayDestroy(hipArray* array)` - + * Destroys an array. + */ + #if HT_NVIDIA +/** + * Test Description + * ------------------------ + * - Validates handling when the device is busy: + * -# When @ref hipFreeArray is called + * - Expected output: return `hipSuccess` + * -# When @ref hipArrayDestroy is called + * - Expected output: return `hipSuccess` + * Test source + * ------------------------ + * - unit/memory/hipFree.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEMPLATE_TEST_CASE("Unit_hipFreeImplicitSyncArray", "", char, float, float2, float4) { CHECK_IMAGE_SUPPORT @@ -123,7 +182,6 @@ TEMPLATE_TEST_CASE("Unit_hipFreeImplicitSyncArray", "", char, float, float2, flo } } #else // AMD - TEMPLATE_TEST_CASE("Unit_hipFreeImplicitSyncArray", "", char, float, float2, float4) { CHECK_IMAGE_SUPPORT @@ -152,34 +210,25 @@ TEMPLATE_TEST_CASE("Unit_hipFreeImplicitSyncArray", "", char, float, float2, flo HIP_CHECK(hipStreamQuery(nullptr)); } } - #endif -// Freeing a invalid pointer with on device -TEST_CASE("Unit_hipFreeNegativeDev") { - SECTION("InvalidPtr") { - char value; - HIP_CHECK_ERROR(hipFree(&value), hipErrorInvalidValue); - } - SECTION("NullPtr") { HIP_CHECK(hipFree(nullptr)); } -} - -// Freeing a invalid pointer with on host -TEST_CASE("Unit_hipFreeNegativeHost") { - SECTION("NullPtr") { HIP_CHECK(hipHostFree(nullptr)); } - SECTION("InvalidPtr") { - char hostPtr; - HIP_CHECK_ERROR(hipHostFree(&hostPtr), hipErrorInvalidValue); - } - SECTION("hipHostRegister") { - char* hostPtr = new char; - auto flag = GENERATE(hipHostRegisterDefault, hipHostRegisterPortable, hipHostRegisterMapped); - HIP_CHECK(hipHostRegister((void*)hostPtr, sizeof(char), flag)); - HIP_CHECK_ERROR(hipHostFree(hostPtr), hipErrorInvalidValue); - delete hostPtr; - } -} - +/** + * Test Description + * ------------------------ + * - Validate handling when array is `nullptr`: + * -# When @ref hipFreeArray is called: + * - Expected output (NVIDIA): return `hipSuccess` + * - Expected output (AMD): return `hipErrorInvalidValue` + * -# When @ref hipArrayDestroy is called: + * - Expected output (NVIDIA): return `hipErrorInvalidResourceHandle` + * - Expected output (AMD): return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipFree.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ #if HT_NVIDIA TEST_CASE("Unit_hipFreeNegativeArray") { DriverContext ctx; @@ -190,36 +239,50 @@ TEST_CASE("Unit_hipFreeNegativeArray") { } } #else - // Freeing a invalid pointer with array TEST_CASE("Unit_hipFreeNegativeArray") { SECTION("ArrayFree") { HIP_CHECK_ERROR(hipFreeArray(nullptr), hipErrorInvalidValue); } SECTION("ArrayDestroy") { HIP_CHECK_ERROR(hipArrayDestroy(nullptr), hipErrorInvalidValue); } } - #endif -TEST_CASE("Unit_hipFreeDoubleDevice") { - size_t width = GENERATE(32, 512, 1024); - char* ptr{}; - size_t size_mult = width; - HIP_CHECK(hipMalloc(&ptr, sizeof(char) * size_mult)); - - HIP_CHECK(hipFree(ptr)); - HIP_CHECK_ERROR(hipFree(ptr), hipErrorInvalidValue); -} -TEST_CASE("Unit_hipFreeDoubleHost") { +#if HT_AMD +/** + * Test Description + * ------------------------ + * - Validates handling of following scenarios: + * -# When @ref hipFreeArray is called two times + * - Expected output: return `hipErrorContextIsDestroyed` + * -# When @ref hipArrayDestroy is called two times + * - Expected output: return `hipErrorContextIsDestroyed` + * Test source + * ------------------------ + * - unit/memory/hipFree.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipFreeDoubleArray") { size_t width = GENERATE(32, 512, 1024); - char* ptr{}; - size_t size_mult = width; + size_t height = GENERATE(0, 32, 512, 1024); + hipArray_t arrayPtr{}; + hipExtent extent{}; + extent.width = width; + extent.height = height; + hipChannelFormatDesc desc = hipCreateChannelDesc(); - HIP_CHECK(hipHostMalloc(&ptr, sizeof(char) * size_mult)); + HIP_CHECK(hipMallocArray(&arrayPtr, &desc, extent.width, extent.height, hipArrayDefault)); - HIP_CHECK(hipHostFree(ptr)); - HIP_CHECK_ERROR(hipHostFree(ptr), hipErrorInvalidValue); + SECTION("ArrayFree") { + HIP_CHECK(hipFreeArray(arrayPtr)); + HIP_CHECK_ERROR(hipFreeArray(arrayPtr), hipErrorContextIsDestroyed); + } + SECTION("ArrayDestroy") { + HIP_CHECK(hipArrayDestroy(arrayPtr)); + HIP_CHECK_ERROR(hipArrayDestroy(arrayPtr), hipErrorContextIsDestroyed); + } } - -#if HT_NVIDIA +#else // NVIDIA TEST_CASE("Unit_hipFreeDoubleArrayFree") { HipTest::HIP_SKIP_TEST("EXSWCPHIPT-120"); return; @@ -285,54 +348,22 @@ TEST_CASE("Unit_hipFreeDoubleArray") { #endif - -TEMPLATE_TEST_CASE("Unit_hipFreeMultiTDev", "", char, int, float2, float4) { - std::vector ptrs(numAllocs); - size_t allocSize = sizeof(TestType) * GENERATE(1, 32, 64, 128); - - for (auto& ptr : ptrs) { - HIP_CHECK(hipMalloc(&ptr, allocSize)); - } - - std::vector threads; - - for (auto ptr : ptrs) { - threads.emplace_back(([ptr] { - HIP_CHECK_THREAD(hipFree(ptr)); - HIP_CHECK_THREAD(hipStreamQuery(nullptr)); - })); - } - - for (auto& t : threads) { - t.join(); - } - HIP_CHECK_THREAD_FINALIZE(); -} - -TEMPLATE_TEST_CASE("Unit_hipFreeMultiTHost", "", char, int, float2, float4) { - std::vector ptrs(numAllocs); - size_t allocSize = sizeof(TestType) * GENERATE(1, 32, 64, 128); - - for (auto& ptr : ptrs) { - HIP_CHECK(hipHostMalloc(&ptr, allocSize)); - } - - std::vector threads; - - for (auto ptr : ptrs) { - threads.emplace_back(([ptr] { - HIP_CHECK_THREAD(hipHostFree(ptr)); - HIP_CHECK_THREAD(hipStreamQuery(nullptr)); - })); - } - - for (auto& t : threads) { - t.join(); - } - HIP_CHECK_THREAD_FINALIZE(); -} - #if HT_NVIDIA +/** + * Test Description + * ------------------------ + * - Validates handling of multiple arrays in multiple threads: + * -# When @ref hipArrayDestroy is called + * - Expected output: return `hipSuccess` + * -# When @ref hipFreeArray is called + * - Expected output: return `hipSuccess` + * Test source + * ------------------------ + * - unit/memory/hipFree.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEMPLATE_TEST_CASE("Unit_hipFreeMultiTArray", "", char, int, float2, float4) { using vec_info = vector_info; diff --git a/catch/unit/memory/hipFreeMipmappedArray.cc b/catch/unit/memory/hipFreeMipmappedArray.cc index df6c4faee..1a6e5327f 100644 --- a/catch/unit/memory/hipFreeMipmappedArray.cc +++ b/catch/unit/memory/hipFreeMipmappedArray.cc @@ -25,16 +25,27 @@ THE SOFTWARE. #include "hipArrayCommon.hh" #include "utils.hh" -/* - * hipFreeMipmappedArray API test scenarios - * 1. Check that hipFreeMipmappedArray implicitly synchronises the device. - * 2. Perform multiple allocations and then call hipFreeMipmappedArray on each pointer concurrently (from unique - * threads) for different memory types and different allocation sizes. - * 3. Pass nullptr as argument and check that correct error code is returned. - * 4. Call hipFreeMipmappedArray twice on the same pointer and check that the implementation handles the second - * call correctly. +/** + * @addtogroup hipFreeMipmappedArray hipFreeMipmappedArray + * @{ + * @ingroup MemoryTest + * `hipFreeMipmappedArray(hipMipmappedArray_t mipmappedArray)` - + * Frees a mipmapped array on the device. */ +/** + * Test Description + * ------------------------ + * - Frees an array when the device is busy. + * - Uses query on null stream for synchronization status. + * Test source + * ------------------------ + * - unit/memory/hipFreeMipmappedArray.cc + * Test requirements + * ------------------------ + * - Host specific (WINDOWS) + * - HIP_VERSION >= 5.2 + */ TEMPLATE_TEST_CASE("Unit_hipFreeMipmappedArrayImplicitSyncArray", "", char, float) { hipMipmappedArray_t arrayPtr{}; hipExtent extent{}; @@ -61,10 +72,36 @@ TEMPLATE_TEST_CASE("Unit_hipFreeMipmappedArrayImplicitSyncArray", "", char, floa HIP_CHECK(hipStreamQuery(nullptr)); } +/** + * Test Description + * ------------------------ + * - Validates handling when mipmapped array handle is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipFreeMipmappedArray.cc + * Test requirements + * ------------------------ + * - Host specific (WINDOWS) + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipFreeMipmappedArray_Negative_Nullptr") { HIP_CHECK_ERROR(hipFreeMipmappedArray(nullptr), hipErrorInvalidValue); } +/** + * Test Description + * ------------------------ + * - Validates handling when free is called twice + * - Expected output: return `hipErrorContextIsDestroyed` + * Test source + * ------------------------ + * - unit/memory/hipFreeMipmappedArray.cc + * Test requirements + * ------------------------ + * - Host specific (WINDOWS) + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipFreeMipmappedArray_Negative_DoubleFree") { hipMipmappedArray_t arrayPtr{}; hipExtent extent{}; @@ -88,6 +125,19 @@ TEST_CASE("Unit_hipFreeMipmappedArray_Negative_DoubleFree") { HIP_CHECK_ERROR(hipFreeMipmappedArray(arrayPtr), hipErrorContextIsDestroyed); } +/** + * Test Description + * ------------------------ + * - Frees multiple arrays from multiple threads. + * Test source + * ------------------------ + * - unit/memory/hipFreeMipmappedArray.cc + * Test requirements + * ------------------------ + * - Multi-threaded device + * - Host specific (WINDOWS) + * - HIP_VERSION >= 5.2 + */ TEMPLATE_TEST_CASE("Unit_hipFreeMipmappedArrayMultiTArray", "", char, int) { constexpr size_t numAllocs = 10; std::vector threads; diff --git a/catch/unit/memory/hipGetSymbolSizeAddress.cc b/catch/unit/memory/hipGetSymbolSizeAddress.cc index 5c011c7e8..e3251a540 100644 --- a/catch/unit/memory/hipGetSymbolSizeAddress.cc +++ b/catch/unit/memory/hipGetSymbolSizeAddress.cc @@ -87,6 +87,27 @@ static void HipGetSymbolSizeAddressTest(const void* symbol) { HipGetSymbolSizeAddressTest( \ SYMBOL(type##_arr)); +/** + * @addtogroup hipGetSymbolAddress hipGetSymbolAddress + * @{ + * @ingroup MemoryTest + * `hipGetSymbolAddress(void** devPtr, const void* symbol)` - + * Gets device pointer associated with symbol on the device. + */ + +/** + * Test Description + * ------------------------ + * - Compares a passed pointer to the address of the symbol itself. + * - Utilizes kernels, and checks that symbol pointer is equal to the address that + * the kernel sees. + * Test source + * ------------------------ + * - unit/memory/hipGetSymbolSizeAddress.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipGetSymbolSizeAddress_Positive_Basic") { SECTION("int") { HIP_GET_SYMBOL_SIZE_ADDRESS_TEST(int); } SECTION("float") { HIP_GET_SYMBOL_SIZE_ADDRESS_TEST(float); } @@ -94,6 +115,22 @@ TEST_CASE("Unit_hipGetSymbolSizeAddress_Positive_Basic") { SECTION("double") { HIP_GET_SYMBOL_SIZE_ADDRESS_TEST(double); } } +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When pointer to the device associated symbol is `nullptr` + * - Platfom specific (AMD) + * - Expected output: return `hipErrorInvalidValue` + * -# When pointer to the symbol name is `nullptr` + * - Expected output: return `hipErrorInvalidSymbol` + * Test source + * ------------------------ + * - unit/memory/hipGetSymbolSizeAddress.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipGetSymbolAddress_Negative_Parameters") { // Causes a segfault in CUDA #if HT_AMD @@ -108,6 +145,37 @@ TEST_CASE("Unit_hipGetSymbolAddress_Negative_Parameters") { } } +/** + * End doxygen group hipGetSymbolAddress. + * @} + */ + +/** + * @addtogroup hipGetSymbolSize hipGetSymbolSize + * @{ + * @ingroup MemoryTest + * `hipGetSymbolSize(size_t* size, const void* symbol)` - + * Gets the size of the given symbol on the device. + * ________________________ + * Test cases from other modules: + * - @ref Unit_hipGetSymbolSizeAddress_Positive_Basic + */ + +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When output pointer to the size is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When pointer to the symbol name is `nullptr` + * - Expected output: return `hipErrorInvalidSymbol` + * Test source + * ------------------------ + * - unit/memory/hipGetSymbolSizeAddress.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipGetSymbolSize_Negative_Parameters") { // Causes a segfault in CUDA #if HT_AMD diff --git a/catch/unit/memory/hipHostGetDevicePointer.cc b/catch/unit/memory/hipHostGetDevicePointer.cc index 7f0746893..112a308ad 100644 --- a/catch/unit/memory/hipHostGetDevicePointer.cc +++ b/catch/unit/memory/hipHostGetDevicePointer.cc @@ -23,6 +23,34 @@ THE SOFTWARE. #include #include +/** + * @addtogroup hipHostGetDevicePointer hipHostGetDevicePointer + * @{ + * @ingroup MemoryTest + * `hipHostGetDevicePointer(void** devPtr, void* hstPtr, unsigned int flags)` - + * Get Device pointer from Host Pointer allocated through `hipHostMalloc`. + */ + +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When output device pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When host pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When host pointer points to non-pinned memory + * - Expected output: return `hipErrorInvalidValue` + * -# When flags are not default (non-zero) + * -Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipHostGetDevicePointer.cc + * Test requirements + * ------------------------ + * - Device supports mapping of host memory + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipHostGetDevicePointer_Negative") { int* hPtr{nullptr}; int* dPtr{nullptr}; @@ -61,6 +89,25 @@ TEST_CASE("Unit_hipHostGetDevicePointer_Negative") { template __global__ void set(T* ptr, T val) { *ptr = val; } +/** + * Test Description + * ------------------------ + * - Validates basic use-case scenarios: + * -# When set the value on device and get device pointer + * - Check that host memory pointer has been updated accordingly + * to device pointer + * - Expected output: return `hipSuccess` + * -# When set the value on device, using registered stack memory + * - Check that value is equal within both pointers + * - Expected output: return `hipSuccess` + * Test source + * ------------------------ + * - unit/memory/hipHostGetDevicePointer.cc + * Test requirements + * ------------------------ + * - Device supports mapping of host memory + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipHostGetDevicePointer_UseCase") { if(!DeviceAttributesSupport(0, hipDeviceAttributeCanMapHostMemory)) { HipTest::HIP_SKIP_TEST("Device does not support mapping host memory"); diff --git a/catch/unit/memory/hipHostGetFlags.cc b/catch/unit/memory/hipHostGetFlags.cc index 25fb5b273..c6ed65fae 100644 --- a/catch/unit/memory/hipHostGetFlags.cc +++ b/catch/unit/memory/hipHostGetFlags.cc @@ -20,16 +20,20 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* -This testcase verifies the basic scenario of hipHostGetFlags API -*/ - #include #include #include #include #include +/** + * @addtogroup hipHostGetFlags hipHostGetFlags + * @{ + * @ingroup MemoryTest + * `hipHostGetFlags(unsigned int* flagsPtr, void* hostPtr)` - + * Return flags associated with host pointer. + */ + std::vector FlagPart1Vec{hipHostMallocDefault, hipHostMallocDefault | hipHostMallocPortable, hipHostMallocDefault | hipHostMallocMapped, @@ -56,26 +60,6 @@ std::vector FlagPart2Vec{0x0}; static constexpr auto LEN{1024 * 1024}; -/* -This testcase verifies hipHostGetFlags API basic scenario -1. Allocates the memory using different flags -2. Gets the flags of the respective variable using - hipHostGetFlags API -3. Validates it with the initial flags used while allocating - memory -*/ - -/* Possible host flags - * hipHostMallocDefault 0x0 - * hipHostMallocPortable 0x1 - * hipHostMallocMapped 0x2 - * hipHostMallocWriteCombined 0x4 - * NOT on Nvidia - * hipHostMallocNumaUser 0x20000000 - * hipHostMallocCoherent 0x40000000 - * hipHostMallocNonCoherent 0x80000000 - */ - inline void checkFlags(unsigned int expected, unsigned int obtained) { // Account for cases where flags from FlagPart1Vec do not include hipHostMallocMapped, // on Nvidia devices it is added by default @@ -85,6 +69,20 @@ inline void checkFlags(unsigned int expected, unsigned int obtained) { REQUIRE(expected == obtained); } +/** + * Test Description + * ------------------------ + * - Validate that flags set when allocating memory are returned. + * - Allocate memory, and get flags. + * - Check that retreived flags are equal to the ones that are set. + * Test source + * ------------------------ + * - unit/memory/hipHostGetFlags.cc + * Test requirements + * ------------------------ + * - Device supports mapping of host memory + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipHostGetFlags_flagCombos") { constexpr auto SIZE{LEN * sizeof(int)}; @@ -118,7 +116,22 @@ TEST_CASE("Unit_hipHostGetFlags_flagCombos") { } } -// Test Allocation with flags and getting flags in another thread +/** + * Test Description + * ------------------------ + * - Validate that flags set when allocating memory in a separate thread, + * are returned. + * - Launch thread that allocates memory. + * - Join thread. + * - Get flags and check that they are equal to the ones that were set. + * Test source + * ------------------------ + * - unit/memory/hipHostGetFlags.cc + * Test requirements + * ------------------------ + * - Device supports mapping of host memory + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipHostGetFlags_DifferentThreads") { constexpr auto SIZE{LEN * sizeof(int)}; int* A_h{nullptr}; @@ -151,7 +164,25 @@ TEST_CASE("Unit_hipHostGetFlags_DifferentThreads") { } } -// Test behaviour of hipHostGetFlags with invalid args +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When the output flag pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When passing device pointer instead of a host pointer + * - Expected output: return `hipErrorInvalidValue` + * -# When passing device pointer instead of a host pointer, + * using `hipHostGetDevicePointer` + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipHostGetFlags.cc + * Test requirements + * ------------------------ + * - Device supports mapping of host memory + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipHostGetFlags_InvalidArgs") { constexpr auto SIZE{LEN * sizeof(int)}; int* A_h{nullptr}; diff --git a/catch/unit/memory/hipHostMalloc.cc b/catch/unit/memory/hipHostMalloc.cc index 6e4c06eb2..8d7b00580 100644 --- a/catch/unit/memory/hipHostMalloc.cc +++ b/catch/unit/memory/hipHostMalloc.cc @@ -35,6 +35,14 @@ This testfile verifies the following scenarios of hipHostMalloc API #include #include +/** + * @addtogroup hipHostMalloc hipHostMalloc + * @{ + * @ingroup MemoryTest + * `hipHostMalloc(void** ptr, size_t size, unsigned int flags)` - + * Allocate device accessible page locked host memory. + */ + #define SYNC_EVENT 0 #define SYNC_STREAM 1 #define SYNC_DEVICE 2 @@ -108,12 +116,21 @@ void CheckHostPointer(int numElements, int* ptr, unsigned eventFlags, HIP_CHECK(hipStreamDestroy(s)); HIP_CHECK(hipEventDestroy(e)); } -/* -This testcase performs the basic scenario of hipHostMalloc API -Allocates the memory using hipHostMalloc API -Launches the kernel and performs vector addition. -validates thes result. -*/ + +/** + * Test Description + * ------------------------ + * - Allocates the memory. + * - Launches the kernel and performs vector addition. + * - Validates the results. + * Test source + * ------------------------ + * - unit/memory/hipHostMalloc.cc + * Test requirements + * ------------------------ + * - Device supports host pinned memory + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipHostMalloc_Basic") { static constexpr auto LEN{1024 * 1024}; static constexpr auto SIZE{LEN * sizeof(float)}; @@ -157,10 +174,21 @@ TEST_CASE("Unit_hipHostMalloc_Basic") { HIP_CHECK(hipHostFree(C_h)); } } -/* -This testcase verifies the hipHostMalloc API by passing nullptr -to the pointer variable -*/ + +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When output pointer is `nullptr` + * - Platform specific (AMD) + * - Expected output: do not return `hipSuccess` + * Test source + * ------------------------ + * - unit/memory/hipHostMalloc.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipHostMalloc_Negative") { #if HT_AMD { @@ -173,14 +201,22 @@ TEST_CASE("Unit_hipHostMalloc_Negative") { } #endif } -/* -This testcase verifies the hipHostMalloc API by -1.Allocating memory using noncoherent flag -2. Launches the kernel and modifies the variable - using different synchronization - techniquies -3. validates the result. -*/ + +/** + * Test Description + * ------------------------ + * - Allocates memory using noncoherent flag. + * - Launches the kernel. + * - Modifies the variable using different synchronization + * techniques. + * - Validates the result. + * Test source + * ------------------------ + * - unit/memory/hipHostMalloc.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipHostMalloc_NonCoherent") { int* A = nullptr; HIP_CHECK(hipHostMalloc(reinterpret_cast(&A), @@ -194,14 +230,21 @@ TEST_CASE("Unit_hipHostMalloc_NonCoherent") { SYNC_EVENT, ptrType); } -/* -This testcase verifies the hipHostMalloc API by -1.Allocating memory using coherent flag -2. Launches the kernel and modifies the variable - using different synchronization - techniquies -3. validates the result. -*/ +/** + * Test Description + * ------------------------ + * - Allocates memory using coherent flag. + * - Launches the kernel. + * - Modifies the variable using different synchronization + * techniques. + * - Validates the result. + * Test source + * ------------------------ + * - unit/memory/hipHostMalloc.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipHostMalloc_Coherent") { int* A = nullptr; if (hipHostMalloc(reinterpret_cast(&A), sizeBytes, @@ -225,14 +268,21 @@ TEST_CASE("Unit_hipHostMalloc_Coherent") { } } -/* -This testcase verifies the hipHostMalloc API by -1.Allocating memory using default flag -2. Launches the kernel and modifies the variable - using different synchronization - techniquies -3. validates the result. -*/ +/** + * Test Description + * ------------------------ + * - Allocates memory using default flag. + * - Launches the kernel. + * - Modifies the variable using different synchronization + * techniques. + * - Validates the result. + * Test source + * ------------------------ + * - unit/memory/hipHostMalloc.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipHostMalloc_Default") { int* A = nullptr; HIP_CHECK(hipHostMalloc(reinterpret_cast(&A), sizeBytes)); @@ -242,6 +292,30 @@ TEST_CASE("Unit_hipHostMalloc_Default") { CheckHostPointer(numElements, A, 0, SYNC_EVENT, ptrType); } +/** + * End doxygen group hipHostMalloc. + * @} + */ + + +/** + * @addtogroup hipHostGetDevicePointer hipHostGetDevicePointer + * @{ + * @ingroup MemoryTest + */ + +/** + * Test Description + * ------------------------ + * - Validates handling of passing `nullptr` for device pointer + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipHostMalloc.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipHostGetDevicePointer_NullCheck") { int* d_a; HIP_CHECK(hipHostMalloc(reinterpret_cast(&d_a), sizeof(int))); diff --git a/catch/unit/memory/hipHostMallocTests.cc b/catch/unit/memory/hipHostMallocTests.cc index 9b25f613a..f408cd56d 100644 --- a/catch/unit/memory/hipHostMallocTests.cc +++ b/catch/unit/memory/hipHostMallocTests.cc @@ -17,22 +17,36 @@ OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/** -Testcase Scenarios : - - 1) Test hipHostMalloc() api with ptr as nullptr and check for return value. - 2) Test hipHostMalloc() api with size as max(size_t) and check for OOM error. - 3) Test hipHostMalloc() api with flags as max(unsigned int) and validate - return value. - 4) Pass size as zero for hipHostMalloc() api and check ptr is reset with - with return value success. -*/ - #include #include /** - * Performs argument validation of hipHostMalloc api. + * @addtogroup hipHostMalloc hipHostMalloc + * @{ + * @ingroup MemoryTest + */ + +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When output pointer to the address pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When allocation size is `size_t` maximum + * - Expected output: return `hipErrorMemoryAllocation` + * -# When flags are `unsigned int` maximum + * - Expected output: return `hipErrorInvalidValue` + * -# When allocation size is zero + * - Expected output: output pointer is `nullptr` and return `hipSuccess` + * -# When coherent and noncoherent flags are passed together + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipHostMallocTests.cc + * Test requirements + * ------------------------ + * - Platform specific (AMD) + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipHostMalloc_ArgValidation") { #if HT_NVIDIA diff --git a/catch/unit/memory/hipHostRegister.cc b/catch/unit/memory/hipHostRegister.cc index cb62532ae..1ca724a43 100644 --- a/catch/unit/memory/hipHostRegister.cc +++ b/catch/unit/memory/hipHostRegister.cc @@ -20,14 +20,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/** - * @addtogroup hipHostRegister hipHostRegister - * @{ - * @ingroup MemoryTest - * `hipError_t hipHostRegister (void *hostPtr, size_t sizeBytes, unsigned int flags)` - - * register host memory so it can be accessed from the current device. - */ - #include "hip/hip_runtime_api.h" #include #include @@ -35,6 +27,14 @@ THE SOFTWARE. #include #include +/** + * @addtogroup hipHostRegister hipHostRegister + * @{ + * @ingroup MemoryTest + * `hipHostRegister(void* hostPtr, size_t sizeBytes, unsigned int flags)` - + * Register host memory so it can be accessed from the current device. + */ + #define OFFSET 128 #define INITIAL_VAL 1 #define EXPECTED_VAL 2 @@ -95,21 +95,21 @@ void doMemCopy(size_t numElements, int offset, T* A, T* Bh, T* Bd, /** * Test Description * ------------------------ - * - This testcase verifies the hipHostRegister API by - * 1. Allocating the memory using malloc - * 2. hipHostRegister that variable - * 3. Getting the corresponding device pointer of the registered varible - * 4. Launching kernel and access the device pointer variable - * 5. performing hipMemset on the device pointer variable + * - Validates that registered memory can be used like host allocated + * memory with a kernel. + * - Allocates the memory with malloc. + * - Registers that variable. + * - Gets the corresponding device pointer of the registered variable. + * - Launches kernel and access the device pointer variable. + * - Performs memset on the variable. * Test source * ------------------------ - * - catch\unit\memory\hipHostRegister.cc + * - unit/memory/hipHostRegister.cc * Test requirements * ------------------------ - * - HIP_VERSION >= 5.2 + * - HIP_VERSION >= 5.2 */ -TEMPLATE_TEST_CASE("Unit_hipHostRegister_ReferenceFromKernelandhipMemset", "", \ - int, float, double) { +TEMPLATE_TEST_CASE("Unit_hipHostRegister_ReferenceFromKernelandhipMemset", "", int, float, double) { size_t sizeBytes{LEN * sizeof(TestType)}; TestType *A, **Ad; int num_devices = 0; @@ -849,14 +849,13 @@ TEST_CASE("Unit_hipHostRegister_MemAdvise_SetGet") { /** * Test Description * ------------------------ - * - This testcase verifies hipHostRegister API by performing memcpy - * on the hipHostRegistered variable. + * - Performs memory copy on the registered variable. * Test source * ------------------------ - * - catch\unit\memory\hipHostRegister.cc + * - unit/memory/hipHostRegister.cc * Test requirements * ------------------------ - * - HIP_VERSION >= 5.2 + * - HIP_VERSION >= 5.2 */ TEMPLATE_TEST_CASE("Unit_hipHostRegister_Memcpy", "", int, float, double) { // 1 refers to hipHostRegister @@ -899,13 +898,15 @@ template __global__ void fill_kernel(T* dataPtr, T value) { /** * Test Description * ------------------------ - * - This testcase verifies all the supported flags of hipHostRegister. + * - Validates that register is successfully performed with various + * valid and invalid flag combinations. * Test source * ------------------------ - * - catch\unit\memory\hipHostRegister.cc + * - unit/memory/hipHostRegister.cc * Test requirements * ------------------------ - * - HIP_VERSION >= 5.2 + * - Platform specific (NVIDIA) + * - HIP_VERSION >= 5.2 */ TEMPLATE_TEST_CASE("Unit_hipHostRegister_Flags", "", int, float, double) { size_t sizeBytes = 1 * sizeof(TestType); @@ -943,13 +944,21 @@ TEMPLATE_TEST_CASE("Unit_hipHostRegister_Flags", "", int, float, double) { /** * Test Description * ------------------------ - * - These negative tests checks invalid parameter values. + * - Validates handling of invalid arguments: + * -# When pointer to host memory is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When size of the memory is zero + * - Expected output: return `hipErrorInvalidValue` + * -# When size of the memory is not valid + * - Expected output: return `hipErrorInvalidValue` + * -# When memory is freed before register + * - Expected output: return `hipErrorInvalidValue` * Test source * ------------------------ - * - catch\unit\memory\hipHostRegister.cc + * - unit/memory/hipHostRegister.cc * Test requirements * ------------------------ - * - HIP_VERSION >= 5.2 + * - HIP_VERSION >= 5.2 */ TEMPLATE_TEST_CASE("Unit_hipHostRegister_Negative", "", int, float, double) { TestType* hostPtr = nullptr; diff --git a/catch/unit/memory/hipHostUnregister.cc b/catch/unit/memory/hipHostUnregister.cc index ea3d018a3..a610aef49 100644 --- a/catch/unit/memory/hipHostUnregister.cc +++ b/catch/unit/memory/hipHostUnregister.cc @@ -22,6 +22,14 @@ THE SOFTWARE. #include +/** + * @addtogroup hipHostUnregister hipHostUnregister + * @{ + * @ingroup MemoryTest + * `hipHostUnregister(void* hostPtr)` - + * Un-register host pointer. + */ + namespace hipHostUnregisterTests { constexpr unsigned int allFlags = hipHostRegisterDefault & // 0 hipHostRegisterPortable & // 1 @@ -44,7 +52,20 @@ inline bool hipHostRegisterSupported() { #endif } - +/** + * Test Description + * ------------------------ + * - Check that unregistering memory makes it an invalid argument + * for getting the device pointer. + * Test source + * ------------------------ + * - unit/memory/hipHostUnregister.cc + * Test requirements + * ------------------------ + * - Device supports host register + * - Platform specific (AMD) + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipHostUnregister_MemoryNotAccessableAfterUnregister") { if (!hipHostRegisterSupported()) { return; @@ -64,21 +85,69 @@ TEST_CASE("Unit_hipHostUnregister_MemoryNotAccessableAfterUnregister") { } } +/** + * Test Description + * ------------------------ + * - Validates handling of `nullptr` host pointer + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipHostUnregister.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipHostUnregister_NullPtr") { HIP_CHECK_ERROR(hipHostUnregister(nullptr), hipErrorInvalidValue); } +/** + * Test Description + * ------------------------ + * - Validates handling when host pointer points to partial allocation + * - Expected output: return `hipErrorHostMemoryNotRegistered` + * Test source + * ------------------------ + * - unit/memory/hipHostUnregister.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipHostUnregister_Ptr_Different_Than_Specified_To_Register") { std::vector alloc(2); HIP_CHECK(hipHostRegister(alloc.data(), alloc.size(), 0)); HIP_CHECK_ERROR(hipHostUnregister(&alloc.data()[1]), hipErrorHostMemoryNotRegistered); } +/** + * Test Description + * ------------------------ + * - Validates handling when host pointer points to unregistered memory + * - Expected output: return `hipErrorHostMemoryNotRegistered` + * Test source + * ------------------------ + * - unit/memory/hipHostUnregister.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipHostUnregister_NotRegisteredPointer") { auto x = std::unique_ptr(new int); HIP_CHECK_ERROR(hipHostUnregister(x.get()), hipErrorHostMemoryNotRegistered); } +/** + * Test Description + * ------------------------ + * - Validates handling of already unregistered pointer + * - Expected output: return `hipErrorHostMemoryNotRegistered` + * Test source + * ------------------------ + * - unit/memory/hipHostUnregister.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipHostUnregister_AlreadyUnregisteredPointer") { if (!hipHostRegisterSupported()) { return; diff --git a/catch/unit/memory/hipMalloc.cc b/catch/unit/memory/hipMalloc.cc index 8692f5d59..8ae674c4a 100644 --- a/catch/unit/memory/hipMalloc.cc +++ b/catch/unit/memory/hipMalloc.cc @@ -23,6 +23,30 @@ THE SOFTWARE. #include #include +/** + * @addtogroup hipMalloc hipMalloc + * @{ + * @ingroup MemoryTest + * `hipMalloc(void** ptr, size_t size)` - + * Allocate memory on the default accelerator. + */ + +/** + * Test Description + * ------------------------ + * - Allocate memory with several allocation sizes: + * -# 10 + * -# page_size / 2 + * -# page_size + * -# 3 * page_size / 2 + * -# 2 * page_size + * Test source + * ------------------------ + * - unit/memory/hipMalloc.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMalloc_Positive_Basic") { constexpr size_t page_size = 4096; void* ptr = nullptr; @@ -34,12 +58,34 @@ TEST_CASE("Unit_hipMalloc_Positive_Basic") { HIP_CHECK(hipFree(ptr)); } +/** + * Test Description + * ------------------------ + * - Allocate memory with size zero. + * Test source + * ------------------------ + * - unit/memory/hipMalloc.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMalloc_Positive_Zero_Size") { void* ptr = reinterpret_cast(0x1); HIP_CHECK(hipMalloc(&ptr, 0)); REQUIRE(ptr == nullptr); } +/** + * Test Description + * ------------------------ + * - Validate alignment of the allocated memory. + * Test source + * ------------------------ + * - unit/memory/hipMalloc.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMalloc_Positive_Alignment") { void *ptr1 = nullptr, *ptr2 = nullptr; HIP_CHECK(hipMalloc(&ptr1, 1)); @@ -50,6 +96,21 @@ TEST_CASE("Unit_hipMalloc_Positive_Alignment") { HIP_CHECK(hipFree(ptr2)); } +/** + * Test Description + * ------------------------ + * - Validate handling of invalid arguments: + * -# When output pointer to the address pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When the allocation size is max size of the `size_t` + * - Expected output: return `hipErrorOutOfMemory` + * Test source + * ------------------------ + * - unit/memory/hipMalloc.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMalloc_Negative_Parameters") { SECTION("ptr == nullptr") { HIP_CHECK_ERROR(hipMalloc(nullptr, 4096), hipErrorInvalidValue); } SECTION("size == max size_t") { diff --git a/catch/unit/memory/hipMalloc3D.cc b/catch/unit/memory/hipMalloc3D.cc index d3edad5a2..d0d7576e9 100644 --- a/catch/unit/memory/hipMalloc3D.cc +++ b/catch/unit/memory/hipMalloc3D.cc @@ -17,15 +17,16 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* -hipMalloc3D API test scenarios -1. Basic Functionality -2. Negative Scenarios -3. Allocating Small and big chunk data -4. Multithreaded scenario -*/ - #include + +/** + * @addtogroup hipMalloc3D hipMalloc3D + * @{ + * @ingroup MemoryTest + * `hipMalloc3D(hipPitchedPtr* pitchedDevPtr, hipExtent extent)` - + * Allocate logical 1D, 2D or 3D memory objects on the device. + */ + static constexpr auto SMALL_SIZE{4}; static constexpr auto CHUNK_LOOP{100}; static constexpr auto BIG_SIZE{100}; @@ -58,9 +59,16 @@ static void Malloc3DThreadFunc(int gpu) { MemoryAlloc3DDiffSizes(gpu); } -/* - * This verifies the hipMalloc3D API by - * assigning width,height and depth as 10 +/** + * Test Description + * ------------------------ + * - Validates that 3D memory can be successfully allocated. + * Test source + * ------------------------ + * - unit/memory/hipMalloc3D.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipMalloc3D_Basic") { CHECK_IMAGE_SUPPORT @@ -83,21 +91,37 @@ TEST_CASE("Unit_hipMalloc3D_Basic") { } } -/* -This testcase verifies the hipMalloc3D API by allocating -smaller and big chunk data. -*/ +/** + * Test Description + * ------------------------ + * - Validates that 3D memory can be successfully allocated when multiple + * arrays of small and big chunks of float data are allocated. + * Test source + * ------------------------ + * - unit/memory/hipMalloc3D.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMalloc3D_SmallandBigChunks") { CHECK_IMAGE_SUPPORT MemoryAlloc3DDiffSizes(0); } -/* -This testcase verifies the hipMalloc3D API in multithreaded -scenario by launching threads in parallel on multiple GPUs -and verifies the hipMalloc3D API with small and big chunks data -*/ +/** + * Test Description + * ------------------------ + * - Validates that 3D memory can be successfully allocated when multiple + * arrays of small and big chunks of float data are allocated. + * - Executes allocation in multiple threads on separate devices. + * Test source + * ------------------------ + * - unit/memory/hipMalloc3D.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMalloc3D_MultiThread") { CHECK_IMAGE_SUPPORT diff --git a/catch/unit/memory/hipMalloc3DArray.cc b/catch/unit/memory/hipMalloc3DArray.cc index a0741a105..67a00bd1d 100644 --- a/catch/unit/memory/hipMalloc3DArray.cc +++ b/catch/unit/memory/hipMalloc3DArray.cc @@ -17,18 +17,19 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* -hipMalloc3DArray API test scenarios -1. Basic Functionality -2. Negative Scenarios -3. Allocating Small and big chunk data -4. Multithreaded scenario -*/ - #include #include #include "hipArrayCommon.hh" +/** + * @addtogroup hipMalloc3DArray hipMalloc3DArray + * @{ + * @ingroup MemoryTest + * `hipMalloc3DArray(hipArray** array, const struct hipChannelFormatDesc* desc, + * struct hipExtent extent, unsigned int flags)` - + * Allocate an array on the device. + */ + static constexpr auto ARRAY_SIZE{4}; static constexpr auto BIG_ARRAY_SIZE{100}; static constexpr auto ARRAY_LOOP{100}; @@ -66,6 +67,18 @@ static void Malloc3DArray_DiffSizes(int gpu) { } } +/** + * Test Description + * ------------------------ + * - Validates handling when multiple arrays of small and + * big chunks of float data are allocated. + * Test source + * ------------------------ + * - unit/memory/hipMalloc3DArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMalloc3DArray_DiffSizes") { CHECK_IMAGE_SUPPORT @@ -73,11 +86,19 @@ TEST_CASE("Unit_hipMalloc3DArray_DiffSizes") { HIP_CHECK_THREAD_FINALIZE(); } -/* -This testcase verifies the hipMalloc3DArray API in multithreaded -scenario by launching threads in parallel on multiple GPUs -and verifies the hipMalloc3DArray API with small and big chunks data -*/ +/** + * Test Description + * ------------------------ + * - Validates handling when multiple arrays of small and + * big chunks of float data are allocated. + * - Executes in multiple threads on separate devices. + * Test source + * ------------------------ + * - unit/memory/hipMalloc3DArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMalloc3DArray_MultiThread") { CHECK_IMAGE_SUPPORT @@ -124,6 +145,18 @@ void checkArrayIsExpected(hipArray_t array, const hipChannelFormatDesc& expected } } // namespace +/** + * Test Description + * ------------------------ + * - Validates that 3D array can be allocated successfully + * for different types of data and supported flags. + * Test source + * ------------------------ + * - unit/memory/hipMalloc3DArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEMPLATE_TEST_CASE("Unit_hipMalloc3DArray_happy", "", char, uchar2, uint2, int4, short4, float, float2, float4) { CHECK_IMAGE_SUPPORT @@ -155,6 +188,19 @@ TEMPLATE_TEST_CASE("Unit_hipMalloc3DArray_happy", "", char, uchar2, uint2, int4, } } +/** + * Test Description + * ------------------------ + * - Validates that 3D array allocation is working correctly for different + * types of data when its width/height/depth are set to maximal size. + * - Maximal size corresponds to maximal texture width/height/depth. + * Test source + * ------------------------ + * - unit/memory/hipMalloc3DArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEMPLATE_TEST_CASE("Unit_hipMalloc3DArray_MaxTexture", "", int, uint4, short, ushort2, unsigned char, float, float4) { CHECK_IMAGE_SUPPORT @@ -246,8 +292,18 @@ hipExtent makeExtent(unsigned int flag, size_t s) { return make_hipExtent(s, s, s); } - -// Providing the array pointer as nullptr should return an error +/** + * Test Description + * ------------------------ + * - Validates handling when array is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMalloc3DArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMalloc3DArray_Negative_NullArrayPtr") { CHECK_IMAGE_SUPPORT @@ -259,7 +315,18 @@ TEST_CASE("Unit_hipMalloc3DArray_Negative_NullArrayPtr") { hipErrorInvalidValue); } -// Providing the description pointer as nullptr should return an error +/** + * Test Description + * ------------------------ + * - Validates handling when descriptor pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMalloc3DArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMalloc3DArray_Negative_NullDescPtr") { CHECK_IMAGE_SUPPORT @@ -272,7 +339,18 @@ TEST_CASE("Unit_hipMalloc3DArray_Negative_NullDescPtr") { hipErrorInvalidValue); } -// Zero width arrays are not allowed +/** + * Test Description + * ------------------------ + * - Validates handling when width is zero + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMalloc3DArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMalloc3DArray_Negative_ZeroWidth") { CHECK_IMAGE_SUPPORT @@ -286,7 +364,18 @@ TEST_CASE("Unit_hipMalloc3DArray_Negative_ZeroWidth") { hipErrorInvalidValue); } -// Zero height arrays are only allowed for 1D arrays and layered arrays +/** + * Test Description + * ------------------------ + * - Validates handling when height is zero + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMalloc3DArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMalloc3DArray_Negative_ZeroHeight") { CHECK_IMAGE_SUPPORT @@ -305,6 +394,18 @@ TEST_CASE("Unit_hipMalloc3DArray_Negative_ZeroHeight") { } } +/** + * Test Description + * ------------------------ + * - Validates handling when flag values in descriptor are not valid + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMalloc3DArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMalloc3DArray_Negative_InvalidFlags") { CHECK_IMAGE_SUPPORT @@ -342,6 +443,18 @@ void testInvalidDescription(hipChannelFormatDesc desc) { HIP_CHECK_ERROR(hipMalloc3DArray(&array, &desc, makeExtent(flag, s), flag), expectedError); } +/** + * Test Description + * ------------------------ + * - Validates handling when channel format in descriptor is not valid + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMalloc3DArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMalloc3DArray_Negative_InvalidFormat") { CHECK_IMAGE_SUPPORT @@ -350,6 +463,19 @@ TEST_CASE("Unit_hipMalloc3DArray_Negative_InvalidFormat") { testInvalidDescription(desc); } +/** + * Test Description + * ------------------------ + * - Validates handling when there is a channel after a zero + * channel is set as parameter + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMalloc3DArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMalloc3DArray_Negative_BadChannelLayout") { CHECK_IMAGE_SUPPORT @@ -373,6 +499,18 @@ TEST_CASE("Unit_hipMalloc3DArray_Negative_BadChannelLayout") { testInvalidDescription(desc); } +/** + * Test Description + * ------------------------ + * - Validates handling when descriptor is set to 8-bit float channels + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMalloc3DArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMalloc3DArray_Negative_8BitFloat") { CHECK_IMAGE_SUPPORT @@ -383,6 +521,18 @@ TEST_CASE("Unit_hipMalloc3DArray_Negative_8BitFloat") { testInvalidDescription(desc); } +/** + * Test Description + * ------------------------ + * - Validates handling when channel sizes are different + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMalloc3DArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMalloc3DArray_Negative_DifferentChannelSizes") { CHECK_IMAGE_SUPPORT @@ -408,6 +558,18 @@ TEST_CASE("Unit_hipMalloc3DArray_Negative_DifferentChannelSizes") { testInvalidDescription(desc); } +/** + * Test Description + * ------------------------ + * - Validates handling when channel sizes in descriptor are invalid + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMalloc3DArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMalloc3DArray_Negative_BadChannelSize") { CHECK_IMAGE_SUPPORT @@ -421,8 +583,19 @@ TEST_CASE("Unit_hipMalloc3DArray_Negative_BadChannelSize") { testInvalidDescription(desc); } - -// hipMalloc3DArray should handle the max numeric value gracefully. +/** + * Test Description + * ------------------------ + * - Validates handle when width/height size are equal to maximum possible + * numerical value + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMalloc3DArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMalloc3DArray_Negative_NumericLimit") { CHECK_IMAGE_SUPPORT @@ -435,7 +608,18 @@ TEST_CASE("Unit_hipMalloc3DArray_Negative_NumericLimit") { hipErrorInvalidValue); } -// texture gather arrays are only allowed to be 2D +/** + * Test Description + * ------------------------ + * - Validates handling when descriptor for array with flag set to texture gather + * is set to represent 1D or 3D array for various types, which is not valid. + * Test source + * ------------------------ + * - unit/memory/hipMalloc3DArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEMPLATE_TEST_CASE("Unit_hipMalloc3DArray_Negative_Non2DTextureGather", "", char, uchar2, short4, float2, float4) { #if HT_AMD diff --git a/catch/unit/memory/hipMallocArray.cc b/catch/unit/memory/hipMallocArray.cc index 33db8b8b1..6a75e4112 100644 --- a/catch/unit/memory/hipMallocArray.cc +++ b/catch/unit/memory/hipMallocArray.cc @@ -17,20 +17,21 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* -hipMallocArray API test scenarios -1. Basic Functionality -2. Negative Scenarios -3. Allocating Small and big chunk data -4. Multithreaded scenario -*/ - #include #include #include #include #include "hipArrayCommon.hh" +/** + * @addtogroup hipMallocArray hipMallocArray + * @{ + * @ingroup MemoryTest + * `hipMallocArray(hipArray** array, const hipChannelFormatDesc* desc, size_t width, + * size_t height __dparm(0), unsigned int flags __dparm(hipArrayDefault))` - + * Allocate an array on the device. + */ + static constexpr size_t NUM_W{4}; static constexpr size_t NUM_H{4}; static constexpr size_t BIGNUM_W{100}; @@ -67,6 +68,18 @@ static void MallocArray_DiffSizes(int gpu) { } } +/** + * Test Description + * ------------------------ + * - Validate that allocation is successfully performed when + * multiple arrays of small and big chunks of float data are allocated. + * Test source + * ------------------------ + * - unit/memory/hipMallocArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocArray_DiffSizes") { CHECK_IMAGE_SUPPORT @@ -74,11 +87,19 @@ TEST_CASE("Unit_hipMallocArray_DiffSizes") { HIP_CHECK_THREAD_FINALIZE(); } -/* -This testcase verifies the hipMallocArray API in multithreaded -scenario by launching threads in parallel on multiple GPUs -and verifies the hipMallocArray API with small and big chunks data -*/ +/** + * Test Description + * ------------------------ + * - Verifies the API in multithreaded scenario by launching + * threads in parallel on multiple GPUs. + * - Verifies the hipMallocArray API with small and big chunks data. + * Test source + * ------------------------ + * - unit/memory/hipMallocArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocArray_MultiThread") { CHECK_IMAGE_SUPPORT @@ -373,8 +394,19 @@ void testArrayAsSurface(hipArray_t arrayPtr, const size_t width, const size_t he HIP_CHECK(hipFree(device_data)); } -// The happy path of a default array and a SurfaceLoadStore array should work -// Selection of types chosen to reduce compile times +/** + * Test Description + * ------------------------ + * - Validates that array allocation is working correctly for different types + * of data when texture is generated from it and reading from texture is successful. + * Test source + * ------------------------ + * - unit/memory/hipMallocArray.cc + * Test requirements + * ------------------------ + * - Platform specific (NVIDIA) + * - HIP_VERSION >= 5.2 + */ TEMPLATE_TEST_CASE("Unit_hipMallocArray_happy", "", uint, int, int4, ushort, short2, char, uchar2, char4, float, float2, float4) { CHECK_IMAGE_SUPPORT @@ -426,8 +458,20 @@ TEMPLATE_TEST_CASE("Unit_hipMallocArray_happy", "", uint, int, int4, ushort, sho HIP_CHECK(hipFreeArray(arrayPtr)); } -// Arrays can be up to the size of maxTexture* but no bigger -// EXSWCPHIPT-71 - no equivalent value for maxSurface and maxTexture2DGather. +/** + * Test Description + * ------------------------ + * - Validates that array allocation is working correctly for different + * types of data when its width/height are set to maximal size. + * - Maximal size corresponds to maximal texture width/height. + * - This test can fail with `hipErrorOutOfMemory` + * Test source + * ------------------------ + * - unit/memory/hipMallocArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEMPLATE_TEST_CASE("Unit_hipMallocArray_MaxTexture_Default", "", uint, int4, ushort, short2, char, char4, float2, float4) { CHECK_IMAGE_SUPPORT @@ -486,8 +530,19 @@ TEMPLATE_TEST_CASE("Unit_hipMallocArray_MaxTexture_Default", "", uint, int4, ush } } - -// Arrays with channels of different size are not allowed. +/** + * Test Description + * ------------------------ + * - Validates handling when channel sizes are different: + * - Expected output (AMD): return `hipErrorInvalidValue` + * - Expected output (NVIDIA): return `hipErrorUnknown` + * Test source + * ------------------------ + * - unit/memory/hipMallocArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocArray_Negative_DifferentChannelSizes") { CHECK_IMAGE_SUPPORT @@ -527,7 +582,18 @@ TEST_CASE("Unit_hipMallocArray_Negative_DifferentChannelSizes") { #endif } -// Zero-width array is not supported +/** + * Test Description + * ------------------------ + * - Validates handling when width is zero: + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMallocArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocArray_Negative_ZeroWidth") { CHECK_IMAGE_SUPPORT @@ -543,7 +609,18 @@ TEST_CASE("Unit_hipMallocArray_Negative_ZeroWidth") { hipErrorInvalidValue); } -// Providing the array pointer as nullptr should return an error +/** + * Test Description + * ------------------------ + * - Validates handling when the output pointer to array is `nullptr`: + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMallocArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocArray_Negative_NullArrayPtr") { CHECK_IMAGE_SUPPORT @@ -552,7 +629,18 @@ TEST_CASE("Unit_hipMallocArray_Negative_NullArrayPtr") { HIP_CHECK_ERROR(hipMallocArray(nullptr, &desc, 1024, 0, hipArrayDefault), hipErrorInvalidValue); } -// Providing the desc pointer as nullptr should return an error +/** + * Test Description + * ------------------------ + * - Validates handling when descriptor pointer is `nullptr`: + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMallocArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocArray_Negative_NullDescPtr") { CHECK_IMAGE_SUPPORT @@ -561,7 +649,18 @@ TEST_CASE("Unit_hipMallocArray_Negative_NullDescPtr") { hipErrorInvalidValue); } -// Inappropriate but related flags should still return an error +/** + * Test Description + * ------------------------ + * - Validates handling when flags are not valid for 1D and 2D: + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMallocArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocArray_Negative_BadFlags") { CHECK_IMAGE_SUPPORT @@ -589,7 +688,19 @@ TEST_CASE("Unit_hipMallocArray_Negative_BadFlags") { } } -// 8-bit float channels are not supported +/** + * Test Description + * ------------------------ + * - Vallidates handling when descriptor is set for 8-bit float channels: + * - Expected output (AMD): return `hipErrorInvalidValue` + * - Expected output (NVIDIA): return `hipErrorUnknown` + * Test source + * ------------------------ + * - unit/memory/hipMallocArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEMPLATE_TEST_CASE("Unit_hipMallocArray_Negative_8bitFloat", "", float, float2, float4) { CHECK_IMAGE_SUPPORT @@ -609,7 +720,19 @@ TEMPLATE_TEST_CASE("Unit_hipMallocArray_Negative_8bitFloat", "", float, float2, #endif } -// Only 8, 16, and 32 bit channels are supported +/** + * Test Description + * ------------------------ + * - Validates handling when channel sizes in descriptor are not valid: + * - Expected output (AMD): return `hipErrorInvalidValue` + * - Expected output (NVIDIA): return `hipErrorUnknown` + * Test source + * ------------------------ + * - unit/memory/hipMallocArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocArray_Negative_BadNumberOfBits") { CHECK_IMAGE_SUPPORT @@ -637,7 +760,19 @@ TEST_CASE("Unit_hipMallocArray_Negative_BadNumberOfBits") { #endif } -// creating elements with 3 channels is not supported. +/** + * Test Description + * ------------------------ + * - Validates handling when channel number in descriptor is equal t o 3: + * - Expected output (AMD): return `hipErrorInvalidValue` + * - Expected output (NVIDIA): return `hipErrorUnknown` + * Test source + * ------------------------ + * - unit/memory/hipMallocArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocArray_Negative_3ChannelElement") { CHECK_IMAGE_SUPPORT @@ -665,7 +800,19 @@ TEST_CASE("Unit_hipMallocArray_Negative_3ChannelElement") { #endif } -// The bit channel description should not allow any channels after a zero channel +/** + * Test Description + * ------------------------ + * - Validates handling when there is a channel after a zero chanel is set as parameter: + * - Expected output (AMD): return `hipErrorInvalidValue` + * - Expected output (NVIDIA): return `hipErrorUnknown` + * Test source + * ------------------------ + * - unit/memory/hipMallocArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocArray_Negative_ChannelAfterZeroChannel") { CHECK_IMAGE_SUPPORT @@ -694,7 +841,19 @@ TEST_CASE("Unit_hipMallocArray_Negative_ChannelAfterZeroChannel") { #endif } -// The channel format should be one of the defined formats +/** + * Test Description + * ------------------------ + * - Validates handling when channel format in descriptor is not valid: + * - Expected output (AMD): return `hipErrorInvalidValue` + * - Expected output (NVIDIA): return `hipErrorUnknown` + * Test source + * ------------------------ + * - unit/memory/hipMallocArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocArray_Negative_InvalidChannelFormat") { CHECK_IMAGE_SUPPORT @@ -719,8 +878,18 @@ TEST_CASE("Unit_hipMallocArray_Negative_InvalidChannelFormat") { #endif } - -// hipMallocArray should handle the max numeric value gracefully. +/** + * Test Description + * ------------------------ + * - Validates handling when width/height sizes are equal to a maximal possible numerical value: + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMallocArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocArray_Negative_NumericLimit") { CHECK_IMAGE_SUPPORT diff --git a/catch/unit/memory/hipMallocConcurrency.cc b/catch/unit/memory/hipMallocConcurrency.cc index 6481885f2..46d47b5e4 100644 --- a/catch/unit/memory/hipMallocConcurrency.cc +++ b/catch/unit/memory/hipMallocConcurrency.cc @@ -17,36 +17,6 @@ OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/** -Testcase Scenarios : - - 1) Test hipMalloc() api passing zero size and confirming *ptr returning - nullptr. Also pass nullptr to hipFree() api. - - 2) Pass maximum value of size_t for hipMalloc() api and make sure appropriate - error is returned. - - 3) Check for hipMalloc() error code, passing invalid/null pointer. - - 4) Regress hipMalloc()/hipFree() in loop for bigger chunk of allocation - with adequate number of iterations and later test for kernel execution on - default gpu. - - 5) Regress hipMalloc()/hipFree() in loop while allocating smaller chunks - keeping maximum number of iterations and then run kernel code on default - gpu, perfom data validation. - - 6) Check hipMalloc() api adaptability when app creates small chunks of memory - continuously, stores it for later use and then frees it at later point - of time. - - 7) Multithread Scenario : Exercise hipMalloc() api parellely on all gpus from - multiple threads and regress the api. - - 8) Validate memory usage with hipMemGetInfo() while regressing hipMalloc() - api. Check for any possible memory leaks. -*/ - #include #include #include @@ -55,6 +25,11 @@ Testcase Scenarios : #include #include +/** + * @addtogroup hipMalloc hipMalloc + * @{ + * @ingroup MemoryTest + */ /* Buffer size for bigger chunks in alloc/free cycles */ static constexpr auto BuffSizeBC = 5 * 1024 * 1024; @@ -117,9 +92,7 @@ static bool validateMemoryOnGPU(int gpu) { } -/** - * Regress memory allocation and free in loop - */ +// Regress memory allocation and free in loop static bool regressAllocInLoop(int gpu) { size_t numBytes; int i = 0; @@ -181,10 +154,7 @@ static bool validateMemoryOnGpuMThread(int gpu) { return TestPassed; } -/** - * Regress memory allocation and free in loop - * In Multithreaded Environment - */ +// Regress memory allocation and free in loop in Multithreaded Environment static bool regressAllocInLoopMthread(int gpu) { size_t numBytes; int i = 0; @@ -209,17 +179,32 @@ static bool regressAllocInLoopMthread(int gpu) { return true; } -/* - * Thread func to regress alloc and check data consistency - */ +// Thread func to regress alloc and check data consistency static void threadFunc(int gpu) { g_thTestPassed = regressAllocInLoopMthread(gpu) && validateMemoryOnGpuMThread(gpu); UNSCOPED_INFO("thread execution status on gpu" << gpu << ":" << g_thTestPassed.load()); } - -/* Performs Argument Validation of api */ +/** + * Test Description + * ------------------------ + * - Validates arguments handling: + * -# When allocation size is zero + * - Expected output: address pointer is `nullptr` + * -# When calling free on `nullptr` + * - Expected output: return `hipSuccess` + * -# When output pointer to the address is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When allocation size is max size of `size_t` + * - Expecterd output: return `hipErrorMemoryAllocation` + * Test source + * ------------------------ + * - unit/memory/hipMallocConcurrency.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMalloc_ArgumentValidation") { int* ptr{nullptr}; @@ -247,6 +232,19 @@ TEST_CASE("Unit_hipMalloc_ArgumentValidation") { * Regress hipMalloc()/hipFree() in loop for bigger chunks and * smaller chunks of memory allocation */ +/** + * Test Description + * ------------------------ + * - Regress memory allocation and deallocation in loop for bigger + * and smaller chunks of memory allocation. + * - Execute kernels on the default device. + * Test source + * ------------------------ + * - unit/memory/hipMallocConcurrency.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMalloc_LoopRegressionAllocFreeCycles") { int devCnt = 0; @@ -259,10 +257,16 @@ TEST_CASE("Unit_hipMalloc_LoopRegressionAllocFreeCycles") { } /** - * Application Behavior Modelling. - * Check hipMalloc() api adaptability when app creates small chunks of memory - * continuously, stores it for later use and then frees it at later point - * of time. + * Test Description + * ------------------------ + * - Regress memory allocation and deallocation in loop smaller chunks of memory allocation. + * - Execute kernels on the default device. + * Test source + * ------------------------ + * - unit/memory/hipMallocConcurrency.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipMalloc_AllocateAndPoolBuffers") { size_t avail{0}, tot{0}; @@ -300,10 +304,18 @@ TEST_CASE("Unit_hipMalloc_AllocateAndPoolBuffers") { REQUIRE(ret == true); } - /** - * Exercise hipMalloc() api parellely on all gpus from - * multiple threads and regress the api. + * Test Description + * ------------------------ + * - Allocate memory on all devices, paralelly from multiple threads. + * Test source + * ------------------------ + * - unit/memory/hipMallocConcurrency.cc + * Test requirements + * ------------------------ + * - Multi-device + * - Multi-threaded device + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipMalloc_Multithreaded_MultiGPU") { std::vector threadlist; diff --git a/catch/unit/memory/hipMallocManaged.cc b/catch/unit/memory/hipMallocManaged.cc index 1b9766ffa..1122934eb 100644 --- a/catch/unit/memory/hipMallocManaged.cc +++ b/catch/unit/memory/hipMallocManaged.cc @@ -17,19 +17,18 @@ THE SOFTWARE. */ -/* Test Case Description: - 1) This testcase verifies the hipMallocManaged basic scenario - supported on - all devices - 2) This testcase verifies the hipMallocManaged advanced scenario - supported - only on HMM enabled devices - 3) This testcase verifies that hipMallocManaged returns an OutOfMemory error - for allocations much larger than the available memory - supported on all devices -*/ - #include "hipMallocManagedCommon.hh" #include #include +/** + * @addtogroup hipMallocManaged hipMallocManaged + * @{ + * @ingroup MemoryMTest + * `hipMallocManaged(void** dev_ptr, + * size_t size, unsigned int flags __dparm(hipMemAttachGlobal))` - + * Allocates memory that will be automatically managed by HIP. + */ // Kernel functions @@ -57,6 +56,19 @@ static unsigned threadsPerBlock{256}; /* This testcase verifies the hipMallocManaged basic scenario - supported on all devices */ +/** + * Test Description + * ------------------------ + * - Allocates managed memory on the device for several arrays. + * - Verifies that the allocation is successfully performed. + * Test source + * ------------------------ + * - unit/memory/hipMallocManaged.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocManaged_Basic") { auto managed = HmmAttrPrint(); if (managed != 1) { @@ -72,9 +84,20 @@ TEST_CASE("Unit_hipMallocManaged_Basic") { HIP_CHECK(hipMallocManaged(&C, numElements * sizeof(float))); } -/* - This testcase verifies the hipMallocManaged advanced scenario - supported only on HMM enabled - devices +/** + * Test Description + * ------------------------ + * - Allocates managed memory on the device for several arrays. + * - Verifies that the allocation is successfully performed. + * - Launches kernel and performs event synchronization. + * - Validates the results from kernel calculation. + * Test source + * ------------------------ + * - unit/memory/hipMallocManaged.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipMallocManaged_Advanced") { auto managed = HmmAttrPrint(); @@ -141,9 +164,17 @@ TEST_CASE("Unit_hipMallocManaged_Advanced") { REQUIRE(maxError != 0.0f); } -/* - This testcase verifies that hipMallocManaged returns an OutOfMemory error for allocations much - larger than the available memory - supported on all devices +/** + * Test Description + * ------------------------ + * - Validates that allocation fails if the requested size is too large. + * - Expected output: return `hipErrorOutOfMemory` + * Test source + * ------------------------ + * - unit/memory/hipMallocManaged.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipMallocManaged_Large") { auto managed = HmmAttrPrint(); diff --git a/catch/unit/memory/hipMallocManagedFlagsTst.cc b/catch/unit/memory/hipMallocManagedFlagsTst.cc index 264320c48..7de1998aa 100644 --- a/catch/unit/memory/hipMallocManagedFlagsTst.cc +++ b/catch/unit/memory/hipMallocManagedFlagsTst.cc @@ -23,6 +23,12 @@ THE SOFTWARE. #include "hipMallocManagedCommon.hh" #include +/** + * @addtogroup hipMallocManaged hipMallocManaged + * @{ + * @ingroup MemoryMTest + */ + // Kernel function __global__ void MallcMangdFlgTst(int n, float* x, float* y) { int index = blockIdx.x * blockDim.x + threadIdx.x; @@ -30,7 +36,22 @@ __global__ void MallcMangdFlgTst(int n, float* x, float* y) { for (int i = index; i < n; i += stride) y[i] = x[i] * x[i]; } -// The following section tests working of hipMallocManaged with flag parameters +/** + * Test Description + * ------------------------ + * - Validates managed memory with attach global flag. + * - Allocates managed memory. + * - Launches calculation kernel. + * - Synchronizes calculation with stream. + * - Verifies results. + * Test source + * ------------------------ + * - unit/memory/hipMallocManagedFlagsTst.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocManaged_FlgParam") { auto managed = HmmAttrPrint(); @@ -118,8 +139,21 @@ TEST_CASE("Unit_hipMallocManaged_FlgParam") { REQUIRE(IfTestPassed); } -// The following function tests Memory access allocated using hipMallocManaged -// in multiple streams +/** + * Test Description + * ------------------------ + * - Validates managed memory while using multiple streams. + * - Allocates managed memory. + * - Launches calculation kernel. + * - Synchronizes calculation with stream. + * - Verifies results. + * Test source + * ------------------------ + * - unit/memory/hipMallocManagedFlagsTst.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocManaged_AccessMultiStream") { auto managed = HmmAttrPrint(); diff --git a/catch/unit/memory/hipMallocManaged_MultiScenario.cc b/catch/unit/memory/hipMallocManaged_MultiScenario.cc index f6809fb93..24e65e190 100644 --- a/catch/unit/memory/hipMallocManaged_MultiScenario.cc +++ b/catch/unit/memory/hipMallocManaged_MultiScenario.cc @@ -17,28 +17,23 @@ THE SOFTWARE. */ -/* - This testcase verifies the hipMallocManaged API in the following scenarios - 1. MultiChunkSingleDevice Scenario - 2. MultiChunkMultiDevice Scenario - 3. Negative Scenarios - 4. OverSubscription scenario - 5. Device context change - 6. Multiple Pointers - */ - #include "hipMallocManagedCommon.hh" #include #include #include +/** + * @addtogroup hipMallocManaged hipMallocManaged + * @{ + * @ingroup MemoryMTest + */ + const size_t MAX_GPU{256}; static size_t N{4 * 1024 * 1024}; static unsigned blocksPerCU{6}; static unsigned threadsPerBlock{256}; #define INIT_VAL 123 - /* * Kernel function to perform addition operation. */ @@ -70,8 +65,19 @@ void HostKernelDouble(float* Hmm, float* hPtr, size_t n) { } } -/* - This testcase verifies the concurrent access of hipMallocManaged Memory on host and device. +/** + * Test Description + * ------------------------ + * - Verifies concurrent access of managed memory on host and device. + * - Launches kernel and validates results. + * Test source + * ------------------------ + * - unit/memory/hipMallocManaged_MultiScenario.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - Multi-threaded device + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipMallocManaged_HostDeviceConcurrent") { auto managed = HmmAttrPrint(); @@ -104,11 +110,20 @@ TEST_CASE("Unit_hipMallocManaged_HostDeviceConcurrent") { HIP_CHECK(hipFree(Hmm)); } -// The following Test case tests the following scenario: -// A large chunk of hipMallocManaged() memory(Hmm) is created -// Equal parts of Hmm is accessed and -// kernel is launched on acessed chunk of hmm memory -// and checks if there are any inconsistencies or access issues +/** + * Test Description + * ------------------------ + * - A large chunk of managed memory is allocated. + * - Equal parts of memory are accessed and kernel is launched on chunks. + * - Verifies that there are no inconsistencies or access issues. + * Test source + * ------------------------ + * - unit/memory/hipMallocManaged_MultiScenario.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocManaged_MultiChunkSingleDevice") { auto managed = HmmAttrPrint(); if (managed != 1) { @@ -156,11 +171,22 @@ TEST_CASE("Unit_hipMallocManaged_MultiChunkSingleDevice") { delete[] Ah; } -// The following Test case tests the following scenario: -// A large chunk of hipMallocManaged() memory(Hmm) is created -// Equal parts of Hmm is accessed on available gpus and -// kernel is launched on acessed chunk of hmm memory -// and checks if there are any inconsistencies or access issues +/** + * Test Description + * ------------------------ + * - A large chunk of managed memory is allocated. + * - Equal parts of managed memory is accessed on available GPUs. + * - Kernel is launched on accessed chunk of managed memory. + * - Verifies that there are no inconsistencies or access issues. + * Test source + * ------------------------ + * - unit/memory/hipMallocManaged_MultiScenario.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - Multi-device + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocManaged_MultiChunkMultiDevice") { auto managed = HmmAttrPrint(); if (managed != 1) { @@ -216,7 +242,20 @@ TEST_CASE("Unit_hipMallocManaged_MultiChunkMultiDevice") { delete[] Ah; } -// The following tests oversubscription hipMallocManaged() api +/** + * Test Description + * ------------------------ + * - Verifies oversubscription of the managed memory. + * - Expected output: return `hipErrorOutOfMemory` + * Test source + * ------------------------ + * - unit/memory/hipMallocManaged_MultiScenario.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - Platform specific (AMD) + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocManaged_OverSubscription") { auto managed = HmmAttrPrint(); if (managed != 1) { @@ -242,8 +281,37 @@ TEST_CASE("Unit_hipMallocManaged_OverSubscription") { HIP_CHECK(hipMallocManaged(&A, (free + 1), hipMemAttachGlobal)); } -// The following test does negative testing of hipMallocManaged() api -// by passing invalid values and check if the behavior is as expected +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When output pointer to the device pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When allocation size is zero, with attach global flag + * - Expected output (AMD): return `hipErrorInvalidValue` + * - Expected output (NVIDIA): return `hipSuccess` + * -# When outputp pointer to the device pointer is `nullptr` + * with attach host flag + * - Expected output: return `hipErrorInvalidValue` + * -# When allocation size is zero with attach host flag + * - Expected output (AMD): return `hipErrorInvalidValue` + * - Expected output (NVIDIA): return `hipSuccess` + * -# When output pointer to the device pointer is `nullptr` + * with size and flags set to zero + * - Expected output: return `hipErrorInvalidValue` + * -# When flag is set to the large invalid value + * - Expected output: return `hipErrorInvalidValue` + * -# When flag is set zero + * - Expected output: return `hipErrorInvalidValue` + * -# When flag is set to the attach host and attach global, both + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMallocManaged_MultiScenario.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocManaged_Negative") { void* A; size_t total = 0, free = 0; @@ -301,9 +369,20 @@ TEST_CASE("Unit_hipMallocManaged_Negative") { } } -// Allocate two pointers using hipMallocManaged(), initialize, -// then launch kernel using these pointers directly and -// later validate the content without using any Memcpy. +/** + * Test Description + * ------------------------ + * - Allocate two pointers to the managed memory. + * - Launch kernel using pointers directly. + * - Validate the content without using any memory copying. + * Test source + * ------------------------ + * - unit/memory/hipMallocManaged_MultiScenario.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEMPLATE_TEST_CASE("Unit_hipMallocManaged_TwoPointers", "", int, float, double) { auto managed = HmmAttrPrint(); if (managed != 1) { @@ -339,11 +418,22 @@ TEMPLATE_TEST_CASE("Unit_hipMallocManaged_TwoPointers", "", int, float, double) } } -// In the following test, a memory is created using hipMallocManaged() by -// setting a device and verified if it is accessible when the context is set -// to all other devices. This include verification and Device two Device -// transfers and kernel launch o discover if there any access issues. - +/** + * Test Description + * ------------------------ + * - Managed memory chunk is allocated for each device. + * - Verifies that memory is accessible when the context is set to all + * other devices. + * - Launches kernel to discover if there are any access issues. + * Test source + * ------------------------ + * - unit/memory/hipMallocManaged_MultiScenario.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - Multi-device + * - HIP_VERSION >= 5.2 + */ TEMPLATE_TEST_CASE("Unit_hipMallocManaged_DeviceContextChange", "", unsigned char, int, float, double) { auto managed = HmmAttrPrint(); diff --git a/catch/unit/memory/hipMallocMipmappedArray.cc b/catch/unit/memory/hipMallocMipmappedArray.cc index 43da90a3e..67fbf093d 100644 --- a/catch/unit/memory/hipMallocMipmappedArray.cc +++ b/catch/unit/memory/hipMallocMipmappedArray.cc @@ -17,18 +17,20 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* -hipMallocMipmappedArray API test scenarios -1. Basic Functionality -2. Negative Scenarios -3. Allocating Small and big chunk data -4. Multithreaded scenario -*/ - #include #include #include "hipArrayCommon.hh" +/** + * @addtogroup hipMallocMipmappedArray hipMallocMipmappedArray + * @{ + * @ingroup MemoryTest + * `hipMallocMipmappedArray(hipMipmappedArray_t *mipmappedArray, + * const struct hipChannelFormatDesc* desc, struct hipExtent extent, + * unsigned int numLevels, unsigned int flags __dparm(0))` - + * Allocate a mipmapped array on the device. + */ + static constexpr auto ARRAY_SIZE{4}; static constexpr auto BIG_ARRAY_SIZE{100}; static constexpr auto ARRAY_LOOP{100}; @@ -74,17 +76,38 @@ static void MallocMipmappedArray_DiffSizes(int gpu) { } } } - +/** + * Test Description + * ------------------------ + * - Validates that mipmapped array can be created correctly when multiple arrays + * of small and big chunks of float data are allocated. + * Test source + * ------------------------ + * - unit/memory/hipMallocMipmappedArray.cc + * Test requirements + * ------------------------ + * - Host specific (WINDOWS) + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocMipmappedArray_DiffSizes") { MallocMipmappedArray_DiffSizes(0); HIP_CHECK_THREAD_FINALIZE(); } -/* -This testcase verifies the hipMallocMipmappedArray API in multithreaded -scenario by launching threads in parallel on multiple GPUs -and verifies the hipMallocMipmappedArray API with small and big chunks data -*/ +/** + * Test Description + * ------------------------ + * - Validates that mipmapped array can be created correctly when multiple arrays + * of small and big chunks of float data are allocated. + * - Executes in multiple threads on separate devices. + * Test source + * ------------------------ + * - unit/memory/hipMallocMipmappedArray.cc + * Test requirements + * ------------------------ + * - Host specific (WINDOWS) + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocMipmappedArray_MultiThread") { std::vector threadlist; int devCnt = 0; @@ -130,7 +153,19 @@ void checkMipmappedArrayIsExpected(hipArray_t level_array, #endif } } // namespace - +/** + * Test Description + * ------------------------ + * - Validates that mipmapped array allocation is working correctly for different + * types of data and supported flags. + * Test source + * ------------------------ + * - unit/memory/hipMallocMipmappedArray.cc + * Test requirements + * ------------------------ + * - Host specific (WINDOWS) + * - HIP_VERSION >= 5.2 + */ TEMPLATE_TEST_CASE("Unit_hipMallocMipmappedArray_happy", "", char, uint2, int4, short4, float) { hipMipmappedArray_t array; const auto desc = hipCreateChannelDesc(); @@ -184,7 +219,19 @@ hipExtent makeMipmappedExtent(unsigned int flag, size_t s) { return make_hipExtent(s, s, s); } -// Providing the array pointer as nullptr should return an error +/** + * Test Description + * ------------------------ + * - Validates handling when output pointer to mipmapped array is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMallocMipmappedArray.cc + * Test requirements + * ------------------------ + * - Host specific (WINDOWS) + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocMipmappedArray_Negative_NullArrayPtr") { hipChannelFormatDesc desc = hipCreateChannelDesc(); unsigned int numLevels = 1; @@ -196,7 +243,19 @@ TEST_CASE("Unit_hipMallocMipmappedArray_Negative_NullArrayPtr") { hipErrorInvalidValue); } -// Providing the description pointer as nullptr should return an error +/** + * Test Description + * ------------------------ + * - Validates handling when descriptor is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMallocMipmappedArray.cc + * Test requirements + * ------------------------ + * - Host specific (WINDOWS) + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocMipmappedArray_Negative_NullDescPtr") { constexpr size_t s = 6; // 6 to keep cubemap happy unsigned int numLevels = 1; @@ -209,7 +268,19 @@ TEST_CASE("Unit_hipMallocMipmappedArray_Negative_NullDescPtr") { hipErrorInvalidValue); } -// Zero width arrays are not allowed +/** + * Test Description + * ------------------------ + * - Validates handling when array width is zero + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMallocMipmappedArray.cc + * Test requirements + * ------------------------ + * - Host specific (WINDOWS) + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocMipmappedArray_Negative_ZeroWidth") { constexpr size_t s = 6; // 6 to keep cubemap happy unsigned int numLevels = 1; @@ -222,7 +293,19 @@ TEST_CASE("Unit_hipMallocMipmappedArray_Negative_ZeroWidth") { hipErrorInvalidValue); } -// Zero height arrays are only allowed for 1D arrays and layered arrays +/** + * Test Description + * ------------------------ + * - Validates handling when array height is zero + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMallocMipmappedArray.cc + * Test requirements + * ------------------------ + * - Host specific (WINDOWS) + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocMipmappedArray_Negative_ZeroHeight") { constexpr size_t s = 6; // 6 to keep cubemap happy unsigned int numLevels = 1; @@ -241,6 +324,19 @@ TEST_CASE("Unit_hipMallocMipmappedArray_Negative_ZeroHeight") { } } +/** + * Test Description + * ------------------------ + * - Validates handling when flag values in descriptor are invalid + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMallocMipmappedArray.cc + * Test requirements + * ------------------------ + * - Host specific (WINDOWS) + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocMipmappedArray_Negative_InvalidFlags") { constexpr size_t s = 6; // 6 to keep cubemap happy unsigned int numLevels = 1; @@ -282,12 +378,42 @@ void testInvalidDescriptionMipmapped(hipChannelFormatDesc desc) { expectedError); } +/** + * Test Description + * ------------------------ + * - Validates handling when channel format descriptor + * is not valid + * - Expected output (AMD): return `hipErrorInvalidValue` + * - Expected output (NVIDIA): return `hipErrorUnknown` + * Test source + * ------------------------ + * - unit/memory/hipMallocMipmappedArray.cc + * Test requirements + * ------------------------ + * - Host specific (WINDOWS) + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocMipmappedArray_Negative_InvalidFormat") { hipChannelFormatDesc desc = hipCreateChannelDesc(); desc.f = GENERATE(hipChannelFormatKindNone, 0xBEEF); testInvalidDescriptionMipmapped(desc); } +/** + * Test Description + * ------------------------ + * - Validates handling when there is a channel after a zero channel + * is set as parameter + * - Expected output (AMD): return `hipErrorInvalidValue` + * - Expected output (NVIDIA): return `hipErrorUnknown` + * Test source + * ------------------------ + * - unit/memory/hipMallocMipmappedArray.cc + * Test requirements + * ------------------------ + * - Host specific (WINDOWS) + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocMipmappedArray_Negative_BadChannelLayout") { const int bits = GENERATE(8, 16, 32); const hipChannelFormatKind formatKind = @@ -309,6 +435,20 @@ TEST_CASE("Unit_hipMallocMipmappedArray_Negative_BadChannelLayout") { testInvalidDescriptionMipmapped(desc); } +/** + * Test Description + * ------------------------ + * - Validates handling when descriptor is set to 8-bit float channels + * - Expected output (AMD): return `hipErrorInvalidValue` + * - Expected output (NVIDIA): return `hipErrorUnknown` + * Test source + * ------------------------ + * - unit/memory/hipMallocMipmappedArray.cc + * Test requirements + * ------------------------ + * - Host specific (WINDOWS) + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocMipmappedArray_Negative_8BitFloat") { hipChannelFormatDesc desc = GENERATE(hipCreateChannelDesc(8, 0, 0, 0, hipChannelFormatKindFloat), hipCreateChannelDesc(8, 8, 0, 0, hipChannelFormatKindFloat), @@ -317,6 +457,20 @@ TEST_CASE("Unit_hipMallocMipmappedArray_Negative_8BitFloat") { testInvalidDescriptionMipmapped(desc); } +/** + * Test Description + * ------------------------ + * - Validates handling when channel sizes are different + * - Expected output (AMD): return `hipErrorInvalidValue` + * - Expected output (NVIDIA): return `hipErrorUnknown` + * Test source + * ------------------------ + * - unit/memory/hipMallocMipmappedArray.cc + * Test requirements + * ------------------------ + * - Host specific (WINDOWS) + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocMipmappedArray_Negative_DifferentChannelSizes") { const int bitsX = GENERATE(8, 16, 32); const int bitsY = GENERATE(8, 16, 32); @@ -340,6 +494,20 @@ TEST_CASE("Unit_hipMallocMipmappedArray_Negative_DifferentChannelSizes") { testInvalidDescriptionMipmapped(desc); } +/** + * Test Description + * ------------------------ + * - Validates handling when channel sizes in descriptor are not valid + * - Expected output (AMD): return `hipErrorInvalidValue` + * - Expected output (NVIDIA): return `hipErrorUnknown` + * Test source + * ------------------------ + * - unit/memory/hipMallocMipmappedArray.cc + * Test requirements + * ------------------------ + * - Host specific (WINDOWS) + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocMipmappedArray_Negative_BadChannelSize") { const int badBits = GENERATE(-1, 0, 10, 100); const hipChannelFormatKind formatKind = @@ -351,8 +519,20 @@ TEST_CASE("Unit_hipMallocMipmappedArray_Negative_BadChannelSize") { testInvalidDescriptionMipmapped(desc); } - -// hipMallocMipmappedArray should handle the max numeric value gracefully. +/** + * Test Description + * ------------------------ + * - Validates handling when width/height size are equal to a maximal possible + * numerical value + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMallocMipmappedArray.cc + * Test requirements + * ------------------------ + * - Host specific (WINDOWS) + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocMipmappedArray_Negative_NumericLimit") { hipMipmappedArray_t arrayPtr; unsigned int numLevels = 1; @@ -365,7 +545,21 @@ TEST_CASE("Unit_hipMallocMipmappedArray_Negative_NumericLimit") { hipErrorInvalidValue); } -// texture gather arrays are only allowed to be 2D +/** + * Test Description + * ------------------------ + * - Validates handling when descriptor for array with flag set to texture gather + * is set to represent 1D or 3D array for various types, which is not valid. + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMallocMipmappedArray.cc + * Test requirements + * ------------------------ + * - Platform specific (NVIDIA) + * - Host specific (WINDOWS) + * - HIP_VERSION >= 5.2 + */ TEMPLATE_TEST_CASE("Unit_hipMallocMipmappedArray_Negative_Non2DTextureGather", "", char, uchar2, float2) { #if HT_AMD @@ -384,6 +578,19 @@ TEMPLATE_TEST_CASE("Unit_hipMallocMipmappedArray_Negative_Non2DTextureGather", " hipErrorInvalidValue); } +/** + * Test Description + * ------------------------ + * - Validates handling when number of levels in channel are not valid + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMallocMipmappedArray.cc + * Test requirements + * ------------------------ + * - Host specific (WINDOWS) + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocMipmappedArray_Negative_NumLevels") { hipMipmappedArray_t array; constexpr size_t size = 6; @@ -396,6 +603,40 @@ TEST_CASE("Unit_hipMallocMipmappedArray_Negative_NumLevels") { hipErrorInvalidValue); } +/** + * End doxygen group hipMallocMipmappedArray. + * @} + */ + +/** + * @addtogroup hipGetMipmappedArrayLevel hipGetMipmappedArrayLevel + * @{ + * @ingroup MemoryTest + * `hipGetMipmappedArrayLevel(hipArray_t *levelArray, + * hipMipmappedArray_const_t mipmappedArray, unsigned int level)` - + * Gets a mipmap level of a HIP mipmapped array. + * ________________________ + * Test cases from other modules: + * - @ref Unit_hipMallocMipmappedArray_happy + * - @ref Unit_hipMallocMipmappedArray_MaxTexture + */ + +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When level is not valid + * - Expected output: return `hipErrorInvalidValue` + * -# When mipmapped array is `nullptr` + * - Expected output: return `hipErrorInvalidResourceHandle` + * Test source + * ------------------------ + * - unit/memory/hipMallocMipmappedArray.cc + * Test requirements + * ------------------------ + * - Host specific (WINDOWS) + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipGetMipmappedArrayLevel_Negative") { constexpr size_t s = 6; unsigned int numLevels = 1; diff --git a/catch/unit/memory/hipMallocMngdMultiThread.cc b/catch/unit/memory/hipMallocMngdMultiThread.cc index a163e9a0a..ed80db8f2 100644 --- a/catch/unit/memory/hipMallocMngdMultiThread.cc +++ b/catch/unit/memory/hipMallocMngdMultiThread.cc @@ -23,6 +23,11 @@ THE SOFTWARE. #include "hipMallocManagedCommon.hh" #include +/** + * @addtogroup hipMallocManaged hipMallocManaged + * @{ + * @ingroup MemoryMTest + */ // Kernel functions __global__ void HmmMultiThread(int n, float* x, float* y) { @@ -284,6 +289,19 @@ static void AllocateHmmMemory(int flag, int device) { } } +/** + * Test Description + * ------------------------ + * - Validates behaviour of allocating managed memory from multiple threads. + * Test source + * ------------------------ + * - unit/memory/hipMallocMngdMultiThread.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - Multi-threaded device + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocManaged_MultiThread") { auto managed = HmmAttrPrint(); if (managed != 1) { @@ -336,8 +354,20 @@ TEST_CASE("Unit_hipMallocManaged_MultiThread") { REQUIRE(IfTestPassed); } -// The following test checks what happens when same Hmm memory is used to -// launch multiple threads over multiple gpus +/** + * Test Description + * ------------------------ + * - Validates the case when same host managed memory is used to launch + * multiple threads over multiple devices. + * Test source + * ------------------------ + * - unit/memory/hipMallocMngdMultiThread.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - Multi-device + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocManaged_MGpuMThread") { auto managed = HmmAttrPrint(); if (managed != 1) { @@ -380,6 +410,19 @@ TEST_CASE("Unit_hipMallocManaged_MGpuMThread") { // The following test checks what happens when multiple kernels are launched // with same Hmm memory +/** + * Test Description + * ------------------------ + * - Validates the case when multiple kernels are launched with + * the same host managed memory. + * Test source + * ------------------------ + * - unit/memory/hipMallocMngdMultiThread.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocManaged_MultiKrnlComnHmm") { auto managed = HmmAttrPrint(); if (managed != 1) { @@ -414,6 +457,19 @@ TEST_CASE("Unit_hipMallocManaged_MultiKrnlComnHmm") { // The following test checks what happens when multiple kernels are launched // with same hipMalloc() memory +/** + * Test Description + * ------------------------ + * - Validates the case when multiple kernels are launched with the same + * pageable memory. + * Test source + * ------------------------ + * - unit/memory/hipMallocMngdMultiThread.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocManaged_MultiKrnlComnMalloc") { auto managed = HmmAttrPrint(); if (managed != 1) { @@ -445,6 +501,20 @@ TEST_CASE("Unit_hipMallocManaged_MultiKrnlComnMalloc") { // The following section tests the scenario wherein multiple threads use their // own stream to launch kernel on common Hmm memory +/** + * Test Description + * ------------------------ + * - Validates the case when multiple treads use their own stream to launch kernel + * on common host memory management. + * Test source + * ------------------------ + * - unit/memory/hipMallocMngdMultiThread.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - Multi-threaded device + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocManaged_MultiThrdMultiStrm") { auto managed = HmmAttrPrint(); if (managed != 1) { @@ -474,9 +544,20 @@ TEST_CASE("Unit_hipMallocManaged_MultiThrdMultiStrm") { } } - -// The following section tests the scenario wherein two threads each use -// different kernel but common HMM memory +/** + * Test Description + * ------------------------ + * - Validates the case when two threads each use different kernel but common + * host managed memory. + * Test source + * ------------------------ + * - unit/memory/hipMallocMngdMultiThread.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - Multi-threaded device + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocManaged_TwoKrnlsComnHmmMem") { auto managed = HmmAttrPrint(); if (managed != 1) { diff --git a/catch/unit/memory/hipMallocPitch.cc b/catch/unit/memory/hipMallocPitch.cc index b3f61c437..579ee2d1a 100644 --- a/catch/unit/memory/hipMallocPitch.cc +++ b/catch/unit/memory/hipMallocPitch.cc @@ -34,10 +34,272 @@ THE SOFTWARE. #endif /** - * @brief Test hipMalloc3D, hipMallocPitch and hipMemAllocPitch with multiple input values. - * Checks that the memory has been allocated with the specified pitch and extent sizes. + * @addtogroup hipMallocPitch hipMallocPitch + * @{ + * @ingroup MemoryTest + * `hipMallocPitch(void** ptr, size_t* pitch, size_t width, size_t height)` - + * Allocates at least width (in bytes) * height bytes of linear memory. */ +static constexpr auto SMALLCHUNK_NUMW{4}; +static constexpr auto SMALLCHUNK_NUMH{4}; +static constexpr auto LARGECHUNK_NUMW{1025}; +static constexpr auto LARGECHUNK_NUMH{1000}; +static constexpr auto NUM_W{10}; +static constexpr auto NUM_H{10}; +static constexpr auto COLUMNS{8}; +static constexpr auto ROWS{8}; +static constexpr auto CHUNK_LOOP{100}; + +template +__global__ void copy_var(T* A, T* B, + size_t ROWS, size_t pitch_A) { + for (uint64_t i = 0; i< ROWS*pitch_A; i= i+pitch_A) { + A[i] = B[i]; + } +} +template +static bool validateResult(T* A, T* B, size_t pitch_A) { + bool testResult = true; + for (uint64_t i=0; i < pitch_A*ROWS; i=i+pitch_A) { + if (A[i] != B[i]) { + testResult = false; + break; + } + } + return testResult; +} + +/* + * This API verifies memory allocations for small and + * bigger chunks of data. + * Two scenarios are verified in this API + * 1. SmallChunk: Allocates SMALLCHUNK_NUMW in a loop and + * releases the memory and verifies the meminfo. + * 2. LargeChunk: Allocates LARGECHUNK_NUMW in a loop and + * releases the memory and verifies the meminfo + * + * In both cases, the memory info before allocation and + * after releasing the memory should be the same + * + */ +template +static void MemoryAllocDiffSizes(int gpu) { + HIP_CHECK(hipSetDevice(gpu)); + std::vector array_size; + array_size.push_back(SMALLCHUNK_NUMH); + array_size.push_back(LARGECHUNK_NUMH); + for (auto &sizes : array_size) { + T* A_d[CHUNK_LOOP]; + size_t pitch_A = 0; + size_t width; + if (sizes == SMALLCHUNK_NUMH) { + width = SMALLCHUNK_NUMW * sizeof(T); + } else { + width = LARGECHUNK_NUMW * sizeof(T); + } + for (int i = 0; i < CHUNK_LOOP; i++) { + HIP_CHECK(hipMallocPitch(reinterpret_cast(&A_d[i]), + &pitch_A, width, sizes)); + } + for (int i = 0; i < CHUNK_LOOP; i++) { + HIP_CHECK(hipFree(A_d[i])); + } + } +} + +/*Thread Function */ +static void threadFunc(int gpu) { + MemoryAllocDiffSizes(gpu); +} + +/** + * Test Description + * ------------------------ + * - Verify basic scenario for different data types. + * Test source + * ------------------------ + * - unit/memory/hipMallocPitch.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEMPLATE_TEST_CASE("Unit_hipMallocPitch_Basic", "[hipMallocPitch]", int, unsigned int, float) { + CHECK_IMAGE_SUPPORT + + TestType* A_d; + size_t pitch_A = 0; + size_t width{NUM_W * sizeof(TestType)}; + REQUIRE(hipMallocPitch(reinterpret_cast(&A_d), + &pitch_A, width, NUM_H) == hipSuccess); + REQUIRE(width <= pitch_A); + HIP_CHECK(hipFree(A_d)); +} + +/** + * Test Description + * ------------------------ + * - Checks that memory is correctly freed after performing many + * allocations on diferent sizes. + * Test source + * ------------------------ + * - unit/memory/hipMallocPitch.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEMPLATE_TEST_CASE("Unit_hipMallocPitch_SmallandBigChunks", "[hipMallocPitch]", int, unsigned int, + float) { + CHECK_IMAGE_SUPPORT + + MemoryAllocDiffSizes(0); +} + +/** + * Test Description + * ------------------------ + * - Perform a pitch allocation and perform memcpy 2D with all direction arguments: + * -# Host -> Device + * -# Device -> Device + * -# Device -> Host + * Test source + * ------------------------ + * - unit/memory/hipMallocPitch.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEMPLATE_TEST_CASE("Unit_hipMallocPitch_Memcpy2D", "", int, float, double) { + CHECK_IMAGE_SUPPORT + + HIP_CHECK(hipSetDevice(0)); + TestType *A_h{nullptr}, *B_h{nullptr}, *C_h{nullptr}, *A_d{nullptr}, + *B_d{nullptr}; + size_t pitch_A = 0, pitch_B = 0; + size_t width{NUM_W * sizeof(TestType)}; + + // Allocating memory + HipTest::initArrays(nullptr, nullptr, nullptr, + &A_h, &B_h, &C_h, NUM_W*NUM_H, false); + HIP_CHECK(hipMallocPitch(reinterpret_cast(&A_d), + &pitch_A, width, NUM_H)); + HIP_CHECK(hipMallocPitch(reinterpret_cast(&B_d), + &pitch_B, width, NUM_H)); + + // Initialize the data + HipTest::setDefaultData(NUM_W*NUM_H, A_h, B_h, C_h); + + // Host to Device + HIP_CHECK(hipMemcpy2D(A_d, pitch_A, A_h, COLUMNS*sizeof(TestType), + COLUMNS*sizeof(TestType), ROWS, hipMemcpyHostToDevice)); + + // Performs D2D on same GPU device + HIP_CHECK(hipMemcpy2D(B_d, pitch_B, A_d, + pitch_A, COLUMNS*sizeof(TestType), + ROWS, hipMemcpyDeviceToDevice)); + + // hipMemcpy2D Device to Host + HIP_CHECK(hipMemcpy2D(B_h, COLUMNS*sizeof(TestType), B_d, pitch_B, + COLUMNS*sizeof(TestType), ROWS, + hipMemcpyDeviceToHost)); + + // Validating the result + REQUIRE(HipTest::checkArray(A_h, B_h, COLUMNS, ROWS) == true); + + + // DeAllocating the memory + HIP_CHECK(hipFree(A_d)); + HIP_CHECK(hipFree(B_d)); + HipTest::freeArrays(nullptr, nullptr, nullptr, + A_h, B_h, C_h, false); +} + +/** + * Test Description + * ------------------------ + * - Launches threads in parallel on all available devices. + * - Verifies that pitch can be allocated with small and big data chunks. + * Test source + * ------------------------ + * - unit/memory/hipMallocPitch.cc + * Test requirements + * ------------------------ + * - Multi-threaded device + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipMallocPitch_MultiThread", "") { + CHECK_IMAGE_SUPPORT + + std::vector threadlist; + int devCnt = 0; + + devCnt = HipTest::getDeviceCount(); + for (int i = 0; i < devCnt; i++) { + threadlist.push_back(std::thread(threadFunc, i)); + } + + for (auto &t : threadlist) { + t.join(); + } +} + +/** + * Test Description + * ------------------------ + * - Allocates pitched memory. + * - Launches the kernel and copies the data from allocated kernel variable + * to another kernel variable. + * - Validates the result. + * Test source + * ------------------------ + * - unit/memory/hipMallocPitch.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEMPLATE_TEST_CASE("Unit_hipMallocPitch_KernelLaunch", "", int, float, double) { + CHECK_IMAGE_SUPPORT + + HIP_CHECK(hipSetDevice(0)); + TestType *A_h{nullptr}, *B_h{nullptr}, *C_h{nullptr}, *A_d{nullptr}, + *B_d{nullptr}; + size_t pitch_A = 0, pitch_B = 0; + size_t width{NUM_W * sizeof(TestType)}; + + // Allocating memory + HipTest::initArrays(nullptr, nullptr, nullptr, + &A_h, &B_h, &C_h, NUM_W*NUM_H, false); + HIP_CHECK(hipMallocPitch(reinterpret_cast(&A_d), + &pitch_A, width, NUM_H)); + HIP_CHECK(hipMallocPitch(reinterpret_cast(&B_d), + &pitch_B, width, NUM_H)); + + // Host to Device + HIP_CHECK(hipMemcpy2D(A_d, pitch_A, A_h, COLUMNS*sizeof(TestType), + COLUMNS*sizeof(TestType), ROWS, hipMemcpyHostToDevice)); + + + hipLaunchKernelGGL(copy_var, dim3(1), dim3(1), + 0, 0, static_cast(A_d), + static_cast(B_d), ROWS, pitch_A); + HIP_CHECK(hipGetLastError()); + + + // hipMemcpy2D Device to Host + HIP_CHECK(hipMemcpy2D(B_h, COLUMNS*sizeof(TestType), B_d, pitch_B, + COLUMNS*sizeof(TestType), ROWS, + hipMemcpyDeviceToHost)); + + // Validating the result + validateResult(A_h, B_h, pitch_A); + + // DeAllocating the memory + HIP_CHECK(hipFree(A_d)); + HIP_CHECK(hipFree(B_d)); + HipTest::freeArrays(nullptr, nullptr, nullptr, + A_h, B_h, C_h, false); +} + static void validateMemory(void* devPtr, hipExtent extent, size_t pitch) { INFO("Width: " << extent.width << " Height: " << extent.height << " Depth: " << extent.depth); @@ -129,39 +391,20 @@ hipExtent generateExtent(AllocationApi api) { return extent; } - -TEST_CASE("Unit_hipMalloc3D_ValidatePitch") { - CHECK_IMAGE_SUPPORT - - hipPitchedPtr hipPitchedPtr; - hipExtent validExtent{generateExtent(AllocationApi::hipMalloc3D)}; - - HIP_CHECK(hipMalloc3D(&hipPitchedPtr, validExtent)); - validateMemory(hipPitchedPtr.ptr, validExtent, hipPitchedPtr.pitch); - HIP_CHECK(hipFree(hipPitchedPtr.ptr)); -} - -TEST_CASE("Unit_hipMemAllocPitch_ValidatePitch") { - CHECK_IMAGE_SUPPORT - - size_t pitch = 0; - hipDeviceptr_t ptr; - hipExtent validExtent{generateExtent(AllocationApi::hipMemAllocPitch)}; - unsigned int elementSizeBytes = GENERATE(4, 8, 16); - - if (validExtent.width == 0 || validExtent.height == 0) { - return; - } - //hipMemAllocPitch is driver API hence explicit init is required on NVidia plaform. - #ifdef __HIP_PLATFORM_NVIDIA__ - DriverContext ctx; - #endif - HIP_CHECK( - hipMemAllocPitch(&ptr, &pitch, validExtent.width, validExtent.height, elementSizeBytes)); - validateMemory(reinterpret_cast(ptr), validExtent, pitch); - HIP_CHECK(hipFree(reinterpret_cast(ptr))); -} - +/** + * Test Description + * ------------------------ + * - Validate that pitched memory is correctly allocated in conjunction with + * `hipMemCpy3D` and `hipMemSet3D`. + * - The test is run for a gamut of randomly generated extent values, as well + * as various element sizes in bytes. + * Test source + * ------------------------ + * - unit/memory/hipMallocPitch.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocPitch_ValidatePitch") { CHECK_IMAGE_SUPPORT @@ -173,58 +416,40 @@ TEST_CASE("Unit_hipMallocPitch_ValidatePitch") { HIP_CHECK(hipFree(ptr)); } -TEST_CASE("Unit_hipMalloc3D_Negative") { +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When pointer to the allocated memory is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When pointer to the pitch is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When pitch width is maximum `size_t` + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When pitch height is maximum `size_t` + * - Expected output: return `hipErrorOutOfMemory` + * Test source + * ------------------------ + * - unit/memory/hipMallocPitch.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipMallocPitch_Negative") { CHECK_IMAGE_SUPPORT + size_t pitch = 0; + void* ptr; + constexpr size_t maxSizeT = std::numeric_limits::max(); + SECTION("Invalid ptr") { - hipExtent validExtent{1, 1, 1}; - HIP_CHECK_ERROR(hipMalloc3D(nullptr, validExtent), hipErrorInvalidValue); + HIP_CHECK_ERROR(hipMallocPitch(nullptr, &pitch, 1, 1), hipErrorInvalidValue); } - hipPitchedPtr ptr; - constexpr size_t maxSizeT = std::numeric_limits::max(); - -#if HT_NVIDIA - //TODO-MATCH-ERRORCODE - SECTION("Max size_t width") { - hipExtent validExtent{maxSizeT, 1, 1}; - HIP_CHECK_ERROR(hipMalloc3D(&ptr, validExtent), hipErrorInvalidValue); - } -#endif - - SECTION("Max size_t height") { - hipExtent validExtent{1, maxSizeT, 1}; - HIP_CHECK_ERROR(hipMalloc3D(&ptr, validExtent), hipErrorOutOfMemory); - } - - SECTION("Max size_t depth") { - hipExtent validExtent{1, 1, maxSizeT}; - HIP_CHECK_ERROR(hipMalloc3D(&ptr, validExtent), hipErrorOutOfMemory); - } - -#if HT_NVIDIA - //TODO-MATCH-ERRORCODE - SECTION("Max size_t all dimensions") { - hipExtent validExtent{maxSizeT, maxSizeT, maxSizeT}; - HIP_CHECK_ERROR(hipMalloc3D(&ptr, validExtent), hipErrorInvalidValue); - } -#endif -} - -TEST_CASE("Unit_hipMallocPitch_Negative") { - CHECK_IMAGE_SUPPORT - - size_t pitch = 0; - void* ptr; - constexpr size_t maxSizeT = std::numeric_limits::max(); - - SECTION("Invalid ptr") { - HIP_CHECK_ERROR(hipMallocPitch(nullptr, &pitch, 1, 1), hipErrorInvalidValue); - } - - SECTION("Invalid pitch") { - HIP_CHECK_ERROR(hipMallocPitch(&ptr, nullptr, 1, 1), hipErrorInvalidValue); - } + SECTION("Invalid pitch") { + HIP_CHECK_ERROR(hipMallocPitch(&ptr, nullptr, 1, 1), hipErrorInvalidValue); + } #if HT_NVIDIA //TODO-MATCH-ERRORCODE @@ -238,6 +463,21 @@ TEST_CASE("Unit_hipMallocPitch_Negative") { } } +/** + * Test Description + * ------------------------ + * - Validates handling when pitch dimensions are zero: + * -# When pitch width is zero + * - Expected output: return `hipSuccess` and output pointer is `nullptr` + * -# When pitch height is zero + * - Expected output: return `hipSuccess` and output pointer is `nullptr` + * Test source + * ------------------------ + * - unit/memory/hipMallocPitch.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocPitch_Zero_Dims") { CHECK_IMAGE_SUPPORT @@ -255,6 +495,84 @@ TEST_CASE("Unit_hipMallocPitch_Zero_Dims") { } } +/** + * End doxygen group hipMallocPitch. + * @} + */ + +/** + * @addtogroup hipMemAllocPitch hipMemAllocPitch + * @{ + * @ingroup MemoryTest + * `hipMemAllocPitch(hipDeviceptr_t* dptr, size_t* pitch, size_t widthInBytes, + * size_t height, unsigned int elementSizeBytes)` - + * Allocates at least width (in bytes) * height bytes of linear memory. + */ + +/** + * Test Description + * ------------------------ + * - Validate that pitched memory is correctly allocated in + * conjunction with `hipMemcpy3D` and `hipMemset3D` + * - The test is run for a gamut of randomly generated extent values, + * as well as various element sizes in bytes. + * Test source + * ------------------------ + * - unit/memory/hipMallocPitch.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipMemAllocPitch_ValidatePitch") { + CHECK_IMAGE_SUPPORT + + size_t pitch = 0; + hipDeviceptr_t ptr; + hipExtent validExtent{generateExtent(AllocationApi::hipMemAllocPitch)}; + unsigned int elementSizeBytes = GENERATE(4, 8, 16); + + if (validExtent.width == 0 || validExtent.height == 0) { + return; + } + //hipMemAllocPitch is driver API hence explicit init is required on NVidia plaform. + #ifdef __HIP_PLATFORM_NVIDIA__ + DriverContext ctx; + #endif + HIP_CHECK( + hipMemAllocPitch(&ptr, &pitch, validExtent.width, validExtent.height, elementSizeBytes)); + validateMemory(reinterpret_cast(ptr), validExtent, pitch); + HIP_CHECK(hipFree(reinterpret_cast(ptr))); +} + +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When element size bytes are not valid + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When width is zero + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When height is zero + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When output pointer to the allocated memory is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When pointer to the pitch is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When width is maximum `size_t` + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When height is maximum `size_t` + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMallocPitch.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemAllocPitch_Negative") { CHECK_IMAGE_SUPPORT @@ -309,233 +627,98 @@ TEST_CASE("Unit_hipMemAllocPitch_Negative") { } } -/* -Test Scenarios of hipMallocPitch API -1. Basic Functionality Scenario -2. Allocate memory using hipMallocPitch API, Launch Kernel validate result. -3. Allocate Memory in small chunks and large chunks and check for possible memory leaks -4. Allocate Memory using hipMallocPitch API, Memcpy2D on the allocated variables. -5. Multithreaded scenario -*/ - -static constexpr auto SMALLCHUNK_NUMW{4}; -static constexpr auto SMALLCHUNK_NUMH{4}; -static constexpr auto LARGECHUNK_NUMW{1025}; -static constexpr auto LARGECHUNK_NUMH{1000}; -static constexpr auto NUM_W{10}; -static constexpr auto NUM_H{10}; -static constexpr auto COLUMNS{8}; -static constexpr auto ROWS{8}; -static constexpr auto CHUNK_LOOP{100}; - - -template -__global__ void copy_var(T* A, T* B, - size_t ROWS, size_t pitch_A) { - for (uint64_t i = 0; i< ROWS*pitch_A; i= i+pitch_A) { - A[i] = B[i]; - } -} -template -static bool validateResult(T* A, T* B, size_t pitch_A) { - bool testResult = true; - for (uint64_t i=0; i < pitch_A*ROWS; i=i+pitch_A) { - if (A[i] != B[i]) { - testResult = false; - break; - } - } - return testResult; -} -/* - * This API verifies memory allocations for small and - * bigger chunks of data. - * Two scenarios are verified in this API - * 1. SmallChunk: Allocates SMALLCHUNK_NUMW in a loop and - * releases the memory and verifies the meminfo. - * 2. LargeChunk: Allocates LARGECHUNK_NUMW in a loop and - * releases the memory and verifies the meminfo - * - * In both cases, the memory info before allocation and - * after releasing the memory should be the same - * +/** + * End doxygen group hipMemAllocPitch. + * @} */ -template -static void MemoryAllocDiffSizes(int gpu) { - HIP_CHECK(hipSetDevice(gpu)); - std::vector array_size; - array_size.push_back(SMALLCHUNK_NUMH); - array_size.push_back(LARGECHUNK_NUMH); - for (auto &sizes : array_size) { - T* A_d[CHUNK_LOOP]; - size_t pitch_A = 0; - size_t width; - if (sizes == SMALLCHUNK_NUMH) { - width = SMALLCHUNK_NUMW * sizeof(T); - } else { - width = LARGECHUNK_NUMW * sizeof(T); - } - for (int i = 0; i < CHUNK_LOOP; i++) { - HIP_CHECK(hipMallocPitch(reinterpret_cast(&A_d[i]), - &pitch_A, width, sizes)); - } - for (int i = 0; i < CHUNK_LOOP; i++) { - HIP_CHECK(hipFree(A_d[i])); - } - } -} -/*Thread Function */ -static void threadFunc(int gpu) { - MemoryAllocDiffSizes(gpu); -} - -/* - * This testcase verifies the basic scenario of - * hipMallocPitch API for different datatypes - * +/** + * @addtogroup hipMalloc3D hipMalloc3D + * @{ + * @ingroup MemoryTest */ -TEMPLATE_TEST_CASE("Unit_hipMallocPitch_Basic", "[hipMallocPitch]", int, unsigned int, float) { - CHECK_IMAGE_SUPPORT - TestType* A_d; - size_t pitch_A = 0; - size_t width{NUM_W * sizeof(TestType)}; - REQUIRE(hipMallocPitch(reinterpret_cast(&A_d), - &pitch_A, width, NUM_H) == hipSuccess); - REQUIRE(width <= pitch_A); - HIP_CHECK(hipFree(A_d)); -} - -/* - * This testcase verifies hipMallocPitch API for small - * and big chunks of data. +/** + * Test Description + * ------------------------ + * - Validates that pitched memory is correctly allocated. + * - The test is run for various extent values and sizes. + * Test source + * ------------------------ + * - unit/memory/hipMallocPitch.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 */ -TEMPLATE_TEST_CASE("Unit_hipMallocPitch_SmallandBigChunks", "[hipMallocPitch]", int, unsigned int, - float) { +TEST_CASE("Unit_hipMalloc3D_ValidatePitch") { CHECK_IMAGE_SUPPORT - MemoryAllocDiffSizes(0); + hipPitchedPtr hipPitchedPtr; + hipExtent validExtent{generateExtent(AllocationApi::hipMalloc3D)}; + + HIP_CHECK(hipMalloc3D(&hipPitchedPtr, validExtent)); + validateMemory(hipPitchedPtr.ptr, validExtent, hipPitchedPtr.pitch); + HIP_CHECK(hipFree(hipPitchedPtr.ptr)); } -/* - * This testcase verifies the memory allocated by hipMallocPitch API - * by performing Memcpy2D on the allocated memory. +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When output device pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When width is set to value higher than maximal texture width + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When height is set to value higher than maximal texture height + * - Expected output: return `hipErrorOutOfMemory` + * -# When depth is set to value higher than maximal texture height + * - Expected output: return `hipErrorOutOfMemory` + * -# When all dimensions are set to value higher than maximal texture value + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMallocPitch.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 */ -TEMPLATE_TEST_CASE("Unit_hipMallocPitch_Memcpy2D", "", int, float, double) { +TEST_CASE("Unit_hipMalloc3D_Negative") { CHECK_IMAGE_SUPPORT - HIP_CHECK(hipSetDevice(0)); - TestType *A_h{nullptr}, *B_h{nullptr}, *C_h{nullptr}, *A_d{nullptr}, - *B_d{nullptr}; - size_t pitch_A = 0, pitch_B = 0; - size_t width{NUM_W * sizeof(TestType)}; - - // Allocating memory - HipTest::initArrays(nullptr, nullptr, nullptr, - &A_h, &B_h, &C_h, NUM_W*NUM_H, false); - HIP_CHECK(hipMallocPitch(reinterpret_cast(&A_d), - &pitch_A, width, NUM_H)); - HIP_CHECK(hipMallocPitch(reinterpret_cast(&B_d), - &pitch_B, width, NUM_H)); - - // Initialize the data - HipTest::setDefaultData(NUM_W*NUM_H, A_h, B_h, C_h); - - // Host to Device - HIP_CHECK(hipMemcpy2D(A_d, pitch_A, A_h, COLUMNS*sizeof(TestType), - COLUMNS*sizeof(TestType), ROWS, hipMemcpyHostToDevice)); - - // Performs D2D on same GPU device - HIP_CHECK(hipMemcpy2D(B_d, pitch_B, A_d, - pitch_A, COLUMNS*sizeof(TestType), - ROWS, hipMemcpyDeviceToDevice)); - - // hipMemcpy2D Device to Host - HIP_CHECK(hipMemcpy2D(B_h, COLUMNS*sizeof(TestType), B_d, pitch_B, - COLUMNS*sizeof(TestType), ROWS, - hipMemcpyDeviceToHost)); - - // Validating the result - REQUIRE(HipTest::checkArray(A_h, B_h, COLUMNS, ROWS) == true); - - - // DeAllocating the memory - HIP_CHECK(hipFree(A_d)); - HIP_CHECK(hipFree(B_d)); - HipTest::freeArrays(nullptr, nullptr, nullptr, - A_h, B_h, C_h, false); -} - + SECTION("Invalid ptr") { + hipExtent validExtent{1, 1, 1}; + HIP_CHECK_ERROR(hipMalloc3D(nullptr, validExtent), hipErrorInvalidValue); + } -/* -This testcase verifies the hipMallocPitch API in multithreaded -scenario by launching threads in parallel on multiple GPUs -and verifies the hipMallocPitch API with small and big chunks data -*/ + hipPitchedPtr ptr; + constexpr size_t maxSizeT = std::numeric_limits::max(); -TEST_CASE("Unit_hipMallocPitch_MultiThread", "") { - CHECK_IMAGE_SUPPORT +#if HT_NVIDIA + //TODO-MATCH-ERRORCODE + SECTION("Max size_t width") { + hipExtent validExtent{maxSizeT, 1, 1}; + HIP_CHECK_ERROR(hipMalloc3D(&ptr, validExtent), hipErrorInvalidValue); + } +#endif - std::vector threadlist; - int devCnt = 0; + SECTION("Max size_t height") { + hipExtent validExtent{1, maxSizeT, 1}; + HIP_CHECK_ERROR(hipMalloc3D(&ptr, validExtent), hipErrorOutOfMemory); + } - devCnt = HipTest::getDeviceCount(); - for (int i = 0; i < devCnt; i++) { - threadlist.push_back(std::thread(threadFunc, i)); + SECTION("Max size_t depth") { + hipExtent validExtent{1, 1, maxSizeT}; + HIP_CHECK_ERROR(hipMalloc3D(&ptr, validExtent), hipErrorOutOfMemory); } - for (auto &t : threadlist) { - t.join(); +#if HT_NVIDIA + //TODO-MATCH-ERRORCODE + SECTION("Max size_t all dimensions") { + hipExtent validExtent{maxSizeT, maxSizeT, maxSizeT}; + HIP_CHECK_ERROR(hipMalloc3D(&ptr, validExtent), hipErrorInvalidValue); } +#endif } -/* - * This testcase verifies hipMallocPitch API by - * 1. Allocating Memory using hipMallocPitch API - * 2. Launching the kernel and copying the data from the allocated kernel - * variable to another kernel variable. - * 3. Validating the result - */ -TEMPLATE_TEST_CASE("Unit_hipMallocPitch_KernelLaunch", "", int, float, double) { - CHECK_IMAGE_SUPPORT - - HIP_CHECK(hipSetDevice(0)); - TestType *A_h{nullptr}, *B_h{nullptr}, *C_h{nullptr}, *A_d{nullptr}, - *B_d{nullptr}; - size_t pitch_A = 0, pitch_B = 0; - size_t width{NUM_W * sizeof(TestType)}; - - // Allocating memory - HipTest::initArrays(nullptr, nullptr, nullptr, - &A_h, &B_h, &C_h, NUM_W*NUM_H, false); - HIP_CHECK(hipMallocPitch(reinterpret_cast(&A_d), - &pitch_A, width, NUM_H)); - HIP_CHECK(hipMallocPitch(reinterpret_cast(&B_d), - &pitch_B, width, NUM_H)); - - // Host to Device - HIP_CHECK(hipMemcpy2D(A_d, pitch_A, A_h, COLUMNS*sizeof(TestType), - COLUMNS*sizeof(TestType), ROWS, hipMemcpyHostToDevice)); - - - hipLaunchKernelGGL(copy_var, dim3(1), dim3(1), - 0, 0, static_cast(A_d), - static_cast(B_d), ROWS, pitch_A); - HIP_CHECK(hipGetLastError()); - - - // hipMemcpy2D Device to Host - HIP_CHECK(hipMemcpy2D(B_h, COLUMNS*sizeof(TestType), B_d, pitch_B, - COLUMNS*sizeof(TestType), ROWS, - hipMemcpyDeviceToHost)); - - // Validating the result - validateResult(A_h, B_h, pitch_A); - - // DeAllocating the memory - HIP_CHECK(hipFree(A_d)); - HIP_CHECK(hipFree(B_d)); - HipTest::freeArrays(nullptr, nullptr, nullptr, - A_h, B_h, C_h, false); -} diff --git a/catch/unit/memory/hipMemAdvise.cc b/catch/unit/memory/hipMemAdvise.cc index ed4d74445..34a4c7210 100644 --- a/catch/unit/memory/hipMemAdvise.cc +++ b/catch/unit/memory/hipMemAdvise.cc @@ -24,6 +24,15 @@ THE SOFTWARE. #include #include +/** + * @addtogroup hipMemAdvise hipMemAdvise + * @{ + * @ingroup MemoryMTest + * `hipMemAdvise(const void* dev_ptr, size_t count, + * hipMemoryAdvise advice, int device)` - + * Advise about the usage of a given memory range to HIP. + */ + static inline hipMemoryAdvise GetUnsetMemAdvice(const hipMemoryAdvise advice) { switch (advice) { case hipMemAdviseSetAccessedBy: @@ -34,7 +43,7 @@ static inline hipMemoryAdvise GetUnsetMemAdvice(const hipMemoryAdvise advice) { return hipMemAdviseUnsetPreferredLocation; default: assert("Invalid hipMemoryAdvise enumerator"); - return advice; + return advice; } } @@ -48,7 +57,7 @@ static inline hipMemRangeAttribute GetMemAdviceAttr(const hipMemoryAdvise advice return hipMemRangeAttributePreferredLocation; default: assert("Invalid hipMemoryAdvise enumerator"); - return static_cast(-1); + return static_cast(-1); } } @@ -65,6 +74,22 @@ std::vector GetDevicesWithAdviseSupport() { return supported_devices; } +/** + * Test Description + * ------------------------ + * - Validate that all advice flags are properly set and unset. + * - The test is run for every supported device and advise: + * -# ReadMostly + * -# AccessedBy + * -# PreferredLocation + * Test source + * ------------------------ + * - unit/memory/hipMemAdvise.cc + * Test requirements + * ------------------------ + * - At least one device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemAdvise_Set_Unset_Basic") { auto supported_devices = GetDevicesWithAdviseSupport(); if (supported_devices.empty()) { @@ -95,6 +120,20 @@ TEST_CASE("Unit_hipMemAdvise_Set_Unset_Basic") { SECTION("hipMemAdviseSetPreferredLocation") { SetUnset(hipMemAdviseSetPreferredLocation); } } +/** + * Test Description + * ------------------------ + * - Validate that setting any advice will not invalidate previously + * set advice. + * - The test is run for every supported device. + * Test source + * ------------------------ + * - unit/memory/hipMemAdvise.cc + * Test requirements + * ------------------------ + * - At least one device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemAdvise_No_Flag_Interference") { auto supported_devices = GetDevicesWithAdviseSupport(); if (supported_devices.empty()) { @@ -123,6 +162,19 @@ TEST_CASE("Unit_hipMemAdvise_No_Flag_Interference") { } } +/** + * Test Description + * ------------------------ + * - Validate that the memory correctly rounds down and rounds up non-aligned + * address and address + count respectively. + * Test source + * ------------------------ + * - unit/memory/hipMemAdvise.cc + * Test requirements + * ------------------------ + * - At least one device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemAdvise_Rounding") { auto supported_devices = GetDevicesWithAdviseSupport(); if (supported_devices.empty()) { @@ -148,12 +200,25 @@ TEST_CASE("Unit_hipMemAdvise_Rounding") { unsigned int attribute = 0; HIP_CHECK(hipMemRangeGetAttribute(&attribute, sizeof(attribute), hipMemRangeAttributeAccessedBy, reinterpret_cast(base), rounded_up)); - REQUIRE(device == static_cast(attribute)); + REQUIRE(device == attribute); HIP_CHECK(hipMemRangeGetAttribute(&attribute, sizeof(attribute), hipMemRangeAttributeAccessedBy, alloc.ptr(), 3 * kPageSize)); - REQUIRE((rounded_up == 3 * kPageSize ? device : hipInvalidDeviceId) == static_cast(attribute)); + REQUIRE((rounded_up == 3 * kPageSize ? device : hipInvalidDeviceId) == attribute); } +/** + * Test Description + * ------------------------ + * - Validate that some flags to not cause a prefetch. + * - This test is run for every supported device. + * Test source + * ------------------------ + * - unit/memory/hipMemAdvise.cc + * Test requirements + * ------------------------ + * - At least one device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemAdvise_Flags_Do_Not_Cause_Prefetch") { auto supported_devices = GetDevicesWithAdviseSupport(); if (supported_devices.empty()) { @@ -180,6 +245,20 @@ TEST_CASE("Unit_hipMemAdvise_Flags_Do_Not_Cause_Prefetch") { #endif } +/** + * Test Description + * ------------------------ + * - Validates that memory for which advice has been applice remains + * read/write accessible to all supported devices. + * - The test is run for every supported device. + * Test source + * ------------------------ + * - unit/memory/hipMemAdvise.cc + * Test requirements + * ------------------------ + * - At least one device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemAdvise_Read_Write_After_Advise") { auto supported_devices = GetDevicesWithAdviseSupport(); if (supported_devices.empty()) { @@ -193,7 +272,7 @@ TEST_CASE("Unit_hipMemAdvise_Read_Write_After_Advise") { std::fill_n(alloc.ptr(), count, -1); ArrayFindIfNot(alloc.ptr(), -1, count); - for (int i = 0; i < static_cast(supported_devices.size()); ++i) { + for (int i = 0; i < supported_devices.size(); ++i) { HIP_CHECK(hipSetDevice(supported_devices[i])); VectorIncrement<<>>(alloc.ptr(), 1, count); HIP_CHECK(hipGetLastError()); @@ -224,6 +303,20 @@ TEST_CASE("Unit_hipMemAdvise_Read_Write_After_Advise") { #endif } +/** + * Test Description + * ------------------------ + * - Validates that prefetching after advise leads to prefetch to correct location + * and advice not being disturbed. + * - Test is run for every supported device. + * Test source + * ------------------------ + * - unit/memory/hipMemAdvise.cc + * Test requirements + * ------------------------ + * - At least one device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemAdvise_Prefetch_After_Advise") { auto supported_devices = GetDevicesWithAdviseSupport(); if (supported_devices.empty()) { @@ -255,6 +348,20 @@ TEST_CASE("Unit_hipMemAdvise_Prefetch_After_Advise") { REQUIRE((advice == hipMemAdviseSetReadMostly ? 1 : device) == attribute); } +/** + * Test Description + * ------------------------ + * - Validate that setting accessed by on a memory region for multiple devices + * works as expected. + * - The test is run for every supported device. + * Test source + * ------------------------ + * - unit/memory/hipMemAdvise.cc + * Test requirements + * ------------------------ + * - At least one device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemAdvise_AccessedBy_All_Devices") { auto supported_devices = GetDevicesWithAdviseSupport(); if (supported_devices.empty()) { @@ -273,6 +380,32 @@ TEST_CASE("Unit_hipMemAdvise_AccessedBy_All_Devices") { REQUIRE_THAT(accessed_by, Catch::Matchers::Equals(supported_devices)); } +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When the advice is not valid (-1) + * - Expected output: return `hipErrorInvalidValue` + * -# When the size in bytes is zero + * - Expected output: return `hipErrorInvalidValue` + * -# When the size in bytes is larger than allocation size + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When the pointer to memory is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When the pointer to memory points to non-managed memory + * - Expected output: return `hipErrorInvalidValue` + * -# When the device ID is not valid + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidDevice` when advice is `ReadMostly` + * Test source + * ------------------------ + * - unit/memory/hipMemAdvise.cc + * Test requirements + * ------------------------ + * - At least one device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemAdvise_Negative_Parameters") { auto supported_devices = GetDevicesWithAdviseSupport(); if (supported_devices.empty()) { diff --git a/catch/unit/memory/hipMemAdviseMmap.cc b/catch/unit/memory/hipMemAdviseMmap.cc index 044f2099c..1d133e191 100644 --- a/catch/unit/memory/hipMemAdviseMmap.cc +++ b/catch/unit/memory/hipMemAdviseMmap.cc @@ -25,11 +25,24 @@ THE SOFTWARE. #include #endif +/** + * @addtogroup hipMemAdvise hipMemAdvise + * @{ + * @ingroup MemoryMTest + */ -/* Test Description: The following test case tests the working of - hipMemAdvise() works with mmap() memory -*/ - +/** + * Test Description + * ------------------------ + * - Validates the case when advised memory works with mapped memory. + * Test source + * ------------------------ + * - unit/memory/hipMemAdviseMmap.cc + * Test requirements + * ------------------------ + * - Device supports pageable memory access + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemAdvise_MmapMem") { int managed = 0, PageableMem = 0; INFO("The following are the attribute values related to HMM for" diff --git a/catch/unit/memory/hipMemAdvise_old.cc b/catch/unit/memory/hipMemAdvise_old.cc index 625c216ef..be69377fd 100644 --- a/catch/unit/memory/hipMemAdvise_old.cc +++ b/catch/unit/memory/hipMemAdvise_old.cc @@ -75,14 +75,13 @@ THE SOFTWARE. #endif // Kernel function -__global__ void MemAdvseKernel(int n, int *x) { +__global__ void MemAdvseKernel(int n, int* x) { int index = blockIdx.x * blockDim.x + threadIdx.x; - if (index < n) - x[index] = x[index] * x[index]; + if (index < n) x[index] = x[index] * x[index]; } // Kernel -__global__ void MemAdvise2(int *Hmm, int n) { +__global__ void MemAdvise2(int* Hmm, int n) { int index = blockIdx.x * blockDim.x + threadIdx.x; int stride = blockDim.x * gridDim.x; for (int i = index; i < n; i += stride) { @@ -91,7 +90,7 @@ __global__ void MemAdvise2(int *Hmm, int n) { } // Kernel -__global__ void MemAdvise3(int *Hmm, int *Hmm1, int n) { +__global__ void MemAdvise3(int* Hmm, int* Hmm1, int n) { int index = blockIdx.x * blockDim.x + threadIdx.x; int stride = blockDim.x * gridDim.x; for (int i = index; i < n; i += stride) { @@ -111,23 +110,20 @@ static bool CheckError(hipError_t err, int LineNo) { static int HmmAttrPrint() { int managed = 0; - WARN("The following are the attribute values related to HMM for" - " device 0:\n"); - HIP_CHECK(hipDeviceGetAttribute(&managed, - hipDeviceAttributeDirectManagedMemAccessFromHost, 0)); + WARN( + "The following are the attribute values related to HMM for" + " device 0:\n"); + HIP_CHECK(hipDeviceGetAttribute(&managed, hipDeviceAttributeDirectManagedMemAccessFromHost, 0)); WARN("hipDeviceAttributeDirectManagedMemAccessFromHost: " << managed); - HIP_CHECK(hipDeviceGetAttribute(&managed, - hipDeviceAttributeConcurrentManagedAccess, 0)); + HIP_CHECK(hipDeviceGetAttribute(&managed, hipDeviceAttributeConcurrentManagedAccess, 0)); WARN("hipDeviceAttributeConcurrentManagedAccess: " << managed); - HIP_CHECK(hipDeviceGetAttribute(&managed, - hipDeviceAttributePageableMemoryAccess, 0)); + HIP_CHECK(hipDeviceGetAttribute(&managed, hipDeviceAttributePageableMemoryAccess, 0)); WARN("hipDeviceAttributePageableMemoryAccess: " << managed); - HIP_CHECK(hipDeviceGetAttribute(&managed, - hipDeviceAttributePageableMemoryAccessUsesHostPageTables, 0)); + HIP_CHECK( + hipDeviceGetAttribute(&managed, hipDeviceAttributePageableMemoryAccessUsesHostPageTables, 0)); WARN("hipDeviceAttributePageableMemoryAccessUsesHostPageTables:" << managed); - HIP_CHECK(hipDeviceGetAttribute(&managed, hipDeviceAttributeManagedMemory, - 0)); + HIP_CHECK(hipDeviceGetAttribute(&managed, hipDeviceAttributeManagedMemory, 0)); WARN("hipDeviceAttributeManagedMemory: " << managed); return managed; } @@ -140,8 +136,8 @@ TEST_CASE("Unit_hipMemAdvise_TstFlags") { if (MangdMem == 1) { bool IfTestPassed = true; int NumDevs = 0, *Outpt = nullptr; - int MEM_SIZE = 4*1024, A_CONST = 9999; - float *Hmm = nullptr; + int MEM_SIZE = 4 * 1024, A_CONST = 9999; + float* Hmm = nullptr; int AttrVal = 0; HIP_CHECK(hipGetDeviceCount(&NumDevs)); Outpt = new int[NumDevs]; @@ -149,20 +145,17 @@ TEST_CASE("Unit_hipMemAdvise_TstFlags") { // With the following for loop we iterate through each of the Gpus in the // system set and unset the flags and check the behavior. for (int i = 0; i < NumDevs; ++i) { - HIP_CHECK(hipMemAdvise(Hmm , MEM_SIZE * 2, hipMemAdviseSetReadMostly, i)); - HIP_CHECK(hipMemRangeGetAttribute(&AttrVal, sizeof(AttrVal), - hipMemRangeAttributeReadMostly, Hmm, - MEM_SIZE * 2)); + HIP_CHECK(hipMemAdvise(Hmm, MEM_SIZE * 2, hipMemAdviseSetReadMostly, i)); + HIP_CHECK(hipMemRangeGetAttribute(&AttrVal, sizeof(AttrVal), hipMemRangeAttributeReadMostly, + Hmm, MEM_SIZE * 2)); if (AttrVal != 1) { WARN("Attempt to set hipMemAdviseSetReadMostly flag failed!\n"); IfTestPassed = false; } - HIP_CHECK(hipMemAdvise(Hmm , MEM_SIZE * 2, hipMemAdviseUnsetReadMostly, - i)); + HIP_CHECK(hipMemAdvise(Hmm, MEM_SIZE * 2, hipMemAdviseUnsetReadMostly, i)); - HIP_CHECK(hipMemRangeGetAttribute(&AttrVal, sizeof(AttrVal), - hipMemRangeAttributeReadMostly, Hmm, - (MEM_SIZE * 2))); + HIP_CHECK(hipMemRangeGetAttribute(&AttrVal, sizeof(AttrVal), hipMemRangeAttributeReadMostly, + Hmm, (MEM_SIZE * 2))); if (AttrVal != 0) { WARN("Attempt to Unset hipMemAdviseSetReadMostly flag failed!\n"); IfTestPassed = false; @@ -171,33 +164,28 @@ TEST_CASE("Unit_hipMemAdvise_TstFlags") { // Currently hipMemAdviseSetPreferredLocation and // hipMemAdviseSetAccessedBy // flags are resulting in issues: SWDEV-267357 - HIP_CHECK(hipMemAdvise(Hmm , MEM_SIZE * 2, - hipMemAdviseSetPreferredLocation, i)); - HIP_CHECK(hipMemRangeGetAttribute(&AttrVal, sizeof(AttrVal), - hipMemRangeAttributePreferredLocation, - Hmm, (MEM_SIZE * 2))); + HIP_CHECK(hipMemAdvise(Hmm, MEM_SIZE * 2, hipMemAdviseSetPreferredLocation, i)); + HIP_CHECK(hipMemRangeGetAttribute( + &AttrVal, sizeof(AttrVal), hipMemRangeAttributePreferredLocation, Hmm, (MEM_SIZE * 2))); if (AttrVal != i) { WARN("Attempt to set hipMemAdviseSetPreferredLocation flag failed!\n"); IfTestPassed = false; } AttrVal = A_CONST; - HIP_CHECK(hipMemAdvise(Hmm , MEM_SIZE * 2, - hipMemAdviseUnsetPreferredLocation, i)); - HIP_CHECK(hipMemRangeGetAttribute(&AttrVal, sizeof(AttrVal), - hipMemRangeAttributePreferredLocation, - Hmm, (MEM_SIZE * 2))); + HIP_CHECK(hipMemAdvise(Hmm, MEM_SIZE * 2, hipMemAdviseUnsetPreferredLocation, i)); + HIP_CHECK(hipMemRangeGetAttribute( + &AttrVal, sizeof(AttrVal), hipMemRangeAttributePreferredLocation, Hmm, (MEM_SIZE * 2))); if (AttrVal == i) { - WARN("Attempt to Unset hipMemAdviseUnsetPreferredLocation "); - WARN("flag failed!\n"); - IfTestPassed = false; + WARN("Attempt to Unset hipMemAdviseUnsetPreferredLocation "); + WARN("flag failed!\n"); + IfTestPassed = false; } for (int m = 0; m < NumDevs; ++m) { Outpt[m] = A_CONST; } - HIP_CHECK(hipMemAdvise(Hmm , MEM_SIZE * 2, hipMemAdviseSetAccessedBy, i)); - HIP_CHECK(hipMemRangeGetAttribute(Outpt, sizeof(Outpt), - hipMemRangeAttributeAccessedBy, Hmm, - (MEM_SIZE * 2))); + HIP_CHECK(hipMemAdvise(Hmm, MEM_SIZE * 2, hipMemAdviseSetAccessedBy, i)); + HIP_CHECK(hipMemRangeGetAttribute(Outpt, sizeof(Outpt), hipMemRangeAttributeAccessedBy, Hmm, + (MEM_SIZE * 2))); if ((Outpt[0]) != i) { WARN("Attempt to set hipMemAdviseSetAccessedBy flag failed!\n"); IfTestPassed = false; @@ -205,22 +193,21 @@ TEST_CASE("Unit_hipMemAdvise_TstFlags") { for (int m = 0; m < NumDevs; ++m) { Outpt[m] = A_CONST; } - HIP_CHECK(hipMemAdvise(Hmm , MEM_SIZE * 2, hipMemAdviseUnsetAccessedBy, - i)); - HIP_CHECK(hipMemRangeGetAttribute(Outpt, sizeof(Outpt), - hipMemRangeAttributeAccessedBy, Hmm, - (MEM_SIZE * 2))); + HIP_CHECK(hipMemAdvise(Hmm, MEM_SIZE * 2, hipMemAdviseUnsetAccessedBy, i)); + HIP_CHECK(hipMemRangeGetAttribute(Outpt, sizeof(Outpt), hipMemRangeAttributeAccessedBy, Hmm, + (MEM_SIZE * 2))); if ((Outpt[0]) >= 0) { WARN("Attempt to Unset hipMemAdviseUnsetAccessedBy flag failed!\n"); IfTestPassed = false; } } - delete [] Outpt; + delete[] Outpt; HIP_CHECK(hipFree(Hmm)); REQUIRE(IfTestPassed); } else { - SUCCEED("GPU 0 doesn't support hipDeviceAttributeManagedMemory " - "attribute. Hence skipping the testing with Pass result.\n"); + SUCCEED( + "GPU 0 doesn't support hipDeviceAttributeManagedMemory " + "attribute. Hence skipping the testing with Pass result.\n"); } } @@ -228,27 +215,36 @@ TEST_CASE("Unit_hipMemAdvise_NegtveTsts") { int MangdMem = HmmAttrPrint(); if (MangdMem == 1) { bool IfTestPassed = true; - int NumDevs = 0, MEM_SIZE = 4*1024; - float *Hmm = nullptr; + int NumDevs = 0, MEM_SIZE = 4 * 1024; + float* Hmm = nullptr; std::string str; HIP_CHECK(hipGetDeviceCount(&NumDevs)); HIP_CHECK(hipMallocManaged(&Hmm, MEM_SIZE * 2, hipMemAttachGlobal)); +#if HT_AMD + // Passing invalid value(99) device param + IfTestPassed &= + CheckError(hipMemAdvise(Hmm, MEM_SIZE * 2, hipMemAdviseSetReadMostly, 99), __LINE__); + + // Passing invalid value(-12) device param + IfTestPassed &= + CheckError(hipMemAdvise(Hmm, MEM_SIZE * 2, hipMemAdviseSetReadMostly, -12), __LINE__); +#endif // Passing NULL as first parameter instead of valid pointer to a memory - IfTestPassed &= CheckError(hipMemAdvise(NULL, MEM_SIZE * 2, - hipMemAdviseSetReadMostly, 0), __LINE__); + IfTestPassed &= + CheckError(hipMemAdvise(NULL, MEM_SIZE * 2, hipMemAdviseSetReadMostly, 0), __LINE__); // Passing 0 for count(2nd param) parameter - IfTestPassed &= CheckError(hipMemAdvise(Hmm, 0, hipMemAdviseSetReadMostly, - 0), __LINE__); + IfTestPassed &= CheckError(hipMemAdvise(Hmm, 0, hipMemAdviseSetReadMostly, 0), __LINE__); // Passing count much more than actually allocated value - IfTestPassed &= CheckError(hipMemAdvise(Hmm, MEM_SIZE * 6, - hipMemAdviseSetReadMostly, 0), __LINE__); + IfTestPassed &= + CheckError(hipMemAdvise(Hmm, MEM_SIZE * 6, hipMemAdviseSetReadMostly, 0), __LINE__); REQUIRE(IfTestPassed); } else { - SUCCEED("GPU 0 doesn't support hipDeviceAttributeManagedMemory " - "attribute. Hence skipping the testing with Pass result.\n"); + SUCCEED( + "GPU 0 doesn't support hipDeviceAttributeManagedMemory " + "attribute. Hence skipping the testing with Pass result.\n"); } } @@ -264,18 +260,16 @@ TEST_CASE("Unit_hipMemAdvise_PrefrdLoc") { bool IfTestPassed = true; HIP_CHECK(hipGetDeviceCount(&NumDevs)); HIP_CHECK(hipMallocManaged(&Hmm, MEM_SIZE * 3, hipMemAttachGlobal)); - for (int i = 0; i < ((MEM_SIZE * 3)/4); ++i) { - Hmm[i] = 4; + for (int i = 0; i < ((MEM_SIZE * 3) / 4); ++i) { + Hmm[i] = 4; } for (int devId = 0; devId < NumDevs; ++devId) { - HIP_CHECK(hipMemAdvise(Hmm, MEM_SIZE * 3, - hipMemAdviseSetPreferredLocation, devId)); - int NumElms = ((MEM_SIZE * 3)/4); - MemAdvseKernel<<>>(NumElms, Hmm); + HIP_CHECK(hipMemAdvise(Hmm, MEM_SIZE * 3, hipMemAdviseSetPreferredLocation, devId)); + int NumElms = ((MEM_SIZE * 3) / 4); + MemAdvseKernel<<>>(NumElms, Hmm); int dev = A_CONST; - HIP_CHECK(hipMemRangeGetAttribute(&dev, sizeof(dev), - hipMemRangeAttributePreferredLocation, - Hmm, MEM_SIZE * 3)); + HIP_CHECK(hipMemRangeGetAttribute(&dev, sizeof(dev), hipMemRangeAttributePreferredLocation, + Hmm, MEM_SIZE * 3)); if (dev != devId) { WARN("Memory observed to be not available on expected location\n"); WARN("line no: " << __LINE__); @@ -291,13 +285,11 @@ TEST_CASE("Unit_hipMemAdvise_PrefrdLoc") { for (int devId = 0; devId < NumDevs; ++devId) { HIP_CHECK(hipSetDevice(devId)); HIP_CHECK(hipStreamCreate(&strm)); - HIP_CHECK(hipMemAdvise(Hmm, MEM_SIZE * 3, - hipMemAdviseSetPreferredLocation, devId)); + HIP_CHECK(hipMemAdvise(Hmm, MEM_SIZE * 3, hipMemAdviseSetPreferredLocation, devId)); HIP_CHECK(hipMemPrefetchAsync(Hmm, MEM_SIZE * 3, devId, strm)); HIP_CHECK(hipStreamSynchronize(strm)); - HIP_CHECK(hipMemRangeGetAttribute(&dev, sizeof(dev), - hipMemRangeAttributeLastPrefetchLocation, - Hmm, MEM_SIZE * 3)); + HIP_CHECK(hipMemRangeGetAttribute(&dev, sizeof(dev), hipMemRangeAttributeLastPrefetchLocation, + Hmm, MEM_SIZE * 3)); if (dev != devId) { WARN("Memory reported to be not available at the Prefetched "); WARN("location with device id: " << devId); @@ -310,8 +302,9 @@ TEST_CASE("Unit_hipMemAdvise_PrefrdLoc") { HIP_CHECK(hipFree(Hmm)); REQUIRE(IfTestPassed); } else { - SUCCEED("GPU 0 doesn't support hipDeviceAttributeManagedMemory " - "attribute. Hence skipping the testing with Pass result.\n"); + SUCCEED( + "GPU 0 doesn't support hipDeviceAttributeManagedMemory " + "attribute. Hence skipping the testing with Pass result.\n"); } } @@ -323,14 +316,14 @@ TEST_CASE("Unit_hipMemAdvise_ReadMostly") { if (MangdMem == 1) { bool IfTestPassed = true; int MEM_SIZE = 4096, A_CONST = 9999; - float *Hmm = nullptr; + float* Hmm = nullptr; HIP_CHECK(hipMallocManaged(&Hmm, MEM_SIZE)); - for (uint64_t i = 0; i < (MEM_SIZE/sizeof(float)); ++i) { + for (uint64_t i = 0; i < (MEM_SIZE / sizeof(float)); ++i) { Hmm[i] = A_CONST; } HIP_CHECK(hipMemAdvise(Hmm, MEM_SIZE, hipMemAdviseSetReadMostly, 0)); // Checking if the data can be read after setting hipMemAdviseSetReadMostly - for (uint64_t i = 0; i < (MEM_SIZE/sizeof(float)); ++i) { + for (uint64_t i = 0; i < (MEM_SIZE / sizeof(float)); ++i) { if (Hmm[i] != A_CONST) { WARN("Didn't find expected value in Hmm memory after setting"); WARN(" hipMemAdviseSetReadMostly flag line no.: " << __LINE__); @@ -339,11 +332,11 @@ TEST_CASE("Unit_hipMemAdvise_ReadMostly") { } // Checking if the memory region can be modified - for (uint64_t i = 0; i < (MEM_SIZE/sizeof(float)); ++i) { + for (uint64_t i = 0; i < (MEM_SIZE / sizeof(float)); ++i) { Hmm[i] = A_CONST; } - for (uint64_t i = 0; i < (MEM_SIZE/sizeof(float)); ++i) { + for (uint64_t i = 0; i < (MEM_SIZE / sizeof(float)); ++i) { if (Hmm[i] != A_CONST) { WARN("Didn't find expected value in Hmm memory after Modification\n"); WARN("line no.: " << __LINE__); @@ -352,8 +345,7 @@ TEST_CASE("Unit_hipMemAdvise_ReadMostly") { } int out = A_CONST; - HIP_CHECK(hipMemRangeGetAttribute(&out, 4, hipMemRangeAttributeReadMostly, - Hmm, MEM_SIZE)); + HIP_CHECK(hipMemRangeGetAttribute(&out, 4, hipMemRangeAttributeReadMostly, Hmm, MEM_SIZE)); if (out != 1) { WARN("out value: " << out); IfTestPassed = false; @@ -361,26 +353,20 @@ TEST_CASE("Unit_hipMemAdvise_ReadMostly") { // Checking the advise attribute after prefetch HIP_CHECK(hipMemPrefetchAsync(Hmm, MEM_SIZE, 0, 0)); HIP_CHECK(hipDeviceSynchronize()); - HIP_CHECK(hipMemRangeGetAttribute(&out, sizeof(int), - hipMemRangeAttributeReadMostly, Hmm, - MEM_SIZE)); + HIP_CHECK( + hipMemRangeGetAttribute(&out, sizeof(int), hipMemRangeAttributeReadMostly, Hmm, MEM_SIZE)); if (out != 1) { WARN("Attribute assigned to memory changed after calling "); WARN("hipMemPrefetchAsync(). line no.: " << __LINE__); WARN("out value: " << out); IfTestPassed = false; } - // hipMemAdvise should succeed for SetReadMostly and UnsetReadMostly - // irrespective of the device - HIP_CHECK(hipMemAdvise(Hmm, MEM_SIZE, hipMemAdviseSetReadMostly, 99)); - - HIP_CHECK(hipMemAdvise(Hmm, MEM_SIZE, hipMemAdviseUnsetReadMostly, -12)); - HIP_CHECK(hipFree(Hmm)); REQUIRE(IfTestPassed); } else { - SUCCEED("GPU 0 doesn't support hipDeviceAttributeManagedMemory " - "attribute. Hence skipping the testing with Pass result.\n"); + SUCCEED( + "GPU 0 doesn't support hipDeviceAttributeManagedMemory " + "attribute. Hence skipping the testing with Pass result.\n"); } } @@ -391,17 +377,16 @@ TEST_CASE("Unit_hipMemAdvise_TstFlgOverrideEffect") { int MangdMem = HmmAttrPrint(); if (MangdMem == 1) { bool IfTestPassed = true; - int MEM_SIZE = 4*4096, A_CONST = 9999; - float *Hmm = nullptr; + int MEM_SIZE = 4 * 4096, A_CONST = 9999; + float* Hmm = nullptr; int NumDevs = 0, dev = A_CONST; HIP_CHECK(hipGetDeviceCount(&NumDevs)); HIP_CHECK(hipMallocManaged(&Hmm, MEM_SIZE, hipMemAttachGlobal)); for (int i = 0; i < NumDevs; ++i) { HIP_CHECK(hipMemAdvise(Hmm, MEM_SIZE, hipMemAdviseSetReadMostly, i)); - HIP_CHECK(hipMemRangeGetAttribute(&dev, sizeof(int), - hipMemRangeAttributeReadMostly, Hmm, - MEM_SIZE)); + HIP_CHECK(hipMemRangeGetAttribute(&dev, sizeof(int), hipMemRangeAttributeReadMostly, Hmm, + MEM_SIZE)); if (dev != 1) { WARN("hipMemAdviseSetReadMostly flag did not take affect despite "); WARN("setting it using hipMemAdvise(). line no.: " << __LINE__); @@ -409,11 +394,9 @@ TEST_CASE("Unit_hipMemAdvise_TstFlgOverrideEffect") { break; } dev = A_CONST; - HIP_CHECK(hipMemAdvise(Hmm, MEM_SIZE, hipMemAdviseSetPreferredLocation, - i)); - HIP_CHECK(hipMemRangeGetAttribute(&dev, sizeof(int), - hipMemRangeAttributePreferredLocation, - Hmm, MEM_SIZE)); + HIP_CHECK(hipMemAdvise(Hmm, MEM_SIZE, hipMemAdviseSetPreferredLocation, i)); + HIP_CHECK(hipMemRangeGetAttribute(&dev, sizeof(int), hipMemRangeAttributePreferredLocation, + Hmm, MEM_SIZE)); if (dev != i) { WARN("hipMemAdviseSetPreferredLocation flag did not take affect "); WARN("despite setting it using hipMemAdvise()\n"); @@ -424,9 +407,8 @@ TEST_CASE("Unit_hipMemAdvise_TstFlgOverrideEffect") { HIP_CHECK(hipMemAdvise(Hmm, MEM_SIZE, hipMemAdviseSetAccessedBy, i)); dev = A_CONST; - HIP_CHECK(hipMemRangeGetAttribute(&dev, sizeof(int), - hipMemRangeAttributeAccessedBy, Hmm, - MEM_SIZE)); + HIP_CHECK(hipMemRangeGetAttribute(&dev, sizeof(int), hipMemRangeAttributeAccessedBy, Hmm, + MEM_SIZE)); if (dev != i) { WARN("hipMemAdviseSetAccessedBy flag did not take affect despite "); WARN("setting it using hipMemAdvise(). line no.: " << __LINE__); @@ -438,8 +420,9 @@ TEST_CASE("Unit_hipMemAdvise_TstFlgOverrideEffect") { HIP_CHECK(hipFree(Hmm)); REQUIRE(IfTestPassed); } else { - SUCCEED("GPU 0 doesn't support hipDeviceAttributeManagedMemory " - "attribute. Hence skipping the testing with Pass result.\n"); + SUCCEED( + "GPU 0 doesn't support hipDeviceAttributeManagedMemory " + "attribute. Hence skipping the testing with Pass result.\n"); } } @@ -451,33 +434,33 @@ TEST_CASE("Unit_hipMemAdvise_TstAccessedByPeer") { int MangdMem = HmmAttrPrint(); if (MangdMem == 1) { bool IfTestPassed = true; - int *Hmm = nullptr, MEM_SIZE = 4*4096, A_CONST = 9999;; + int *Hmm = nullptr, MEM_SIZE = 4 * 4096, A_CONST = 9999; + ; int NumDevs = 0, CanAccessPeer = A_CONST, flag = 0; HIP_CHECK(hipGetDeviceCount(&NumDevs)); if (NumDevs < 2) { - SUCCEED("Test TestSetAccessedByPeer() need atleast two Gpus to test" - " the scenario. This system has GPUs less than 2"); + SUCCEED( + "Test TestSetAccessedByPeer() need atleast two Gpus to test" + " the scenario. This system has GPUs less than 2"); } HIP_CHECK(hipMallocManaged(&Hmm, MEM_SIZE, hipMemAttachGlobal)); for (int i = 0; i < NumDevs; ++i) { HIP_CHECK(hipMemPrefetchAsync(Hmm, MEM_SIZE, i, 0)); for (int j = 0; j < NumDevs; ++j) { - if (i == j) - continue; + if (i == j) continue; HIP_CHECK(hipSetDevice(j)); HIP_CHECK(hipDeviceCanAccessPeer(&CanAccessPeer, j, i)); if (CanAccessPeer) { HIP_CHECK(hipMemAdvise(Hmm, MEM_SIZE, hipMemAdviseSetAccessedBy, j)); - for (uint64_t m = 0; m < (MEM_SIZE/sizeof(int)); ++m) { + for (uint64_t m = 0; m < (MEM_SIZE / sizeof(int)); ++m) { Hmm[m] = 4; } HIP_CHECK(hipDeviceEnablePeerAccess(i, 0)); - MemAdvseKernel<<<(MEM_SIZE/sizeof(int)/32), 32>>>( - (MEM_SIZE/sizeof(int)), Hmm); + MemAdvseKernel<<<(MEM_SIZE / sizeof(int) / 32), 32>>>((MEM_SIZE / sizeof(int)), Hmm); HIP_CHECK(hipDeviceSynchronize()); // Verifying the result - for (uint64_t m = 0; m < (MEM_SIZE/sizeof(int)); ++m) { + for (uint64_t m = 0; m < (MEM_SIZE / sizeof(int)); ++m) { if (Hmm[m] != 16) { flag = 1; } @@ -494,8 +477,9 @@ TEST_CASE("Unit_hipMemAdvise_TstAccessedByPeer") { HIP_CHECK(hipFree(Hmm)); REQUIRE(IfTestPassed); } else { - SUCCEED("GPU 0 doesn't support hipDeviceAttributeManagedMemory " - "attribute. Hence skipping the testing with Pass result.\n"); + SUCCEED( + "GPU 0 doesn't support hipDeviceAttributeManagedMemory " + "attribute. Hence skipping the testing with Pass result.\n"); } } #endif @@ -507,18 +491,18 @@ TEST_CASE("Unit_hipMemAdvise_TstAccessedByFlg") { int managed = HmmAttrPrint(); if (managed == 1) { int *Hmm = NULL, data = 999; - HIP_CHECK(hipMallocManaged(&Hmm, 2*4096)); - HIP_CHECK(hipMemAdvise(Hmm, 2*4096, hipMemAdviseSetAccessedBy, 0)); - HIP_CHECK(hipMemRangeGetAttribute(&data, sizeof(int), - hipMemRangeAttributeLastPrefetchLocation, - Hmm, 2*4096)); + HIP_CHECK(hipMallocManaged(&Hmm, 2 * 4096)); + HIP_CHECK(hipMemAdvise(Hmm, 2 * 4096, hipMemAdviseSetAccessedBy, 0)); + HIP_CHECK(hipMemRangeGetAttribute(&data, sizeof(int), hipMemRangeAttributeLastPrefetchLocation, + Hmm, 2 * 4096)); if (data != -2) { WARN("Didnt get expected value!!\n"); REQUIRE(false); } } else { - SUCCEED("GPU 0 doesn't support hipDeviceAttributeManagedMemory " - "attribute. Hence skipping the testing with Pass result.\n"); + SUCCEED( + "GPU 0 doesn't support hipDeviceAttributeManagedMemory " + "attribute. Hence skipping the testing with Pass result.\n"); } } @@ -533,27 +517,27 @@ TEST_CASE("Unit_hipMemAdvise_TstAccessedByFlg2") { if (Ngpus >= 2) { hipStream_t strm; HIP_CHECK(hipStreamCreate(&strm)); - HIP_CHECK(hipMallocManaged(&Hmm, 2*4096)); - HIP_CHECK(hipMemAdvise(Hmm, 2*4096, hipMemAdviseSetAccessedBy, 0)); - HIP_CHECK(hipMemPrefetchAsync(Hmm, 2*4096, 1, strm)); - HIP_CHECK(hipMemRangeGetAttribute(&data, sizeof(int), - hipMemRangeAttributeAccessedBy, Hmm, 2*4096)); + HIP_CHECK(hipMallocManaged(&Hmm, 2 * 4096)); + HIP_CHECK(hipMemAdvise(Hmm, 2 * 4096, hipMemAdviseSetAccessedBy, 0)); + HIP_CHECK(hipMemPrefetchAsync(Hmm, 2 * 4096, 1, strm)); + HIP_CHECK(hipMemRangeGetAttribute(&data, sizeof(int), hipMemRangeAttributeAccessedBy, Hmm, + 2 * 4096)); if (data != 0) { WARN("Didnt get expected behavior at line: " << __LINE__); REQUIRE(false); } - HIP_CHECK(hipMemAdvise(Hmm, 2*4096, hipMemAdviseUnsetAccessedBy, 0)); + HIP_CHECK(hipMemAdvise(Hmm, 2 * 4096, hipMemAdviseUnsetAccessedBy, 0)); HIP_CHECK(hipStreamDestroy(strm)); HIP_CHECK(hipFree(Hmm)); } } else { - SUCCEED("GPU 0 doesn't support hipDeviceAttributeManagedMemory " - "attribute. Hence skipping the testing with Pass result.\n"); + SUCCEED( + "GPU 0 doesn't support hipDeviceAttributeManagedMemory " + "attribute. Hence skipping the testing with Pass result.\n"); } } - /* 1) Set AccessedBy to device 0 followed by PreferredLocation to device 1 check for AccessedBy flag using hipMemRangeGetAttribute() it should return 0 @@ -567,20 +551,20 @@ TEST_CASE("Unit_hipMemAdvise_TstAccessedByFlg3") { int *Hmm = NULL, data = 999, Ngpus = 0; HIP_CHECK(hipGetDeviceCount(&Ngpus)); if (Ngpus >= 2) { - HIP_CHECK(hipMallocManaged(&Hmm, 2*4096)); - HIP_CHECK(hipMemAdvise(Hmm, 2*4096, hipMemAdviseSetAccessedBy, 0)); - HIP_CHECK(hipMemAdvise(Hmm, 2*4096, hipMemAdviseSetPreferredLocation, 1)); - HIP_CHECK(hipMemRangeGetAttribute(&data, sizeof(int), - hipMemRangeAttributeAccessedBy, Hmm, 2*4096)); + HIP_CHECK(hipMallocManaged(&Hmm, 2 * 4096)); + HIP_CHECK(hipMemAdvise(Hmm, 2 * 4096, hipMemAdviseSetAccessedBy, 0)); + HIP_CHECK(hipMemAdvise(Hmm, 2 * 4096, hipMemAdviseSetPreferredLocation, 1)); + HIP_CHECK(hipMemRangeGetAttribute(&data, sizeof(int), hipMemRangeAttributeAccessedBy, Hmm, + 2 * 4096)); if (data != 0) { WARN("Didnt get expected behavior at line: " << __LINE__); REQUIRE(false); } - HIP_CHECK(hipMemAdvise(Hmm, 2*4096, hipMemAdviseUnsetAccessedBy, 0)); - HIP_CHECK(hipMemAdvise(Hmm, 2*4096, hipMemAdviseSetAccessedBy, 1)); - HIP_CHECK(hipMemAdvise(Hmm, 2*4096, hipMemAdviseSetPreferredLocation, 0)); - HIP_CHECK(hipMemRangeGetAttribute(&data, sizeof(int), - hipMemRangeAttributeAccessedBy, Hmm, 2*4096)); + HIP_CHECK(hipMemAdvise(Hmm, 2 * 4096, hipMemAdviseUnsetAccessedBy, 0)); + HIP_CHECK(hipMemAdvise(Hmm, 2 * 4096, hipMemAdviseSetAccessedBy, 1)); + HIP_CHECK(hipMemAdvise(Hmm, 2 * 4096, hipMemAdviseSetPreferredLocation, 0)); + HIP_CHECK(hipMemRangeGetAttribute(&data, sizeof(int), hipMemRangeAttributeAccessedBy, Hmm, + 2 * 4096)); if (data != 1) { WARN("Didnt get expected behavior at line: " << __LINE__); REQUIRE(false); @@ -588,8 +572,9 @@ TEST_CASE("Unit_hipMemAdvise_TstAccessedByFlg3") { HIP_CHECK(hipFree(Hmm)); } } else { - SUCCEED("GPU 0 doesn't support hipDeviceAttributeManagedMemory " - "attribute. Hence skipping the testing with Pass result.\n"); + SUCCEED( + "GPU 0 doesn't support hipDeviceAttributeManagedMemory " + "attribute. Hence skipping the testing with Pass result.\n"); } } @@ -605,14 +590,13 @@ TEST_CASE("Unit_hipMemAdvise_TstAccessedByFlg4") { hipStream_t strm; HIP_CHECK(hipStreamCreate(&strm)); HIP_CHECK(hipMallocManaged(&Hmm, (NumElms * sizeof(int)))); - HIP_CHECK(hipMemAdvise(Hmm, (NumElms * sizeof(int)), - hipMemAdviseSetAccessedBy, 0)); + HIP_CHECK(hipMemAdvise(Hmm, (NumElms * sizeof(int)), hipMemAdviseSetAccessedBy, 0)); // Initializing memory for (int i = 0; i < NumElms; ++i) { Hmm[i] = InitVal; } dim3 dimBlock(blockSize, 1, 1); - dim3 dimGrid((NumElms + blockSize -1)/blockSize, 1, 1); + dim3 dimGrid((NumElms + blockSize - 1) / blockSize, 1, 1); // launching kernel from each one of the gpus MemAdvise2<<>>(Hmm, NumElms); HIP_CHECK(hipStreamSynchronize(strm)); @@ -629,13 +613,12 @@ TEST_CASE("Unit_hipMemAdvise_TstAccessedByFlg4") { REQUIRE(false); } - HIP_CHECK(hipMemAdvise(Hmm, (NumElms * sizeof(int)), - hipMemAdviseUnsetAccessedBy, 0)); + HIP_CHECK(hipMemAdvise(Hmm, (NumElms * sizeof(int)), hipMemAdviseUnsetAccessedBy, 0)); MemAdvise2<<>>(Hmm, NumElms); HIP_CHECK(hipStreamSynchronize(strm)); // verifying the final result for (int i = 0; i < NumElms; ++i) { - if (Hmm[i] != (InitVal + (2*10))) { + if (Hmm[i] != (InitVal + (2 * 10))) { DataMismatch++; } } @@ -647,8 +630,9 @@ TEST_CASE("Unit_hipMemAdvise_TstAccessedByFlg4") { HIP_CHECK(hipFree(Hmm)); HIP_CHECK(hipStreamDestroy(strm)); } else { - SUCCEED("GPU 0 doesn't support hipDeviceAttributeManagedMemory " - "attribute. Hence skipping the testing with Pass result.\n"); + SUCCEED( + "GPU 0 doesn't support hipDeviceAttributeManagedMemory " + "attribute. Hence skipping the testing with Pass result.\n"); } } @@ -712,16 +696,16 @@ TEST_CASE("Unit_hipMemAdvise_TstMemAdvisePrefrdLoc") { int *Hmm = NULL, data = 999; HIP_CHECK(hipMallocManaged(&Hmm, 4096)); HIP_CHECK(hipMemAdvise(Hmm, 4096, hipMemAdviseSetPreferredLocation, 0)); - HIP_CHECK(hipMemRangeGetAttribute(&data, sizeof(int), - hipMemRangeAttributeLastPrefetchLocation, - Hmm, 4096)); + HIP_CHECK(hipMemRangeGetAttribute(&data, sizeof(int), hipMemRangeAttributeLastPrefetchLocation, + Hmm, 4096)); if (data != -2) { WARN("Didnt receive expected value."); REQUIRE(false); } } else { - SUCCEED("GPU 0 doesn't support hipDeviceAttributeManagedMemory " - "attribute. Hence skipping the testing with Pass result.\n"); + SUCCEED( + "GPU 0 doesn't support hipDeviceAttributeManagedMemory " + "attribute. Hence skipping the testing with Pass result.\n"); } } @@ -745,15 +729,15 @@ TEST_CASE("Unit_hipMemAdvise_TstMemAdviseLstPreftchLoc") { HIP_CHECK(hipMemPrefetchAsync(Hmm, 4096, 1, strm)); HIP_CHECK(hipStreamSynchronize(strm)); HIP_CHECK(hipMemRangeGetAttribute(&data, sizeof(int), - hipMemRangeAttributeLastPrefetchLocation, - Hmm, 4096)); + hipMemRangeAttributeLastPrefetchLocation, Hmm, 4096)); if (data != 1) { WARN("Didnt receive expected value!!"); REQUIRE(false); } } else { - SUCCEED("GPU 0 doesn't support hipDeviceAttributeManagedMemory " - "attribute. Hence skipping the testing with Pass result.\n"); + SUCCEED( + "GPU 0 doesn't support hipDeviceAttributeManagedMemory " + "attribute. Hence skipping the testing with Pass result.\n"); } } else { SUCCEED("This system has less than 2 gpus hence skipping the test.\n"); @@ -774,29 +758,27 @@ TEST_CASE("Unit_hipMemAdvise_TstMemAdviseMultiFlag") { HIP_CHECK(hipMallocManaged(&Hmm, 4096)); HIP_CHECK(hipMemAdvise(Hmm, 4096, hipMemAdviseSetReadMostly, 0)); HIP_CHECK(hipMemAdvise(Hmm, 4096, hipMemAdviseSetPreferredLocation, 0)); - HIP_CHECK(hipMemRangeGetAttribute(&data, sizeof(int), - hipMemRangeAttributeReadMostly, Hmm, - 4096)); + HIP_CHECK( + hipMemRangeGetAttribute(&data, sizeof(int), hipMemRangeAttributeReadMostly, Hmm, 4096)); if (data != 1) { WARN("Didnt receive expected value at line: " << data); REQUIRE(false); } - HIP_CHECK(hipMemRangeGetAttribute(&data, sizeof(int), - hipMemRangeAttributePreferredLocation, Hmm, - 4096)); + HIP_CHECK(hipMemRangeGetAttribute(&data, sizeof(int), hipMemRangeAttributePreferredLocation, + Hmm, 4096)); if (data != 0) { WARN("Didnt receive expected value at line: " << data); REQUIRE(false); } HIP_CHECK(hipFree(Hmm)); } else { - SUCCEED("GPU 0 doesn't support hipDeviceAttributeManagedMemory " - "attribute. Hence skipping the testing with Pass result.\n"); + SUCCEED( + "GPU 0 doesn't support hipDeviceAttributeManagedMemory " + "attribute. Hence skipping the testing with Pass result.\n"); } } - /*Allocate Hmm memory, advise it to ReadMostly for gpu: 0 and launch kernel on all other gpus except 0. This test case may discover any effect or access denial case arising due to setting ReadMostly only to a particular @@ -808,8 +790,9 @@ TEST_CASE("Unit_hipMemAdvise_ReadMosltyMgpuTst") { int Ngpus = 0; HIP_CHECK(hipGetDeviceCount(&Ngpus)); if (Ngpus < 2) { - SUCCEED("This test needs atleast two gpus to run." - "Hence skipping the test.\n"); + SUCCEED( + "This test needs atleast two gpus to run." + "Hence skipping the test.\n"); } int *Hmm = NULL, NumElms = (1024 * 1024), InitVal = 123, blockSize = 64; int *Hmm1 = NULL, DataMismatch = 0; @@ -820,10 +803,9 @@ TEST_CASE("Unit_hipMemAdvise_ReadMosltyMgpuTst") { for (int i = 0; i < NumElms; ++i) { Hmm[i] = InitVal; } - HIP_CHECK(hipMemAdvise(Hmm, (NumElms * sizeof(int)), - hipMemAdviseSetReadMostly, 0)); + HIP_CHECK(hipMemAdvise(Hmm, (NumElms * sizeof(int)), hipMemAdviseSetReadMostly, 0)); dim3 dimBlock(blockSize, 1, 1); - dim3 dimGrid((NumElms + blockSize -1)/blockSize, 1, 1); + dim3 dimGrid((NumElms + blockSize - 1) / blockSize, 1, 1); #if HT_AMD SECTION("Launch Kernel on all other gpus") { // launching kernel from each one of the gpus @@ -851,8 +833,7 @@ TEST_CASE("Unit_hipMemAdvise_ReadMosltyMgpuTst") { for (int i = 0; i < Ngpus; ++i) { DataMismatch = 0; HIP_CHECK(hipSetDevice(i)); - HIP_CHECK(hipMemAdvise(Hmm, (NumElms * sizeof(int)), - hipMemAdviseSetReadMostly, i)); + HIP_CHECK(hipMemAdvise(Hmm, (NumElms * sizeof(int)), hipMemAdviseSetReadMostly, i)); MemAdvise2<<>>(Hmm, NumElms); HIP_CHECK(hipStreamSynchronize(strm)); } @@ -872,8 +853,9 @@ TEST_CASE("Unit_hipMemAdvise_ReadMosltyMgpuTst") { HIP_CHECK(hipFree(Hmm)); HIP_CHECK(hipStreamDestroy(strm)); } else { - SUCCEED("GPU 0 doesn't support hipDeviceAttributeManagedMemory " - "attribute. Hence skipping the testing with Pass result.\n"); + SUCCEED( + "GPU 0 doesn't support hipDeviceAttributeManagedMemory " + "attribute. Hence skipping the testing with Pass result.\n"); } } @@ -882,24 +864,24 @@ TEST_CASE("Unit_hipMemAdvise_TstSetUnsetPrfrdLoc") { int managed = HmmAttrPrint(); if (managed == 1) { int *Hmm = NULL, data = 999; - HIP_CHECK(hipMallocManaged(&Hmm, 2*4096)); - HIP_CHECK(hipMemAdvise(Hmm, 2*4096, hipMemAdviseSetPreferredLocation, 0)); - HIP_CHECK(hipMemRangeGetAttribute(&data, sizeof(int), - hipMemRangeAttributePreferredLocation, Hmm, 2*4096)); + HIP_CHECK(hipMallocManaged(&Hmm, 2 * 4096)); + HIP_CHECK(hipMemAdvise(Hmm, 2 * 4096, hipMemAdviseSetPreferredLocation, 0)); + HIP_CHECK(hipMemRangeGetAttribute(&data, sizeof(int), hipMemRangeAttributePreferredLocation, + Hmm, 2 * 4096)); if (data != 0) { WARN("Didnt receive expected value!!"); REQUIRE(false); } - HIP_CHECK(hipMemAdvise(Hmm, 2*4096, hipMemAdviseUnsetPreferredLocation, 0)); - HIP_CHECK(hipMemRangeGetAttribute(&data, sizeof(int), - hipMemRangeAttributePreferredLocation, Hmm, 2*4096)); + HIP_CHECK(hipMemAdvise(Hmm, 2 * 4096, hipMemAdviseUnsetPreferredLocation, 0)); + HIP_CHECK(hipMemRangeGetAttribute(&data, sizeof(int), hipMemRangeAttributePreferredLocation, + Hmm, 2 * 4096)); if (data != -2) { WARN("Didnt receive expected value!!"); REQUIRE(false); } } else { - SUCCEED("GPU 0 doesn't support hipDeviceAttributeManagedMemory " - "attribute. Hence skipping the testing with Pass result.\n"); + SUCCEED( + "GPU 0 doesn't support hipDeviceAttributeManagedMemory " + "attribute. Hence skipping the testing with Pass result.\n"); } } - diff --git a/catch/unit/memory/hipMemCoherencyTst.cc b/catch/unit/memory/hipMemCoherencyTst.cc index 6e2c2b588..8b1ccfaa9 100644 --- a/catch/unit/memory/hipMemCoherencyTst.cc +++ b/catch/unit/memory/hipMemCoherencyTst.cc @@ -17,20 +17,6 @@ THE SOFTWARE. */ -/* Test Case Description: - Scenario 1: The test validates if fine grain - behavior is observed or not with memory allocated using hipHostMalloc() - Scenario 2: The test validates if fine grain - behavior is observed or not with memory allocated using hipMallocManaged() - Scenario 3: The test validates if memory access is fine - with memory allocated using hipMallocManaged() and CoarseGrain Advise - Scenario 4: The test validates if memory access is fine - with memory allocated using hipMalloc() and CoarseGrain Advise - Scenario 5: The test validates if fine grain - behavior is observed or not with memory allocated using - hipExtMallocWithFlags()*/ - - #include #include @@ -92,11 +78,26 @@ static void TstCoherency(int* ptr, bool hmmMem) { } } -/* Test case description: The following test validates if fine grain - behavior is observed or not with memory allocated using hipHostMalloc()*/ -// The following tests are disabled for Nvidia as they are not consistently -// passing #if HT_AMD +/** + * @addtogroup hipHostMalloc hipHostMalloc + * @{ + * @ingroup MemoryTest + */ + +/** + * Test Description + * ------------------------ + * - Validates if fine grain behaviour is observed or not with memory allocated + * using this API. + * Test source + * ------------------------ + * - unit/memory/hipMemCoherencyTst.cc + * Test requirements + * ------------------------ + * - Platform specific (AMD) + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipHostMalloc_CoherentTst") { int *Ptr = nullptr, SIZE = sizeof(int); bool HmmMem = false; @@ -117,14 +118,32 @@ TEST_CASE("Unit_hipHostMalloc_CoherentTst") { HIP_CHECK(hipHostFree(Ptr)); REQUIRE(YES_COHERENT); } +/** + * End doxygen group hipHostMalloc. + * @} + */ #endif - -/* Test case description: The following test validates if fine grain - behavior is observed or not with memory allocated using hipMallocManaged()*/ -// The following tests are disabled for Nvidia as they are not consistently -// passing +/** + * @addtogroup hipMallocManaged hipMallocManaged + * @{ + * @ingroup MemoryMTest + */ #if HT_AMD +/** + * Test Description + * ------------------------ + * - Validates if fine grain behaviour is observed or not with memory allocated + * using this API. + * Test source + * ------------------------ + * - unit/memory/hipMemCoherencyTst.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - Platform specific (AMD) + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocManaged_CoherentTst") { int *Ptr = nullptr, SIZE = sizeof(int), managed = 0; bool HmmMem = true; @@ -153,6 +172,19 @@ TEST_CASE("Unit_hipMallocManaged_CoherentTst") { /* Test case description: The following test validates if memory access is fine with memory allocated using hipMallocManaged() and CoarseGrain Advise*/ +/** + * Test Description + * ------------------------ + * - Validates if memory access is fine grained with memory allocates using + * this API and coarse grain advice. + * Test source + * ------------------------ + * - unit/memory/hipMemCoherencyTst.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMallocManaged_CoherentTstWthAdvise") { int *Ptr = nullptr, SIZE = sizeof(int), managed = 0; YES_COHERENT = false; @@ -190,11 +222,30 @@ TEST_CASE("Unit_hipMallocManaged_CoherentTstWthAdvise") { } } +/** + * End doxygen group hipMallocManaged. + * @} + */ -/* Test case description: The following test validates if memory allocated - using hipMalloc() are of type Coarse Grain*/ -// The following tests are disabled for Nvidia as they are not applicable #if HT_AMD +/** + * @addtogroup hipMalloc hipMalloc + * @{ + * @ingroup MemoryTest + */ + +/** + * Test Description + * ------------------------ + * - Validates if memory allocated using this API are of type coarse grain. + * Test source + * ------------------------ + * - unit/memory/hipMemCoherencyTst.cc + * Test requirements + * ------------------------ + * - Platform specific (AMD) + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMalloc_CoherentTst") { int *Ptr = nullptr, SIZE = sizeof(int); uint32_t svm_attrib = 0; @@ -209,11 +260,33 @@ TEST_CASE("Unit_hipMalloc_CoherentTst") { HIP_CHECK(hipFree(Ptr)); REQUIRE(IfTstPassed); } +/** + * End doxygen group hipMalloc. + * @} + */ #endif -/* Test case description: The following test validates if fine grain - behavior is observed or not with memory allocated using - hipExtMallocWithFlags()*/ + #if HT_AMD +/** + * @addtogroup hipExtMallocWithFlags hipExtMallocWithFlags + * @{ + * @ingroup MemoryTest + */ + +/** + * Test Description + * ------------------------ + * - Validates if fine grain behaviour is observed or not with memory allocated + * using this API. + * Test source + * ------------------------ + * - unit/memory/hipMemCoherencyTst.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * or pageable memory access + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipExtMallocWithFlags_CoherentTst") { int *Ptr = nullptr, SIZE = sizeof(int), InitVal = 9, Pageable = 0, managed = 0, finegrain = 0; bool FineGrain = true; @@ -265,5 +338,8 @@ TEST_CASE("Unit_hipExtMallocWithFlags_CoherentTst") { "device attribute. Hence skipping the test with Pass result.\n"); } } +/** + * End doxygen group hipExtMallocWithFlags. + * @} + */ #endif - diff --git a/catch/unit/memory/hipMemGetAddressRange.cc b/catch/unit/memory/hipMemGetAddressRange.cc index c6237bbd1..b8c96ce4d 100644 --- a/catch/unit/memory/hipMemGetAddressRange.cc +++ b/catch/unit/memory/hipMemGetAddressRange.cc @@ -16,7 +16,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - #include #include #include @@ -33,11 +32,11 @@ THE SOFTWARE. /** * Test Description * ------------------------ - * - Allocate memory and check if base and size match allocated memory values. - * - Check for various offset values from base memory address: - * - Host address range - * - Device address range - * - Pitch address range + * - Validates handling of various memory allocation types and offsets. + * - Following memory allocation types are considered: + * -# Host address range + * -# Device address range + * -# Pitch address range * Test source * ------------------------ * - unit/memory/hipMemGetAddressRange.cc @@ -89,9 +88,9 @@ TEST_CASE("Unit_hipMemGetAddressRange_Positive") { * Test Description * ------------------------ * - Validates handling of invalid arguments: - * -# When device handle is not valid + * -# When device pointer is not valid * - Expected output: return `hipErrorNotFound` - * -# When offset is greated than allocated size + * -# When offset is greater than allocated size * - Expected output: return `hipErrorNotFound` * Test source * ------------------------ @@ -107,7 +106,7 @@ TEST_CASE("Unit_hipMemGetAddressRange_Negative") { const int offset = kPageSize; LinearAllocGuard host_alloc(LinearAllocs::hipHostMalloc, allocation_size); - hipDeviceptr_t dummy_ptr = NULL; + hipDeviceptr_t dummy_ptr; SECTION("Device pointer is invalid") { HIP_CHECK_ERROR(hipMemGetAddressRange(&base_ptr, &mem_size, dummy_ptr), hipErrorNotFound); diff --git a/catch/unit/memory/hipMemGetInfo.cc b/catch/unit/memory/hipMemGetInfo.cc index 0aa34fbfa..b3c9aa337 100644 --- a/catch/unit/memory/hipMemGetInfo.cc +++ b/catch/unit/memory/hipMemGetInfo.cc @@ -19,6 +19,706 @@ THE SOFTWARE. #include +/** + * @addtogroup hipMemGetInfo hipMemGetInfo + * @{ + * @ingroup MemoryTest + * `hipMemGetInfo(size_t* free, size_t* total)` - + * Query memory info. + * Return snapshot of free memory, and total allocatable memory on the device. + */ + +struct MinAlloc { + private: + int value; + MinAlloc() { + size_t freeMemInit; + size_t totalMemInit; + + unsigned int* A_mem{nullptr}; + size_t mallocSize{1}; + + HIP_CHECK(hipMemGetInfo(&freeMemInit, &totalMemInit)); + // allocate 1 byte + HIP_CHECK(hipMalloc(reinterpret_cast(&A_mem), mallocSize)); + + size_t freeMemRet; + size_t totalMemRet; + // actual allocation should be bigger to reflect the minimum allocation on device + HIP_CHECK(hipMemGetInfo(&freeMemRet, &totalMemRet)); + REQUIRE(freeMemInit >= freeMemRet); + HIP_CHECK(hipFree(A_mem)); + + // store the size of minimum allocation + value = (freeMemInit - freeMemRet); + } + + public: + static int Get() { + static MinAlloc instance; + return instance.value; + } +}; + +// if the memory being allocated is not divisible by the minimum allocation add an extra minimum +// allocation AddedAllocation = InitialAllocation + (MinAllocation - divisionRemainer) +void fixAllocSize(size_t& allocation) { + REQUIRE(MinAlloc::Get() >= 0); + if (allocation % MinAlloc::Get() != 0) { + auto adjustment = allocation % MinAlloc::Get(); // FIXME This does mod by zero + adjustment = MinAlloc::Get() - adjustment; + allocation = allocation + adjustment; + } +} + +// Print information about memory +#define MEMINFO(totalMem, freeMemInit, freeMemRet, usedMem) \ + INFO("Total memory: \t\t\t" << totalMem << "\n" \ + << "Memory used: \t\t\t\t" << freeMemInit - freeMemRet << "\n" \ + << "Free memory after alloc: \t\t" << freeMemRet << "\n" \ + << "Free memory initally: \t\t" << freeMemInit << "\n" \ + << "Memory assumed to be used: \t\t" << usedMem); + + +/** + * Test Description + * ------------------------ + * - Allocates different small chunks of memory. + * - Retrieves info for each chunk and validates results. + * Test source + * ------------------------ + * - unit/memory/hipMemGetInfo.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipMemGetInfo_DifferentMallocSmall") { + size_t freeMemInit; + size_t totalMemInit; + HIP_CHECK(hipMemGetInfo(&freeMemInit, &totalMemInit)); + + unsigned int* A_mem{nullptr}; + size_t freeMemRet; + size_t totalMemRet; + // allocate smaller chunk than minimum + size_t Malloc1Size = 2; + + HIP_CHECK(hipMalloc(reinterpret_cast(&A_mem), Malloc1Size)); + + HIP_CHECK(hipMemGetInfo(&freeMemRet, &totalMemRet)); + MEMINFO(totalMemRet, freeMemInit, freeMemRet, Malloc1Size); + + auto assumedFreeMem = freeMemInit - Malloc1Size; + // Free memory should be less than assumed for + // single allocation smaller than min allocation chunk + REQUIRE(freeMemRet < assumedFreeMem); + // confirms that allocated memory is at least equal to smallest allocation + assumedFreeMem = freeMemInit - MinAlloc::Get(); + REQUIRE(freeMemRet <= assumedFreeMem); + + HIP_CHECK(hipFree(A_mem)); + + // allocate smallest chunk of memory + HIP_CHECK(hipMalloc(reinterpret_cast(&A_mem), MinAlloc::Get())); + HIP_CHECK(hipMemGetInfo(&freeMemRet, &totalMemRet)); + + MEMINFO(totalMemRet, freeMemInit, freeMemRet, MinAlloc::Get()); + + assumedFreeMem = freeMemInit - MinAlloc::Get(); + // confirms that allocated memory is at least equal to smallest allocation + REQUIRE(freeMemRet <= assumedFreeMem); + + HIP_CHECK(hipFree(A_mem)); +} + +#if 0 // FIXME_jatinx Disabled for now because the formula to calulcate memget info is incorrect + // To be enabled after correct formula is found. + +/** + * Test Description + * ------------------------ + * - Allocates different large chunks of memory. + * - Retrieves info for each chunk and validates results. + * Test source + * ------------------------ + * - unit/memory/hipMemGetInfo.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipMemGetInfo_DifferentMallocLarge") { + size_t freeMemInit; + size_t totalMemInit; + HIP_CHECK(hipMemGetInfo(&freeMemInit, &totalMemInit)); + + unsigned int* A_mem{nullptr}; + unsigned int* B_mem{nullptr}; + + size_t freeMemRet; + size_t totalMemRet; + int device; + HIP_CHECK(hipGetDevice(&device)); + hipDeviceProp_t prop; + HIP_CHECK(hipGetDeviceProperties(&prop, device)); + auto totalMemory = prop.totalGlobalMem; + + + // allocate half of free mem + auto Malloc1Size = freeMemInit >> 1; + // if the allocation is not divisible by the MinAllocation + // take into account and add padding + fixAllocSize(Malloc1Size); + HIP_CHECK(hipMalloc(reinterpret_cast(&A_mem), Malloc1Size)); + + // allocate an extra quarter of free mem + auto Malloc2Size = Malloc1Size >> 1; + fixAllocSize(Malloc2Size); + HIP_CHECK(hipMalloc(reinterpret_cast(&B_mem), Malloc2Size)); + + HIP_CHECK(hipMemGetInfo(&freeMemRet, &totalMemRet)); + + MEMINFO(totalMemRet, freeMemInit, freeMemRet, Malloc1Size + Malloc2Size); + // check if device property total memory is the same as + // total memory returned from hipMemGetInfo + REQUIRE(totalMemory == totalMemRet); + auto allocSize = Malloc1Size + Malloc2Size; + auto assumedFreeMem = freeMemInit - allocSize; + + REQUIRE(freeMemRet <= assumedFreeMem); + HIP_CHECK(hipFree(A_mem)); + HIP_CHECK(hipFree(B_mem)); +} + +/** + * Test Description + * ------------------------ + * - Allocates different multiple small chunks of memory. + * - Retrieves info for each chunk and validates results. + * Test source + * ------------------------ + * - unit/memory/hipMemGetInfo.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipMemGetInfo_DifferentMallocMultiSmall") { + size_t freeMemInit; + size_t totalMemInit; + HIP_CHECK(hipMemGetInfo(&freeMemInit, &totalMemInit)); + + unsigned int* A_mem{nullptr}; + unsigned int* B_mem{nullptr}; + size_t freeMemRet; + size_t totalMemRet; + + // Allocate memory that is a quarter of the min allocation + // Expected behaviour is to reuse the min allocation memory + size_t MallocSize = MinAlloc::Get() >> 2; + + HIP_CHECK(hipMalloc(reinterpret_cast(&A_mem), MallocSize)); + HIP_CHECK(hipMalloc(reinterpret_cast(&B_mem), MallocSize)); + + HIP_CHECK(hipMemGetInfo(&freeMemRet, &totalMemRet)); + MEMINFO(totalMemRet, freeMemInit, freeMemRet, MallocSize * 2); + + + auto assumedFreeMem = freeMemInit - (MallocSize * 2); + // freeMemRet should be FreeMem - (1 * MinAlloc) + // instead of FreeMem - (MinAlloc * 2) + // since MinAlloc > MallocSize*2 + REQUIRE(freeMemRet < assumedFreeMem); + fixAllocSize(MallocSize); + assumedFreeMem = freeMemInit - (MallocSize * 2); + // Ensure memory allocated is less than 2 * minimum allocation + REQUIRE(freeMemRet > assumedFreeMem); + + // confirms that allocated memory is at least equal to Min Allocation + assumedFreeMem = freeMemInit - MinAlloc::Get(); + REQUIRE(freeMemRet <= assumedFreeMem); + HIP_CHECK(hipFree(A_mem)); + HIP_CHECK(hipFree(B_mem)); +} + +/** + * Test Description + * ------------------------ + * - Allocates different chunks of memory that cannot be divided. + * - Retrieves info for each chunk and validates results. + * Test source + * ------------------------ + * - unit/memory/hipMemGetInfo.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipMemGetInfo_DifferentMallocNotDiv") { + size_t freeMemInit; + size_t totalMemInit; + HIP_CHECK(hipMemGetInfo(&freeMemInit, &totalMemInit)); + + unsigned int* A_mem{nullptr}; + size_t freeMemRet; + size_t totalMemRet; + // Allocate memory that is just a bit larger than the min allocation + // Expected behaviour is to allocate 2x min allocation size + size_t MallocSize = MinAlloc::Get() + 1; + + HIP_CHECK(hipMalloc(reinterpret_cast(&A_mem), MallocSize)); + + HIP_CHECK(hipMemGetInfo(&freeMemRet, &totalMemRet)); + MEMINFO(totalMemRet, freeMemInit, freeMemRet, MallocSize); + + + auto freeMemExpected = freeMemInit - MallocSize; + // Free Memory after allocation should be less than + // expected free memory + REQUIRE(freeMemRet < freeMemExpected); + // confirms that allocated memory is at least 2 x Min Allocaton + fixAllocSize(MallocSize); + freeMemExpected = freeMemInit - MallocSize; + REQUIRE(freeMemRet <= freeMemExpected); + HIP_CHECK(hipFree(A_mem)); +} + +/** + * Test Description + * ------------------------ + * - Allocates an array. + * - Retrieves info for the array and validates results. + * Test source + * ------------------------ + * - unit/memory/hipMemGetInfo.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEMPLATE_TEST_CASE("Unit_hipMemGetInfo_MallocArray", "", int, int4, char) { + // get initial mem data + size_t freeMemInit; + size_t totalMemInit; + HIP_CHECK(hipMemGetInfo(&freeMemInit, &totalMemInit)); + + // create and allocate an Array + hipArray_t arrayPtr{}; + + auto bytesPerItem = sizeof(TestType); + hipChannelFormatDesc desc = hipCreateChannelDesc(); + hipExtent extent{}; + extent.width = GENERATE(32, 128, 256, 512, 1024); + + extent.height = GENERATE(0, 32, 128, 256, 512, 1024); + + HIP_CHECK(hipMallocArray(&arrayPtr, &desc, extent.width, extent.height, hipArrayDefault)); + + // check if memory is correct + size_t freeMemRet; + size_t totalMemRet; + HIP_CHECK(hipMemGetInfo(&freeMemRet, &totalMemRet)); + + // calculate used memory, take into account 1D array (height = 0) + size_t usedMem = bytesPerItem * extent.width * (extent.height != 0 ? extent.height : 1); + + // ensure we allocate at least the min allocation for the array + fixAllocSize(usedMem); + MEMINFO(totalMemRet, freeMemInit, freeMemRet, usedMem); + + size_t assumedFreeMem = freeMemInit - usedMem; + + REQUIRE(freeMemRet <= assumedFreeMem); + + HIP_CHECK(hipFreeArray(arrayPtr)); +} + +/** + * Test Description + * ------------------------ + * - Allocates an 3D memory chunk. + * - Retrieves info for the chunk and validates results. + * Test source + * ------------------------ + * - unit/memory/hipMemGetInfo.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipMemGetInfo_Malloc3D") { + // Get initial memory + size_t freeMemInit; + size_t totalMemInit; + HIP_CHECK(hipMemGetInfo(&freeMemInit, &totalMemInit)); + + // Allocate 3D object + hipExtent extent{}; + // extent is given in bytes for with + extent.width = GENERATE(32, 128, 256, 512); + extent.height = GENERATE(32, 128, 256, 512); + extent.depth = GENERATE(32, 128, 256, 512); + hipPitchedPtr A_mem{}; + HIP_CHECK(hipMalloc3D(&A_mem, extent)); + + // Get memory after allocation + size_t freeMemRet; + size_t totalMemRet; + HIP_CHECK(hipMemGetInfo(&freeMemRet, &totalMemRet)); + + // Verify result + size_t mallocSize = A_mem.pitch * extent.height * extent.depth; + fixAllocSize(mallocSize); + + size_t assumedFreeMem = freeMemInit - mallocSize; + MEMINFO(totalMemRet, freeMemInit, freeMemRet, mallocSize); + + REQUIRE(freeMemRet <= assumedFreeMem); + + HIP_CHECK(hipFree(A_mem.ptr)); +} + +/** + * Test Description + * ------------------------ + * - Allocates an 3D array. + * - Retrieves info for the array and validates results. + * Test source + * ------------------------ + * - unit/memory/hipMemGetInfo.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEMPLATE_TEST_CASE("Unit_hipMemGetInfo_Malloc3DArray", "", char, int, int4) { + // Get initial memory + size_t freeMemInit; + size_t totalMemInit; + HIP_CHECK(hipMemGetInfo(&freeMemInit, &totalMemInit)); + // Allocate 3D object + hipArray_t arrayPtr{}; + size_t sizeInBytes = (size_t)sizeof(TestType); + hipChannelFormatDesc desc = hipCreateChannelDesc(); + + int device; + HIP_CHECK(hipGetDevice(&device)); + int allignSize{0}; + hipDeviceGetAttribute(&allignSize, hipDeviceAttributeTextureAlignment, device); + +#if HT_NVIDIA + auto flag = GENERATE(hipArrayDefault, hipArrayLayered, hipArrayCubemap, + hipArrayLayered | hipArrayCubemap); +#else + // hipArrayCubemap not supported on AMD + auto flag = GENERATE(hipArrayDefault, hipArrayLayered); +#endif + + hipExtent extent{}; + extent.width = GENERATE(32, 128, 256, 512); + extent.height = GENERATE(0, 32, 128, 256, 512); + if (flag == hipArrayCubemap) { + // width must be equal to height, and depth must be six. + extent.height = extent.width; + extent.depth = 6; + } else if (flag == hipArrayLayered | hipArrayCubemap) { + // width must be equal to height, and depth must be a multiple six. + extent.height = extent.width; + extent.depth = 6 * GENERATE(4, 8, 16, 32); + } else if (extent.height == 0 && flag != hipArrayLayered) { + // if height = 0 the depth must be 0 unless using hipArrayLayered flag + extent.depth = 0; + } else { + extent.depth = GENERATE(32, 128, 256, 512); + } + + + // Get memory after allocation + auto h = extent.height == 0 ? 1 : extent.height; + auto d = extent.depth == 0 ? 1 : extent.depth; + auto w = extent.width * sizeInBytes; + size_t mallocSize = w * h * d; + + HIP_CHECK(hipMalloc3DArray(&arrayPtr, &desc, extent, flag)); + + // Verify result + size_t freeMemRet; + size_t totalMemRet; + HIP_CHECK(hipMemGetInfo(&freeMemRet, &totalMemRet)); + + // Sometimes hipMemGetInfo reports that no new memory has be allocated for testcase + // take this into account + if (freeMemInit == freeMemRet) { + // no new memory allocation has occured verify that memory trying + // to be allocated is less than a min allocation block + MEMINFO(totalMemRet, freeMemInit, freeMemRet, mallocSize); + REQUIRE(mallocSize <= static_cast(MinAlloc::Get())); + + } else { + // account for min allocation + fixAllocSize(mallocSize); + + MEMINFO(totalMemRet, freeMemInit, freeMemRet, mallocSize); + size_t assumedFreeMem = freeMemInit - mallocSize; + REQUIRE(freeMemRet <= assumedFreeMem); + } + HIP_CHECK(hipFreeArray(arrayPtr)); +} + +/** + * Test Description + * ------------------------ + * - Validates the case when info is retreived from multiple + * threads for large memory chunks. + * Test source + * ------------------------ + * - unit/memory/hipMemGetInfo.cc + * Test requirements + * ------------------------ + * - Multi-threaded device + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipMemGetInfo_ParaLarge") { + size_t freeMemInit; + size_t totalMemInit; + HIP_CHECK(hipMemGetInfo(&freeMemInit, &totalMemInit)); + unsigned int* A_mem{nullptr}; + unsigned int* B_mem{nullptr}; + + // allocate half of free mem + auto Malloc1Size = freeMemInit >> 1; + // if the allocation is not divisible by the MinAllocation + // take into account and add padding + fixAllocSize(Malloc1Size); + std::thread t1( + [&]() { HIP_CHECK_THREAD(hipMalloc(reinterpret_cast(&A_mem), Malloc1Size)); }); + + // allocate an extra quarter of free mem + auto Malloc2Size = Malloc1Size >> 1; + fixAllocSize(Malloc2Size); + std::thread t2( + [&]() { HIP_CHECK_THREAD(hipMalloc(reinterpret_cast(&B_mem), Malloc2Size)); }); + + t1.join(); + t2.join(); + HIP_CHECK_THREAD_FINALIZE(); + + size_t freeMemRet; + size_t totalMemRet; + HIP_CHECK(hipMemGetInfo(&freeMemRet, &totalMemRet)); + + MEMINFO(totalMemRet, freeMemInit, freeMemRet, Malloc1Size + Malloc2Size); + auto allocSize = Malloc1Size + Malloc2Size; + REQUIRE(freeMemRet <= freeMemInit - allocSize); + + HIP_CHECK(hipFree(A_mem)); + HIP_CHECK(hipFree(B_mem)); +} + +#endif + +/** + * Test Description + * ------------------------ + * - Validates the case when info is retreived from multiple + * threads for small memory chunks. + * Test source + * ------------------------ + * - unit/memory/hipMemGetInfo.cc + * Test requirements + * ------------------------ + * - Multi-threaded device + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipMemGetInfo_ParaSmall") { + size_t freeMemInit; + size_t totalMemInit; + HIP_CHECK(hipMemGetInfo(&freeMemInit, &totalMemInit)); + unsigned int* A_mem{nullptr}; + // allocate smaller chunk than minimum + size_t Malloc1Size = 2; + + std::thread t1( + [&]() { HIP_CHECK_THREAD(hipMalloc(reinterpret_cast(&A_mem), Malloc1Size)) }); + t1.join(); + HIP_CHECK_THREAD_FINALIZE(); + size_t freeMemRet; + size_t totalMemRet; + HIP_CHECK(hipMemGetInfo(&freeMemRet, &totalMemRet)); + MEMINFO(totalMemRet, freeMemInit, freeMemRet, Malloc1Size); + + + auto assumedFreeMem = freeMemInit - Malloc1Size; + // Free memory should be less than assumed for + // single allocation smaller than min allocation chunk + REQUIRE(freeMemRet < assumedFreeMem); + // confirms that allocated memory is at least equal to smallest allocation allowed + assumedFreeMem = freeMemInit - MinAlloc::Get(); + REQUIRE(freeMemRet <= assumedFreeMem); + + HIP_CHECK(hipFree(A_mem)); + + // allocate smallest chunck of memory + std::thread t2( + [&]() { HIP_CHECK_THREAD(hipMalloc(reinterpret_cast(&A_mem), MinAlloc::Get())); }); + t2.join(); + HIP_CHECK_THREAD_FINALIZE(); + + HIP_CHECK(hipMemGetInfo(&freeMemRet, &totalMemRet)); + + MEMINFO(totalMemRet, freeMemInit, freeMemRet, MinAlloc::Get()); + + assumedFreeMem = freeMemInit - MinAlloc::Get(); + REQUIRE(freeMemRet <= assumedFreeMem); + + HIP_CHECK(hipFree(A_mem)); +} + +/** + * Test Description + * ------------------------ + * - Validates the case when info is retreived from multiple + * threads for memory chunks that cannot be divided. + * Test source + * ------------------------ + * - unit/memory/hipMemGetInfo.cc + * Test requirements + * ------------------------ + * - Multi-threaded device + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipMemGetInfo_ParaNonDiv") { + size_t freeMemInit; + size_t totalMemInit; + HIP_CHECK(hipMemGetInfo(&freeMemInit, &totalMemInit)); + unsigned int* A_mem{nullptr}; + + // Allocate memory that is just 1 byte larger than the min allocation + // Expected behaviour is to allocate 2x min allocation size + size_t Malloc1Size = MinAlloc::Get() + 1; + + std::thread t1( + [&]() { HIP_CHECK_THREAD(hipMalloc(reinterpret_cast(&A_mem), Malloc1Size)); }); + t1.join(); + HIP_CHECK_THREAD_FINALIZE(); + + size_t freeMemRet; + size_t totalMemRet; + HIP_CHECK(hipMemGetInfo(&freeMemRet, &totalMemRet)); + MEMINFO(totalMemRet, freeMemInit, freeMemRet, Malloc1Size); + + + auto allocSize = freeMemInit - Malloc1Size; + // should not be equal + REQUIRE(freeMemRet != allocSize); + // confirms that allocated memory is equal to 2 x Min Allocaton + allocSize = MinAlloc::Get() * 2; + auto assumedAllocSize = freeMemInit - allocSize; + REQUIRE(freeMemRet <= assumedAllocSize); + HIP_CHECK(hipFree(A_mem)); +} + +/** + * Test Description + * ------------------------ + * - Allocates different multiple small chunks of memory. + * - Retrieves info for each chunk from multiple threads and validates results. + * Test source + * ------------------------ + * - unit/memory/hipMemGetInfo.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipMemGetInfo_ParaMultiSmall") { + size_t freeMemInit; + size_t totalMemInit; + HIP_CHECK(hipMemGetInfo(&freeMemInit, &totalMemInit)); + unsigned int* A_mem{nullptr}; + unsigned int* B_mem{nullptr}; + + // Allocate memory that is a quarter of the min allocation + // Expected behaviour is to reuse the min allocation memory + size_t MallocSize = MinAlloc::Get() >> 2; + + std::thread t1( + [&]() { HIP_CHECK_THREAD(hipMalloc(reinterpret_cast(&A_mem), MallocSize)); }); + std::thread t2( + [&]() { HIP_CHECK_THREAD(hipMalloc(reinterpret_cast(&B_mem), MallocSize)); }); + + t1.join(); + t2.join(); + HIP_CHECK_THREAD_FINALIZE(); + + size_t freeMemRet; + size_t totalMemRet; + HIP_CHECK(hipMemGetInfo(&freeMemRet, &totalMemRet)); + MEMINFO(totalMemRet, freeMemInit, freeMemRet, MallocSize * 2); + + auto assumedFreeMem = freeMemInit - MallocSize * 2; + // freeMemRet should be less than assumedFreeMem + REQUIRE(freeMemRet < assumedFreeMem); + // confirms that allocated memory is equal to Min Allocation + assumedFreeMem = freeMemInit - MinAlloc::Get(); + REQUIRE(freeMemRet <= assumedFreeMem); + HIP_CHECK(hipFree(A_mem)); + HIP_CHECK(hipFree(B_mem)); +} + +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When size is zero + * - Expected output: return `hipSuccess` + * -# When free is `nullptr` + * - Expected output: return `hipSuccess` + * -# When total memory is `nullptr` + * - Expected output: return `hipSuccess` + * -# When both arguments are `nullptr` + * - Expected output: return `hipSuccess` + * Test source + * ------------------------ + * - unit/memory/hipMemGetInfo.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipMemGetInfo_Negative") { + size_t freeMemInit; + size_t totalMemInit; + HIP_CHECK(hipMemGetInfo(&freeMemInit, &totalMemInit)); + + unsigned int* A_mem{nullptr}; + auto MallocSize = MinAlloc::Get(); + + SECTION("Zero allocation") { + size_t freeMemRet; + size_t totalMemRet; + HIP_CHECK(hipMalloc(reinterpret_cast(&A_mem), 0)); + HIP_CHECK(hipMemGetInfo(&freeMemRet, &totalMemRet)); + + REQUIRE(freeMemRet == freeMemInit); + } + SECTION("Nullptr as first param passed to hipMemGetInfo") { + size_t* freeMemRet = nullptr; + size_t totalMemRet; + HIP_CHECK(hipMalloc(reinterpret_cast(&A_mem), MallocSize)); + // Segfaults on AMD and returns hipSuccess on Nvidia + HIP_CHECK(hipMemGetInfo(freeMemRet, &totalMemRet)); + } + SECTION("Nullptr as second param passed to hipMemGetInfo") { + size_t freeMemRet; + size_t* totalMemRet = nullptr; + HIP_CHECK(hipMalloc(reinterpret_cast(&A_mem), MallocSize)); + // Segfaults on AMD and returns hipSuccess on Nvidia + HIP_CHECK(hipMemGetInfo(&freeMemRet, totalMemRet)); + } + SECTION("Nullptr as both params passed to hipMemGetInfo") { + size_t* freeMemRet = nullptr; + size_t* totalMemRet = nullptr; + HIP_CHECK(hipMalloc(reinterpret_cast(&A_mem), MallocSize)); + // Segfaults on AMD and returns hipSuccess on Nvidia + HIP_CHECK(hipMemGetInfo(freeMemRet, totalMemRet)); + } + + HIP_CHECK(hipFree(A_mem)); +} + TEST_CASE("Unit_hipMemGetInfo_FreeLessThanTotal") { unsigned int *A_mem{nullptr}; size_t freeMemInit, totalMemInit; diff --git a/catch/unit/memory/hipMemPrefetchAsync.cc b/catch/unit/memory/hipMemPrefetchAsync.cc index 6bdd02794..f31441e8e 100644 --- a/catch/unit/memory/hipMemPrefetchAsync.cc +++ b/catch/unit/memory/hipMemPrefetchAsync.cc @@ -26,6 +26,15 @@ THE SOFTWARE. #include #include +/** + * @addtogroup hipMemPrefetchAsync hipMemPrefetchAsync + * @{ + * @ingroup MemoryMTest + * `hipMemPrefetchAsync(const void* dev_ptr, + * size_t count, int device, hipStream_t stream __dparm(0))` - + * Prefetches memory to the specified destination device using HIP. + */ + std::vector GetDevicesWithPrefetchSupport() { const auto device_count = HipTest::getDeviceCount(); std::vector supported_devices; @@ -47,6 +56,20 @@ __global__ void MemPrefetchAsyncKernel(int* C_d, const int* A_d, size_t N) { } } +/** + * Test Description + * ------------------------ + * - Prefetches memory to a device. + * - Launches a kernel on said device and verifies results. + * - The same is performed with prefetching to the host. + * Test source + * ------------------------ + * - unit/memory/hipMemPrefetchAsync.cc + * Test requirements + * ------------------------ + * - At least one device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemPrefetchAsync_Basic") { const auto supported_devices = GetDevicesWithPrefetchSupport(); if (supported_devices.empty()) { @@ -76,6 +99,18 @@ TEST_CASE("Unit_hipMemPrefetchAsync_Basic") { ArrayFindIfNot(alloc1.ptr(), fill_value, count); } +/** + * Test Description + * ------------------------ + * - Validate that prefetch is successful when synchronization is performed. + * Test source + * ------------------------ + * - unit/memory/hipMemPrefetchAsync.cc + * Test requirements + * ------------------------ + * - At least one device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemPrefetchAsync_Sync_Behavior") { const auto supported_devices = GetDevicesWithPrefetchSupport(); if (supported_devices.empty()) { @@ -92,6 +127,19 @@ TEST_CASE("Unit_hipMemPrefetchAsync_Sync_Behavior") { HIP_CHECK(hipStreamSynchronize(sg.stream())); } +/** + * Test Description + * ------------------------ + * - Validate that fertch correctly rounds down and rounds up + * non-aligned pointer and pointer + increment respectively. + * Test source + * ------------------------ + * - unit/memory/hipMemPrefetchAsync.cc + * Test requirements + * ------------------------ + * - At least one device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemPrefetchAsync_Rounding_Behavior") { auto supported_devices = GetDevicesWithPrefetchSupport(); if (supported_devices.empty()) { @@ -116,13 +164,38 @@ TEST_CASE("Unit_hipMemPrefetchAsync_Rounding_Behavior") { HIP_CHECK(hipMemRangeGetAttribute(&attribute, sizeof(attribute), hipMemRangeAttributeLastPrefetchLocation, reinterpret_cast(base), rounded_up)); - REQUIRE(device == static_cast(attribute)); + REQUIRE(device == attribute); HIP_CHECK(hipMemRangeGetAttribute(&attribute, sizeof(attribute), hipMemRangeAttributeLastPrefetchLocation, alloc.ptr(), 3 * kPageSize)); - REQUIRE((rounded_up == 3 * kPageSize ? device : hipInvalidDeviceId) == static_cast(attribute)); + REQUIRE((rounded_up == 3 * kPageSize ? device : hipInvalidDeviceId) == attribute); } +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When prefetch pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When pointer points to the non-managed memory + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When size in bytes to prefetch is zero + * - Expected output: return `hipErrorInvalidValue` + * -# When size in bytes to prefetch is larger than allocation size + * - Expected output: return `hipErrorInvalidValue` + * -# When the device ID is not valid + * - Expected output: return `hipErrorInvalidDevice` + * -# When the stream is not valid + * - Expected output: return `hipErrorContextIsDestroyed` + * Test source + * ------------------------ + * - unit/memory/hipMemPrefetchAsync.cc + * Test requirements + * ------------------------ + * - At least one device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemPrefetchAsync_Negative_Parameters") { auto supported_devices = GetDevicesWithPrefetchSupport(); if (supported_devices.empty()) { diff --git a/catch/unit/memory/hipMemPrefetchAsyncExtTsts.cc b/catch/unit/memory/hipMemPrefetchAsyncExtTsts.cc index 51ae0be14..ee28c2e8c 100644 --- a/catch/unit/memory/hipMemPrefetchAsyncExtTsts.cc +++ b/catch/unit/memory/hipMemPrefetchAsyncExtTsts.cc @@ -17,23 +17,14 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* Test Case Description: - 1) Allocate managed memory --> prefetch to gpu 0 - call hipMemAdvise() on the memory and apply the flags ReadMostly, - AccessedBy, and PreferredLocation for gpus other than gpu 0 and verify - the flags using hipMemGetAttribute() - 2) Allocate managed memory --> set AccessedBy using - hipMemAdvise() to gpu1 prefetch the memory to gpu 0 and then query for - AccessedBy using hipMemGetAttribute() and validate if AccessedBy is still - set to gpu1. Similar tests are done with ReadMostly and PreferredLocation - flags - 3) Negative testing with hipMemPrefetchAsync() api - 4) In this test case I am trying to allocate HMM memory - which is not multiple of page Size, but still trying to launch kernel and - see if we are getting values as expected. +#include + +/** + * @addtogroup hipMemPrefetchAsync hipMemPrefetchAsync + * @{ + * @ingroup MemoryMTest */ -#include // Kernel function __global__ void MemPrftchAsyncKernel1(int* Hmm, size_t N) { @@ -68,10 +59,22 @@ static int HmmAttrPrint() { return managed; } -/* Test Case Description: Allocate managed memory --> prefetch to gpu 0 - call hipMemAdvise() on the memory and apply the flags ReadMostly, - AccessedBy, and PreferredLocation for gpus other than gpu 0 and verify - the flags using hipMemGetAttribute()*/ +/** + * Test Description + * ------------------------ + * - Checks that memory advise is applied after an async prefetch. + * - Allocate managed memory and prefetch to the device 0. + * - Apply different flags for the devices other than device 0. + * - Verify the values of the flags. + * Test source + * ------------------------ + * - unit/memory/hipMemPrefetchAsyncExtTsts.cc + * Test requirements + * ------------------------ + * - Device 0 supports managed memory management + * - Multi-device + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemPrefetchAsyncAdviseFlgTst") { int NGpus = 0; HIP_CHECK(hipGetDeviceCount(&NGpus)); @@ -133,6 +136,19 @@ TEST_CASE("Unit_hipMemPrefetchAsyncAdviseFlgTst") { AccessedBy using hipMemGetAttribute() and validate if AccessedBy is still set to gpu1. Similar tests are done with ReadMostly and PreferredLocation flags */ +/** + * Test Description + * ------------------------ + * - Checks that the memory advise can be applied before an async prefetch. + * - Allocates managed memory and sets flags on the cevice 1. + * - Prefetches the memory to the device 0 and checks that the valid flag is set. + * Test source + * ------------------------ + * - unit/memory/hipMemPrefetchAsyncExtTsts.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemPrefetchAsyncAccsdByTst") { int NGpus = 0; HIP_CHECK(hipGetDeviceCount(&NGpus)); @@ -219,7 +235,25 @@ TEST_CASE("Unit_hipMemPrefetchAsyncAccsdByTst") { } } -/*Test Case description: Negative testing with hipMemPrefetchAsync() api*/ +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When prefetch pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When size in bytes to prefetch is not usual + * - Expected output: return `hipErrorInvalidValue` + * -# When the device ID is not valid + * - Expected output: return `hipErrorInvalidDevice` + * -# When the stream is not valid + * - Expected output: return `hipErrorContextIsDestroyed` + * Test source + * ------------------------ + * - unit/memory/hipMemPrefetchAsyncExtTsts.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemPrefetchAsyncNegativeTst") { int MangdMem = HmmAttrPrint(); if (MangdMem == 1) { @@ -321,6 +355,21 @@ TEST_CASE("Unit_hipMemPrefetchAsyncNegativeTst") { /* Test Case description: In this test case I am trying to allocate HMM memory which is not multiple of page Size, but still trying to launch kernel and see if we are getting values as expected.*/ + +/** + * Test Description + * ------------------------ + * - Allocate an amount of memory that is not a multiple of a page size (4KB). + * - Prefetches memory. + * - Launches kernel. + * - Validates the results. + * Test source + * ------------------------ + * - unit/memory/hipMemPrefetchAsyncExtTsts.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemPrefetchAsync_NonPageSz") { int *Hmm = nullptr, NumElms = 4096*2, InitVal = 123; hipStream_t strm; diff --git a/catch/unit/memory/hipMemPtrGetInfo.cc b/catch/unit/memory/hipMemPtrGetInfo.cc index 0e737efb9..47b478c2f 100644 --- a/catch/unit/memory/hipMemPtrGetInfo.cc +++ b/catch/unit/memory/hipMemPtrGetInfo.cc @@ -20,23 +20,35 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* -This testfile verifies the basic scenario of hipMemPtrGetInfo API -*/ #include + +/** + * @addtogroup hipMemPtrGetInfo hipMemPtrGetInfo + * @{ + * @ingroup MemoryTest + * `hipMemPtrGetInfo(void* ptr, size_t* size)` - + * Query memory info. + * Return snapshot of free memory, and total allocatable memory on the device. + */ + struct MemInfo{ float a; int b; void* c; }; -/* -This testcase verifies the basic scenario of -hipMemPtrGetInfo API -1. Allocates specific size of memory for the variables -2. Gets the allocated size of that variable using hipMemPtrGetInfo API -3. Validates the initial size and allocated size -*/ +/** + * Test Description + * ------------------------ + * - Allocates specific size of memory for the variables. + * - Gets the allocates size and compares it to the initial size. + * Test source + * ------------------------ + * - unit/memory/hipMemPtrGetInfo.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemPtrGetInfo_Basic") { int* iPtr; float* fPtr; diff --git a/catch/unit/memory/hipMemRangeGetAttribute.cc b/catch/unit/memory/hipMemRangeGetAttribute.cc index ed58d0e27..3273cff17 100644 --- a/catch/unit/memory/hipMemRangeGetAttribute.cc +++ b/catch/unit/memory/hipMemRangeGetAttribute.cc @@ -25,6 +25,27 @@ THE SOFTWARE. #include #include +/** + * @addtogroup hipMemRangeGetAttribute hipMemRangeGetAttribute + * @{ + * @ingroup MemoryMTest + * `hipMemRangeGetAttribute(void* data, size_t data_size, + * hipMemRangeAttribute attribute, const void* dev_ptr, size_t count)` - + * Query an attribute of a given memory range in HIP. + */ + +/** + * Test Description + * ------------------------ + * - Verify fetching of read mostly attribute. + * Test source + * ------------------------ + * - unit/memory/hipMemRangeGetAttribute.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemRangeGetAttribute_Positive_ReadMostly_Basic") { if (!DeviceAttributesSupport(0, hipDeviceAttributeManagedMemory)) { HipTest::HIP_SKIP_TEST("Managed memory not supported"); @@ -46,6 +67,18 @@ TEST_CASE("Unit_hipMemRangeGetAttribute_Positive_ReadMostly_Basic") { REQUIRE(data == 1); } +/** + * Test Description + * ------------------------ + * - Verify partial fetching of read mostly attribute. + * Test source + * ------------------------ + * - unit/memory/hipMemRangeGetAttribute.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemRangeGetAttribute_Positive_ReadMostly_Partial_Range") { if (!DeviceAttributesSupport(0, hipDeviceAttributeManagedMemory)) { HipTest::HIP_SKIP_TEST("Managed memory not supported"); @@ -68,6 +101,18 @@ TEST_CASE("Unit_hipMemRangeGetAttribute_Positive_ReadMostly_Partial_Range") { REQUIRE(data == 1); } +/** + * Test Description + * ------------------------ + * - Verify fetching of preferred location attribute. + * Test source + * ------------------------ + * - unit/memory/hipMemRangeGetAttribute.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemRangeGetAttribute_Positive_PreferredLocation_Basic") { if (!DeviceAttributesSupport(0, hipDeviceAttributeManagedMemory)) { HipTest::HIP_SKIP_TEST("Managed memory not supported"); @@ -89,6 +134,18 @@ TEST_CASE("Unit_hipMemRangeGetAttribute_Positive_PreferredLocation_Basic") { REQUIRE(data == 0); } +/** + * Test Description + * ------------------------ + * - Verify fetching of read mostly attribute when the CPU is preferred location. + * Test source + * ------------------------ + * - unit/memory/hipMemRangeGetAttribute.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemRangeGetAttribute_Positive_PreferredLocation_CPU") { if (!DeviceAttributesSupport(0, hipDeviceAttributeManagedMemory)) { HipTest::HIP_SKIP_TEST("Managed memory not supported"); @@ -107,6 +164,18 @@ TEST_CASE("Unit_hipMemRangeGetAttribute_Positive_PreferredLocation_CPU") { REQUIRE(data == hipCpuDeviceId); } +/** + * Test Description + * ------------------------ + * - Verify partial fetching of read mostly attribute when the CPU is preferred location. + * Test source + * ------------------------ + * - unit/memory/hipMemRangeGetAttribute.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemRangeGetAttribute_Positive_PreferredLocation_Partial_Range") { if (!DeviceAttributesSupport(0, hipDeviceAttributeManagedMemory)) { HipTest::HIP_SKIP_TEST("Managed memory not supported"); @@ -129,6 +198,18 @@ TEST_CASE("Unit_hipMemRangeGetAttribute_Positive_PreferredLocation_Partial_Range REQUIRE(data == 0); } +/** + * Test Description + * ------------------------ + * - Verify fetching of last prefetched location attribute. + * Test source + * ------------------------ + * - unit/memory/hipMemRangeGetAttribute.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemRangeGetAttribute_Positive_LastPrefetchLocation_Basic") { if (!DeviceAttributesSupport(0, hipDeviceAttributeManagedMemory)) { HipTest::HIP_SKIP_TEST("Managed memory not supported"); @@ -150,6 +231,18 @@ TEST_CASE("Unit_hipMemRangeGetAttribute_Positive_LastPrefetchLocation_Basic") { REQUIRE(data == 0); } +/** + * Test Description + * ------------------------ + * - Verify fetching of last prefetched location attribute when the CPU is last prefetch location. + * Test source + * ------------------------ + * - unit/memory/hipMemRangeGetAttribute.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemRangeGetAttribute_Positive_LastPrefetchLocation_CPU") { if (!DeviceAttributesSupport(0, hipDeviceAttributeManagedMemory)) { HipTest::HIP_SKIP_TEST("Managed memory not supported"); @@ -167,6 +260,18 @@ TEST_CASE("Unit_hipMemRangeGetAttribute_Positive_LastPrefetchLocation_CPU") { REQUIRE(data == hipCpuDeviceId); } +/** + * Test Description + * ------------------------ + * - Verify partial fetching of last prefetch location attribute. + * Test source + * ------------------------ + * - unit/memory/hipMemRangeGetAttribute.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemRangeGetAttribute_Positive_LastPrefetchLocation_Partial_Range") { if (!DeviceAttributesSupport(0, hipDeviceAttributeManagedMemory)) { HipTest::HIP_SKIP_TEST("Managed memory not supported"); @@ -189,6 +294,18 @@ TEST_CASE("Unit_hipMemRangeGetAttribute_Positive_LastPrefetchLocation_Partial_Ra REQUIRE(data == 0); } +/** + * Test Description + * ------------------------ + * - Verify fetching of accessed by attribute. + * Test source + * ------------------------ + * - unit/memory/hipMemRangeGetAttribute.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemRangeGetAttribute_Positive_AccessedBy_Basic") { if (!DeviceAttributesSupport(0, hipDeviceAttributeManagedMemory)) { HipTest::HIP_SKIP_TEST("Managed memory not supported"); @@ -218,8 +335,35 @@ TEST_CASE("Unit_hipMemRangeGetAttribute_Positive_AccessedBy_Basic") { for (auto it = cbegin(data) + 2; it != cend(data); ++it) { REQUIRE(*it == hipInvalidDeviceId); } + + LinearAllocGuard allocation(LinearAllocs::hipMallocManaged, 2 * kPageSize); + + HIP_CHECK(hipMemPrefetchAsync(allocation.ptr(), kPageSize, 0)); + + int32_t data; + HIP_CHECK(hipMemRangeGetAttribute(&data, sizeof(data), hipMemRangeAttributeLastPrefetchLocation, + allocation.ptr(), 2 * kPageSize)); + + REQUIRE(data == hipInvalidDeviceId); + + HIP_CHECK(hipMemRangeGetAttribute(&data, sizeof(data), hipMemRangeAttributeLastPrefetchLocation, + allocation.ptr(), kPageSize)); + + REQUIRE(data == 0); } +/** + * Test Description + * ------------------------ + * - Verify partial fetching of last prefetched location attribute. + * Test source + * ------------------------ + * - unit/memory/hipMemRangeGetAttribute.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemRangeGetAttribute_Positive_AccessedBy_Partial_Range") { if (!DeviceAttributesSupport(0, hipDeviceAttributeManagedMemory)) { HipTest::HIP_SKIP_TEST("Managed memory not supported"); @@ -252,6 +396,19 @@ TEST_CASE("Unit_hipMemRangeGetAttribute_Positive_AccessedBy_Partial_Range") { } } +/** + * Test Description + * ------------------------ + * - Verify fetching of accessed by attribute on all devices. + * Test source + * ------------------------ + * - unit/memory/hipMemRangeGetAttribute.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - Multi-device + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemRangeGetAttribute_Positive_AccessedBy_MultiDevice") { if (!DeviceAttributesSupport(0, hipDeviceAttributeManagedMemory)) { HipTest::HIP_SKIP_TEST("Managed memory not supported"); @@ -267,7 +424,7 @@ TEST_CASE("Unit_hipMemRangeGetAttribute_Positive_AccessedBy_MultiDevice") { LinearAllocGuard allocation(LinearAllocs::hipMallocManaged, kPageSize); std::vector data(device_count); - HIP_CHECK(hipMemRangeGetAttribute(data.data(), sizeof(int32_t) * data.size(), hipMemRangeAttributeAccessedBy, + HIP_CHECK(hipMemRangeGetAttribute(data.data(), sizeof(data), hipMemRangeAttributeAccessedBy, allocation.ptr(), kPageSize)); for (auto device : data) { @@ -278,7 +435,7 @@ TEST_CASE("Unit_hipMemRangeGetAttribute_Positive_AccessedBy_MultiDevice") { HIP_CHECK(hipMemAdvise(allocation.ptr(), kPageSize, hipMemAdviseSetAccessedBy, device)); } - HIP_CHECK(hipMemRangeGetAttribute(data.data(), sizeof(int32_t) * data.size(), hipMemRangeAttributeAccessedBy, + HIP_CHECK(hipMemRangeGetAttribute(data.data(), sizeof(data), hipMemRangeAttributeAccessedBy, allocation.ptr(), kPageSize)); // Use std::find since there is no guaranteed order in which devices will be returned @@ -287,6 +444,38 @@ TEST_CASE("Unit_hipMemRangeGetAttribute_Positive_AccessedBy_MultiDevice") { } } +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When data pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When the data size is zero + * - Expected output: return `hipErrorInvalidValue` + * -# When the data size is not equal to four, with read mostly attribute set + * - Expected output: return `hipErrorInvalidValue` + * -# When the data size is not equal to four, with preferred location attribute set + * - Expected output: return `hipErrorInvalidValue` + * -# When the data size is not equal to four, with last prefetch location attribute set + * - Expected output: return `hipErrorInvalidValue` + * -# When the data size is not a multiple of four, with acessed by attribute set + * - Expected output: return `hipErrorInvalidValue` + * -# When the attribute is not valid + * - Expected output: return `hipErrorInvalidValue` + * -# When the device pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When the device pointer points to the non-managed memory + * - Expected output: return `hipErrorInvalidValue` + * -# When the range size is zero + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMemRangeGetAttribute.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemRangeGetAttribute_Negative_Parameters") { if (!DeviceAttributesSupport(0, hipDeviceAttributeManagedMemory)) { HipTest::HIP_SKIP_TEST("Managed memory not supported"); diff --git a/catch/unit/memory/hipMemRangeGetAttributes.cc b/catch/unit/memory/hipMemRangeGetAttributes.cc index a3a9a5bf2..3df7f0c21 100644 --- a/catch/unit/memory/hipMemRangeGetAttributes.cc +++ b/catch/unit/memory/hipMemRangeGetAttributes.cc @@ -25,6 +25,28 @@ THE SOFTWARE. #include #include +/** + * @addtogroup hipMemRangeGetAttributes hipMemRangeGetAttributes + * @{ + * @ingroup MemoryMTest + * `hipMemRangeGetAttributes(void** data, size_t* data_sizes, + * hipMemRangeAttribute* attributes, size_t num_attributes, + * const void* dev_ptr, size_t count)` - + * Query attributes of a given memory range in HIP. + */ + +/** + * Test Description + * ------------------------ + * - Verify fetching of multiple attributes at once. + * Test source + * ------------------------ + * - unit/memory/hipMemRangeGetAttributes.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemRangeGetAttributes_Positive_Basic") { if (!DeviceAttributesSupport(0, hipDeviceAttributeManagedMemory)) { HipTest::HIP_SKIP_TEST("Managed memory not supported"); @@ -63,6 +85,38 @@ TEST_CASE("Unit_hipMemRangeGetAttributes_Positive_Basic") { } } +/** + * Test Description + * ------------------------ + * - Test case description: + * -# When the data array is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When the data array contains invalid `nullptr` pointers + * - Expected output: return `hipErrorInvalidValue` + * -# When the size array is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When the size array contains invalid values + * - Expected output: return `hipErrorInvalidValue` + * -# When the attributes array is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When the attributes array contains invalid attributes + * - Expected output: return `hipErrorInvalidValue` + * -# When number of attributes is zero + * - Expected output: return `hipErrorInvalidValue` + * -# When device pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When device pointer points to the non-managed memory + * - Expected output: return `hipErrorInvalidValue` + * -# When count is zero + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMemRangeGetAttributes.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemRangeGetAttributes_Negative_Parameters") { if (!DeviceAttributesSupport(0, hipDeviceAttributeManagedMemory)) { HipTest::HIP_SKIP_TEST("Managed memory not supported"); diff --git a/catch/unit/memory/hipMemcpy2D.cc b/catch/unit/memory/hipMemcpy2D.cc index 2ae89fc5c..4f83bcf96 100644 --- a/catch/unit/memory/hipMemcpy2D.cc +++ b/catch/unit/memory/hipMemcpy2D.cc @@ -27,6 +27,34 @@ THE SOFTWARE. #include #include +/** + * @addtogroup hipMemcpy2D hipMemcpy2D + * @{ + * @ingroup MemoryTest + * `hipMemcpy2D(void* dst, size_t dpitch, const void* src, size_t spitch, + * size_t width, size_t height, hipMemcpyKind kind)` - + * Copies data between host and device. + */ + +/** + * Test Description + * ------------------------ + * - Verifies basic test cases for copying 2D memory between + * device and host. + * - Validates following memcpy directions: + * -# Device to host + * -# Device to device + * - Peer access disabled + * - Peer access enabled + * -# Host to device + * -# Host to host + * Test source + * ------------------------ + * - unit/memory/hipMemcpy2D.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy2D_Positive_Basic") { constexpr bool async = false; @@ -42,6 +70,27 @@ TEST_CASE("Unit_hipMemcpy2D_Positive_Basic") { SECTION("Host to Host") { Memcpy2DHostToHostShell(hipMemcpy2D); } } +/** + * Test Description + * ------------------------ + * - Validates that API synchronizes regarding to host when copying from + * device memory to the pageable or pinned host memory. + * - Validates following memcpy directions: + * -# Host to device + * -# Device to host + * - Pageable host memory + * - Pinned host memory + * -# Device to device + * - Platform specific (NVIDIA) + * -# Host to host + * - Platform specific (NVIDIA) + * Test source + * ------------------------ + * - unit/memory/hipMemcpy2D.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy2D_Positive_Synchronization_Behavior") { HIP_CHECK(hipDeviceSynchronize()); @@ -65,11 +114,58 @@ TEST_CASE("Unit_hipMemcpy2D_Positive_Synchronization_Behavior") { #endif } +/** + * Test Description + * ------------------------ + * - Validates that nothing will be copied if width or height are set to zero. + * - Validates following memcpy directions: + * -# Device to host + * -# Device to device + * -# Host to device + * -# Host to host + * Test source + * ------------------------ + * - unit/memory/hipMemcpy2D.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy2D_Positive_Parameters") { constexpr bool async = false; Memcpy2DZeroWidthHeight(hipMemcpy2D); } +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When destination pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When source pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When destination pitch is less than width + * - Expected output: return `hipErrorInvalidPitchValue` + * -# When source pitch is less than width + * - Expected output: return `hipErrorInvalidPitchValue` + * -# When destination pitch is larger than maximum pitch + * - Expected output: return `hipErrorInvalidValue` + * -# When source pitch is larger than maximum pitch + * - Expected output: return `hipErrorInvalidValue` + * -# When memcpy kind is not valid (-1) + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * - All cases are executed for following memcpy directions: + * -# Host to device + * -# Device to host + * -# Host to host + * -# Device to device + * Test source + * ------------------------ + * - unit/memory/hipMemcpy2D.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy2D_Negative_Parameters") { constexpr size_t cols = 128; constexpr size_t rows = 128; diff --git a/catch/unit/memory/hipMemcpy2DAsync.cc b/catch/unit/memory/hipMemcpy2DAsync.cc index 4639993b9..b80dc0762 100644 --- a/catch/unit/memory/hipMemcpy2DAsync.cc +++ b/catch/unit/memory/hipMemcpy2DAsync.cc @@ -27,6 +27,38 @@ THE SOFTWARE. #include #include +/** + * @addtogroup hipMemcpy2DAsync hipMemcpy2DAsync + * @{ + * @ingroup MemoryTest + * `hipMemcpy2DAsync(void* dst, size_t dpitch, const void* src, + * size_t spitch, size_t width, size_t height, hipMemcpyKind kind, + * hipStream_t stream __dparm(0))` - + * Copies data between host and device. + */ + +/** + * Test Description + * ------------------------ + * - Validates basic scenario of 2D asynchronous copying. + * - Uses following types of streams: + * -# Default (null stream) + * -# Per thread + * -# Created (non-null stream) + * - Validates following memcpy directions: + * -# Device to host + * -# Device to device + * - Peer access disabled + * - Peer access enabled + * -# Host to device + * -# Host to host + * Test source + * ------------------------ + * - unit/memory/hipMemcpy2DAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy2DAsync_Positive_Basic") { using namespace std::placeholders; @@ -63,6 +95,26 @@ TEST_CASE("Unit_hipMemcpy2DAsync_Positive_Basic") { } } +/** + * Test Description + * ------------------------ + * - Validates that API synchronizes regarding to host when copying + * from device memory to pageable or pinned host memory. + * - Validates following memcpy directions: + * -# Host to device + * -# Device to pageable host + * - Platform specific (NVIDIA) + * -# Device to pinned host + * -# Device to device + * -# Host to host + * - Platform specific (NVIDIA) + * Test source + * ------------------------ + * - unit/memory/hipMemcpy2DAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy2DAsync_Positive_Synchronization_Behavior") { using namespace std::placeholders; @@ -98,12 +150,62 @@ TEST_CASE("Unit_hipMemcpy2DAsync_Positive_Synchronization_Behavior") { #endif } +/** + * Test Description + * ------------------------ + * - Validates that nothing will be copied if width or height are set to zero. + * - Validates following memcpy directions: + * -# Device to host + * -# Device to device + * -# Host to device + * -# Host to host + * Test source + * ------------------------ + * - unit/memory/hipMemcpy2DAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy2DAsync_Positive_Parameters") { using namespace std::placeholders; constexpr bool async = true; Memcpy2DZeroWidthHeight(std::bind(hipMemcpy2DAsync, _1, _2, _3, _4, _5, _6, _7, nullptr)); } +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When destination pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When source pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When destination pitch is less than width + * - Expected output: return `hipErrorInvalidPitchValue` + * -# When source pitch is less than width + * - Expected output: return `hipErrorInvalidPitchValue` + * -# When destination pitch is larger than maximum pitch + * - Expected output: return `hipErrorInvalidValue` + * -# When source pitch is larger than maximum pitch + * - Expected output: return `hipErrorInvalidValue` + * -# When memcpy kind is not valid (-1) + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When stream is not valid + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorContextIsDestroyed` + * - All cases are executed for following memcpy directions: + * -# Host to device + * -# Device to host + * -# Host to host + * -# Device to device + * Test source + * ------------------------ + * - unit/memory/hipMemcpy2DAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy2DAsync_Negative_Parameters") { constexpr size_t cols = 128; constexpr size_t rows = 128; diff --git a/catch/unit/memory/hipMemcpy2DFromArray.cc b/catch/unit/memory/hipMemcpy2DFromArray.cc index 013aa3922..d792c58cd 100644 --- a/catch/unit/memory/hipMemcpy2DFromArray.cc +++ b/catch/unit/memory/hipMemcpy2DFromArray.cc @@ -16,17 +16,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* -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 @@ -34,7 +23,39 @@ invalid #include #include +/** + * @addtogroup hipMemcpy2DFromArray hipMemcpy2DFromArray + * @{ + * @ingroup MemoryTest + * `hipMemcpy2DFromArray( void* dst, size_t dpitch, hipArray_const_t src, size_t wOffset, + * size_t hOffset, size_t width, size_t height, hipMemcpyKind kind)` - + * Copies data between host and device. + */ +/** + * Test Description + * ------------------------ + * - Validates basic behaviour for copying array from the 2D memory + * between host and device. + * - The test is run for a various width/height sizes, host allocation types + * and flag combinations: + * -# Array on the device to host + * -# Array to the host with default kind + * -# Array to device + * - Peer access disabled + * - Peer access enabled + * - Platform specific (NVIDIA) + * -# Array to device with default kind + * - Peer access disabled + * - Peer access enabled + * - Platform specific (NVIDIA) + * Test source + * ------------------------ + * - unit/memory/hipMemcpy2DFromArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy2DFromArray_Positive_Default") { CHECK_IMAGE_SUPPORT @@ -88,6 +109,22 @@ TEST_CASE("Unit_hipMemcpy2DFromArray_Positive_Default") { #endif } +/** + * Test Description + * ------------------------ + * - Validates that API is asynchronous regarding to host when copying + * from device memory to device memory. + * - Validates following memcpy directions: + * -# Array to host + * -# Array to device + * - Platform specific (NVIDIA) + * Test source + * ------------------------ + * - unit/memory/hipMemcpy2DFromArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy2DFromArray_Positive_Synchronization_Behavior") { CHECK_IMAGE_SUPPORT @@ -117,6 +154,24 @@ TEST_CASE("Unit_hipMemcpy2DFromArray_Positive_Synchronization_Behavior") { #endif } +/** + * Test Description + * ------------------------ + * - Validate that nothing will be copied if width or height are set to zero. + * - Following scenarios are considered: + * -# When copying array to host + * - Heigth is 0 + * - Width is 0 + * -# When copying from array to device + * - Height is 0 + * - Width is 0 + * Test source + * ------------------------ + * - unit/memory/hipMemcpy2DFromArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy2DFromArray_Positive_ZeroWidthHeight") { CHECK_IMAGE_SUPPORT @@ -152,6 +207,33 @@ TEST_CASE("Unit_hipMemcpy2DFromArray_Positive_ZeroWidthHeight") { } } +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When destination pointer is `nullptr` + * - Expected output: return `hipErrorInvalidHandle` + * -# When source pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When source pitch is less than width + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidPitchValue` + * -# When width/height increased by offset overflows + * - Expected output: return `hipErrorInvalidValue` + * -# When width/height overflows + * - Expected output: return `hipErrorInvalidValue` + * -# When memcpy direction is not valid + * - Expected output: return `hipErrorInvalidMemcpyDirection` + * - Following scenarios are repeated for: + * -# Array to host + * -# Array to device + * Test source + * ------------------------ + * - unit/memory/hipMemcpy2DFromArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy2DFromArray_Negative_Parameters") { CHECK_IMAGE_SUPPORT diff --git a/catch/unit/memory/hipMemcpy2DFromArrayAsync.cc b/catch/unit/memory/hipMemcpy2DFromArrayAsync.cc index 65c772008..cbf321468 100644 --- a/catch/unit/memory/hipMemcpy2DFromArrayAsync.cc +++ b/catch/unit/memory/hipMemcpy2DFromArrayAsync.cc @@ -16,17 +16,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* -Testcase Scenarios : -Unit_hipMemcpy2DFromArrayAsync_Positive_Default - Test basic async memcpy -between 2D array and host/device with hipMemcpy2DFromArrayAsync api -Unit_hipMemcpy2DFromArrayAsync_Positive_Synchronization_Behavior - Test -synchronization behavior for hipMemcpy2DFromArrayAsync api -Unit_hipMemcpy2DFromArrayAsync_Positive_ZeroWidthHeight - Test that no data is -copied when width/height is set to 0 -Unit_hipMemcpy2DFromArrayAsync_Negative_Parameters - Test unsuccessful execution -of hipMemcpy2DFromArrayAsync api when parameters are invalid -*/ #include "array_memcpy_tests_common.hh" #include @@ -34,6 +23,39 @@ of hipMemcpy2DFromArrayAsync api when parameters are invalid #include #include +/** + * @addtogroup hipMemcpy2DFromArrayAsync hipMemcpy2DFromArrayAsync + * @{ + * @ingroup MemoryTest + * `hipMemcpy2DFromArrayAsync( void* dst, size_t dpitch, hipArray_const_t src, size_t wOffset, + * size_t hOffset, size_t width, size_t height, hipMemcpyKind kind, hipStream_t stream __dparm(0))` + * - Copies data between host and device asynchronously. + */ + +/** + * Test Description + * ------------------------ + * - Validates basic behaviour for copying array to the 2D memory + * between host and device, asynchronously. + * - The test is run for a various width/height sizes, host allocation types + * and flag combinations: + * -# Array on the device to host + * -# Array to host with default kind + * -# Array to device + * - Peer access disabled + * - Peer access enabled + * - Platform specific (NVIDIA) + * -# Array to device with default kind + * - Peer access disabled + * - Peer access enabled + * - Platform specific (NVIDIA) + * Test source + * ------------------------ + * - unit/memory/hipMemcpy2DFromArrayAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy2DFromArrayAsync_Positive_Default") { CHECK_IMAGE_SUPPORT @@ -92,6 +114,21 @@ TEST_CASE("Unit_hipMemcpy2DFromArrayAsync_Positive_Default") { #endif } +/** + * Test Description + * ------------------------ + * - Validates that API is asynchronous regarding to host when copying + * from device memory to device memory. + * - Validates following memcpy directions: + * -# Array to host + * -# Array to device + * Test source + * ------------------------ + * - unit/memory/hipMemcpy2DFromArrayAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy2DFromArrayAsync_Positive_Synchronization_Behavior") { CHECK_IMAGE_SUPPORT @@ -122,6 +159,28 @@ TEST_CASE("Unit_hipMemcpy2DFromArrayAsync_Positive_Synchronization_Behavior") { } } +/** + * Test Description + * ------------------------ + * - Validate that nothing will be copied if width or height are set to zero. + * - Following scenarios are considered: + * -# When copying array to host + * - Heigth is 0 + * - Width is 0 + * -# When copying from array to device + * - Height is 0 + * - Width is 0 + * - Different streams are utilized + * -# Default (null) stream + * -# Per thread stream + * -# Created (non-null) stream + * Test source + * ------------------------ + * - unit/memory/hipMemcpy2DFromArrayAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy2DFromArrayAsync_Positive_ZeroWidthHeight") { CHECK_IMAGE_SUPPORT @@ -162,6 +221,35 @@ TEST_CASE("Unit_hipMemcpy2DFromArrayAsync_Positive_ZeroWidthHeight") { } } +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When destination pointer is `nullptr` + * - Expected output: return `hipErrorInvalidHandle` + * -# When source pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When source pitch is less than width + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidPitchValue` + * -# When width/height increased by offset overflows + * - Expected output: return `hipErrorInvalidValue` + * -# When width/height overflows + * - Expected output: return `hipErrorInvalidValue` + * -# When memcpy direction is not valid + * - Expected output: return `hipErrorInvalidMemcpyDirection` + * -# When stream is not valid + * - Expected output: return `hipErrorContextIsDestroyed` + * - Following scenarios are repeated for: + * -# Array to host + * -# Array to device + * Test source + * ------------------------ + * - unit/memory/hipMemcpy2DFromArrayAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy2DFromArrayAsync_Negative_Parameters") { CHECK_IMAGE_SUPPORT @@ -173,12 +261,10 @@ TEST_CASE("Unit_hipMemcpy2DFromArrayAsync_Negative_Parameters") { const unsigned int flag = hipArrayDefault; -#if HT_NVIDIA constexpr auto InvalidStream = [] { StreamGuard sg(Streams::created); return sg.stream(); }; -#endif ArrayAllocGuard array_alloc(make_hipExtent(width, height, 0), flag); LinearAllocGuard2D device_alloc(width, height); diff --git a/catch/unit/memory/hipMemcpy2DToArray.cc b/catch/unit/memory/hipMemcpy2DToArray.cc index 544578557..5e0e999c8 100644 --- a/catch/unit/memory/hipMemcpy2DToArray.cc +++ b/catch/unit/memory/hipMemcpy2DToArray.cc @@ -16,16 +16,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* -Testcase Scenarios : -Unit_hipMemcpy2DToArray_Positive_Default - Test basic memcpy between host/device -and 2D array with hipMemcpy2DToArray api -Unit_hipMemcpy2DToArray_Positive_Synchronization_Behavior - Test synchronization -behavior for hipMemcpy2DToArray api -Unit_hipMemcpy2DToArray_Positive_ZeroWidthHeight - Test that no data is copied -when width/height is set to 0 Unit_hipMemcpy2DToArray_Negative_Parameters - Test -unsuccessful execution of hipMemcpy2DToArray api when parameters are invalid -*/ #include "array_memcpy_tests_common.hh" #include @@ -33,7 +23,39 @@ unsuccessful execution of hipMemcpy2DToArray api when parameters are invalid #include #include +/** + * @addtogroup hipMemcpy2DToArray hipMemcpy2DToArray + * @{ + * @ingroup MemoryTest + * `hipMemcpy2DToArray(hipArray* dst, size_t wOffset, size_t hOffset, const void* src, + * size_t spitch, size_t width, size_t height, hipMemcpyKind kind)` - + * Copies data between host and device. + */ +/** + * Test Description + * ------------------------ + * - Validates basic behaviour for copying 2D memory to the array + * between host and device. + * - The test is run for a various width/height sizes, host allocation types + * and flag combinations: + * -# Host to array on the device + * -# Host to array with default kind + * -# Device to array + * - Peer access disabled + * - Peer access enabled + * - Platform specific (NVIDIA) + * -# Device to array with default kind + * - Peer access disabled + * - Peer access enabled + * - Platform specific (NVIDIA) + * Test source + * ------------------------ + * - unit/memory/hipMemcpy2DToArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy2DToArray_Positive_Default") { CHECK_IMAGE_SUPPORT @@ -86,6 +108,22 @@ TEST_CASE("Unit_hipMemcpy2DToArray_Positive_Default") { #endif } +/** + * Test Description + * ------------------------ + * - Validates that API is asynchronous regarding to host when copying + * from device memory to device memory. + * - Validates following memcpy directions: + * -# Host to array + * -# Device to array + * - Platform specific (NVIDIA) + * Test source + * ------------------------ + * - unit/memory/hipMemcpy2DToArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy2DToArray_Positive_Synchronization_Behavior") { CHECK_IMAGE_SUPPORT @@ -112,6 +150,24 @@ TEST_CASE("Unit_hipMemcpy2DToArray_Positive_Synchronization_Behavior") { #endif } +/** + * Test Description + * ------------------------ + * - Validate that nothing will be copied if width or height are set to zero. + * - Following scenarios are considered: + * -# When copying array to host + * - Heigth is 0 + * - Width is 0 + * -# When copying from array to device + * - Height is 0 + * - Width is 0 + * Test source + * ------------------------ + * - unit/memory/hipMemcpy2DToArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy2DToArray_Positive_ZeroWidthHeight") { CHECK_IMAGE_SUPPORT @@ -147,6 +203,33 @@ TEST_CASE("Unit_hipMemcpy2DToArray_Positive_ZeroWidthHeight") { } } +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When destination pointer is `nullptr` + * - Expected output: return `hipErrorInvalidHandle` + * -# When source pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When source pitch is less than width + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidPitchValue` + * -# When width/height increased by offset overflows + * - Expected output: return `hipErrorInvalidValue` + * -# When width/height overflows + * - Expected output: return `hipErrorInvalidValue` + * -# When memcpy direction is not valid + * - Expected output: return `hipErrorInvalidMemcpyDirection` + * - Following scenarios are repeated for: + * -# Host to array + * -# Device to array + * Test source + * ------------------------ + * - unit/memory/hipMemcpy2DToArray.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy2DToArray_Negative_Parameters") { CHECK_IMAGE_SUPPORT diff --git a/catch/unit/memory/hipMemcpy2DToArrayAsync.cc b/catch/unit/memory/hipMemcpy2DToArrayAsync.cc index d8190ccae..9902f148e 100644 --- a/catch/unit/memory/hipMemcpy2DToArrayAsync.cc +++ b/catch/unit/memory/hipMemcpy2DToArrayAsync.cc @@ -16,17 +16,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* -Testcase Scenarios : -Unit_hipMemcpy2DToArrayAsync_Positive_Default - Test basic async memcpy between -host/device and 2D array with hipMemcpy2DToArrayAsync api -Unit_hipMemcpy2DToArrayAsync_Positive_Synchronization_Behavior - Test -synchronization behavior for hipMemcpy2DToArrayAsync api -Unit_hipMemcpy2DToArrayAsync_Positive_ZeroWidthHeight - Test that no data is -copied when width/height is set to 0 -Unit_hipMemcpy2DToArrayAsync_Negative_Parameters - Test unsuccessful execution -of hipMemcpy2DToArrayAsync api when parameters are invalid -*/ #include "array_memcpy_tests_common.hh" #include @@ -34,7 +23,40 @@ of hipMemcpy2DToArrayAsync api when parameters are invalid #include #include +/** + * @addtogroup hipMemcpy2DToArrayAsync hipMemcpy2DToArrayAsync + * @{ + * @ingroup MemoryTest + * `hipMemcpy2DToArrayAsync(hipArray* dst, size_t wOffset, size_t hOffset, const void* src, + * size_t spitch, size_t width, size_t height, hipMemcpyKind kind, + * hipStream_t stream __dparm(0))` - + * Copies data between host and device. + */ +/** + * Test Description + * ------------------------ + * - Validates basic behaviour for copying 2D memory to the array + * between host and device, asynchronously. + * - The test is run for a various width/height sizes, host allocation types + * and flag combinations: + * -# Host to array on the device + * -# Host to array with default kind + * -# Device to array + * - Peer access disabled + * - Peer access enabled + * - Platform specific (NVIDIA) + * -# Device to array with default kind + * - Peer access disabled + * - Peer access enabled + * - Platform specific (NVIDIA) + * Test source + * ------------------------ + * - unit/memory/hipMemcpy2DToArrayAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy2DToArrayAsync_Positive_Default") { CHECK_IMAGE_SUPPORT @@ -93,6 +115,21 @@ TEST_CASE("Unit_hipMemcpy2DToArrayAsync_Positive_Default") { #endif } +/** + * Test Description + * ------------------------ + * - Validates that API is asynchronous regarding to host when copying + * from device memory to device memory. + * - Validates following memcpy directions: + * -# Host to array + * -# Device to array + * Test source + * ------------------------ + * - unit/memory/hipMemcpy2DToArrayAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy2DToArrayAsync_Positive_Synchronization_Behavior") { CHECK_IMAGE_SUPPORT @@ -118,6 +155,28 @@ TEST_CASE("Unit_hipMemcpy2DToArrayAsync_Positive_Synchronization_Behavior") { } } +/** + * Test Description + * ------------------------ + * - Validate that nothing will be copied if width or height are set to zero. + * - Following scenarios are considered: + * -# When copying array to host + * - Heigth is 0 + * - Width is 0 + * -# When copying from array to device + * - Height is 0 + * - Width is 0 + * - Different streams are utilized + * -# Default (null) stream + * -# Per thread stream + * -# Created (non-null) stream + * Test source + * ------------------------ + * - unit/memory/hipMemcpy2DToArrayAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy2DToArrayAsync_Positive_ZeroWidthHeight") { CHECK_IMAGE_SUPPORT @@ -157,6 +216,35 @@ TEST_CASE("Unit_hipMemcpy2DToArrayAsync_Positive_ZeroWidthHeight") { } } +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When destination pointer is `nullptr` + * - Expected output: return `hipErrorInvalidHandle` + * -# When source pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When source pitch is less than width + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidPitchValue` + * -# When width/height increased by offset overflows + * - Expected output: return `hipErrorInvalidValue` + * -# When width/height overflows + * - Expected output: return `hipErrorInvalidValue` + * -# When memcpy direction is not valid + * - Expected output: return `hipErrorInvalidMemcpyDirection` + * -# When stream is not valid + * - Expected output: return `hipErrorContextIsDestroyed` + * - Following scenarios are repeated for: + * -# Host to array + * -# Device to array + * Test source + * ------------------------ + * - unit/memory/hipMemcpy2DToArrayAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy2DToArrayAsync_Negative_Parameters") { CHECK_IMAGE_SUPPORT @@ -168,12 +256,10 @@ TEST_CASE("Unit_hipMemcpy2DToArrayAsync_Negative_Parameters") { const unsigned int flag = hipArrayDefault; -#if HT_NVIDIA constexpr auto InvalidStream = [] { StreamGuard sg(Streams::created); return sg.stream(); }; -#endif ArrayAllocGuard array_alloc(make_hipExtent(width, height, 0), flag); LinearAllocGuard2D device_alloc(width, height); diff --git a/catch/unit/memory/hipMemcpy3D.cc b/catch/unit/memory/hipMemcpy3D.cc index b62f23c8a..73e526d76 100644 --- a/catch/unit/memory/hipMemcpy3D.cc +++ b/catch/unit/memory/hipMemcpy3D.cc @@ -30,6 +30,33 @@ THE SOFTWARE. #pragma clang diagnostic ignored "-Wunused-variable" +/** + * @addtogroup hipMemcpy3D hipMemcpy3D + * @{ + * @ingroup MemoryTest + * `hipMemcpy3D(const struct hipMemcpy3DParms* p)` - + * Copies data between host and device. + */ + +/** + * Test Description + * ------------------------ + * - Verifies basic test cases for copying 3D memory between + * device and host. + * - Validates following memcpy directions: + * -# Device to host + * -# Device to device + * - Peer access disabled + * - Peer access enabled + * -# Host to device + * -# Host to host + * Test source + * ------------------------ + * - unit/memory/hipMemcpy3D.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy3D_Positive_Basic") { CHECK_IMAGE_SUPPORT @@ -49,6 +76,26 @@ TEST_CASE("Unit_hipMemcpy3D_Positive_Basic") { SECTION("Host to Host") { Memcpy3DHostToHostShell(Memcpy3DWrapper<>); } } +/** + * Test Description + * ------------------------ + * - Validates that API synchronizes regarding to host when copying from + * device memory to the pageable or pinned host memory. + * - Validates following memcpy directions: + * -# Host to device + * -# Device to pageable host + * -# Device to pinned host + * -# Device to device + * - Platform specific (NVIDIA) + * -# Host to host + * - Platform specific (NVIDIA) + * Test source + * ------------------------ + * - unit/memory/hipMemcpy3D.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy3D_Positive_Synchronization_Behavior") { CHECK_IMAGE_SUPPORT @@ -73,6 +120,22 @@ TEST_CASE("Unit_hipMemcpy3D_Positive_Synchronization_Behavior") { #endif } +/** + * Test Description + * ------------------------ + * - Validates that nothing will be copied if width, height or depth are set to zero. + * - Validates following memcpy directions: + * -# Device to host + * -# Device to device + * -# Host to device + * -# Host to host + * Test source + * ------------------------ + * - unit/memory/hipMemcpy3D.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy3D_Positive_Parameters") { CHECK_IMAGE_SUPPORT @@ -80,6 +143,24 @@ TEST_CASE("Unit_hipMemcpy3D_Positive_Parameters") { Memcpy3DZeroWidthHeightDepth(Memcpy3DWrapper); } +/** + * Test Description + * ------------------------ + * - Validates that an array is successfully copied. + * - Validates following memcpy directions: + * -# Device to host + * -# Host to host + * -# Device to device + * - Plaform specific (NVIDIA) + * -# Host to device + * - Plaform specific (NVIDIA) + * Test source + * ------------------------ + * - unit/memory/hipMemcpy3D.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy3D_Positive_Array") { CHECK_IMAGE_SUPPORT @@ -90,6 +171,55 @@ TEST_CASE("Unit_hipMemcpy3D_Positive_Array") { #endif } +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When destination pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When source pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When destination pitch is less than width + * - Expected output: return `hipErrorInvalidPitchValue` + * -# When source pitch is less than width + * - Expected output: return `hipErrorInvalidPitchValue` + * -# When destination pitch is larger than maximum pitch + * - Expected output: return `hipErrorInvalidValue` + * -# When source pitch is larger than maximum pitch + * - Expected output: return `hipErrorInvalidValue` + * -# When extent.width + dst_pos.x > dst_ptr.pitch + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When extent.width + src_pos.x > src_ptr.pitch + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When dst_pos.y out of bounds + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When src_pos.y out of bounds + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When dst_pos.z out of bounds + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When src_pos.z out of bounds + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When memcpy kind is not valid (-1) + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * - All cases are executed for following memcpy directions: + * -# Host to device + * -# Device to host + * -# Host to host + * -# Device to device + * Test source + * ------------------------ + * - unit/memory/hipMemcpy3D.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy3D_Negative_Parameters") { CHECK_IMAGE_SUPPORT diff --git a/catch/unit/memory/hipMemcpy3DAsync.cc b/catch/unit/memory/hipMemcpy3DAsync.cc index 870672844..e507d7155 100644 --- a/catch/unit/memory/hipMemcpy3DAsync.cc +++ b/catch/unit/memory/hipMemcpy3DAsync.cc @@ -30,6 +30,33 @@ THE SOFTWARE. #pragma clang diagnostic ignored "-Wunused-variable" +/** + * @addtogroup hipMemcpy3DAsync hipMemcpy3DAsync + * @{ + * @ingroup MemoryTest + * `hipMemcpy3DAsync(const struct hipMemcpy3DParms* p, hipStream_t stream __dparm(0))` - + * Copies data between host and device asynchronously. + */ + +/** + * Test Description + * ------------------------ + * - Verifies basic test cases for copying 3D memory between + * device and host asynchronously. + * - Validates following memcpy directions: + * -# Device to host + * -# Device to device + * - Peer access disabled + * - Peer access enabled + * -# Host to device + * -# Host to host + * Test source + * ------------------------ + * - unit/memory/hipMemcpy3DAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy3DAsync_Positive_Basic") { CHECK_IMAGE_SUPPORT @@ -55,6 +82,26 @@ TEST_CASE("Unit_hipMemcpy3DAsync_Positive_Basic") { SECTION("Host to Host") { Memcpy3DHostToHostShell(Memcpy3DWrapper, stream); } } +/** + * Test Description + * ------------------------ + * - Validates that API synchronizes regarding to host when copying from + * device memory to the pageable or pinned host memory. + * - Validates following memcpy directions: + * -# Host to device + * -# Device to pageable host + * - Platform specific (NVIDIA) + * -# Device to pinned host + * -# Device to device + * -# Host to host + * - Platform specific (NVIDIA) + * Test source + * ------------------------ + * - unit/memory/hipMemcpy3DAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy3DAsync_Positive_Synchronization_Behavior") { CHECK_IMAGE_SUPPORT @@ -81,6 +128,22 @@ TEST_CASE("Unit_hipMemcpy3DAsync_Positive_Synchronization_Behavior") { #endif } +/** + * Test Description + * ------------------------ + * - Validates that nothing will be copied if width, height or depth are set to zero. + * - Validates following memcpy directions: + * -# Device to host + * -# Device to device + * -# Host to device + * -# Host to host + * Test source + * ------------------------ + * - unit/memory/hipMemcpy3DAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy3DAsync_Positive_Parameters") { CHECK_IMAGE_SUPPORT @@ -88,6 +151,24 @@ TEST_CASE("Unit_hipMemcpy3DAsync_Positive_Parameters") { Memcpy3DZeroWidthHeightDepth(Memcpy3DWrapper); } +/** + * Test Description + * ------------------------ + * - Validates that an array is successfully copied. + * - Validates following memcpy directions: + * -# Device to host + * -# Host to host + * -# Device to device + * - Plaform specific (NVIDIA) + * -# Host to device + * - Plaform specific (NVIDIA) + * Test source + * ------------------------ + * - unit/memory/hipMemcpy3DAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy3DAsync_Positive_Array") { CHECK_IMAGE_SUPPORT @@ -98,6 +179,58 @@ TEST_CASE("Unit_hipMemcpy3DAsync_Positive_Array") { #endif } +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When destination pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When source pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When destination pitch is less than width + * - Expected output: return `hipErrorInvalidPitchValue` + * -# When source pitch is less than width + * - Expected output: return `hipErrorInvalidPitchValue` + * -# When destination pitch is larger than maximum pitch + * - Expected output: return `hipErrorInvalidValue` + * -# When source pitch is larger than maximum pitch + * - Expected output: return `hipErrorInvalidValue` + * -# When extent.width + dst_pos.x > dst_ptr.pitch + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When extent.width + src_pos.x > src_ptr.pitch + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When dst_pos.y out of bounds + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When src_pos.y out of bounds + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When dst_pos.z out of bounds + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When src_pos.z out of bounds + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When memcpy kind is not valid (-1) + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When stream is not valid + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorContextIsDestroyed` + * - All cases are executed for following memcpy directions: + * -# Host to device + * -# Device to host + * -# Host to host + * -# Device to device + * Test source + * ------------------------ + * - unit/memory/hipMemcpy3DAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy3DAsync_Negative_Parameters") { CHECK_IMAGE_SUPPORT diff --git a/catch/unit/memory/hipMemcpyAllApiNegative.cc b/catch/unit/memory/hipMemcpyAllApiNegative.cc index bb54701af..5eebbf348 100644 --- a/catch/unit/memory/hipMemcpyAllApiNegative.cc +++ b/catch/unit/memory/hipMemcpyAllApiNegative.cc @@ -22,18 +22,43 @@ THE SOFTWARE. #include #include #include -/* -This testfile verifies the following scenarios of all hipMemcpy API -1. Negative Scenarios -2. Half Memory copy scenarios -3. Null check scenario -*/ -static constexpr auto NUM_ELM{1024*1024}; +/** + * @addtogroup hipMemcpy hipMemcpy + * @{ + * @ingroup MemoryTest + */ +static constexpr auto NUM_ELM{1024*1024}; -/*This testcase verifies the negative scenarios of hipMemcpy APIs -*/ +/** + * Test Description + * ------------------------ + * - Verifies negative scenarios for all memcpy APIs: + * -# When destination pointer is `nullptr` + * - Expected output: do not return `hipSuccess` + * -# When source pointer is `nullptr` + * - Expected output: do not return `hipSuccess` + * -# When both source and destination pointers are `nullptr` + * - Expected output: do not return `hipSuccess` + * -# When source and destination pointer is the same + * - Expected output: return `hipSuccess` + * - Following APIs are tested: + * -# @ref hipMemcpy + * -# @ref hipMemcpyHtoD + * -# @ref hipMemcpyDtoH + * -# @ref hipMemcpyDtoD + * -# @ref hipMemcpyAsync + * -# @ref hipMemcpyHtoDAsync + * -# @ref hipMemcpyDtoHAsync + * -# @ref hipMemcpyDtoDAsync + * Test source + * ------------------------ + * - unit/memory/hipMemcpyAllApiNegative.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy_Negative") { // Initialization of variables float *A_d{nullptr}, *B_d{nullptr}, *C_d{nullptr}; @@ -138,9 +163,25 @@ TEST_CASE("Unit_hipMemcpy_Negative") { HIP_CHECK(hipStreamDestroy(stream)); } -/* -This testcase verifies the Nullcheck for all the 8 Memcpy APIs -*/ +/** + * Test Description + * ------------------------ + * - Verifies the case when size is zero for following APIs: + * -# @ref hipMemcpy + * -# @ref hipMemcpyHtoD + * -# @ref hipMemcpyDtoH + * -# @ref hipMemcpyDtoD + * -# @ref hipMemcpyAsync + * -# @ref hipMemcpyHtoDAsync + * -# @ref hipMemcpyDtoHAsync + * -# @ref hipMemcpyDtoDAsync + * Test source + * ------------------------ + * - unit/memory/hipMemcpyAllApiNegative.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy_NullCheck") { // Initialization of variables float *A_d{nullptr}, *B_d{nullptr}, *C_d{nullptr}; @@ -227,10 +268,25 @@ TEST_CASE("Unit_hipMemcpy_NullCheck") { HIP_CHECK(hipStreamDestroy(stream)); } -/* -This testcase verifies all the hipMemcpy APIs by -copying half the memory. -*/ +/** + * Test Description + * ------------------------ + * - Verifies the case when half of the memory is copied for following APIs: + * -# @ref hipMemcpy + * -# @ref hipMemcpyHtoD + * -# @ref hipMemcpyDtoH + * -# @ref hipMemcpyDtoD + * -# @ref hipMemcpyAsync + * -# @ref hipMemcpyHtoDAsync + * -# @ref hipMemcpyDtoHAsync + * -# @ref hipMemcpyDtoDAsync + * Test source + * ------------------------ + * - unit/memory/hipMemcpyAllApiNegative.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy_HalfMemCopy") { // Initialization of variables float *A_d{nullptr}, *B_d{nullptr}, *C_d{nullptr}; diff --git a/catch/unit/memory/hipMemcpyAsync.cc b/catch/unit/memory/hipMemcpyAsync.cc index a57449e84..59e0c730a 100644 --- a/catch/unit/memory/hipMemcpyAsync.cc +++ b/catch/unit/memory/hipMemcpyAsync.cc @@ -25,6 +25,42 @@ THE SOFTWARE. #include #include +/** + * @addtogroup hipMemcpyAsync hipMemcpyAsync + * @{ + * @ingroup MemoryTest + * `hipMemcpyAsync(void* dst, const void* src, size_t sizeBytes, + * hipMemcpyKind kind, hipStream_t stream __dparm(0))` - + * Copy data from src to dst asynchronously. + * ________________________ + * Test cases from other modules: + * - @ref Unit_hipMemcpy_MultiThread_AllAPIs + */ + +/** + * Test Description + * ------------------------ + * - Validate basic device to host behaviour with Device to Host and Default kind. + * - Following copy scenarios are considered: + * -# Device to Host + * -# Device to Host with default kind + * -# Host to Device + * -# Host to Device with default kind + * -# Host to Host + * -# Host to Host with default kind + * -# Device to Device + * - Peer access enabled + * - Peer access disabled + * -# Device to Device with default kind + * - Peer access enabled + * - Peer access disabled + * Test source + * ------------------------ + * - unit/memory/hipMemcpyAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyAsync_Positive_Basic") { using namespace std::placeholders; const auto stream_type = GENERATE(Streams::nullstream, Streams::perThread, Streams::created); @@ -34,6 +70,24 @@ TEST_CASE("Unit_hipMemcpyAsync_Positive_Basic") { MemcpyWithDirectionCommonTests(std::bind(hipMemcpyAsync, _1, _2, _3, _4, stream)); } +/** + * Test Description + * ------------------------ + * - Validates that the API is asynchronous regarding to: + * -# Copying from pageable or pinned host memory to device memory + * - Platform specific (NVIDIA) + * -# Copying from device memory to pageable or pinned host memory + * - Validates that the API is asynchronous regarding to: + * -# Copying from device memory to device memory + * -# Copying from pageable or pinned host memory to pageable or pinned + * host memory + * Test source + * ------------------------ + * - unit/memory/hipMemcpyAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyAsync_Positive_Synchronization_Behavior") { using namespace std::placeholders; HIP_CHECK(hipDeviceSynchronize()); @@ -69,6 +123,30 @@ TEST_CASE("Unit_hipMemcpyAsync_Positive_Synchronization_Behavior") { } } +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When the destination pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When the source pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When memcpy kind is not valid (-1) + * - Expected output: return `hipErrorInvalidMemcpyDirection` + * -# When stream is not valid + * - Expected output: return `hipErrorContextIsDestroyed` + * - Perform handling for following directions: + * -# Host to device + * -# Device to host + * -# Host to host + * -# Device to device + * Test source + * ------------------------ + * - unit/memory/hipMemcpyAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyAsync_Negative_Parameters") { using namespace std::placeholders; constexpr auto InvalidStream = [] { diff --git a/catch/unit/memory/hipMemcpyAsync_derivatives.cc b/catch/unit/memory/hipMemcpyAsync_derivatives.cc index 251c630d5..8bb157542 100644 --- a/catch/unit/memory/hipMemcpyAsync_derivatives.cc +++ b/catch/unit/memory/hipMemcpyAsync_derivatives.cc @@ -25,11 +25,42 @@ THE SOFTWARE. #include #include +/** + * @addtogroup hipMemcpyDtoHAsync hipMemcpyDtoHAsync + * @{ + * @ingroup MemoryTest + * `hipMemcpyDtoHAsync(void* dst, hipDeviceptr_t src, size_t sizeBytes, hipStream_t stream)` - + * Copy data from Device to Host asynchronously. + * ________________________ + * Test cases from other modules: + * - @ref Unit_hipMemcpy_MultiThread_AllAPIs + * - @ref Unit_hipMemcpy_Negative + * - @ref Unit_hipMemcpy_NullCheck + * - @ref Unit_hipMemcpy_HalfMemCopy + */ + static hipStream_t InvalidStream() { StreamGuard sg(Streams::created); return sg.stream(); } +/** + * Test Description + * ------------------------ + * - Validates basic behaviour: + * -# Allocate array on host. + * -# Copy memory from Host to Device. + * -# Synchronize on stream. + * -# Launch kernel. + * -# Copy memory from Device to Host. + * -# Validate results. + * Test source + * ------------------------ + * - unit/memory/hipMemcpyAsync_derivatives.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyDtoHAsync_Positive_Basic") { const auto stream_type = GENERATE(Streams::nullstream, Streams::perThread, Streams::created); const StreamGuard stream_guard(stream_type); @@ -40,6 +71,18 @@ TEST_CASE("Unit_hipMemcpyDtoHAsync_Positive_Basic") { MemcpyDeviceToHostShell(f, stream_guard.stream()); } +/** + * Test Description + * ------------------------ + * - Validate that API synchronizes regarding to host when copying from + * device to pageable and pinned host memory. + * Test source + * ------------------------ + * - unit/memory/hipMemcpyAsync_derivatives.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyDtoHAsync_Positive_Synchronization_Behavior") { HIP_CHECK(hipDeviceSynchronize()); @@ -60,6 +103,23 @@ TEST_CASE("Unit_hipMemcpyDtoHAsync_Positive_Synchronization_Behavior") { } } +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When the destination pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When the source pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When stream is not valid + * - Expected output: return `hipErrorContextIsDestroyed` + * Test source + * ------------------------ + * - unit/memory/hipMemcpyAsync_derivatives.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyDtoHAsync_Negative_Parameters") { using namespace std::placeholders; LinearAllocGuard device_alloc(LinearAllocs::hipMalloc, kPageSize); @@ -79,6 +139,43 @@ TEST_CASE("Unit_hipMemcpyDtoHAsync_Negative_Parameters") { } } +/** + * End doxygen group hipMemcpyDtoHAsync. + * @} + */ + +/** + * @addtogroup hipMemcpyHtoDAsync hipMemcpyHtoDAsync + * @{ + * @ingroup MemoryTest + * `hipMemcpyHtoDAsync(hipDeviceptr_t dst, void* src, + * size_t sizeBytes, hipStream_t stream)` - + * Copy data from Host to Device asynchronously. + * ________________________ + * Test cases from other modules: + * - @ref Unit_hipMemcpy_MultiThread_AllAPIs + * - @ref Unit_hipMemcpy_Negative + * - @ref Unit_hipMemcpy_NullCheck + * - @ref Unit_hipMemcpy_HalfMemCopy + */ + +/** + * Test Description + * ------------------------ + * - Validates basic behaviour: + * -# Allocate array on host. + * -# Copy memory from Host to Device. + * -# Synchronize on stream. + * -# Launch kernel. + * -# Copy memory from Device to Host. + * -# Validate results. + * Test source + * ------------------------ + * - unit/memory/hipMemcpyAsync_derivatives.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyHtoDAsync_Positive_Basic") { const auto stream_type = GENERATE(Streams::nullstream, Streams::perThread, Streams::created); const StreamGuard stream_guard(stream_type); @@ -89,6 +186,19 @@ TEST_CASE("Unit_hipMemcpyHtoDAsync_Positive_Basic") { MemcpyHostToDeviceShell(f, stream_guard.stream()); } +/** + * Test Description + * ------------------------ + * - Validates that the API is asynchronous regarding to: + * -# Copying from pageable or pinned host memory to device memory + * - Platform specific (NVIDIA) + * Test source + * ------------------------ + * - unit/memory/hipMemcpyAsync_derivatives.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyHtoDAsync_Positive_Synchronization_Behavior") { // This behavior differs on NVIDIA and AMD, on AMD the hipMemcpy calls is synchronous with // respect to the host @@ -105,6 +215,23 @@ TEST_CASE("Unit_hipMemcpyHtoDAsync_Positive_Synchronization_Behavior") { false); } +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When the destination pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When the source pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When stream is not valid + * - Expected output: return `hipErrorContextIsDestroyed` + * Test source + * ------------------------ + * - unit/memory/hipMemcpyAsync_derivatives.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyHtoDAsync_Negative_Parameters") { using namespace std::placeholders; LinearAllocGuard device_alloc(LinearAllocs::hipMalloc, kPageSize); @@ -123,6 +250,45 @@ TEST_CASE("Unit_hipMemcpyHtoDAsync_Negative_Parameters") { } } +/** + * End doxygen group hipMemcpyHtoDAsync. + * @} + */ + +/** + * @addtogroup hipMemcpyDtoDAsync hipMemcpyDtoDAsync + * @{ + * @ingroup MemoryTest + * `hipMemcpyDtoDAsync(hipDeviceptr_t dst, hipDeviceptr_t src, + * size_t sizeBytes, hipStream_t stream)` - + * Copy data from Device to Device asynchronously. + * ________________________ + * Test cases from other modules: + * - @ref Unit_hipMemcpy_MultiThread_AllAPIs + * - @ref Unit_hipMemcpy_Negative + * - @ref Unit_hipMemcpy_NullCheck + * - @ref Unit_hipMemcpy_HalfMemCopy + */ + +/** + * Test Description + * ------------------------ + * - Validates basic behaviour: + * -# Allocate array on host. + * -# Allocate another array on host. + * -# Copy memory from Host to Device. + * -# Synchronize on stream. + * -# Validate results. + * - Cheks two possible scenarios: + * -# Peer access enabled + * -# Peer access disabled + * Test source + * ------------------------ + * - unit/memory/hipMemcpyAsync_derivatives.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyDtoDAsync_Positive_Basic") { const auto stream_type = GENERATE(Streams::nullstream, Streams::perThread, Streams::created); const StreamGuard stream_guard(stream_type); @@ -145,6 +311,18 @@ TEST_CASE("Unit_hipMemcpyDtoDAsync_Positive_Basic") { } } +/** + * Test Description + * ------------------------ + * - Validates that API is asynchronous regaring to host when copying from device + * memory to device memory. + * Test source + * ------------------------ + * - unit/memory/hipMemcpyAsync_derivatives.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyDtoDAsync_Positive_Synchronization_Behavior") { MemcpyDtoDSyncBehavior( [](void* dst, void* src, size_t count) { @@ -154,6 +332,23 @@ TEST_CASE("Unit_hipMemcpyDtoDAsync_Positive_Synchronization_Behavior") { false); } +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When the destination pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When the source pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When stream is not valid + * - Expected output: return `hipErrorContextIsDestroyed` + * Test source + * ------------------------ + * - unit/memory/hipMemcpyAsync_derivatives.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyDtoDAsync_Negative_Parameters") { using namespace std::placeholders; LinearAllocGuard src_alloc(LinearAllocs::hipMalloc, kPageSize); @@ -172,4 +367,4 @@ TEST_CASE("Unit_hipMemcpyDtoDAsync_Negative_Parameters") { InvalidStream()), hipErrorContextIsDestroyed); } -} \ No newline at end of file +} diff --git a/catch/unit/memory/hipMemcpyAtoH.cc b/catch/unit/memory/hipMemcpyAtoH.cc index 493345429..a35bbc2b4 100644 --- a/catch/unit/memory/hipMemcpyAtoH.cc +++ b/catch/unit/memory/hipMemcpyAtoH.cc @@ -24,6 +24,28 @@ THE SOFTWARE. #include #include +/** + * @addtogroup hipMemcpyAtoH hipMemcpyAtoH + * @{ + * @ingroup MemoryTest + * `hipMemcpyAtoH(void* dst, hipArray* srcArray, size_t srcOffset, size_t count)` - + * Copies data between host and device. + */ + +/** + * Test Description + * ------------------------ + * - Validates basic behaviour for copying memory from device array + * to the host. + * - The test is run for a various sizes, host allocation types and flag + * combinations. + * Test source + * ------------------------ + * - unit/memory/hipMemcpyAtoH.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyAtoH_Positive_Default") { CHECK_IMAGE_SUPPORT @@ -35,6 +57,18 @@ TEST_CASE("Unit_hipMemcpyAtoH_Positive_Default") { MemcpyAtoHShell(std::bind(hipMemcpyAtoH, _1, _2, 0, allocation_size), width); } +/** + * Test Description + * ------------------------ + * - Validates that API synchronizes regarding to host when copying from + * pageable or pinned host memory to device memory. + * Test source + * ------------------------ + * - unit/memory/hipMemcpyAtoH.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyAtoH_Positive_Synchronization_Behavior") { CHECK_IMAGE_SUPPORT @@ -51,11 +85,22 @@ TEST_CASE("Unit_hipMemcpyAtoH_Positive_Synchronization_Behavior") { } /* -This testcase verifies size 0 check of hipMemcpyAtoH API Excluded the testcase for amd,as there is already a bug raised SWDEV-274683 */ #if HT_NVIDIA +/** + * Test Description + * ------------------------ + * - Validates that nothing will be copied if count is set to zero. + * Test source + * ------------------------ + * - unit/memory/hipMemcpyAtoH.cc + * Test requirements + * ------------------------ + * - Platfom specific (NVIDIA) + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyAtoH_Positive_ZeroCount") { CHECK_IMAGE_SUPPORT @@ -80,6 +125,27 @@ TEST_CASE("Unit_hipMemcpyAtoH_Positive_ZeroCount") { } #endif +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When destination pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When source pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When offset is greater than allocated size + * - Expected output: return `hipErrorInvalidValue` + * -# When count is greater than allocated size + * - Expected output: return `hipErrorInvalidValue` + * -# When 2D array is allocated + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMemcpyAtoH.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyAtoH_Negative_Parameters") { CHECK_IMAGE_SUPPORT diff --git a/catch/unit/memory/hipMemcpyDtoD.cc b/catch/unit/memory/hipMemcpyDtoD.cc index ff5eb2c90..aec12c889 100644 --- a/catch/unit/memory/hipMemcpyDtoD.cc +++ b/catch/unit/memory/hipMemcpyDtoD.cc @@ -17,27 +17,31 @@ OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* -This testcase verifies the hipMemcpyDtoD basic scenario -1. H2D-KernelLaunch-D2H scenario -*/ - #include #include #include +/** + * @addtogroup hipMemcpyDtoD hipMemcpyDtoD + * @{ + * @ingroup MemoryTest + */ + static constexpr auto NUM_ELM{1024}; -/* -This testcase verifies hipMemcpyDtoD API -1.Initializes device variables -2.Launches kernel and performs the sum of device variables -3.Copies the result to host variable and validates the result. -4.Sets the peer device -5.D2D copy from GPU-0 to GPU-1 -6.Kernel Launch -7.DtoH copy and validating the result -*/ +/** + * Test Description + * ------------------------ + * - Validates basic device to device test case. + * - Launches kernels and validates the results. + * Test source + * ------------------------ + * - unit/memory/hipMemcpyDtoD.cc + * Test requirements + * ------------------------ + * - Devices support peer to peer access + * - HIP_VERSION >= 5.2 + */ TEMPLATE_TEST_CASE("Unit_hipMemcpyDtoD_Basic", "", int, float, double) { size_t Nbytes = NUM_ELM * sizeof(TestType); diff --git a/catch/unit/memory/hipMemcpyDtoDAsync.cc b/catch/unit/memory/hipMemcpyDtoDAsync.cc index 8dc20bf61..7fda68865 100644 --- a/catch/unit/memory/hipMemcpyDtoDAsync.cc +++ b/catch/unit/memory/hipMemcpyDtoDAsync.cc @@ -17,28 +17,31 @@ OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* -This testcase verifies the Basic scenario -1. H2D-KernelLaunch-D2H then D2D-KernelLaunch-D2H in peer GPU -*/ - #include #include #include -static constexpr auto NUM_ELM{1024}; +/** + * @addtogroup hipMemcpyDtoDAsync hipMemcpyDtoDAsync + * @{ + * @ingroup MemoryTest + */ -/* -This testcase verifies hipMemcpyDtoDAsync API -1.Initializes device variables -2.Launches kernel and performs the sum of device variables -3.Copies the result to host variable and validates the result. -4.Sets the peer device -5.D2D copy from GPU-0 to GPU-1 -6.Kernel Launch -7.DtoH copy and validating the result -*/ +static constexpr auto NUM_ELM{1024}; +/** + * Test Description + * ------------------------ + * - Validates basic device to device asynchronous test case. + * - Launches kernels and validates the results. + * Test source + * ------------------------ + * - unit/memory/hipMemcpyDtoDAsync.cc + * Test requirements + * ------------------------ + * - Device supports peer to peer access + * - HIP_VERSION >= 5.2 + */ TEMPLATE_TEST_CASE("Unit_hipMemcpyDtoDAsync_Basic", "", int, float, double) { size_t Nbytes = NUM_ELM * sizeof(TestType); diff --git a/catch/unit/memory/hipMemcpyFromSymbol.cc b/catch/unit/memory/hipMemcpyFromSymbol.cc index ff38ddd06..89c734bae 100644 --- a/catch/unit/memory/hipMemcpyFromSymbol.cc +++ b/catch/unit/memory/hipMemcpyFromSymbol.cc @@ -19,11 +19,44 @@ THE SOFTWARE. #include +/** + * @addtogroup hipMemcpyToSymbol hipMemcpyToSymbol + * @{ + * @ingroup MemoryTest + * `hipMemcpyToSymbol(const void* symbol, const void* src, size_t sizeBytes, + * size_t offset __dparm(0), hipMemcpyKind kind __dparm(hipMemcpyHostToDevice))` - + * Copies data to the given symbol on the device. + */ + __device__ int devSymbol[10]; -/* Test verifies hipMemcpy[From/To]Symbol[Async] API Negative scenarios. +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When source pointer is `nullptr` + * - Expected output for @ref hipMemcpyToSymbol + * and @ref hipMemcpyToSymbolAsync : return `hipErrorInvalidSymbol` + * - Expected output for @ref hipMemcpyFromSymbol + * and @ref hipMemcpyFromSymbolAsync : return `hipErrorInvalidValue` + * -# When destination pointer is `nullptr` + * - Expected output for @ref hipMemcpyToSymbol + * and @ref hipMemcpyToSymbolAsync : return `hipErrorInvalidValue` + * - Expected output for @ref hipMemcpyFromSymbol + * and @ref hipMemcpyFromSymbolAsync : return `hipErrorInvalidSymbol` + * -# When size is not valid + * - Expected output: return `hipErrorInvalidValue` + * -# When offset is not valid + * - Expected output: return `hipErrorInvalidValue` + * -# When direction is not valid (-1) + * - Expected output: return `hipErrorInvalidMemcpyDirection` + * Test source + * ------------------------ + * - unit/memory/hipMemcpyFromSymbol.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 */ - TEST_CASE("Unit_hipMemcpyFromToSymbol_Negative") { SECTION("Invalid Src Ptr") { int result{0}; @@ -104,12 +137,21 @@ TEST_CASE("Unit_hipMemcpyFromToSymbol_Negative") { } } -/* - * Test Verifies hipMemcpyToSymbol/hipMemcpyFromSymbol and Async Variants for simple use case - * For single valuea To and From Symbol - * For Array Values To and From Symbol - * For Array Values with offset To and From Symbol - * For Sync and Async Variants*/ +/** + * Test Description + * ------------------------ + * - Validates that the valid symbol is returned after being set. + * - Executes test cases for both synchronous and asynchronous API versions: + * -# When symbol is singular value + * -# When symbol is array value + * -# When symbol is offset'ed value + * Test source + * ------------------------ + * - unit/memory/hipMemcpyFromSymbol.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyToFromSymbol_SyncAndAsync") { enum StreamTestType { NullStream = 0, StreamPerThread, CreatedStream, NoStream }; @@ -188,3 +230,59 @@ TEST_CASE("Unit_hipMemcpyToFromSymbol_SyncAndAsync") { } } } + +/** + * End doxygen group hipMemcpyToSymbol. + * @} + */ + +/** + * @addtogroup hipMemcpyToSymbolAsync hipMemcpyToSymbolAsync + * @{ + * @ingroup MemoryTest + * `hipMemcpyToSymbolAsync(const void* symbol, const void* src, size_t sizeBytes, + * size_t offset, hipMemcpyKind kind, hipStream_t stream __dparm(0))` - + * Copies data to the given symbol on the device asynchronously. + * ________________________ + * Test cases from other modules: + * - @ref Unit_hipMemcpyFromToSymbol_Negative + * - @ref Unit_hipMemcpyToFromSymbol_SyncAndAsync + */ +/** + * End doxygen group hipMemcpyToSymbolAsync. + * @} + */ + +/** + * @addtogroup hipMemcpyFromSymbol hipMemcpyFromSymbol + * @{ + * @ingroup MemoryTest + * `hipMemcpyFromSymbol(void* dst, const void* symbol, size_t sizeBytes, + * size_t offset __dparm(0), hipMemcpyKind kind __dparm(hipMemcpyDeviceToHost))` - + * Copies data from the given symbol on the device. + * ________________________ + * Test cases from other modules: + * - @ref Unit_hipMemcpyFromToSymbol_Negative + * - @ref Unit_hipMemcpyToFromSymbol_SyncAndAsync + */ +/** + * End doxygen group hipMemcpyFromSymbol. + * @} + */ + +/** + * @addtogroup hipMemcpyFromSymbolAsync hipMemcpyFromSymbolAsync + * @{ + * @ingroup MemoryTest + * `hipMemcpyFromSymbolAsync(void* dst, const void* symbol, size_t sizeBytes, + * size_t offset, hipMemcpyKind kind, hipStream_t stream __dparm(0))` - + * Copies data from the given symbol on the device asynchronously. + * ________________________ + * Test cases from other modules: + * - @ref Unit_hipMemcpyFromToSymbol_Negative + * - @ref Unit_hipMemcpyToFromSymbol_SyncAndAsync + */ +/** + * End doxygen group hipMemcpyFromSymbolAsync. + * @} + */ diff --git a/catch/unit/memory/hipMemcpyHtoA.cc b/catch/unit/memory/hipMemcpyHtoA.cc index 6243b452f..82d191fe3 100644 --- a/catch/unit/memory/hipMemcpyHtoA.cc +++ b/catch/unit/memory/hipMemcpyHtoA.cc @@ -16,16 +16,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* -Testcase Scenarios : -Unit_hipMemcpyHtoA_Positive_Default - Test basic memcpy between host and 1D -array with hipMemcpyHtoA api -Unit_hipMemcpyHtoA_Positive_Synchronization_Behavior - Test synchronization -behavior for hipMemcpyHtoA api Unit_hipMemcpyHtoA_Positive_ZeroCount - Test that -no data is copied when allocation_size is set to 0 -Unit_hipMemcpyHtoA_Negative_Parameters - Test unsuccessful execution of -hipMemcpyHtoA api when parameters are invalid -*/ #include "array_memcpy_tests_common.hh" #include @@ -33,7 +23,29 @@ hipMemcpyHtoA api when parameters are invalid #include #include - +/** + * @addtogroup hipMemcpyHtoA hipMemcpyHtoA + * @{ + * @ingroup MemoryTest + * `hipMemcpyHtoA(hipArray* dstArray, size_t dstOffset, + * const void* srcHost, size_t count)` - + * Copies data between host and device. + */ + +/** + * Test Description + * ------------------------ + * - Validates basic behaviour for copying memory from host + * to the device array. + * - The test is run for a various sizes, host allocation types and flag + * combinations. + * Test source + * ------------------------ + * - unit/memory/hipMemcpyHtoA.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyHtoA_Positive_Default") { CHECK_IMAGE_SUPPORT @@ -45,6 +57,18 @@ TEST_CASE("Unit_hipMemcpyHtoA_Positive_Default") { MemcpyHtoAShell(std::bind(hipMemcpyHtoA, _1, 0, _2, allocation_size), width); } +/** + * Test Description + * ------------------------ + * - Validates that API synchronizes regarding to host when copying from + * pageable or pinned host memory to device memory. + * Test source + * ------------------------ + * - unit/memory/hipMemcpyHtoA.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyHtoA_Positive_Synchronization_Behavior") { CHECK_IMAGE_SUPPORT @@ -58,11 +82,22 @@ TEST_CASE("Unit_hipMemcpyHtoA_Positive_Synchronization_Behavior") { } /* -This testcase verifies the size 0 check of hipMemcpyHtoA API This is excluded for AMD as we have a bug already raised SWDEV-274683 */ #if HT_NVIDIA +/** + * Test Description + * ------------------------ + * - Validates that nothing will be copied if count is set to zero. + * Test source + * ------------------------ + * - unit/memory/hipMemcpyHtoA.cc + * Test requirements + * ------------------------ + * - Platfom specific (NVIDIA) + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyHtoA_Positive_ZeroCount") { CHECK_IMAGE_SUPPORT @@ -90,6 +125,27 @@ TEST_CASE("Unit_hipMemcpyHtoA_Positive_ZeroCount") { } #endif +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When destination pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When source pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When offset is greater than allocated size + * - Expected output: return `hipErrorInvalidValue` + * -# When count is greater than allocated size + * - Expected output: return `hipErrorInvalidValue` + * -# When 2D array is allocated + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMemcpyHtoA.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyHtoA_Negative_Parameters") { CHECK_IMAGE_SUPPORT diff --git a/catch/unit/memory/hipMemcpyParam2D.cc b/catch/unit/memory/hipMemcpyParam2D.cc index f2b5b270c..109482f81 100644 --- a/catch/unit/memory/hipMemcpyParam2D.cc +++ b/catch/unit/memory/hipMemcpyParam2D.cc @@ -27,6 +27,35 @@ THE SOFTWARE. #include #include +/** + * @addtogroup hipMemcpyParam2D hipMemcpyParam2D + * @{ + * @ingroup MemoryTest + * `hipMemcpyParam2D(const hip_Memcpy2D* pCopy)` - + * Copies memory for 2D arrays. + */ + +/** + * Test Description + * ------------------------ + * - Verifies basic test cases for copying 2D memory between + * device and host, using parameters. + * - Validates following memcpy directions: + * -# Device to host + * - Platform specific (NVIDIA) + * -# Device to device + * - Peer access disabled + * - Peer access enabled + * -# Host to device + * -# Host to host + * - Platform specific (NVIDIA) + * Test source + * ------------------------ + * - unit/memory/hipMemcpyParam2D.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyParam2D_Positive_Basic") { constexpr bool async = false; @@ -50,6 +79,27 @@ TEST_CASE("Unit_hipMemcpyParam2D_Positive_Basic") { #endif } +/** + * Test Description + * ------------------------ + * - Validates that API synchronizes regarding to host when copying from + * device memory to the pageable or pinned host memory. + * - Validates following memcpy directions: + * -# Host to device + * -# Device to pageable host + * -# Device to pinned host + * - Platform specific (NVIDIA) + * -# Device to device + * - Platform specific (NVIDIA) + * -# Host to host + * - Platform specific (NVIDIA) + * Test source + * ------------------------ + * - unit/memory/hipMemcpyParam2D.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyParam2D_Positive_Synchronization_Behavior") { HIP_CHECK(hipDeviceSynchronize()); @@ -78,11 +128,43 @@ TEST_CASE("Unit_hipMemcpyParam2D_Positive_Synchronization_Behavior") { #endif } +/** + * Test Description + * ------------------------ + * - Validates that nothing will be copied if width or height are set to zero. + * - Validates following memcpy directions: + * -# Device to host + * -# Device to device + * -# Host to device + * -# Host to host + * Test source + * ------------------------ + * - unit/memory/hipMemcpyParam2D.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyParam2D_Positive_Parameters") { constexpr bool async = false; Memcpy2DZeroWidthHeight(MemcpyParam2DAdapter()); } +/** + * Test Description + * ------------------------ + * - Validates that an array is successfully copied. + * - Validates following memcpy directions: + * -# Device to host + * -# Device to device + * -# Host to device + * -# Host to host + * Test source + * ------------------------ + * - unit/memory/hipMemcpyParam2D.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyParam2D_Positive_Array") { constexpr bool async = false; SECTION("Array from/to Host") { @@ -93,6 +175,46 @@ TEST_CASE("Unit_hipMemcpyParam2D_Positive_Array") { } } +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When destination pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When source pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When destination pitch is less than width + * - Expected output: return `hipErrorInvalidPitchValue` + * -# When source pitch is less than width + * - Expected output: return `hipErrorInvalidPitchValue` + * -# When destination pitch is larger than maximum pitch + * - Expected output: return `hipErrorInvalidValue` + * -# When source pitch is larger than maximum pitch + * - Expected output: return `hipErrorInvalidValue` + * -# When WidthInBytes + srcXInBytes > srcPitch + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When WidthInBytes + dstXInBytes > dstPitch + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When srcY out of bounds, without adjusting height accordingly + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When dstY out of bounds, without adjusting height accordingly + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * - All cases are executed for following memcpy directions: + * -# Host to device + * -# Device to host + * -# Host to host + * -# Device to device + * Test source + * ------------------------ + * - unit/memory/hipMemcpyParam2D.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyParam2D_Negative_Parameters") { constexpr size_t cols = 128; constexpr size_t rows = 128; @@ -192,4 +314,4 @@ TEST_CASE("Unit_hipMemcpyParam2D_Negative_Parameters") { NegativeTests(dst_alloc.ptr(), dst_alloc.pitch(), src_alloc.ptr(), src_alloc.pitch(), dst_alloc.width(), dst_alloc.height(), hipMemcpyDeviceToDevice); } -} \ No newline at end of file +} diff --git a/catch/unit/memory/hipMemcpyParam2DAsync.cc b/catch/unit/memory/hipMemcpyParam2DAsync.cc index 44ec9b01c..0ab8c0c3a 100644 --- a/catch/unit/memory/hipMemcpyParam2DAsync.cc +++ b/catch/unit/memory/hipMemcpyParam2DAsync.cc @@ -27,6 +27,39 @@ THE SOFTWARE. #include #include +/** + * @addtogroup hipMemcpyParam2DAsync hipMemcpyParam2DAsync + * @{ + * @ingroup MemoryTest + * `hipMemcpyParam2DAsync(const hip_Memcpy2D* pCopy, hipStream_t stream __dparm(0))` - + * Copies memory for 2D arrays. + */ + +/** + * Test Description + * ------------------------ + * - Validates basic scenario of 2D asynchronous copying + * with params. + * - Uses following types of streams: + * -# Default (null stream) + * -# Per thread + * -# Created (non-null stream) + * - Validates following memcpy directions: + * -# Device to host + * - Platform specific (NVIDIA) + * -# Device to device + * - Peer access disabled + * - Peer access enabled + * -# Host to device + * -# Host to host + * - Platform specific (NVIDIA) + * Test source + * ------------------------ + * - unit/memory/hipMemcpyParam2DAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyParam2DAsync_Positive_Basic") { using namespace std::placeholders; @@ -64,6 +97,27 @@ TEST_CASE("Unit_hipMemcpyParam2DAsync_Positive_Basic") { #endif } +/** + * Test Description + * ------------------------ + * - Validates that API synchronizes regarding to host when copying + * from device memory to pageable or pinned host memory. + * - Validates following memcpy directions: + * -# Host to device + * -# Device to pageable host + * - Platform specific (NVIDIA) + * -# Device to pinned host + * - Platform specific (NVIDIA) + * -# Device to device + * -# Host to host + * - Platform specific (NVIDIA) + * Test source + * ------------------------ + * - unit/memory/hipMemcpyParam2DAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyParam2DAsync_Positive_Synchronization_Behavior") { using namespace std::placeholders; @@ -99,11 +153,43 @@ TEST_CASE("Unit_hipMemcpyParam2DAsync_Positive_Synchronization_Behavior") { #endif } +/** + * Test Description + * ------------------------ + * - Validates that nothing will be copied if width or height are set to zero. + * - Validates following memcpy directions: + * -# Device to host + * -# Device to device + * -# Host to device + * -# Host to host + * Test source + * ------------------------ + * - unit/memory/hipMemcpyParam2DAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyParam2DAsync_Positive_Parameters") { constexpr bool async = true; Memcpy2DZeroWidthHeight(MemcpyParam2DAdapter()); } +/** + * Test Description + * ------------------------ + * - Validates that an array is successfully copied. + * - Validates following memcpy directions: + * -# Device to host + * -# Device to device + * -# Host to device + * -# Host to host + * Test source + * ------------------------ + * - unit/memory/hipMemcpyParam2DAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyParam2DAsync_Positive_Array") { constexpr bool async = true; SECTION("Array from/to Host") { @@ -114,6 +200,49 @@ TEST_CASE("Unit_hipMemcpyParam2DAsync_Positive_Array") { } } +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When destination pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When source pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When destination pitch is less than width + * - Expected output: return `hipErrorInvalidPitchValue` + * -# When source pitch is less than width + * - Expected output: return `hipErrorInvalidPitchValue` + * -# When destination pitch is larger than maximum pitch + * - Expected output: return `hipErrorInvalidValue` + * -# When source pitch is larger than maximum pitch + * - Expected output: return `hipErrorInvalidValue` + * -# When WidthInBytes + srcXInBytes > srcPitch + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When WidthInBytes + dstXInBytes > dstPitch + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When srcY out of bounds, without adjusting height accordingly + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When dstY out of bounds, without adjusting height accordingly + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When stream is not valid + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorContextIsDestroyed` + * - All cases are executed for following memcpy directions: + * -# Host to device + * -# Device to host + * -# Host to host + * -# Device to device + * Test source + * ------------------------ + * - unit/memory/hipMemcpyParam2DAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyParam2DAsync_Negative_Parameters") { constexpr bool async = true; @@ -217,4 +346,4 @@ TEST_CASE("Unit_hipMemcpyParam2DAsync_Negative_Parameters") { NegativeTests(dst_alloc.ptr(), dst_alloc.pitch(), src_alloc.ptr(), src_alloc.pitch(), dst_alloc.width(), dst_alloc.height(), hipMemcpyDeviceToDevice); } -} \ No newline at end of file +} diff --git a/catch/unit/memory/hipMemcpyPeer.cc b/catch/unit/memory/hipMemcpyPeer.cc index c04a84c02..0a3bf5a46 100644 --- a/catch/unit/memory/hipMemcpyPeer.cc +++ b/catch/unit/memory/hipMemcpyPeer.cc @@ -16,7 +16,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - #include #include #include @@ -179,9 +178,9 @@ TEST_CASE("Unit_hipMemcpyPeer_Positive_ZeroSize") { const auto element_count = allocation_size / sizeof(*src_alloc.ptr()); constexpr auto thread_count = 1024; const auto block_count = element_count / thread_count + 1; - constexpr int set_value_s = 22; + constexpr int set_value = 22; HIP_CHECK(hipSetDevice(src_device)); - VectorSet<<>>(src_alloc.ptr(), set_value_s, element_count); + VectorSet<<>>(src_alloc.ptr(), set_value, element_count); HIP_CHECK(hipGetLastError()); constexpr int expected_value = 20; diff --git a/catch/unit/memory/hipMemcpyPeerAsync.cc b/catch/unit/memory/hipMemcpyPeerAsync.cc index d86da680d..d0bb7a165 100644 --- a/catch/unit/memory/hipMemcpyPeerAsync.cc +++ b/catch/unit/memory/hipMemcpyPeerAsync.cc @@ -16,7 +16,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - #include #include #include @@ -193,19 +192,13 @@ TEST_CASE("Unit_hipMemcpyPeerAsync_Positive_ZeroSize") { const auto element_count = allocation_size / sizeof(*src_alloc.ptr()); constexpr auto thread_count = 1024; const auto block_count = element_count / thread_count + 1; - constexpr int set_value_s = 22; + constexpr int set_value = 22; HIP_CHECK(hipSetDevice(src_device)); - VectorSet<<>>(src_alloc.ptr(), set_value_s, element_count); + VectorSet<<>>(src_alloc.ptr(), set_value, element_count); HIP_CHECK(hipGetLastError()); - constexpr int expected_value = 20; - HIP_CHECK(hipSetDevice(dst_device)); - VectorSet<<>>(dst_alloc.ptr(), expected_value, element_count); - HIP_CHECK(hipGetLastError()); - HIP_CHECK(hipSetDevice(src_device)); - - constexpr int set_value_h = 21; - std::fill_n(result.host_ptr(), element_count, set_value_h); + constexpr int expected_value = 21; + std::fill_n(src_alloc.host_ptr(), element_count, expected_value); HIP_CHECK( hipMemcpyPeerAsync(dst_alloc.ptr(), dst_device, src_alloc.ptr(), src_device, 0, stream)); @@ -259,7 +252,7 @@ TEST_CASE("Unit_hipMemcpyPeerAsync_Negative_Parameters") { const hipStream_t stream = stream_guard.stream(); constexpr auto InvalidStream = [] { - const StreamGuard sg(Streams::created); + StreamGuard sg(Streams::created); return sg.stream(); }; diff --git a/catch/unit/memory/hipMemcpySync.cc b/catch/unit/memory/hipMemcpySync.cc index bef3c953f..e71492f3f 100644 --- a/catch/unit/memory/hipMemcpySync.cc +++ b/catch/unit/memory/hipMemcpySync.cc @@ -177,6 +177,23 @@ static void runMemcpyTests(hipStream_t stream, bool async, allocType type, memTy #if HT_AMD /* Disabled because frequency based wait is timing out on nvidia platforms */ +/** + * @addtogroup hipMemcpy hipMemcpy + * @{ + * @ingroup MemoryTest + */ +/** + * Test Description + * ------------------------ + * - Validates synchronization behaviour of the API. + * Test source + * ------------------------ + * - unit/memory/hipMemcpySync.cc + * Test requirements + * ------------------------ + * - Platform specific (AMD) + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpySync") { #if HT_AMD // To be removed when EXSWCPHIPT-127 is fixed HipTest::HIP_SKIP_TEST("EXSWCPHIPT-127 - Sync behaviour differs on AMD and Nvidia"); @@ -190,7 +207,28 @@ TEST_CASE("Unit_hipMemcpySync") { doMemTest(runMemcpyTests, type, memcpy_type, data); // Uses long running kernel } +/** + * End doxygen group hipMemcpy. + * @} + */ +/** + * @addtogroup hipMemcpy2D hipMemcpy2D + * @{ + * @ingroup MemoryTest + */ +/** + * Test Description + * ------------------------ + * - Validates synchronization behaviour of the API. + * Test source + * ------------------------ + * - unit/memory/hipMemcpySync.cc + * Test requirements + * ------------------------ + * - Platform specific (AMD) + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy2DSync") { #if HT_AMD HipTest::HIP_SKIP_TEST("EXSWCPHIPT-127 - Sync behaviour differs on AMD and Nvidia"); @@ -206,7 +244,28 @@ TEST_CASE("Unit_hipMemcpy2DSync") { doMemTest(runMemcpyTests, mallocType, memcpy_type, data); } +/** + * End doxygen group hipMemcpy2D. + * @} + */ +/** + * @addtogroup hipMemcpy3D hipMemcpy3D + * @{ + * @ingroup MemoryTest + */ +/** + * Test Description + * ------------------------ + * - Validates synchronization behaviour of the API. + * Test source + * ------------------------ + * - unit/memory/hipMemcpySync.cc + * Test requirements + * ------------------------ + * - Platform specific (AMD) + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy3DSync") { #if HT_AMD HipTest::HIP_SKIP_TEST("EXSWCPHIPT-127 - Sync behaviour differs on AMD and Nvidia"); diff --git a/catch/unit/memory/hipMemcpyWithStream.cc b/catch/unit/memory/hipMemcpyWithStream.cc index 24e11c25f..ea8a7c5da 100644 --- a/catch/unit/memory/hipMemcpyWithStream.cc +++ b/catch/unit/memory/hipMemcpyWithStream.cc @@ -25,8 +25,59 @@ THE SOFTWARE. #include #include +/** + * @addtogroup hipMemcpyWithStream hipMemcpyWithStream + * @{ + * @ingroup MemoryTest + * `hipMemcpyWithStream(void* dst, const void* src, size_t sizeBytes, + * hipMemcpyKind kind, hipStream_t stream)` - + * Copy data from src to dst over specified stream. + */ + +/** + * Test Description + * ------------------------ + * - Validate basic device to host behaviour with Device to Host and Default kind. + * - Following copy scenarios are considered: + * -# Device to Host + * -# Device to Host with default kind + * -# Host to Device + * -# Host to Device with default kind + * -# Host to Host + * -# Host to Host with default kind + * -# Device to Device + * - Peer access enabled + * - Peer access disabled + * -# Device to Device with default kind + * - Peer access enabled + * - Peer access disabled + * Test source + * ------------------------ + * - unit/memory/hipMemcpyWithStream.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy_Positive_Basic") { MemcpyWithDirectionCommonTests(hipMemcpy); } +/** + * Test Description + * ------------------------ + * - Validates that the API synchronizes regarding to: + * -# Copying from pageable or pinned host memory to device memory + * -# Copying from device memory to pageable or pinned host memory + * - Validates that the API is asynchronous regarding to: + * -# Copying from device memory to device memory + * - Platform specific (NVIDIA) + * -# Copying from pageable or pinned host memory to pageable or pinned + * host memory + * Test source + * ------------------------ + * - unit/memory/hipMemcpyWithStream.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy_Positive_Synchronization_Behavior") { using namespace std::placeholders; HIP_CHECK(hipDeviceSynchronize()); @@ -68,6 +119,29 @@ TEST_CASE("Unit_hipMemcpy_Positive_Synchronization_Behavior") { } } +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When the destination pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When the source pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When memcpy kind is not valid (-1) + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidMemcpyDirection` + * - Following scenarios are performed for the following memcpy kinds: + * -# Host to Device + * -# Device to Host + * -# Host to Host + * -# Device to Device + * Test source + * ------------------------ + * - unit/memory/hipMemcpyWithStream.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpy_Negative_Parameters") { using namespace std::placeholders; diff --git a/catch/unit/memory/hipMemcpyWithStreamMultiThread.cc b/catch/unit/memory/hipMemcpyWithStreamMultiThread.cc index 6e906d6ab..19327686f 100644 --- a/catch/unit/memory/hipMemcpyWithStreamMultiThread.cc +++ b/catch/unit/memory/hipMemcpyWithStreamMultiThread.cc @@ -17,17 +17,16 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* - * Different test for checking functionality of - * hipError_t hipMemcpyWithStream(void* dst, const void* src, size_t sizeBytes, - * hipMemcpyKind kind, hipStream_t stream); - */ - - #include #include #include +/** + * @addtogroup hipMemcpyWithStream hipMemcpyWithStream + * @{ + * @ingroup MemoryTest + */ + #define LEN 64 #define SIZE LEN << 2 #define THREADS 2 @@ -579,6 +578,19 @@ void HipMemcpyWithStreamMultiThreadtests::TestkindHtoH(bool& val_res) { HIP_CHECK_THREAD(hipStreamDestroy(stream)); } +/** + * Test Description + * ------------------------ + * - Validates basic behaviour of the memcpy with stream when + * executed from multiple threads. + * Test source + * ------------------------ + * - unit/memory/hipMemcpyWithStreamMultiThread.cc + * Test requirements + * ------------------------ + * - Multi-thread device + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyWithStream_MultiThread") { const auto Threadcount{10}; bool ret_val[Threadcount]; diff --git a/catch/unit/memory/hipMemcpy_MultiThread.cc b/catch/unit/memory/hipMemcpy_MultiThread.cc index d9c08f318..f2ab38a08 100644 --- a/catch/unit/memory/hipMemcpy_MultiThread.cc +++ b/catch/unit/memory/hipMemcpy_MultiThread.cc @@ -22,10 +22,13 @@ THE SOFTWARE. #include #include #include -/* -This testfile verifies the following scenarios of all hipMemcpy API -1. Multi thread -*/ + +/** + * @addtogroup hipMemcpy hipMemcpy + * @{ + * @ingroup MemoryTest + */ + static constexpr auto NUM_ELM{1024}; static constexpr auto NUM_THREADS{5}; static auto Available_Gpus{0}; @@ -304,9 +307,27 @@ void Thread_func(bool &ret_val) { } } - - -TEST_CASE("Unit_hipMemcpy_MultiThread-AllAPIs") { +/** + * Test Description + * ------------------------ + * - Validates behaviour of all memcpy APIs when multiple + * threads are utilized: + * -# @ref hipMemcpy + * -# @ref hipMemcpyHtoD + * -# @ref hipMemcpyDtoH + * -# @ref hipMemcpyDtoD + * -# @ref hipMemcpyAsync + * -# @ref hipMemcpyHtoDAsync + * -# @ref hipMemcpyDtoHAsync + * -# @ref hipMemcpyDtoDAsync + * Test source + * ------------------------ + * - unit/memory/hipMemcpy_MultiThread.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipMemcpy_MultiThread_AllAPIs") { std::thread Thrd[NUM_THREADS]; bool ret_val[NUM_THREADS]; for (int i = 0; i < NUM_THREADS; i++) diff --git a/catch/unit/memory/hipMemcpy_derivatives.cc b/catch/unit/memory/hipMemcpy_derivatives.cc index 037560250..194712eac 100644 --- a/catch/unit/memory/hipMemcpy_derivatives.cc +++ b/catch/unit/memory/hipMemcpy_derivatives.cc @@ -25,13 +25,54 @@ THE SOFTWARE. #include #include -// hipMemcpyDtoH +/** + * @addtogroup hipMemcpyDtoH hipMemcpyDtoH + * @{ + * @ingroup MemoryTest + * `hipMemcpyDtoH(void* dst, hipDeviceptr_t src, size_t sizeBytes)` - + * Copy data from Device to Host. + * ________________________ + * Test cases from other modules: + * - @ref Unit_hipMemcpy_MultiThread_AllAPIs + * - @ref Unit_hipMemcpy_Negative + * - @ref Unit_hipMemcpy_NullCheck + * - @ref Unit_hipMemcpy_HalfMemCopy + */ + +/** + * Test Description + * ------------------------ + * - Validates basic behaviour: + * -# Allocate array on host. + * -# Copy memory from Host to Device. + * -# Launch kernel. + * -# Copy memory from Device to Host. + * -# Validate results. + * Test source + * ------------------------ + * - unit/memory/hipMemcpy_derivatives.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyDtoH_Positive_Basic") { MemcpyDeviceToHostShell([](void* dst, void* src, size_t count) { return hipMemcpyDtoH(dst, reinterpret_cast(src), count); }); } +/** + * Test Description + * ------------------------ + * - Validates that the API synchronizes regarding to host when + * copying from device memory to pageable or pinned host memory. + * Test source + * ------------------------ + * - unit/memory/hipMemcpy_derivatives.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyDtoH_Positive_Synchronization_Behavior") { const auto f = [](void* dst, void* src, size_t count) { return hipMemcpyDtoH(dst, reinterpret_cast(src), count); @@ -40,6 +81,21 @@ TEST_CASE("Unit_hipMemcpyDtoH_Positive_Synchronization_Behavior") { MemcpyDtoHPinnedSyncBehavior(f, true); } +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When the destination pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When the source pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMemcpy_derivatives.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyDtoH_Negative_Parameters") { using namespace std::placeholders; LinearAllocGuard device_alloc(LinearAllocs::hipMalloc, kPageSize); @@ -52,13 +108,59 @@ TEST_CASE("Unit_hipMemcpyDtoH_Negative_Parameters") { host_alloc.ptr(), device_alloc.ptr(), kPageSize); } -// hipMemcpyHtoD +/** + * End doxygen group hipMemcpyDtoH. + * @} + */ + +/** + * @addtogroup hipMemcpyHtoD hipMemcpyHtoD + * @{ + * @ingroup MemoryTest + * `hipMemcpyHtoD(hipDeviceptr_t dst, void* src, size_t sizeBytes)` - + * Copy data from Host to Device. + * ________________________ + * Test cases from other modules: + * - @ref Unit_hipMemcpy_MultiThread_AllAPIs + * - @ref Unit_hipMemcpy_Negative + * - @ref Unit_hipMemcpy_NullCheck + * - @ref Unit_hipMemcpy_HalfMemCopy + */ + +/** + * Test Description + * ------------------------ + * - Validates basic behaviour: + * -# Allocate array on host. + * -# Copy memory from Host to Device. + * -# Launch kernel. + * -# Copy memory from Device to Host. + * -# Validate results. + * Test source + * ------------------------ + * - unit/memory/hipMemcpy_derivatives.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyHtoD_Positive_Basic") { MemcpyHostToDeviceShell([](void* dst, void* src, size_t count) { return hipMemcpyHtoD(reinterpret_cast(dst), src, count); }); } +/** + * Test Description + * ------------------------ + * - Validates that the API synchronizes regarding to host when + * copying from pageable or pinned host memory to device memory. + * Test source + * ------------------------ + * - unit/memory/hipMemcpy_derivatives.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyHtoD_Positive_Synchronization_Behavior") { MemcpyHtoDSyncBehavior( [](void* dst, void* src, size_t count) { @@ -67,6 +169,21 @@ TEST_CASE("Unit_hipMemcpyHtoD_Positive_Synchronization_Behavior") { true); } +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When the destination pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When the source pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMemcpy_derivatives.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyHtoD_Negative_Parameters") { using namespace std::placeholders; LinearAllocGuard device_alloc(LinearAllocs::hipMalloc, kPageSize); @@ -79,7 +196,45 @@ TEST_CASE("Unit_hipMemcpyHtoD_Negative_Parameters") { device_alloc.ptr(), host_alloc.ptr(), kPageSize); } -// hipMemcpyDtoD +/** + * End doxygen group hipMemcpyHtoD. + * @} + */ + +/** + * @addtogroup hipMemcpyDtoD hipMemcpyDtoD + * @{ + * @ingroup MemoryTest + * `hipMemcpyDtoD(hipDeviceptr_t dst, hipDeviceptr_t src, size_t sizeBytes)` - + * Copy data from Device to Device. + * ________________________ + * Test cases from other modules: + * - @ref Unit_hipMemcpy_MultiThread_AllAPIs + * - @ref Unit_hipMemcpy_Negative + * - @ref Unit_hipMemcpy_NullCheck + * - @ref Unit_hipMemcpy_HalfMemCopy + */ + +/** + * Test Description + * ------------------------ + * - Validates basic behaviour: + * -# Allocate memory on the device and host. + * -# Allocate memory on another device. + * -# Launch kernel. + * -# Copy results from device to device. + * -# Copy results from device to host. + * -# Validate results. + * - Basic behavior is checked for following scenarios: + * -# Peer access enabled + * -# Peer access disabled + * Test source + * ------------------------ + * - unit/memory/hipMemcpy_derivatives.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyDtoD_Positive_Basic") { const auto f = [](void* dst, void* src, size_t count) { return hipMemcpyDtoD(reinterpret_cast(dst), @@ -89,6 +244,19 @@ TEST_CASE("Unit_hipMemcpyDtoD_Positive_Basic") { SECTION("Peer access disabled") { MemcpyDeviceToDeviceShell(f); } } +/** + * Test Description + * ------------------------ + * - Validates that API is asynchronous regarding to host when copying + * from device memory to device memory. + * Test source + * ------------------------ + * - unit/memory/hipMemcpy_derivatives.cc + * Test requirements + * ------------------------ + * - Platform specific (NVIDIA) + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyDtoD_Positive_Synchronization_Behavior") { // This behavior differs on NVIDIA and AMD, on AMD the hipMemcpy calls is synchronous with // respect to the host @@ -105,6 +273,21 @@ TEST_CASE("Unit_hipMemcpyDtoD_Positive_Synchronization_Behavior") { false); } +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When the destination pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When the source pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipMemcpy_derivatives.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemcpyDtoD_Negative_Parameters") { using namespace std::placeholders; LinearAllocGuard src_alloc(LinearAllocs::hipMalloc, kPageSize); @@ -116,4 +299,4 @@ TEST_CASE("Unit_hipMemcpyDtoD_Negative_Parameters") { reinterpret_cast(src), count); }, dst_alloc.ptr(), src_alloc.ptr(), kPageSize); -} \ No newline at end of file +} diff --git a/catch/unit/memory/hipMemoryAllocateCoherent.cc b/catch/unit/memory/hipMemoryAllocateCoherent.cc index e9fed1fc8..5d21497e3 100644 --- a/catch/unit/memory/hipMemoryAllocateCoherent.cc +++ b/catch/unit/memory/hipMemoryAllocateCoherent.cc @@ -17,15 +17,16 @@ OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* -This testcase verifies the following scenario -1. Allocating the memory and modifying it coherently -*/ - #include #include #include +/** + * @addtogroup hipHostMalloc hipHostMalloc + * @{ + * @ingroup MemoryTest + */ + constexpr auto wait_sec = 5000; __global__ void Kernel(float* hostRes, int clkRate) { @@ -33,34 +34,34 @@ __global__ void Kernel(float* hostRes, int clkRate) { hostRes[tid] = tid + 1; __threadfence_system(); // expecting that the data is getting flushed to host here! - uint64_t start = clock64()/clkRate, cur; - if (clkRate > 1) { - do { cur = clock64()/clkRate-start;}while (cur < wait_sec); - } else { - do { cur = clock64()/start;}while (cur < wait_sec); - } -} - -__global__ void Kernel_gfx11(float* hostRes, int clkRate) { -#if HT_AMD - int tid = threadIdx.x + blockIdx.x * blockDim.x; - hostRes[tid] = tid + 1; - __threadfence_system(); - // expecting that the data is getting flushed to host here! - uint64_t start = wall_clock64()/clkRate, cur; + uint64_t start = clock64() / clkRate, cur; if (clkRate > 1) { - do { cur = wall_clock64()/clkRate-start;}while (cur < wait_sec); + do { + cur = clock64() / clkRate - start; + } while (cur < wait_sec); } else { - do { cur = wall_clock64()/start;}while (cur < wait_sec); + do { + cur = clock64() / start; + } while (cur < wait_sec); } -#endif } +/** + * Test Description + * ------------------------ + * - Allocates the memory. + * - Modifies it with coherent access. + * Test source + * ------------------------ + * - unit/memory/hipMemoryAllocateCoherent.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipHostMalloc_CoherentAccess") { int blocks = 2; float* hostRes; - HIP_CHECK(hipHostMalloc(&hostRes, blocks * sizeof(float), - hipHostMallocMapped)); + HIP_CHECK(hipHostMalloc(&hostRes, blocks * sizeof(float), hipHostMallocMapped)); hostRes[0] = 0; hostRes[1] = 0; int clkRate; @@ -71,15 +72,15 @@ TEST_CASE("Unit_hipHostMalloc_CoherentAccess") { } std::cout << clkRate << std::endl; auto Kernel_used = IsGfx11() ? Kernel_gfx11 : Kernel; - hipLaunchKernelGGL(HIP_KERNEL_NAME(Kernel_used), dim3(1), dim3(blocks), - 0, 0, hostRes, clkRate); + hipLaunchKernelGGL(HIP_KERNEL_NAME(Kernel_used), dim3(1), dim3(blocks), 0, 0, hostRes, clkRate); HIP_CHECK(hipGetLastError()); int eleCounter = 0; while (eleCounter < blocks) { // blocks until the value changes - while (hostRes[eleCounter] == 0) {printf("waiting for counter inc\n");} + while (hostRes[eleCounter] == 0) { + printf("waiting for counter inc\n"); + } eleCounter++; } - HIP_CHECK(hipHostFree(reinterpret_cast(hostRes))); + HIP_CHECK(hipHostFree(reinterpret_cast(hostRes))); } - diff --git a/catch/unit/memory/hipMemset.cc b/catch/unit/memory/hipMemset.cc index c4adb15e5..5b80f84ff 100644 --- a/catch/unit/memory/hipMemset.cc +++ b/catch/unit/memory/hipMemset.cc @@ -17,20 +17,8 @@ * THE SOFTWARE. */ -/** -Testcase Scenarios : - 1) Test hipMemset small size buffers with unique memset values. - 2) Test hipMemset, hipMemsetD8, hipMemsetD16, hipMemsetD32 apis with unique - number of elements and memset values. - 3) Test hipMemsetAsync, hipMemsetD8Async, hipMemsetD16Async, hipMemsetD32Async - apis with unique number of elements and memset values. - 4) Test two memset async operations at the same time. -*/ - - #include - // Table with unique number of elements and memset values. // (N, memsetval, memsetD32val, memsetD16val, memsetD8val) typedef std::tuple tupletype; @@ -140,10 +128,31 @@ static bool testhipMemsetAsync(T *A_h, T *A_d, T memsetval, return testResult; } +/** + * @addtogroup hipMemset hipMemset + * @{ + * @ingroup MemoryTest + * `hipMemset(void* dst, int value, size_t sizeBytes)` - + * Fills the first sizeBytes bytes of the memory area pointed to by dest with the constant + * byte value value. + */ /** - * Test hipMemset, hipMemsetD8, hipMemsetD16, hipMemsetD32 apis with unique - * number of elements and memset values. + * Test Description + * ------------------------ + * - Uses offsets to set desired value to memory range. + * - Validates that the memory is set as expected. + * - Performs memset for following APIs: + * -# @ref hipMemset + * -# @ref hipMemsetD32 + * -# @ref hipMemsetD16 + * -# @ref hipMemsetD8 + * Test source + * ------------------------ + * - unit/memory/hipMemset.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipMemset_SetMemoryWithOffset") { char memsetval; @@ -182,10 +191,141 @@ TEST_CASE("Unit_hipMemset_SetMemoryWithOffset") { } } +/** + * Test Description + * ------------------------ + * - Tests setting unique values to small buffers. + * Test source + * ------------------------ + * - unit/memory/hipMemset.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipMemset_SmallBufferSizes") { + char *A_d, *A_h; + constexpr int memsetval = 0x24; + + auto numElements = GENERATE(range(1, 4)); + int numBytes = numElements * sizeof(char); + + HIP_CHECK(hipMalloc(&A_d, numBytes)); + A_h = reinterpret_cast (malloc(numBytes)); + + HIP_CHECK(hipMemset(A_d, memsetval, numBytes)); + HIP_CHECK(hipMemcpy(A_h, A_d, numBytes, hipMemcpyDeviceToHost)); + + for (int i = 0; i < numBytes; i++) { + if (A_h[i] != memsetval) { + INFO("Mismatch at index:" << i << " computed:" << A_h[i] + << " memsetval:" << memsetval); + REQUIRE(false); + } + } + + HIP_CHECK(hipFree(A_d)); + free(A_h); +} + +/** + * End doxygen group hipMemset. + * @} + */ + +/** + * @addtogroup hipMemsetD8 hipMemsetD8 + * @{ + * @ingroup MemoryTest + * `hipMemsetD8(hipDeviceptr_t dest, unsigned char value, size_t count)` - + * Fills the first sizeBytes bytes of the memory area pointed to by dest with the constant + * byte value value. + * ________________________ + * Test cases from other modules: + * - @ref Unit_hipMemset_SetMemoryWithOffset + * - @ref Unit_hipMemset_Negative_InvalidPtr + * - @ref Unit_hipMemset_Negative_OutOfBoundsSize + * - @ref Unit_hipMemset_Negative_OutOfBoundsPtr + * - @ref Unit_hipMemsetFunctional_PartialSet_1D + */ +/** + * End doxygen group hipMemsetD8. + * @} + */ + +/** + * @addtogroup hipMemsetD16 hipMemsetD16 + * @{ + * @ingroup MemoryTest + * `hipMemsetD16(hipDeviceptr_t dest, unsigned short value, size_t count)` - + * Fills the first sizeBytes bytes of the memory area pointed to by dest with the constant + * short value value. + * ________________________ + * Test cases from other modules: + * - @ref Unit_hipMemset_SetMemoryWithOffset + * - @ref Unit_hipMemset_Negative_InvalidPtr + * - @ref Unit_hipMemset_Negative_OutOfBoundsSize + * - @ref Unit_hipMemset_Negative_OutOfBoundsPtr + * - @ref Unit_hipMemsetFunctional_PartialSet_1D + */ +/** + * End doxygen group hipMemsetD16. + * @} + */ + +/** + * @addtogroup hipMemsetD32 hipMemsetD32 + * @{ + * @ingroup MemoryTest + * `hipMemsetD32(hipDeviceptr_t dest, int value, size_t count)` - + * Fills the memory area pointed to by dest with the constant integer + * value for specified number of times. + * ________________________ + * Test cases from other modules: + * - @ref Unit_hipMemset_SetMemoryWithOffset + * - @ref Unit_hipMemset_Negative_InvalidPtr + * - @ref Unit_hipMemset_Negative_OutOfBoundsSize + * - @ref Unit_hipMemset_Negative_OutOfBoundsPtr + * - @ref Unit_hipMemsetFunctional_PartialSet_1D + */ +/** + * End doxygen group hipMemsetD32. + * @} + */ /** - * Test hipMemsetAsync, hipMemsetD8Async, hipMemsetD16Async, hipMemsetD32Async - * apis with unique number of elements and memset values. + * @addtogroup hipMemsetAsync hipMemsetAsync + * @{ + * @ingroup MemoryTest + * `hipMemsetAsync(void* dst, int value, size_t sizeBytes, hipStream_t stream __dparm(0))` - + * Fills the first sizeBytes bytes of the memory area pointed to by dev with the constant + * byte value value. + * ________________________ + * Test cases from other modules: + * - @ref Unit_hipMemset_Negative_InvalidPtr + * - @ref Unit_hipMemset_Negative_OutOfBoundsSize + * - @ref Unit_hipMemset_Negative_OutOfBoundsPtr + * - @ref Unit_hipMemsetFunctional_ZeroValue_hipMemset + * - @ref Unit_hipMemsetFunctional_SmallSize_hipMemset + * - @ref Unit_hipMemsetFunctional_ZeroSize_hipMemset + * - @ref Unit_hipMemsetFunctional_PartialSet_1D + */ + +/** + * Test Description + * ------------------------ + * - Uses offsets to set desired value to memory range. + * - Validates that the memory is set as expected. + * - Performs memset for following APIs: + * -# @ref hipMemsetAsync + * -# @ref hipMemsetD32Async + * -# @ref hipMemsetD16Async + * -# @ref hipMemsetD8Async + * Test source + * ------------------------ + * - unit/memory/hipMemset.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipMemsetAsync_SetMemoryWithOffset") { char memsetval; @@ -225,36 +365,18 @@ TEST_CASE("Unit_hipMemsetAsync_SetMemoryWithOffset") { } /** - * Test hipMemset small size buffers with unique memset values. - */ -TEST_CASE("Unit_hipMemset_SmallBufferSizes") { - char *A_d, *A_h; - constexpr int memsetval = 0x24; - - auto numElements = GENERATE(range(1, 4)); - int numBytes = numElements * sizeof(char); - - HIP_CHECK(hipMalloc(&A_d, numBytes)); - A_h = reinterpret_cast (malloc(numBytes)); - - HIP_CHECK(hipMemset(A_d, memsetval, numBytes)); - HIP_CHECK(hipMemcpy(A_h, A_d, numBytes, hipMemcpyDeviceToHost)); - - for (int i = 0; i < numBytes; i++) { - if (A_h[i] != memsetval) { - INFO("Mismatch at index:" << i << " computed:" << A_h[i] - << " memsetval:" << memsetval); - REQUIRE(false); - } - } - - HIP_CHECK(hipFree(A_d)); - free(A_h); -} - - -/** - * Test two memset async operations at the same time. + * Test Description + * ------------------------ + * - Test running two memset asynchronous operations + * in parallel. + * - Perform synchronization. + * - Validate the results. + * Test source + * ------------------------ + * - unit/memory/hipMemset.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipMemset_2AsyncOperations") { std::vector v; @@ -279,3 +401,90 @@ TEST_CASE("Unit_hipMemset_2AsyncOperations") { REQUIRE(v[0] == 0); REQUIRE(v[1024] == 1.75f); } + +/** + * End doxygen group hipMemsetAsync. + * @} + */ + +/** + * @addtogroup hipMemsetD8Async hipMemsetD8Async + * @{ + * @ingroup MemoryTest + * `hipMemsetD8Async(hipDeviceptr_t dest, unsigned char value, + * size_t count, hipStream_t stream __dparm(0))` - + * Fills the first sizeBytes bytes of the memory area pointed to by dest with the constant + * byte value value. + * ________________________ + * Test cases from other modules: + * - @ref Unit_hipMemsetAsync_SetMemoryWithOffset + * - @ref Unit_hipMemset_2AsyncOperations + * - @ref Unit_hipMemset_Negative_InvalidPtr + * - @ref Unit_hipMemset_Negative_OutOfBoundsSize + * - @ref Unit_hipMemset_Negative_OutOfBoundsPtr + * - @ref Unit_hipMemsetAsync_VerifyExecutionWithKernel + * - @ref Unit_hipMemsetAsync_QueueJobsMultithreaded + * - @ref Unit_hipMemsetFunctional_ZeroValue_hipMemsetD8 + * - @ref Unit_hipMemsetFunctional_SmallSize_hipMemsetD8 + * - @ref Unit_hipMemsetFunctional_ZeroSize_hipMemsetD8 + * - @ref Unit_hipMemsetFunctional_PartialSet_1D + */ +/** + * End doxygen group hipMemsetD8Async. + * @} + */ + +/** + * @addtogroup hipMemsetD16Async hipMemsetD16Async + * @{ + * @ingroup MemoryTest + * `hipMemsetD16Async(hipDeviceptr_t dest, unsigned short value, + * size_t count, hipStream_t stream __dparm(0))` - + * Fills the first sizeBytes bytes of the memory area pointed to by dest with the constant + * short value value. + * ________________________ + * Test cases from other modules: + * - @ref Unit_hipMemsetAsync_SetMemoryWithOffset + * - @ref Unit_hipMemset_2AsyncOperations + * - @ref Unit_hipMemset_Negative_InvalidPtr + * - @ref Unit_hipMemset_Negative_OutOfBoundsSize + * - @ref Unit_hipMemset_Negative_OutOfBoundsPtr + * - @ref Unit_hipMemsetDASyncMulti + * - @ref Unit_hipMemsetAsync_VerifyExecutionWithKernel + * - @ref Unit_hipMemsetAsync_QueueJobsMultithreaded + * - @ref Unit_hipMemsetFunctional_ZeroValue_hipMemsetD16 + * - @ref Unit_hipMemsetFunctional_SmallSize_hipMemsetD16 + * - @ref Unit_hipMemsetFunctional_ZeroSize_hipMemsetD16 + * - @ref Unit_hipMemsetFunctional_PartialSet_1D + */ +/** + * End doxygen group hipMemsetD16Async. + * @} + */ + +/** + * @addtogroup hipMemsetD32Async hipMemsetD32Async + * @{ + * @ingroup MemoryTest + * `hipMemsetD32Async(hipDeviceptr_t dst, int value, size_t count, + * hipStream_t stream __dparm(0))` - + * Fills the memory area pointed to by dev with the constant integer + * value for specified number of times. + * ________________________ + * - @ref Unit_hipMemsetAsync_SetMemoryWithOffset + * - @ref Unit_hipMemset_2AsyncOperations + * - @ref Unit_hipMemset_Negative_InvalidPtr + * - @ref Unit_hipMemset_Negative_OutOfBoundsSize + * - @ref Unit_hipMemset_Negative_OutOfBoundsPtr + * - @ref Unit_hipMemsetDASyncMulti + * - @ref Unit_hipMemsetAsync_VerifyExecutionWithKernel + * - @ref Unit_hipMemsetAsync_QueueJobsMultithreaded + * - @ref Unit_hipMemsetFunctional_ZeroValue_hipMemsetD32 + * - @ref Unit_hipMemsetFunctional_SmallSize_hipMemsetD32 + * - @ref Unit_hipMemsetFunctional_ZeroSize_hipMemsetD32 + * - @ref Unit_hipMemsetFunctional_PartialSet_1D + */ +/** + * End doxygen group hipMemsetD32Async. + * @} + */ diff --git a/catch/unit/memory/hipMemset2D.cc b/catch/unit/memory/hipMemset2D.cc index 27284850b..b8fe846ad 100644 --- a/catch/unit/memory/hipMemset2D.cc +++ b/catch/unit/memory/hipMemset2D.cc @@ -17,16 +17,15 @@ * THE SOFTWARE. */ -/** - Testcase Scenarios : - 1) hipMemset2D api with basic functionality. - 2) hipMemset2DAsync api with basic functionality. - 3) hipMemset2D api with partial memset and unique width/height. -*/ - - #include +/** + * @addtogroup hipMemset2D hipMemset2D + * @{ + * @ingroup MemoryTest + * `hipMemset2D(void* dst, size_t pitch, int value, size_t width, size_t height)` - + * Fills the memory area pointed to by dst with the constant value. + */ // Table with unique width/height and memset values. // (width2D, height2D, memsetWidth, memsetHeight) @@ -42,10 +41,17 @@ static constexpr std::initializer_list tableItems { std::make_tuple(100, 100, 0, 0), }; - - /** - * Basic Functionality of hipMemset2D + * Test Description + * ------------------------ + * - Sets 2D allocated pitch memory. + * - Performs copy and compares the results. + * Test source + * ------------------------ + * - unit/memory/hipMemset2D.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipMemset2D_BasicFunctional") { CHECK_IMAGE_SUPPORT @@ -84,9 +90,17 @@ TEST_CASE("Unit_hipMemset2D_BasicFunctional") { free(A_h); } - /** - * Basic Functionality of hipMemset2DAsync + * Test Description + * ------------------------ + * - Sets 2D allocated pitch memory. + * - Performs copy and compares the results. + * Test source + * ------------------------ + * - unit/memory/hipMemset2D.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipMemset2DAsync_BasicFunctional") { CHECK_IMAGE_SUPPORT @@ -131,7 +145,15 @@ TEST_CASE("Unit_hipMemset2DAsync_BasicFunctional") { /** - * Memset partial buffer with unique Width and Height + * Test Description + * ------------------------ + * - Sets partial buffer with unique width and height. + * Test source + * ------------------------ + * - unit/memory/hipMemset2D.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipMemset2D_UniqueWidthHeight") { CHECK_IMAGE_SUPPORT @@ -179,3 +201,73 @@ TEST_CASE("Unit_hipMemset2D_UniqueWidthHeight") { free(A_h); } +/** + * End doxygen group hipMemset2D. + * @} + */ + +/** + * @addtogroup hipMemset2DAsync hipMemset2DAsync + * @{ + * @ingroup MemoryTest + * `hipMemset2DAsync(void* dst, size_t pitch, int value, size_t width, + * size_t height,hipStream_t stream __dparm(0))` - + * Fills asynchronously the memory area pointed to by dst with the constant value. + * ________________________ + * Test cases from other modules: + * - @ref Unit_hipMemsetFunctional_ZeroValue_2D + * - @ref Unit_hipMemsetFunctional_SmallSize_2D + * - @ref Unit_hipMemsetFunctional_ZeroSize_2D + * - @ref Unit_hipMemsetFunctional_PartialSet_2D + */ + +/** + * Test Description + * ------------------------ + * - Sets 2D allocated pitch memory, asynchronously. + * - Performs copy and compares the results. + * Test source + * ------------------------ + * - unit/memory/hipMemset2D.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipMemset2DAsync_BasicFunctional") { + constexpr int memsetval = 0x26; + constexpr size_t numH = 256; + constexpr size_t numW = 256; + size_t pitch_A; + size_t width = numW * sizeof(char); + size_t sizeElements = width * numH; + size_t elements = numW * numH; + char *A_d, *A_h; + + HIP_CHECK(hipMallocPitch(reinterpret_cast(&A_d), &pitch_A, + width, numH)); + A_h = reinterpret_cast(malloc(sizeElements)); + REQUIRE(A_h != nullptr); + + for (size_t i = 0; i < elements; i++) { + A_h[i] = 1; + } + + hipStream_t stream; + HIP_CHECK(hipStreamCreate(&stream)); + HIP_CHECK(hipMemset2DAsync(A_d, pitch_A, memsetval, numW, numH, stream)); + HIP_CHECK(hipStreamSynchronize(stream)); + HIP_CHECK(hipMemcpy2D(A_h, width, A_d, pitch_A, numW, numH, + hipMemcpyDeviceToHost)); + + for (size_t i=0; i < elements; i++) { + if (A_h[i] != memsetval) { + INFO("Memset2DAsync mismatch at index:" << i << " computed:" + << A_h[i] << " memsetval:" << memsetval); + REQUIRE(false); + } + } + + HIP_CHECK(hipFree(A_d)); + HIP_CHECK(hipStreamDestroy(stream)); + free(A_h); +} diff --git a/catch/unit/memory/hipMemset2DAsyncMultiThreadAndKernel.cc b/catch/unit/memory/hipMemset2DAsyncMultiThreadAndKernel.cc index f70736da8..1e500e98f 100644 --- a/catch/unit/memory/hipMemset2DAsyncMultiThreadAndKernel.cc +++ b/catch/unit/memory/hipMemset2DAsyncMultiThreadAndKernel.cc @@ -17,17 +17,16 @@ * THE SOFTWARE. */ -/** - Testcase Scenarios : - 1) Order of execution of device kernel and hipMemset2DAsync api - 2) hipMemSet2DAsync execution in multiple threads -*/ - #include #include #include #include +/** + * @addtogroup hipMemset2DAsync hipMemset2DAsync + * @{ + * @ingroup MemoryTest + */ /* Defines */ #define NUM_THREADS 1000 @@ -49,6 +48,21 @@ void queueJobsForhipMemset2DAsync(char* A_d, char* A_h, size_t pitch, /** * Order of execution of device kernel and hipMemset2DAsync api. */ +/** + * Test Description + * ------------------------ + * - Validates order of execution of device kernel and + * asynchronous memset. + * - Validates the results, utilizing following streams: + * -# Created (non-null) stream + * -# Stream per thread + * Test source + * ------------------------ + * - unit/memory/hipMemset2DAsyncMultiThreadAndKernel.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemset2DAsync_WithKernel") { CHECK_IMAGE_SUPPORT @@ -129,9 +143,18 @@ TEST_CASE("Unit_hipMemset2DAsync_WithKernel") { free(A_h); free(B_h); } - /** - * hipMemSet2DAsync execution in multiple threads. + * Test Description + * ------------------------ + * - Executes memset 2D asynchronously wihin multiple threads + * on one device. + * Test source + * ------------------------ + * - unit/memory/hipMemset2DAsyncMultiThreadAndKernel.cc + * Test requirements + * ------------------------ + * - Multi-threaded device + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipMemset2DAsync_MultiThread") { CHECK_IMAGE_SUPPORT diff --git a/catch/unit/memory/hipMemset3D.cc b/catch/unit/memory/hipMemset3D.cc index be6ff9198..9e4203d28 100644 --- a/catch/unit/memory/hipMemset3D.cc +++ b/catch/unit/memory/hipMemset3D.cc @@ -20,16 +20,28 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/** - Functional test for Memset3D and Memset3DAsync - */ - - #include +/** + * @addtogroup hipMemset3D hipMemset3D + * @{ + * @ingroup MemoryTest + * `hipMemset3D(hipPitchedPtr pitchedDevPtr, int value, hipExtent extent )` - + * Fills synchronously the memory area pointed to by pitchedDevPtr with the constant value. + */ /** - * Basic Functional test of hipMemset3D + * Test Description + * ------------------------ + * - Allocates 3D memory chunk. + * - Sets memory to the unique value. + * - Performs copy and validates results. + * Test source + * ------------------------ + * - unit/memory/hipMemset3D.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipMemset3D_BasicFunctional") { CHECK_IMAGE_SUPPORT @@ -79,7 +91,36 @@ TEST_CASE("Unit_hipMemset3D_BasicFunctional") { } /** - * Basic Functional test of hipMemset3DAsync + * End doxygen group hipMemset3D. + * @} + */ + +/** + * @addtogroup hipMemset3DAsync hipMemset3DAsync + * @{ + * @ingroup MemoryTest + * `hipMemset3DAsync(hipPitchedPtr pitchedDevPtr, int value, + * hipExtent extent ,hipStream_t stream __dparm(0))` - + * Fills asynchronously the memory area pointed to by pitchedDevPtr with the constant value. + * ________________________ + * Test cases from other modules: + * - @ref Unit_hipMemsetFunctional_ZeroValue_3D + * - @ref Unit_hipMemsetFunctional_SmallSize_3D + * - @ref Unit_hipMemsetFunctional_ZeroSize_3D + * - @ref Unit_hipMemsetFunctional_PartialSet_3D + */ + +/** + * Test Description + * ------------------------ + * - Sets 3D allocated pitch memory, asynchronously. + * - Performs copy and compares the results. + * Test source + * ------------------------ + * - unit/memory/hipMemset3D.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipMemset3DAsync_BasicFunctional") { CHECK_IMAGE_SUPPORT diff --git a/catch/unit/memory/hipMemset3DFunctional.cc b/catch/unit/memory/hipMemset3DFunctional.cc index aae255e04..dcce43c8c 100644 --- a/catch/unit/memory/hipMemset3DFunctional.cc +++ b/catch/unit/memory/hipMemset3DFunctional.cc @@ -86,7 +86,7 @@ Testcase Scenarios : #define XPOS_END 19 -/** +/* * Memset with extent passed and verify data to be intact */ static void testMemsetWithExtent(bool bAsync, hipExtent tstExtent) { @@ -165,7 +165,7 @@ static void testMemsetWithExtent(bool bAsync, hipExtent tstExtent) { } -/** +/* * Validates data after performing memory set operation with max memset value */ static void testMemsetMaxValue(bool bAsync) { @@ -225,7 +225,7 @@ static void testMemsetMaxValue(bool bAsync) { free(A_h); } -/** +/* * Function seeks device ptr to random slice and performs Memset operation * on the slice selected. */ @@ -314,7 +314,7 @@ static void seekAndSet3DArraySlice(bool bAsync) { HIP_CHECK(hipFree(devicePitchedPointer.ptr)); } -/** +/* * Function seeks device ptr to selected portion of 3d array * and performs Memset operation on the portion. */ @@ -409,11 +409,27 @@ static void seekAndSet3DArrayPortion(bool bAsync) { HIP_CHECK(hipFree(devicePitchedPointer.ptr)); } - +/** + * @addtogroup hipMemset3D hipMemset3D + * @{ + * @ingroup MemoryTest + */ /** - * Test Memset3D with different combinations of extent - * taking zero and non-zero fields. + * Test Description + * ------------------------ + * - Validates functionality with different combinations + * of extent taking zero and non-zero fields: + * -# Memset with extent width(0) + * -# Memset with extend height(0) + * -# Memset with extent depth(0) + * -# Memset with extent width, height and depth as 0 + * Test source + * ------------------------ + * - unit/memory/hipMemset3DFunctional.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipMemset3D_MemsetWithExtent") { CHECK_IMAGE_SUPPORT @@ -446,10 +462,79 @@ TEST_CASE("Unit_hipMemset3D_MemsetWithExtent") { } } +/** + * Test Description + * ------------------------ + * - Verifies functionality of memset with maximum unsigned char value. + * Test source + * ------------------------ + * - unit/memory/hipMemset3DFunctional.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipMemset3D_MemsetMaxValue") { + testMemsetMaxValue(0); +} + +/** + * Test Description + * ------------------------ + * - Seeks and sets random slice of 3D array. + * - Verifies the results. + * Test source + * ------------------------ + * - unit/memory/hipMemset3DFunctional.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipMemset3D_SeekSetSlice") { + seekAndSet3DArraySlice(0); +} + +/** + * Test Description + * ------------------------ + * - Sets the selected portion of a 3D array. + * - Verifies the results. + * Test source + * ------------------------ + * - unit/memory/hipMemset3DFunctional.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ +TEST_CASE("Unit_hipMemset3D_SeekSetArrayPortion") { + seekAndSet3DArrayPortion(0); +} + +/** + * End doxygen group hipMemset3D. + * @} + */ + +/** + * @addtogroup hipMemset3DAsync hipMemset3DAsync + * @{ + * @ingroup MemoryTest + */ /** - * Test Memset3DAsync with different combinations of extent - * taking zero and non-zero fields. + * Test Description + * ------------------------ + * - Validates functionality with different combinations + * of extent taking zero and non-zero fields: + * -# Memset with extent width(0) + * -# Memset with extend height(0) + * -# Memset with extent depth(0) + * -# Memset with extent width, height and depth as 0 + * Test source + * ------------------------ + * - unit/memory/hipMemset3DFunctional.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipMemset3DAsync_MemsetWithExtent") { CHECK_IMAGE_SUPPORT @@ -483,7 +568,15 @@ TEST_CASE("Unit_hipMemset3DAsync_MemsetWithExtent") { } /** - * Memset3D with max unsigned char and verify memset operation is success + * Test Description + * ------------------------ + * - Verifies functionality of synchronous memset with maximum unsigned char value. + * Test source + * ------------------------ + * - unit/memory/hipMemset3DFunctional.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipMemset3D_MemsetMaxValue") { CHECK_IMAGE_SUPPORT @@ -492,7 +585,15 @@ TEST_CASE("Unit_hipMemset3D_MemsetMaxValue") { } /** - * Memset3DAsync with max unsigned char and verify memset operation is success + * Test Description + * ------------------------ + * - Verifies functionality of asynchronous memset with maximum unsigned char value. + * Test source + * ------------------------ + * - unit/memory/hipMemset3DFunctional.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipMemset3DAsync_MemsetMaxValue") { CHECK_IMAGE_SUPPORT @@ -501,7 +602,16 @@ TEST_CASE("Unit_hipMemset3DAsync_MemsetMaxValue") { } /** - * Seek and set random slice of 3d array, verify memset is success + * Test Description + * ------------------------ + * - Seeks and synchronously sets random slice of 3D array. + * - Verifies the results. + * Test source + * ------------------------ + * - unit/memory/hipMemset3DFunctional.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipMemset3D_SeekSetSlice") { CHECK_IMAGE_SUPPORT @@ -510,7 +620,16 @@ TEST_CASE("Unit_hipMemset3D_SeekSetSlice") { } /** - * Seek and set random slice of 3d array with async, verify memset is success + * Test Description + * ------------------------ + * - Seeks and asynchronously sets random slice of 3D array. + * - Verifies the results. + * Test source + * ------------------------ + * - unit/memory/hipMemset3DFunctional.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipMemset3DAsync_SeekSetSlice") { CHECK_IMAGE_SUPPORT @@ -519,7 +638,16 @@ TEST_CASE("Unit_hipMemset3DAsync_SeekSetSlice") { } /** - * Memset3D selected portion of 3d array + * Test Description + * ------------------------ + * - Synchronously sets the selected portion of a 3D array. + * - Verifies the results. + * Test source + * ------------------------ + * - unit/memory/hipMemset3DFunctional.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipMemset3D_SeekSetArrayPortion") { CHECK_IMAGE_SUPPORT @@ -528,7 +656,16 @@ TEST_CASE("Unit_hipMemset3D_SeekSetArrayPortion") { } /** - * Memset3DAsync selected portion of 3d array + * Test Description + * ------------------------ + * - Asynchronously sets the selected portion of a 3D array. + * - Verifies the results. + * Test source + * ------------------------ + * - unit/memory/hipMemset3DFunctional.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipMemset3DAsync_SeekSetArrayPortion") { CHECK_IMAGE_SUPPORT diff --git a/catch/unit/memory/hipMemset3DRegressMultiThread.cc b/catch/unit/memory/hipMemset3DRegressMultiThread.cc index a30af0cea..0ee128dad 100644 --- a/catch/unit/memory/hipMemset3DRegressMultiThread.cc +++ b/catch/unit/memory/hipMemset3DRegressMultiThread.cc @@ -17,28 +17,15 @@ OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/** -Testcase Scenarios : - 1) Validate Async behavior of hipMemset3DAsync with commands queued - concurrently from multiple threads. - 2) Validate hipMemset3DAsync behavior when api is queued along with kernel - function operating on same memory. - 3) Perform regression of hipMemset3D api in loop with device memory allocated - on different gpus. - 4) Perform regression of hipMemset3DAsync api in loop with device memory - allocated on different gpus. -*/ - #include - /* * Defines */ #define MAX_REGRESS_ITERS 2 #define MAX_THREADS 10 -/** +/* * kernel function sets device memory with value passed */ static __global__ void func_set_value(hipPitchedPtr devicePitchedPointer, @@ -69,7 +56,7 @@ static __global__ void func_set_value(hipPitchedPtr devicePitchedPointer, } -/** +/* * Thread function queues kernel function and memset cmds */ static void threadFunc(hipStream_t stream, hipPitchedPtr devpPtr, @@ -89,8 +76,7 @@ static void threadFunc(hipStream_t stream, hipPitchedPtr devpPtr, HIPCHECK(hipMemcpy3DAsync(&myparms, stream)); } - -/** +/* * Performs api regression in loop */ bool loopRegression(bool bAsync) { @@ -184,8 +170,23 @@ bool loopRegression(bool bAsync) { } /** - * Perform regression of hipMemset3D api with device memory allocated - * on different gpus. + * @addtogroup hipMemset3D hipMemset3D + * @{ + * @ingroup MemoryTest + */ + +/** + * Test Description + * ------------------------ + * - Performs regression of 3D memset API with device memory allocated + * on different devices. + * Test source + * ------------------------ + * - unit/memory/hipMemset3DRegressMultiThread.cc + * Test requirements + * ------------------------ + * - Multi-device + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipMemset3D_RegressInLoop") { CHECK_IMAGE_SUPPORT @@ -197,8 +198,27 @@ TEST_CASE("Unit_hipMemset3D_RegressInLoop") { } /** - * Perform regression of hipMemset3DAsync api with device memory allocated - * on different gpus. + * End doxygen group hipMemset3D. + * @} + */ + +/** + * @addtogroup hipMemset3DAsync hipMemset3DAsync + * @{ + * @ingroup MemoryTest + */ + +/** + * Test Description + * ------------------------ + * - Performs regression of 3D asynchronous memset API with device + * memory allocated on different devices. + * Test source + * ------------------------ + * - unit/memory/hipMemset3DRegressMultiThread.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipMemset3DAsync_RegressInLoop") { CHECK_IMAGE_SUPPORT @@ -210,7 +230,16 @@ TEST_CASE("Unit_hipMemset3DAsync_RegressInLoop") { } /** - * Async commands queued concurrently and executed + * Test Description + * ------------------------ + * - Validates the scenarion when asynchronous commands are + * queued concurrently and executed. + * Test source + * ------------------------ + * - unit/memory/hipMemset3DRegressMultiThread.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipMemset3DAsync_ConcurrencyMthread") { CHECK_IMAGE_SUPPORT diff --git a/catch/unit/memory/hipMemsetAsync.cc b/catch/unit/memory/hipMemsetAsync.cc index 10391be42..400177252 100644 --- a/catch/unit/memory/hipMemsetAsync.cc +++ b/catch/unit/memory/hipMemsetAsync.cc @@ -75,10 +75,25 @@ static void doMemsetTest(allocType mallocType, memType memset_type, MultiDData d if (streamType == CREATEDSTR) HIP_CHECK(hipStreamDestroy(stream)); } -/* - * test 2 async hipMemset's on the same memory at different offsets +/** + * @addtogroup hipMemsetD8Async hipMemsetD8Async + * @{ + * @ingroup MemoryTest */ +/** + * Test Description + * ------------------------ + * - Validates the case when two asynchronous memset APIs are called + * on the same memory at different offesets. + * Test source + * ------------------------ + * - unit/memory/hipMemsetAsync.cc + * Test requirements + * ------------------------ + * - Platform specific (NVIDIA) + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemsetASyncMulti") { allocType mallocType = GENERATE(allocType::hostMalloc, allocType::deviceMalloc, @@ -94,8 +109,18 @@ TEST_CASE("Unit_hipMemsetASyncMulti") { doMemsetTest(mallocType, mem_type, data1, data2); } -/* - * test 2 async hipMemsetD[8,16,32]'s on the same memory at different offsets +/** + * Test Description + * ------------------------ + * - Validates the case when two asynchronous memset APIS are called on the same memory + * at different offsets. + * Test source + * ------------------------ + * - unit/memory/hipMemsetAsync.cc + * Test requirements + * ------------------------ + * - Platform specific (NVIDIA) + * - HIP_VERSION >= 5.2 */ TEMPLATE_TEST_CASE("Unit_hipMemsetDASyncMulti", "", int8_t, int16_t, uint32_t) { allocType mallocType = GENERATE(allocType::hostRegisted, allocType::deviceMalloc, @@ -118,8 +143,29 @@ TEMPLATE_TEST_CASE("Unit_hipMemsetDASyncMulti", "", int8_t, int16_t, uint32_t) { doMemsetTest(mallocType, memset_type, data1, data2); } -/* - * test 2 async hipMemset2D's on the same memory at different offsets +/** + * End doxygen group hipMemsetD8Async. + * @} + */ + +/** + * @addtogroup hipMemset2DAsync hipMemset2DAsync + * @{ + * @ingroup MemoryTest + */ + +/** + * Test Description + * ------------------------ + * - Validates the case when two asynchronous memset APIS are called on the same memory + * at different offsets. + * Test source + * ------------------------ + * - unit/memory/hipMemsetAsync.cc + * Test requirements + * ------------------------ + * - Platform specific (NVIDIA) + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipMemset2DASyncMulti") { #if HT_AMD @@ -140,8 +186,30 @@ TEST_CASE("Unit_hipMemset2DASyncMulti") { doMemsetTest(mallocType, memset_type, data1, data2); } -/* - * test 2 async hipMemset3D's on the same memory at different offsets + +/** + * End doxygen group hipMemset2DAsync. + * @} + */ + +/** + * @addtogroup hipMemset3DAsync hipMemset3DAsync + * @{ + * @ingroup MemoryTest + */ + +/** + * Test Description + * ------------------------ + * - Validates the case when two asynchronous memset APIS are called on the same memory + * at different offsets. + * Test source + * ------------------------ + * - unit/memory/hipMemsetAsync.cc + * Test requirements + * ------------------------ + * - Platform specific (NVIDIA) + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipMemset3DASyncMulti") { #if HT_AMD diff --git a/catch/unit/memory/hipMemsetAsyncAndKernel.cc b/catch/unit/memory/hipMemsetAsyncAndKernel.cc index a3578e9b2..018d68e0d 100644 --- a/catch/unit/memory/hipMemsetAsyncAndKernel.cc +++ b/catch/unit/memory/hipMemsetAsyncAndKernel.cc @@ -167,10 +167,27 @@ static bool testhipMemsetD8AsyncWithKernel() { return obj.resultAfterAllIterations(); } +/** + * @addtogroup hipMemsetAsync hipMemsetAsync + * @{ + * @ingroup MemoryTest + */ -/* - * Test for checking order of execution of device kernel and - * hipMemsetAsync apis on all gpus +/** + * Test Description + * ------------------------ + * - Validates the order of execution of device kernel and memset API on all devices: + * -# When @ref hipMemsetAsync is called with kernel + * -# When @ref hipMemsetAsync is called with kernel using per thread stream + * -# When @ref hipMemsetD32Async is called with kernel + * -# When @ref hipMemsetD16Async is called with kernel + * -# When @ref hipMemsetD8Async is called with kernel + * Test source + * ------------------------ + * - unit/memory/hipMemsetAsyncAndKernel.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipMemsetAsync_VerifyExecutionWithKernel") { int numDevices = 0; diff --git a/catch/unit/memory/hipMemsetFunctional.cc b/catch/unit/memory/hipMemsetFunctional.cc index 1694d530e..91d912d8d 100644 --- a/catch/unit/memory/hipMemsetFunctional.cc +++ b/catch/unit/memory/hipMemsetFunctional.cc @@ -17,17 +17,6 @@ * THE SOFTWARE. */ -/** - * Testcase Scenarios: - * For hipMemset, hipMemsetD8, hipMemsetD16, hipMemsetD32, hipMemset2D, hipMemset3D and all async - * counterparts - * 1) (ZeroValue) - Test setting a specified range to zero. - * 2) (SmallSize) - Test setting a unique memset value for small sizes. - * 3) (ZeroSize) - Test that trying to set memory with a zero dimension does not fail and doesn't - * affect the memory. - * 4) (PartialSet) - Test setting a partial range of total allocated memory and - * ensure the full range isn't affected. - */ #include constexpr size_t FULL_DIM = 10; @@ -202,6 +191,25 @@ void partialMemsetTest(T valA, T valB, size_t count, size_t offset, MemsetType m HIP_CHECK(hipFree(devPtr)); } +/** + * @addtogroup hipMemset hipMemset + * @{ + * @ingroup MemoryTest + */ + +/** + * Test Description + * ------------------------ + * - Sets a full region of memory with an initial value. + * - Sets a smaller subregion with another value. + * - Checks that the memset API do not write outside of a subregion of data. + * Test source + * ------------------------ + * - unit/memory/hipMemsetFunctional.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemsetFunctional_PartialSet_1D") { auto widthOffset = GENERATE(8, 16, 32, 64, 128, 256, 512, 1024); SECTION("hipMemset - Partial Set") { @@ -280,6 +288,23 @@ void checkMemset2D(T value, size_t width, size_t height, bool async = false, siz HIP_CHECK(hipStreamDestroy(stream)); } +/** + * @addtogroup hipMemset2D hipMemset2D + * @{ + * @ingroup MemoryTest + */ + +/** + * Test Description + * ------------------------ + * - Validates the case when zero value is set for width and height. + * Test source + * ------------------------ + * - unit/memory/hipMemsetFunctional.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemsetFunctional_ZeroValue_2D") { CHECK_IMAGE_SUPPORT @@ -290,6 +315,17 @@ TEST_CASE("Unit_hipMemsetFunctional_ZeroValue_2D") { SECTION("hipMemset2DAsync - Zero Value") { checkMemset2D(memsetVal, width, height, true); } } +/** + * Test Description + * ------------------------ + * - Validates the case when small size for width and height is set. + * Test source + * ------------------------ + * - unit/memory/hipMemsetFunctional.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemsetFunctional_SmallSize_2D") { CHECK_IMAGE_SUPPORT @@ -298,6 +334,17 @@ TEST_CASE("Unit_hipMemsetFunctional_SmallSize_2D") { SECTION("hipMemset2DAsync - Small Size") { checkMemset2D(memsetVal, 1, 1, true); } } +/** + * Test Description + * ------------------------ + * - Validates the case when zero value is set for width and height. + * Test source + * ------------------------ + * - unit/memory/hipMemsetFunctional.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemsetFunctional_ZeroSize_2D") { CHECK_IMAGE_SUPPORT @@ -380,6 +427,19 @@ void partialMemsetTest2D(T valA, T valB, size_t width, size_t height, size_t wid HIP_CHECK(hipFree(devPtr)); } +/** + * Test Description + * ------------------------ + * - Sets a full region of memory with an initial value. + * - Sets a smaller subregion with another value. + * - Checks that the memset API do not write outside of the subregion data. + * Test source + * ------------------------ + * - unit/memory/hipMemsetFunctional.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemsetFunctional_PartialSet_2D") { CHECK_IMAGE_SUPPORT @@ -395,6 +455,11 @@ TEST_CASE("Unit_hipMemsetFunctional_PartialSet_2D") { } } +/** + * End doxygen group hipMemset2D. + * @} + */ + // Helper function that copies the device data to the host and returns a unique_ptr to that data. template std::unique_ptr get_device_data_3D(hipPitchedPtr& devPitchedPtr, hipExtent extent) { @@ -494,18 +559,57 @@ void check_memset_3D(std::string sectionStr, size_t width, size_t height, size_t } } +/** + * @addtogroup hipMemset3D hipMemset3D + * @{ + * @ingroup MemoryTest + */ + +/** + * Test Description + * ------------------------ + * - Validates the case when zero value is set for width, height and depth. + * Test source + * ------------------------ + * - unit/memory/hipMemsetFunctional.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemsetFunctional_ZeroValue_3D") { CHECK_IMAGE_SUPPORT check_memset_3D("Zero Value", 128, 128, 10, 0); } +/** + * Test Description + * ------------------------ + * - Validates the case when small size for width, height and depth is set. + * Test source + * ------------------------ + * - unit/memory/hipMemsetFunctional.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemsetFunctional_SmallSize_3D") { CHECK_IMAGE_SUPPORT check_memset_3D("Small Size", 1, 1, 1, 0x42); } +/** + * Test Description + * ------------------------ + * - Validates the case when zero value is set for width, height and depth. + * Test source + * ------------------------ + * - unit/memory/hipMemsetFunctional.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemsetFunctional_ZeroSize_3D") { CHECK_IMAGE_SUPPORT @@ -558,6 +662,19 @@ void partialMemsetTest3D(T valA, T valB, size_t width, size_t height, size_t dep HIP_CHECK(hipFree(devPitchedPtr.ptr)); } +/** + * Test Description + * ------------------------ + * - Sets a full region of memory with an initial value. + * - Sets a smaller subregion with another value. + * - Checks that the memset API do not write outside of the subregion data. + * Test source + * ------------------------ + * - unit/memory/hipMemsetFunctional.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemsetFunctional_PartialSet_3D") { CHECK_IMAGE_SUPPORT diff --git a/catch/unit/memory/hipMemsetNegative.cc b/catch/unit/memory/hipMemsetNegative.cc index 4af79a66f..9bf4b9834 100644 --- a/catch/unit/memory/hipMemsetNegative.cc +++ b/catch/unit/memory/hipMemsetNegative.cc @@ -54,6 +54,38 @@ inline void testHipMemset3DApis(hipPitchedPtr& pitchedDevPtr, int value, const h HIP_CHECK_ERROR(hipMemset3DAsync(pitchedDevPtr, value, extent, nullStream), expectedReturn); } +/** + * @addtogroup hipMemset hipMemset + * @{ + * @ingroup MemoryTest + */ + +/** + * Test Description + * ------------------------ + * - Validates handling of invalid pointers: + * -# When destination pointer is not initialized + * - Expected output: return `hipErrorInvalidValue` + * -# When destination pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When host pointer is passed as destination pointer + * - Expected output: return `hipErrorInvalidValue` + * - Performs memset for following APIs: + * -# @ref hipMemset + * -# @ref hipMemsetAsync + * -# @ref hipMemsetD32 + * -# @ref hipMemsetD32Async + * -# @ref hipMemsetD16 + * -# @ref hipMemsetD16Async + * -# @ref hipMemsetD8 + * -# @ref hipMemsetD8Async + * Test source + * ------------------------ + * - unit/memory/hipMemsetNegative.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemset_Negative_InvalidPtr") { void* dst; @@ -69,7 +101,28 @@ TEST_CASE("Unit_hipMemset_Negative_InvalidPtr") { testHipMemsetApis(dst, memsetVal, width); } - +/** + * Test Description + * ------------------------ + * - Verifies the case when trying to set the memory that is out of + * bounds regarding size. + * - Performs memset for following APIs: + * -# @ref hipMemset + * -# @ref hipMemsetAsync + * -# @ref hipMemsetD32 + * -# @ref hipMemsetD32Async + * -# @ref hipMemsetD16 + * -# @ref hipMemsetD16Async + * -# @ref hipMemsetD8 + * -# @ref hipMemsetD8Async + * Test source + * ------------------------ + * - unit/memory/hipMemsetNegative.cc + * Test requirements + * ------------------------ + * - Platform specific (NVIDIA) + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemset_Negative_OutOfBoundsSize") { #if !HT_AMD @@ -82,6 +135,27 @@ TEST_CASE("Unit_hipMemset_Negative_OutOfBoundsSize") { #endif } +/** + * Test Description + * ------------------------ + * - Verifies the case when trying to set the memory that is out of + * bounds regarding address. + * - Performs memset for following APIs: + * -# @ref hipMemset + * -# @ref hipMemsetAsync + * -# @ref hipMemsetD32 + * -# @ref hipMemsetD32Async + * -# @ref hipMemsetD16 + * -# @ref hipMemsetD16Async + * -# @ref hipMemsetD8 + * -# @ref hipMemsetD8Async + * Test source + * ------------------------ + * - unit/memory/hipMemsetNegative.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipMemset_Negative_OutOfBoundsPtr") { void* dst; HIP_CHECK(hipMalloc(&dst, width)); @@ -90,6 +164,11 @@ TEST_CASE("Unit_hipMemset_Negative_OutOfBoundsPtr") { HIP_CHECK(hipFree(dst)); } +/** + * End doxygen group hipMemset. + * @} + */ + TEST_CASE("Unit_hipMemset2D_Negative_InvalidPtr") { CHECK_IMAGE_SUPPORT diff --git a/catch/unit/memory/hipPointerGetAttribute.cc b/catch/unit/memory/hipPointerGetAttribute.cc index 16101a628..080b495a1 100644 --- a/catch/unit/memory/hipPointerGetAttribute.cc +++ b/catch/unit/memory/hipPointerGetAttribute.cc @@ -16,35 +16,19 @@ 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. */ -/* -Added Negative and Functional tests for hipPointerGetAttribute API - -Functional Scenarios: - -1. Allocate memory using different Allocation APIs and check whether - correct memory type and device oridinal are returned. - -2. Allocate device variable and get the pointer info by calling hipPointerGetAttribute API - with HIP_POINTER_ATTRIBUTE_DEVICE_POINTER/HIP_POINTER_ATTRIBUTE_START_ADDRESS - and Launch kernel with device variable and verify whether the pointer variable of - hipPointerGetAttribute is getting updated or not - -3. Allocate device memory in GPU-0 and get the pointer info in peer GPU - -4. Allocate device memory and get the buffer ID by calling - hipPointerGetAttribute API with HIP_POINTER_ATTRIBUTE_BUFFER_ID, - DeAllocate and Allocate the memory again and ensure that the buffer ID is unique - -5. Allocate host memory and get the device ordinal by calling - hipPointerGetAttribute API with HIP_POINTER_ATTRIBUTE_DEVICE_ORDINAL - and ensure that it matches with CUDA result(which returns 100) - -6. Allocate managed memory with different flags and trigger - hipPointerGetAttribute with the following flags HIP_POINTER_ATTRIBUTE_MAPPED and verify the behaviour -*/ #include #include + +/** + * @addtogroup hipPointerGetAttribute hipPointerGetAttribute + * @{ + * @ingroup MemoryTest + * `hipPointerGetAttribute(void* data, hipPointer_attribute attribute, + * hipDeviceptr_t ptr)` - + * Returns information about the specified pointer.[BETA] + */ + static constexpr auto NUM_W{16}; static constexpr auto NUM_H{16}; static constexpr size_t N {10}; @@ -56,8 +40,18 @@ static __global__ void var_update(int* data) { } } -/* Allocate memory using different Allocation APIs and check whether - correct memory type and device oridinal are returned */ +/** + * Test Description + * ------------------------ + * - Allocate memory using different Allocation APIs and check whether + * correct memory type and device oridinal are returned. + * Test source + * ------------------------ + * - unit/memory/hipPointerGetAttribute.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipPointerGetAttribute_MemoryTypes") { CHECK_IMAGE_SUPPORT @@ -107,13 +101,18 @@ TEST_CASE("Unit_hipPointerGetAttribute_MemoryTypes") { #endif } -/* - * This testcase verifies the following scenario - * Initializes A_d with A_h and get pointer info using hipPointerGetAttribute - * The result of the API is passed to kernel for validation - * and modifies it in kernel. - * Validates the device variable to check whether the - * data is updated or not. +/** + * Test Description + * ------------------------ + * - Allocates device variable and gets the pointer attribute. + * - Launches kernel with the device variable. + * - Verifies that the pointer attribute variable is getting updated. + * Test source + * ------------------------ + * - unit/memory/hipPointerGetAttribute.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipPointerGetAttribute_KernelUpdation") { HIP_CHECK(hipSetDevice(0)); @@ -141,10 +140,19 @@ TEST_CASE("Unit_hipPointerGetAttribute_KernelUpdation") { HIP_CHECK(hipFree(A_d)); free(A_h); } -/* - * This testcase verifies the pointer info of device variable - * from peer GPU device.It validates the memory type and - * device ordinal in peer GPU + +/** + * Test Description + * ------------------------ + * - Verifies the pointer info of device variable + * from peer GPU device. + * - Validates the memory type and device ordinal in peer GPU. + * Test source + * ------------------------ + * - unit/memory/hipPointerGetAttribute.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 */ TEST_CASE("Unit_hipPointerGetAttribute_PeerGPU") { HIP_CHECK(hipSetDevice(0)); @@ -179,10 +187,19 @@ TEST_CASE("Unit_hipPointerGetAttribute_PeerGPU") { HIP_CHECK(hipFree(A_d)); } -/* Allocate device memory and get the buffer ID by calling - hipPointerGetAttribute API with HIP_POINTER_ATTRIBUTE_BUFFER_ID, - DeAllocate and Allocate the memory again and - ensure that the buffer ID is unique */ +/** + * Test Description + * ------------------------ + * - Allocate device memory and get the buffer ID. + * - DeAllocate and Allocate the memory again and ensure + * that the buffer ID is unique. + * Test source + * ------------------------ + * - unit/memory/hipPointerGetAttribute.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipPointerGetAttribute_BufferID") { HIP_CHECK(hipSetDevice(0)); size_t Nbytes = 0; @@ -201,11 +218,19 @@ TEST_CASE("Unit_hipPointerGetAttribute_BufferID") { REQUIRE(bufid1 != bufid2); } -/* Allocate host memory and get the device ordinal by calling - hipPointerGetAttribute API with HIP_POINTER_ATTRIBUTE_DEVICE_ORDINAL - and ensure that it matches with CUDA result -*/ #if HT_AMD +/** + * Test Description + * ------------------------ + * - Allocate host memory and get the device ordinal. + * - Ensure that it matches with CUDA result. + * Test source + * ------------------------ + * - unit/memory/hipPointerGetAttribute.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipPointerGetAttribute_HostDeviceOrdinal") { size_t Nbytes = 0; Nbytes = N * sizeof(int); @@ -226,9 +251,19 @@ TEST_CASE("Unit_hipPointerGetAttribute_HostDeviceOrdinal") { } #endif -/* Allocate managed memory with different flags and trigger - hipPointerGetAttribute with the following flags HIP_POINTER_ATTRIBUTE_MAPPED - and verify the behaviour */ +/** + * Test Description + * ------------------------ + * - Allocate managed memory with different flags. + * - Get attribute for the mapped attribute. + * - Verify behaviour. + * Test source + * ------------------------ + * - unit/memory/hipPointerGetAttribute.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipPointerGetAttribute_MappedMem") { HIP_CHECK(hipSetDevice(0)); size_t Nbytes = 0; @@ -258,7 +293,34 @@ TEST_CASE("Unit_hipPointerGetAttribute_MappedMem") { free(A_h); } -/* This testcase verifies negative scenarios of hipPointerGetAttribute API */ +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When output pointer to the attribute is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When address pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When required start address of host pointer + * - Expected output: return `hipErrorInvalidValue` + * -# When memory is deallocated before getting attribute + * - Expected output: return `hipErrorInvalidValue` + * -# When host pointer attribute is required from the device + * - Expected output: return `hipErrorInvalidValue` + * -# When buffer ID attribute is required from the host pointer + * - Expected output: return `hipErrorInvalidValue` + * -# When invalid attribute (-1) is passed + * - Expected output: return `hipErrorInvalidValue` + * -# When getting attributes not supported by the device + * - Platform specific (AMD) + * - Expected output: return `hipErrorNotSupported` + * Test source + * ------------------------ + * - unit/memory/hipPointerGetAttribute.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipPointerGetAttribute_Negative") { HIP_CHECK(hipSetDevice(0)); size_t Nbytes = 0; diff --git a/catch/unit/memory/hipPointerGetAttributes.cc b/catch/unit/memory/hipPointerGetAttributes.cc index 4c34a6edc..45a2f8d1c 100644 --- a/catch/unit/memory/hipPointerGetAttributes.cc +++ b/catch/unit/memory/hipPointerGetAttributes.cc @@ -20,14 +20,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* -Following scenarios are verified for hipPointerGetAttributes API -1. Run through a couple simple cases to test lookups host pointer arithmetic -2. Allocates memory across all devices withing the specified size range -3. Allocates tiny memory across all devices -4. Multi-threaded test with many simul allocs. - -*/ #include #include #include @@ -37,16 +29,18 @@ Following scenarios are verified for hipPointerGetAttributes API #include #include #include -size_t Nbytes = 0; -constexpr size_t N{1000000}; + /** * @addtogroup hipPointerGetAttributes hipPointerGetAttributes * @{ * @ingroup MemoryTest - * `hipError_t hipPointerGetAttributes (hipPointerAttribute_t *attributes, const void *ptr)` - - * Queries the memory pointer attributes. + * `hipPointerGetAttributes(hipPointerAttribute_t* attributes, const void* ptr)` - + * Return attributes for the specified pointer. */ +size_t Nbytes = 0; +constexpr size_t N{1000000}; + //================================================================================================= // Utility Functions: //================================================================================================= @@ -219,11 +213,16 @@ void clusterAllocs(int numAllocs, size_t minSize, size_t maxSize) { } } } + /** * Test Description * ------------------------ - * - Run through a couple simple cases to test lookups host pointer arithmetic -// specified size range + * - Runs through a couple simple cases to test lookups and pointer arithmetic. + * - Tests functionality of following types of memory: + * -# Device memory + * -# Device visible host memory + * -# OS memory + * Test source * ------------------------ * - unit/memory/hipPointerGetAttributes.cc * Test requirements @@ -317,6 +316,19 @@ TEST_CASE("Unit_hipPointerGetAttributes_Basic") { * - HIP_VERSION >= 5.7 */ +/** + * Test Description + * ------------------------ + * - Performs a couple of large allocations. + * - Randomly determines whether the allocation is performed on the device or host. + * - The size of the allocation is a random number between min_size and max_size bytes. + * Test source + * ------------------------ + * - unit/memory/hipPointerGetAttributes.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipPointerGetAttributes_ClusterAlloc") { srand(0x100); printf("\n=============================================\n"); @@ -334,6 +346,19 @@ TEST_CASE("Unit_hipPointerGetAttributes_ClusterAlloc") { * - HIP_VERSION >= 5.7 */ +/** + * Test Description + * ------------------------ + * - Performs many small allocations. + * - Randomly determines whether the allocation is performed on the device or host. + * - The size of the allocation is a random number between min_size and max_size bytes. + * Test source + * ------------------------ + * - unit/memory/hipPointerGetAttributes.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipPointerGetAttributes_TinyClusterAlloc") { srand(0x200); printf("\n=============================================\n"); @@ -377,6 +402,22 @@ TEST_CASE("Unit_hipPointerGetAttributes_MultiThread") { * - HIP_VERSION >= 5.7 */ +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When output pointer to the attributes is `nullptr` + * - Platform specific (AMD) + * - Expected output: return `hipErrorInvalidValue` + * -# When address pointer is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipPointerGetAttributes.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipPointerGetAttributes_Negative") { #if HT_AMD // Nvidia crashed in hipPointerGetAttributes on nullptr SECTION("Invalid Attributes Pointer") { @@ -398,13 +439,17 @@ TEST_CASE("Unit_hipPointerGetAttributes_Negative") { /** * Test Description * ------------------------ - * - Run this test for all devices for DeviceMemory, - * HostMemory and MappedMemory + * - Get address pointer attributes for each device and memory type: + * -# Device Memory + * -# Host Memory + * -# Mapped Memory + * - Require valid values of attributes. * Test source * ------------------------ * - unit/memory/hipPointerGetAttributes.cc * Test requirements * ------------------------ + * - Multi-device * - HIP_VERSION >= 6.0 */ TEST_CASE("Unit_hipPointerGetAttributes_GpuIter") { diff --git a/catch/unit/memory/hipPtrGetAttribute.cc b/catch/unit/memory/hipPtrGetAttribute.cc index 69a97fc9d..a219a21b1 100644 --- a/catch/unit/memory/hipPtrGetAttribute.cc +++ b/catch/unit/memory/hipPtrGetAttribute.cc @@ -20,15 +20,29 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* - Run through few sanity tests to verify different attributes of hipPointerGetAttribute -*/ #include #include #include #include -// Run few simple cases including host pointer arithmetic: + +/** + * @addtogroup hipPointerGetAttribute hipPointerGetAttribute + * @{ + * @ingroup MemoryTest + */ + +/** + * Test Description + * ------------------------ + * - Runs few simple cases including host pointer arithmetic. + * Test source + * ------------------------ + * - unit/memory/hipPtrGetAttribute.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipPtrGetAttribute_Simple") { HIP_CHECK(hipSetDevice(0)); size_t Nbytes = 0; diff --git a/catch/unit/memory/hipStreamAttachMemAsync.cc b/catch/unit/memory/hipStreamAttachMemAsync.cc index 05a73e5cc..4f5997e98 100644 --- a/catch/unit/memory/hipStreamAttachMemAsync.cc +++ b/catch/unit/memory/hipStreamAttachMemAsync.cc @@ -26,6 +26,30 @@ THE SOFTWARE. #include #include +/** + * @addtogroup hipStreamAttachMemAsync hipStreamAttachMemAsync + * @{ + * @ingroup MemoryMTest + * `hipStreamAttachMemAsync(hipStream_t stream, void* dev_ptr, + * size_t length __dparm(0), unsigned int flags __dparm(hipMemAttachSingle))` - + * Attach memory to a stream asynchronously in HIP. + */ + +/** + * Test Description + * ------------------------ + * - Verify basic case using managed memory. + * - Allocate managed memory chunk. + * - Attach stream. + * - Perform stream synchronization. + * Test source + * ------------------------ + * - unit/memory/hipStreamAttachMemAsync.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipStreamAttachMemAsync_Positive_Basic") { if (!DeviceAttributesSupport(0, hipDeviceAttributeManagedMemory)) { HipTest::HIP_SKIP_TEST("Managed memory is not supported"); @@ -40,6 +64,22 @@ TEST_CASE("Unit_hipStreamAttachMemAsync_Positive_Basic") { HIP_CHECK(hipStreamSynchronize(stream.stream())); } +/** + * Test Description + * ------------------------ + * - Vefify basic case using pageable memory. + * - Allocate pageale memory chunk. + * - Attach stream. + * - Perform stream synchronization. + * Test source + * ------------------------ + * - unit/memory/hipStreamAttachMemAsync.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - Device supports pageable memory access + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipStreamAttachMemAsync_Positive_Pageable") { if (!DeviceAttributesSupport(0, hipDeviceAttributeManagedMemory)) { HipTest::HIP_SKIP_TEST("Managed memory is not supported"); @@ -61,6 +101,23 @@ TEST_CASE("Unit_hipStreamAttachMemAsync_Positive_Pageable") { // CUDA docs: // If the cudaMemAttachGlobal flag is specified, the memory can be accessed by any stream on any // device. +/** + * Test Description + * ------------------------ + * - Verify behaviour of attach global attribute. + * - Allocate managed memory chunk. + * - Attach stream. + * - Launch kernel. + * - Perform stream synchronization. + * - Verify results. + * Test source + * ------------------------ + * - unit/memory/hipStreamAttachMemAsync.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipStreamAttachMemAsync_Positive_AttachGlobal") { if (!DeviceAttributesSupport(0, hipDeviceAttributeManagedMemory)) { HipTest::HIP_SKIP_TEST("Managed memory is not supported"); @@ -103,6 +160,24 @@ TEST_CASE("Unit_hipStreamAttachMemAsync_Positive_AttachGlobal") { // If the cudaMemAttachHost flag is specified, the program makes a guarantee that it won't access // the memory on the device from any stream on a device that has a zero value for the device // attribute cudaDevAttrConcurrentManagedAccess. +/** + * Test Description + * ------------------------ + * - Verify attach host attribute behaviour when concurrent managed + * access is not supported. + * - Allocate managed memory chunk. + * - Attach stream. + * - Launch kernel. + * - Perform stream synchronization. + * Test source + * ------------------------ + * - unit/memory/hipStreamAttachMemAsync.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - Device does not support concurrent managed access + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipStreamAttachMemAsync_Positive_AttachHost") { if (!DeviceAttributesSupport(0, hipDeviceAttributeManagedMemory)) { HipTest::HIP_SKIP_TEST("Managed memory is not supported"); @@ -134,6 +209,24 @@ TEST_CASE("Unit_hipStreamAttachMemAsync_Positive_AttachHost") { // If the cudaMemAttachSingle flag is specified and stream is associated with a device that has a // zero value for the device attribute cudaDevAttrConcurrentManagedAccess, the program makes a // guarantee that it will only access the memory on the device from stream. +/** + * Test Description + * ------------------------ + * - Verify attach single attribute behaviour when concurrent managed + * access is not supported. + * - Allocate managed memory chunk. + * - Attach stream. + * - Launch kernel. + * - Perform stream synchronization. + * Test source + * ------------------------ + * - unit/memory/hipStreamAttachMemAsync.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - Device does not support concurrent managed access + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipStreamAttachMemAsync_Positive_AttachSingle") { if (!DeviceAttributesSupport(0, hipDeviceAttributeManagedMemory)) { HipTest::HIP_SKIP_TEST("Managed memory is not supported"); @@ -171,6 +264,34 @@ TEST_CASE("Unit_hipStreamAttachMemAsync_Positive_AttachSingle") { REQUIRE(*managed_single.ptr() == 128); } +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When the stream is not valid + * - Expected output: return `hipErrorContextIsDestroyed` + * -# When pointer to memory `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When length is not zero nor entire allocation size + * - Expected output: return `hipErrorInvalidValue` + * -# When flags are not valid + * - Expected output: return `hipErrorInvalidValue` + * -# When attach single to `nullptr` stream + * - Expected output: return `hipErrorInvalidValue` + * -# When pageable memory access is not supported + * and device pointer points to the pageable memory + * - Expected output: return `hipErrorInvalidValue` + * -# When pageable memory access is supported and + * length for pageable memory is zero + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/memory/hipStreamAttachMemAsync.cc + * Test requirements + * ------------------------ + * - Device supports managed memory management + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipStreamAttachMemAsync_Negative_Parameters") { if (!DeviceAttributesSupport(0, hipDeviceAttributeManagedMemory)) { HipTest::HIP_SKIP_TEST("Managed memory is not supported"); @@ -221,4 +342,4 @@ TEST_CASE("Unit_hipStreamAttachMemAsync_Negative_Parameters") { hipErrorInvalidValue); } } -} \ No newline at end of file +} diff --git a/catch/unit/vulkan_interop/hipDestroyExternalMemory.cc b/catch/unit/vulkan_interop/hipDestroyExternalMemory.cc index cb1b0766c..f6fb299b1 100644 --- a/catch/unit/vulkan_interop/hipDestroyExternalMemory.cc +++ b/catch/unit/vulkan_interop/hipDestroyExternalMemory.cc @@ -21,10 +21,32 @@ THE SOFTWARE. #include "vulkan_test.hh" -#if HT_AMD && 0 +/** + * @addtogroup hipDestroyExternalMemory hipDestroyExternalMemory + * @{ + * @ingroup MemoryTest + * `hipDestroyExternalMemory(hipExternalMemory_t extMem)` - + * Destroys an external memory object. + */ + constexpr bool enable_validation = false; -#endif +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When pointer to the external memory is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When external memory has already been destroyed + * - Platform specific (AMD) + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/vulkan_interop/hipDestroyExternalMemory.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipDestroyExternalMemory_Vulkan_Negative_Parameters") { SECTION("extMem == nullptr") { HIP_CHECK_ERROR(hipDestroyExternalMemory(nullptr), hipErrorInvalidValue); diff --git a/catch/unit/vulkan_interop/hipDestroyExternalSemaphore.cc b/catch/unit/vulkan_interop/hipDestroyExternalSemaphore.cc index e4b7dbb08..d8f48fa0f 100644 --- a/catch/unit/vulkan_interop/hipDestroyExternalSemaphore.cc +++ b/catch/unit/vulkan_interop/hipDestroyExternalSemaphore.cc @@ -21,6 +21,31 @@ THE SOFTWARE. #include "vulkan_test.hh" +/** + * @addtogroup hipDestroyExternalSemaphore hipDestroyExternalSemaphore + * @{ + * @ingroup MemoryTest + * `hipDestroyExternalSemaphore(hipExternalSemaphore_t extSem)` - + * Destroys an external semaphore object and releases any references to the underlying resource. + * Any outstanding signals or waits must have completed before the semaphore is destroyed. + */ + +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When pointer to the external semaphore is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When semaphore has already been destroyed: + * - Platform specific (AMD) + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/vulkan_interop/hipDestroyExternalSemaphore.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipDestroyExternalSemaphore_Vulkan_Negative_Parameters") { SECTION("extSem == nullptr") { HIP_CHECK_ERROR(hipDestroyExternalSemaphore(nullptr), hipErrorInvalidValue); diff --git a/catch/unit/vulkan_interop/hipExternalMemoryGetMappedBuffer.cc b/catch/unit/vulkan_interop/hipExternalMemoryGetMappedBuffer.cc index a2f4dc0b6..d69ecc8b3 100644 --- a/catch/unit/vulkan_interop/hipExternalMemoryGetMappedBuffer.cc +++ b/catch/unit/vulkan_interop/hipExternalMemoryGetMappedBuffer.cc @@ -21,10 +21,33 @@ THE SOFTWARE. #include "vulkan_test.hh" +/** + * @addtogroup hipExternalMemoryGetMappedBuffer hipExternalMemoryGetMappedBuffer + * @{ + * @ingroup MemoryTest + * `hipExternalMemoryGetMappedBuffer(void **devPtr, hipExternalMemory_t extMem, + * const hipExternalMemoryBufferDesc *bufferDesc)` - + * Maps a buffer onto an imported memory object. + */ + constexpr bool enable_validation = false; template __global__ void Set(T* ptr, const T val) { ptr[threadIdx.x] = val; } +/** + * Test Description + * ------------------------ + * - Imports external memory into a buffer. + * - Gets mapped buffer from the external memory. + * - Launches kernel. + * - Validates results. + * Test source + * ------------------------ + * - unit/vulkan_interop/hipExternalMemoryGetMappedBuffer.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipExternalMemoryGetMappedBuffer_Vulkan_Positive_Read_Write") { VulkanTest vkt(enable_validation); using type = uint8_t; @@ -69,6 +92,21 @@ TEST_CASE("Unit_hipExternalMemoryGetMappedBuffer_Vulkan_Positive_Read_Write") { } // Disabled on AMD due to defect - EXSWHTEC-175 +/** + * Test Description + * ------------------------ + * - Imports external memory into a buffer. + * - Gets mapped buffer from the external memory with offset. + * - Launches kernel. + * - Validates results. + * Test source + * ------------------------ + * - unit/vulkan_interop/hipExternalMemoryGetMappedBuffer.cc + * Test requirements + * ------------------------ + * - Platform specific (NVIDIA) + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipExternalMemoryGetMappedBuffer_Vulkan_Positive_Read_Write_With_Offset") { VulkanTest vkt(enable_validation); using type = uint8_t; @@ -104,6 +142,29 @@ TEST_CASE("Unit_hipExternalMemoryGetMappedBuffer_Vulkan_Positive_Read_Write_With HIP_CHECK(hipDestroyExternalMemory(hip_ext_memory)); } +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When device pointer is `nullptr` + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When buffer descriptor pointer is `nullptr` + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When buffer descriptor flags are not zero (non-default) + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When bufferDesc.offset + bufferDesc.size > hipExternalMemHandleDesc.size + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/vulkan_interop/hipExternalMemoryGetMappedBuffer.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipExternalMemoryGetMappedBuffer_Vulkan_Negative_Parameters") { VulkanTest vkt(enable_validation); const auto vk_storage = vkt.CreateMappedStorage(1, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true); @@ -116,9 +177,7 @@ TEST_CASE("Unit_hipExternalMemoryGetMappedBuffer_Vulkan_Negative_Parameters") { hipExternalMemoryBufferDesc external_mem_buffer_desc = {}; external_mem_buffer_desc.size = vk_storage.size; -#if HT_NVIDIA void* hip_dev_ptr = nullptr; -#endif // Disabled on AMD due to defect - EXSWHTEC-176 #if HT_NVIDIA diff --git a/catch/unit/vulkan_interop/hipImportExternalMemory.cc b/catch/unit/vulkan_interop/hipImportExternalMemory.cc index db541ea28..3f9cdef74 100644 --- a/catch/unit/vulkan_interop/hipImportExternalMemory.cc +++ b/catch/unit/vulkan_interop/hipImportExternalMemory.cc @@ -21,15 +21,51 @@ THE SOFTWARE. #include "vulkan_test.hh" +/** + * @addtogroup hipImportExternalMemory hipImportExternalMemory + * @{ + * @ingroup MemoryTest + * `hipImportExternalMemory(hipExternalMemory_t* extMem_out, + * const hipExternalMemoryHandleDesc* memHandleDesc)` - + * Imports an external memory object. + */ + constexpr bool enable_validation = false; +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When external memory pointer is `nullptr` + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When memory handle descriptor is `nullptr` + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue + * -# When size within memory handle descriptor is 0 + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When flags within memory handle descriptor are not valid + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When type within memory handle descriptor is not valid (-1) + * - Platform specific (NVIDIA) + * - Expected output: return `hipErrorInvalidValue` + * -# When handle within memory handle descriptor is `nullptr` + * - Host specific (WINDOWS) + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/vulkan_interop/hipImportExternalMemory.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipImportExternalMemory_Vulkan_Negative_Parameters") { VulkanTest vkt(enable_validation); -#if HT_NVIDIA const auto storage = vkt.CreateMappedStorage(1, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true); auto desc = vkt.BuildMemoryDescriptor(storage.memory, sizeof(*storage.host_ptr)); hipExternalMemory_t ext_memory; -#endif // Disabled due to defect - EXSWHTEC-182 #if HT_NVIDIA diff --git a/catch/unit/vulkan_interop/hipImportExternalSemaphore.cc b/catch/unit/vulkan_interop/hipImportExternalSemaphore.cc index 06c856023..ca8456f1f 100644 --- a/catch/unit/vulkan_interop/hipImportExternalSemaphore.cc +++ b/catch/unit/vulkan_interop/hipImportExternalSemaphore.cc @@ -21,8 +21,39 @@ THE SOFTWARE. #include "vulkan_test.hh" +/** + * @addtogroup hipImportExternalSemaphore hipImportExternalSemaphore + * @{ + * @ingroup MemoryTest + * `hipImportExternalSemaphore(hipExternalSemaphore_t* extSem_out, + * const hipExternalSemaphoreHandleDesc* semHandleDesc)` - + * Imports an external semaphore. + */ + constexpr bool enable_validation = false; +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When pointer to external semaphore is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When pointer to the semaphore descriptor is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When flags within descriptor are zero + * - Expected output: return `hipErrorInvalidValue` + * -# When type within descriptor is not valid (-1) + * - Expected output: return `hipErrorInvalidValue` + * -# When handle within descriptor is `nullptr` + * - Host specific (WINDOWS) + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/vulkan_interop/hipImportExternalSemaphore.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipImportExternalSemaphore_Vulkan_Negative_Parameters") { VulkanTest vkt(enable_validation); const auto semaphore = vkt.CreateExternalSemaphore(VK_SEMAPHORE_TYPE_BINARY); diff --git a/catch/unit/vulkan_interop/hipSignalExternalSemaphoresAsync.cc b/catch/unit/vulkan_interop/hipSignalExternalSemaphoresAsync.cc index 4485a3ad5..869a25311 100644 --- a/catch/unit/vulkan_interop/hipSignalExternalSemaphoresAsync.cc +++ b/catch/unit/vulkan_interop/hipSignalExternalSemaphoresAsync.cc @@ -21,8 +21,33 @@ THE SOFTWARE. #include "vulkan_test.hh" +/** + * @addtogroup hipSignalExternalSemaphoresAsync hipSignalExternalSemaphoresAsync + * @{ + * @ingroup MemoryTest + * `hipSignalExternalSemaphoresAsync(const hipExternalSemaphore_t* extSemArray, + * const hipExternalSemaphoreSignalParams* paramsArray, + * unsigned int numExtSems, hipStream_t stream)` - + * Signals a set of external semaphore objects. + */ + constexpr bool enable_validation = false; +/** + * Test Description + * ------------------------ + * - Creates two host visible Vulkan buffers. + * - Adds a buffer copy command which will copy from one buffer to another. + * - Creates an external Vulkan binary semaphore. + * - Createas a Vulkan fence and signals semaphore asynchronously. + * - Waits for the operation to finish successfully. + * Test source + * ------------------------ + * - unit/vulkan_interop/hipSignalExternalSemaphoresAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipSignalExternalSemaphoresAsync_Vulkan_Positive_Binary_Semaphore") { VulkanTest vkt(enable_validation); @@ -69,6 +94,20 @@ TEST_CASE("Unit_hipSignalExternalSemaphoresAsync_Vulkan_Positive_Binary_Semaphor // Timeline semaphores unsupported on AMD #if HT_NVIDIA +/** + * Test Description + * ------------------------ + * - Creates an external Vulkan timeline semaphore. + * - Imports the semapthore and signals. + * - Waits for the operation to finish successfully. + * Test source + * ------------------------ + * - unit/vulkan_interop/hipSignalExternalSemaphoresAsync.cc + * Test requirements + * ------------------------ + * - Platfom specific (NVIDIA) + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipSignalExternalSemaphoresAsync_Vulkan_Positive_Timeline_Semaphore") { VulkanTest vkt(enable_validation); constexpr uint64_t signal_value = 2; @@ -93,6 +132,21 @@ TEST_CASE("Unit_hipSignalExternalSemaphoresAsync_Vulkan_Positive_Timeline_Semaph HIP_CHECK(hipDestroyExternalSemaphore(hip_ext_semaphore)); } +/** + * Test Description + * ------------------------ + * - Creates two host visible Vulkan buffers. + * - Adds a buffer copy command which will copy from one buffer to another. + * - Creates multiple external Vulkan binary semaphores. + * - Createas a Vulkan fence and signals semaphores. + * - Waits for the operations to finish successfully. + * Test source + * ------------------------ + * - unit/vulkan_interop/hipSignalExternalSemaphoresAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipSignalExternalSemaphoresAsync_Vulkan_Positive_Multiple_Semaphores") { VulkanTest vkt(enable_validation); @@ -169,6 +223,25 @@ TEST_CASE("Unit_hipSignalExternalSemaphoresAsync_Vulkan_Positive_Multiple_Semaph } #endif +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When external semaphore array is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When array parameters are `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When flags are not zero (non-default) + * - Expected output: return `hipErrorInvalidValue` + * -# When stream is not valid + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/vulkan_interop/hipSignalExternalSemaphoresAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipSignalExternalSemaphoresAsync_Vulkan_Negative_Parameters") { VulkanTest vkt(enable_validation); hipExternalSemaphoreSignalParams signal_params = {}; diff --git a/catch/unit/vulkan_interop/hipWaitExternalSemaphoresAsync.cc b/catch/unit/vulkan_interop/hipWaitExternalSemaphoresAsync.cc index edebebe52..5d13c2f45 100644 --- a/catch/unit/vulkan_interop/hipWaitExternalSemaphoresAsync.cc +++ b/catch/unit/vulkan_interop/hipWaitExternalSemaphoresAsync.cc @@ -21,8 +21,33 @@ THE SOFTWARE. #include "vulkan_test.hh" +/** + * @addtogroup hipWaitExternalSemaphoresAsync hipWaitExternalSemaphoresAsync + * @{ + * @ingroup MemoryTest + * `hipWaitExternalSemaphoresAsync(const hipExternalSemaphore_t* extSemArray, + * const hipExternalSemaphoreWaitParams* paramsArray, + * unsigned int numExtSems, hipStream_t stream)` - + * Waits on a set of external semaphore objects. + */ + constexpr bool enable_validation = false; +/** + * Test Description + * ------------------------ + * - Creates two host visible Vulkan buffers. + * - Adds a buffer copy command which will copy from one buffer to another. + * - Creates an external Vulkan binary semaphore. + * - Createas a Vulkan fence and signals semaphore asynchronously. + * - Waits for the operation to finish successfully. + * Test source + * ------------------------ + * - unit/vulkan_interop/hipWaitExternalSemaphoresAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipWaitExternalSemaphoresAsync_Vulkan_Positive_Binary_Semaphore") { VulkanTest vkt(enable_validation); @@ -78,6 +103,20 @@ TEST_CASE("Unit_hipWaitExternalSemaphoresAsync_Vulkan_Positive_Binary_Semaphore" // Timeline semaphores unsupported on AMD #if HT_NVIDIA +/** + * Test Description + * ------------------------ + * - Creates an external Vulkan timeline semaphore. + * - Imports the semapthore and signals. + * - Waits for the operation to finish successfully. + * Test source + * ------------------------ + * - unit/vulkan_interop/hipWaitExternalSemaphoresAsync.cc + * Test requirements + * ------------------------ + * - Platfom specific (NVIDIA) + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipWaitExternalSemaphoresAsync_Vulkan_Positive_Timeline_Semaphore") { VulkanTest vkt(enable_validation); @@ -114,6 +153,21 @@ TEST_CASE("Unit_hipWaitExternalSemaphoresAsync_Vulkan_Positive_Timeline_Semaphor } #endif +/** + * Test Description + * ------------------------ + * - Creates two host visible Vulkan buffers. + * - Adds a buffer copy command which will copy from one buffer to another. + * - Creates multiple external Vulkan binary semaphores. + * - Createas a Vulkan fence and signals semaphores. + * - Waits for the operations to finish successfully. + * Test source + * ------------------------ + * - unit/vulkan_interop/hipWaitExternalSemaphoresAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipWaitExternalSemaphoresAsync_Vulkan_Positive_Multiple_Semaphores") { VulkanTest vkt(enable_validation); @@ -194,6 +248,25 @@ TEST_CASE("Unit_hipWaitExternalSemaphoresAsync_Vulkan_Positive_Multiple_Semaphor HIP_CHECK(hipDestroyExternalSemaphore(hip_binary_ext_semaphore)); } +/** + * Test Description + * ------------------------ + * - Validates handling of invalid arguments: + * -# When external semaphore array is `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When array parameters are `nullptr` + * - Expected output: return `hipErrorInvalidValue` + * -# When flags are not zero (non-default) + * - Expected output: return `hipErrorInvalidValue` + * -# When stream is not valid + * - Expected output: return `hipErrorInvalidValue` + * Test source + * ------------------------ + * - unit/vulkan_interop/hipWaitExternalSemaphoresAsync.cc + * Test requirements + * ------------------------ + * - HIP_VERSION >= 5.2 + */ TEST_CASE("Unit_hipWaitExternalSemaphoresAsync_Vulkan_Negative_Parameters") { VulkanTest vkt(enable_validation); hipExternalSemaphoreWaitParams wait_params = {};