blob: 24a099ea4cf2a2d4690a97b5ad81ccc460581d0f [file] [log] [blame] [edit]
//===----------------------------------------------------------------------===//
//
// 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 <sycl/__impl/usm_functions.hpp>
#include <detail/device_impl.hpp>
#include <detail/offload/offload_utils.hpp>
#include <OffloadAPI.h>
#include <algorithm>
_LIBSYCL_BEGIN_NAMESPACE_SYCL
// SYCL 2020 4.8.3.2. Device allocation functions.
void *malloc_device(std::size_t numBytes, const device &syclDevice,
const context &syclContext, const property_list &propList) {
return malloc(numBytes, syclDevice, syclContext, usm::alloc::device,
propList);
}
void *malloc_device(std::size_t numBytes, const queue &syclQueue,
const property_list &propList) {
return malloc_device(numBytes, syclQueue.get_device(),
syclQueue.get_context(), propList);
}
// SYCL 2020 4.8.3.3. Host allocation functions.
void *malloc_host(std::size_t numBytes, const context &syclContext,
const property_list &propList) {
auto ContextDevices = syclContext.get_devices();
assert(!ContextDevices.empty() && "Context can't be created without device");
if (std::none_of(
ContextDevices.begin(), ContextDevices.end(),
[](device Dev) { return Dev.has(aspect::usm_host_allocations); }))
throw sycl::exception(
sycl::errc::feature_not_supported,
"All devices of context do not support host USM allocations.");
return malloc(numBytes, ContextDevices[0], syclContext, usm::alloc::host,
propList);
}
void *malloc_host(std::size_t numBytes, const queue &syclQueue,
const property_list &propList) {
return malloc_host(numBytes, syclQueue.get_context(), propList);
}
// SYCL 2020 4.8.3.4. Shared allocation functions.
void *malloc_shared(std::size_t numBytes, const device &syclDevice,
const context &syclContext, const property_list &propList) {
return malloc(numBytes, syclDevice, syclContext, usm::alloc::shared,
propList);
}
void *malloc_shared(std::size_t numBytes, const queue &syclQueue,
const property_list &propList) {
return malloc_shared(numBytes, syclQueue.get_device(),
syclQueue.get_context(), propList);
}
// SYCL 2020 4.8.3.5. Parameterized allocation functions.
static aspect getAspectByAllocationKind(usm::alloc kind) {
switch (kind) {
case usm::alloc::host:
return aspect::usm_host_allocations;
case usm::alloc::device:
return aspect::usm_device_allocations;
case usm::alloc::shared:
return aspect::usm_shared_allocations;
case usm::alloc::unknown:
// usm::alloc::unknown can be returned to user from get_pointer_type but
// it can't be converted to a valid backend type.
throw exception(sycl::make_error_code(sycl::errc::invalid),
"Invalid USM allocation kind requested");
}
}
void *malloc(std::size_t numBytes, const device &syclDevice,
const context &syclContext, usm::alloc kind,
const property_list &propList) {
auto ContextDevices = syclContext.get_devices();
assert(!ContextDevices.empty() && "Context can't be created without device");
if (std::none_of(ContextDevices.begin(), ContextDevices.end(),
[&syclDevice](device Dev) { return Dev == syclDevice; }))
throw exception(make_error_code(errc::invalid),
"Specified device is not contained by specified context.");
if (!syclDevice.has(getAspectByAllocationKind(kind)))
throw sycl::exception(
sycl::errc::feature_not_supported,
"Device doesn't support requested kind of USM allocation");
if (!numBytes)
return nullptr;
void *Ptr{};
auto Result = detail::callNoCheck(
olMemAlloc, detail::getSyclObjImpl(syclDevice)->getOLHandle(),
detail::getOlAllocType(kind), numBytes, &Ptr);
return detail::isFailed(Result) ? nullptr : Ptr;
}
void *malloc(std::size_t numBytes, const queue &syclQueue, usm::alloc kind,
const property_list &propList) {
return malloc(numBytes, syclQueue.get_device(), syclQueue.get_context(), kind,
propList);
}
// SYCL 2020 4.8.3.6. Memory deallocation functions.
void free(void *ptr, const context &ctxt) {
std::ignore = ctxt;
detail::callAndThrow(olMemFree, ptr);
}
void free(void *ptr, const queue &q) { return free(ptr, q.get_context()); }
_LIBSYCL_END_NAMESPACE_SYCL