blob: ba446ee4cd7eccc91625412477efc57845ff116b [file] [edit]
//===------- 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 <OffloadAPI.h>
#include <gtest/gtest.h>
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<uint8_t *>(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<uint8_t *>(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<int>(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<uint8_t *>(Allocs[I])[J],
static_cast<uint8_t>(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));
}