/* * Copyright (c) Advanced Micro Devices, Inc., or its affiliates. * * SPDX-License-Identifier: MIT */ #include __device__ int devSymbol[10]; __constant__ int constSymbol[10]; /* Test verifies hipMemcpy[From/To]Symbol[Async] API Negative scenarios. */ HIP_TEST_CASE(Unit_hipMemcpyFromToSymbol_Negative) { SECTION("Invalid Src Ptr") { int result{0}; HIP_CHECK_ERROR( hipMemcpyFromSymbol(nullptr, HIP_SYMBOL(devSymbol), sizeof(int), 0, hipMemcpyDeviceToHost), hipErrorInvalidValue); HIP_CHECK_ERROR(hipMemcpyToSymbol(nullptr, &result, sizeof(int), 0, hipMemcpyHostToDevice), hipErrorInvalidSymbol); HIP_CHECK_ERROR( hipMemcpyToSymbolAsync(nullptr, &result, sizeof(int), 0, hipMemcpyHostToDevice, nullptr), hipErrorInvalidSymbol); HIP_CHECK_ERROR(hipMemcpyFromSymbolAsync(nullptr, HIP_SYMBOL(devSymbol), sizeof(int), 0, hipMemcpyDeviceToHost, nullptr), hipErrorInvalidValue); } SECTION("Invalid Dst Ptr") { int result{0}; HIP_CHECK_ERROR(hipMemcpyFromSymbol(&result, nullptr, sizeof(int), 0, hipMemcpyDeviceToHost), hipErrorInvalidSymbol); HIP_CHECK_ERROR( hipMemcpyToSymbol(HIP_SYMBOL(devSymbol), nullptr, sizeof(int), 0, hipMemcpyHostToDevice), hipErrorInvalidValue); HIP_CHECK_ERROR(hipMemcpyToSymbolAsync(HIP_SYMBOL(devSymbol), nullptr, sizeof(int), 0, hipMemcpyHostToDevice, nullptr), hipErrorInvalidValue); HIP_CHECK_ERROR( hipMemcpyFromSymbolAsync(&result, nullptr, sizeof(int), 0, hipMemcpyDeviceToHost, nullptr), hipErrorInvalidSymbol); } SECTION("Invalid Size") { int result{0}; HIP_CHECK_ERROR(hipMemcpyFromSymbol(&result, HIP_SYMBOL(devSymbol), sizeof(int) * 100, 0, hipMemcpyDeviceToHost), hipErrorInvalidValue); HIP_CHECK_ERROR(hipMemcpyToSymbol(HIP_SYMBOL(devSymbol), &result, sizeof(int) * 100, 0, hipMemcpyHostToDevice), hipErrorInvalidValue); HIP_CHECK_ERROR(hipMemcpyToSymbolAsync(HIP_SYMBOL(devSymbol), &result, sizeof(int) * 100, 0, hipMemcpyHostToDevice, nullptr), hipErrorInvalidValue); HIP_CHECK_ERROR(hipMemcpyFromSymbolAsync(&result, HIP_SYMBOL(devSymbol), sizeof(int) * 100, 0, hipMemcpyDeviceToHost, nullptr), hipErrorInvalidValue); } SECTION("Invalid Offset") { int result{0}; HIP_CHECK_ERROR(hipMemcpyFromSymbol(&result, HIP_SYMBOL(devSymbol), sizeof(int), 300, hipMemcpyDeviceToHost), hipErrorInvalidValue); HIP_CHECK_ERROR( hipMemcpyToSymbol(HIP_SYMBOL(devSymbol), &result, sizeof(int), 300, hipMemcpyHostToDevice), hipErrorInvalidValue); HIP_CHECK_ERROR(hipMemcpyToSymbolAsync(HIP_SYMBOL(devSymbol), &result, sizeof(int), 300, hipMemcpyHostToDevice, nullptr), hipErrorInvalidValue); HIP_CHECK_ERROR(hipMemcpyFromSymbolAsync(&result, HIP_SYMBOL(devSymbol), sizeof(int), 300, hipMemcpyDeviceToHost, nullptr), hipErrorInvalidValue); } SECTION("Invalid Direction") { int result{0}; HIP_CHECK_ERROR( hipMemcpyFromSymbol(&result, HIP_SYMBOL(devSymbol), sizeof(int), 0, hipMemcpyHostToDevice), hipErrorInvalidMemcpyDirection); HIP_CHECK_ERROR( hipMemcpyToSymbol(HIP_SYMBOL(devSymbol), &result, sizeof(int), 0, hipMemcpyDeviceToHost), hipErrorInvalidMemcpyDirection); HIP_CHECK_ERROR(hipMemcpyToSymbolAsync(HIP_SYMBOL(devSymbol), &result, sizeof(int), 0, hipMemcpyDeviceToHost, nullptr), hipErrorInvalidMemcpyDirection); HIP_CHECK_ERROR(hipMemcpyFromSymbolAsync(&result, HIP_SYMBOL(devSymbol), sizeof(int), 0, hipMemcpyHostToDevice, nullptr), hipErrorInvalidMemcpyDirection); } } /* * 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*/ HIP_TEST_CASE(Unit_hipMemcpyToFromSymbol_SyncAndAsync) { enum StreamTestType { NullStream = 0, StreamPerThread, CreatedStream, NoStream }; /* Test type NoStream - Use Sync variants, else use async variants */ auto streamType = GENERATE(StreamTestType::NoStream, StreamTestType::NullStream, StreamTestType::StreamPerThread, StreamTestType::CreatedStream); hipStream_t stream{nullptr}; if (streamType == StreamTestType::StreamPerThread) { stream = hipStreamPerThread; } else if (streamType == StreamTestType::CreatedStream) { HIP_CHECK(hipStreamCreate(&stream)); } INFO("Stream :: " << streamType); hipError_t memcpy_err = hipSuccess; SECTION("Singular Value") { int set{42}; int result{0}; if (streamType == StreamTestType::NoStream) { memcpy_err = hipSuccess; BEGIN_CAPTURE_SYNC(memcpy_err, false); HIP_CHECK_ERROR(hipMemcpyToSymbol(HIP_SYMBOL(devSymbol), &set, sizeof(int)), memcpy_err); HIP_CHECK_ERROR(hipMemcpyFromSymbol(&result, HIP_SYMBOL(devSymbol), sizeof(int)), memcpy_err); END_CAPTURE_SYNC(memcpy_err); } else { HIP_CHECK(hipMemcpyToSymbolAsync(HIP_SYMBOL(devSymbol), &set, sizeof(int), 0, hipMemcpyHostToDevice, stream)); HIP_CHECK(hipMemcpyFromSymbolAsync(&result, HIP_SYMBOL(devSymbol), sizeof(int), 0, hipMemcpyDeviceToHost, stream)); HIP_CHECK(hipStreamSynchronize(stream)); } if (memcpy_err == hipSuccess) { REQUIRE(result == set); } } SECTION("Array Values") { constexpr size_t size{10}; int set[size] = {4, 2, 4, 2, 4, 2, 4, 2, 4, 2}; int result[size] = {0}; if (streamType == StreamTestType::NoStream) { memcpy_err = hipSuccess; BEGIN_CAPTURE_SYNC(memcpy_err, false); HIP_CHECK_ERROR(hipMemcpyToSymbol(HIP_SYMBOL(devSymbol), set, sizeof(int) * size), memcpy_err); HIP_CHECK_ERROR(hipMemcpyFromSymbol(&result, HIP_SYMBOL(devSymbol), sizeof(int) * size), memcpy_err); END_CAPTURE_SYNC(memcpy_err); } else { HIP_CHECK(hipMemcpyToSymbolAsync(HIP_SYMBOL(devSymbol), set, sizeof(int) * size, 0, hipMemcpyHostToDevice, stream)); HIP_CHECK(hipMemcpyFromSymbolAsync(&result, HIP_SYMBOL(devSymbol), sizeof(int) * size, 0, hipMemcpyDeviceToHost, stream)); HIP_CHECK(hipStreamSynchronize(stream)); } if (memcpy_err == hipSuccess) { for (size_t i = 0; i < size; i++) { REQUIRE(result[i] == set[i]); } } } SECTION("Offset'ed Values") { constexpr size_t size{10}; constexpr size_t offset = 5 * sizeof(int); int set[size] = {9, 9, 9, 9, 9, 2, 4, 2, 4, 2}; int result[size] = {0}; if (streamType == StreamTestType::NoStream) { memcpy_err = hipSuccess; BEGIN_CAPTURE_SYNC(memcpy_err, false); HIP_CHECK_ERROR(hipMemcpyToSymbol(HIP_SYMBOL(devSymbol), set, offset), memcpy_err); HIP_CHECK_ERROR(hipMemcpyToSymbol(HIP_SYMBOL(devSymbol), set + 5, offset, offset), memcpy_err); HIP_CHECK_ERROR(hipMemcpyFromSymbol(result, HIP_SYMBOL(devSymbol), sizeof(int) * size), memcpy_err); END_CAPTURE_SYNC(memcpy_err); } else { HIP_CHECK(hipMemcpyToSymbolAsync(HIP_SYMBOL(devSymbol), set, offset, 0, hipMemcpyHostToDevice, stream)); HIP_CHECK(hipMemcpyToSymbolAsync(HIP_SYMBOL(devSymbol), set + 5, offset, offset, hipMemcpyHostToDevice, stream)); HIP_CHECK(hipMemcpyFromSymbolAsync(result, HIP_SYMBOL(devSymbol), offset, 0, hipMemcpyDeviceToHost, stream)); HIP_CHECK(hipMemcpyFromSymbolAsync(result + 5, HIP_SYMBOL(devSymbol), offset, offset, hipMemcpyDeviceToHost, stream)); HIP_CHECK(hipStreamSynchronize(stream)); } if (memcpy_err == hipSuccess) { for (size_t i = 0; i < size; i++) { REQUIRE(result[i] == set[i]); } } } if (streamType == StreamTestType::CreatedStream) { HIP_CHECK(hipStreamDestroy(stream)); } } /** * Test Description * ------------------------ * - Basic functional testcase to trigger capturehipMemcpyToSymbolAsync * and capturehipMemcpyFromSymbolAsync internal apis to improve * code coverage. * Test source * ------------------------ * - unit/memory/hipMemcpyFromSymbol.cc * Test requirements * ------------------------ * - HIP_VERSION >= 6.0 */ HIP_TEST_CASE(Unit_hipMemcpyToFromSymbol_Capture) { hipStream_t stream = nullptr; HIP_CHECK(hipStreamCreate(&stream)); constexpr int kExpectedValue = 42; int host_value = 0; GENERATE_CAPTURE(); BEGIN_CAPTURE(stream); SECTION("ConstantSymbolTransfer") { HIP_CHECK(hipMemcpyToSymbolAsync(HIP_SYMBOL(constSymbol), &kExpectedValue, sizeof(int), 0, hipMemcpyHostToDevice, stream)); HIP_CHECK(hipMemcpyFromSymbolAsync(&host_value, HIP_SYMBOL(constSymbol), sizeof(int), 0, hipMemcpyDeviceToHost, stream)); } SECTION("DeviceSymbolTransfer") { HIP_CHECK(hipMemcpyToSymbolAsync(HIP_SYMBOL(devSymbol), &kExpectedValue, sizeof(int), 0, hipMemcpyHostToDevice, stream)); HIP_CHECK(hipMemcpyFromSymbolAsync(&host_value, HIP_SYMBOL(devSymbol), sizeof(int), 0, hipMemcpyDeviceToHost, stream)); } END_CAPTURE(stream); HIP_CHECK(hipStreamSynchronize(stream)); REQUIRE(host_value == kExpectedValue); HIP_CHECK(hipStreamDestroy(stream)); }