//===------- Offload API tests - olMemPrefetch ----------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "../common/Fixtures.hpp" #include #include using olMemPrefetchTest = OffloadQueueTest; OFFLOAD_TESTS_INSTANTIATE_DEVICE_FIXTURE(olMemPrefetchTest); TEST_P(olMemPrefetchTest, SuccessHostToDevice) { constexpr size_t Size = 1024; void *Alloc; ASSERT_SUCCESS(olMemAlloc(Device, OL_ALLOC_TYPE_MANAGED, Size, &Alloc)); std::memset(Alloc, 0x42, Size); const void *Mems[] = {Alloc}; const size_t Sizes[] = {Size}; ASSERT_SUCCESS(olMemPrefetch(Queue, 1, Mems, Sizes, OL_MEM_MIGRATION_FLAG_HOST_TO_DEVICE)); ASSERT_SUCCESS(olSyncQueue(Queue)); for (size_t I = 0; I < Size; I++) ASSERT_EQ(static_cast(Alloc)[I], 0x42); ASSERT_SUCCESS(olMemFree(Alloc)); } TEST_P(olMemPrefetchTest, SuccessDeviceToHost) { constexpr size_t Size = 1024; void *Alloc; ASSERT_SUCCESS(olMemAlloc(Device, OL_ALLOC_TYPE_MANAGED, Size, &Alloc)); std::memset(Alloc, 0x21, Size); const void *Mems[] = {Alloc}; const size_t Sizes[] = {Size}; // Migrate to the device first, then bring it back. ASSERT_SUCCESS(olMemPrefetch(Queue, 1, Mems, Sizes, OL_MEM_MIGRATION_FLAG_HOST_TO_DEVICE)); ASSERT_SUCCESS(olMemPrefetch(Queue, 1, Mems, Sizes, OL_MEM_MIGRATION_FLAG_DEVICE_TO_HOST)); ASSERT_SUCCESS(olSyncQueue(Queue)); for (size_t I = 0; I < Size; I++) ASSERT_EQ(static_cast(Alloc)[I], 0x21); ASSERT_SUCCESS(olMemFree(Alloc)); } TEST_P(olMemPrefetchTest, SuccessMultiple) { constexpr size_t NumAllocs = 3; constexpr size_t Size = 1024; void *Allocs[NumAllocs]; const void *Mems[NumAllocs]; size_t Sizes[NumAllocs]; for (size_t I = 0; I < NumAllocs; I++) { ASSERT_SUCCESS(olMemAlloc(Device, OL_ALLOC_TYPE_MANAGED, Size, &Allocs[I])); std::memset(Allocs[I], static_cast(0x10 + I), Size); Mems[I] = Allocs[I]; Sizes[I] = Size; } ASSERT_SUCCESS(olMemPrefetch(Queue, NumAllocs, Mems, Sizes, OL_MEM_MIGRATION_FLAG_HOST_TO_DEVICE)); ASSERT_SUCCESS(olSyncQueue(Queue)); for (size_t I = 0; I < NumAllocs; I++) { for (size_t J = 0; J < Size; J++) ASSERT_EQ(static_cast(Allocs[I])[J], static_cast(0x10 + I)); ASSERT_SUCCESS(olMemFree(Allocs[I])); } } TEST_P(olMemPrefetchTest, SuccessZeroCount) { ASSERT_SUCCESS(olMemPrefetch(Queue, 0, nullptr, nullptr, OL_MEM_MIGRATION_FLAG_HOST_TO_DEVICE)); ASSERT_SUCCESS(olSyncQueue(Queue)); } TEST_P(olMemPrefetchTest, SuccessZeroSize) { constexpr size_t Size = 1024; void *Alloc; ASSERT_SUCCESS(olMemAlloc(Device, OL_ALLOC_TYPE_MANAGED, Size, &Alloc)); const void *Mems[] = {Alloc}; const size_t Sizes[] = {0}; ASSERT_SUCCESS(olMemPrefetch(Queue, 1, Mems, Sizes, OL_MEM_MIGRATION_FLAG_HOST_TO_DEVICE)); ASSERT_SUCCESS(olSyncQueue(Queue)); ASSERT_SUCCESS(olMemFree(Alloc)); } TEST_P(olMemPrefetchTest, SuccessUnsupportedAllocType) { // Prefetching a non-managed allocation is not meaningful, but per the API // contract the hint must be silently ignored and the call must still succeed. constexpr size_t Size = 1024; void *Alloc; ASSERT_SUCCESS(olMemAlloc(Device, OL_ALLOC_TYPE_DEVICE, Size, &Alloc)); const void *Mems[] = {Alloc}; const size_t Sizes[] = {Size}; ASSERT_SUCCESS(olMemPrefetch(Queue, 1, Mems, Sizes, OL_MEM_MIGRATION_FLAG_HOST_TO_DEVICE)); ASSERT_SUCCESS(olSyncQueue(Queue)); ASSERT_SUCCESS(olMemFree(Alloc)); } TEST_P(olMemPrefetchTest, InvalidFlags) { constexpr size_t Size = 1024; void *Alloc; ASSERT_SUCCESS(olMemAlloc(Device, OL_ALLOC_TYPE_MANAGED, Size, &Alloc)); const void *Mems[] = {Alloc}; const size_t Sizes[] = {Size}; ASSERT_ERROR(OL_ERRC_INVALID_ENUMERATION, olMemPrefetch(Queue, 1, Mems, Sizes, 0xdeadbeef)); ASSERT_SUCCESS(olMemFree(Alloc)); } TEST_P(olMemPrefetchTest, InvalidNullMems) { const size_t Sizes[] = {0}; ASSERT_ERROR(OL_ERRC_INVALID_NULL_POINTER, olMemPrefetch(Queue, 1, nullptr, Sizes, OL_MEM_MIGRATION_FLAG_HOST_TO_DEVICE)); } TEST_P(olMemPrefetchTest, InvalidNullSizes) { constexpr size_t Size = 1024; void *Alloc; ASSERT_SUCCESS(olMemAlloc(Device, OL_ALLOC_TYPE_MANAGED, Size, &Alloc)); const void *Mems[] = {Alloc}; ASSERT_ERROR(OL_ERRC_INVALID_NULL_POINTER, olMemPrefetch(Queue, 1, Mems, nullptr, OL_MEM_MIGRATION_FLAG_HOST_TO_DEVICE)); ASSERT_SUCCESS(olMemFree(Alloc)); }