| //===----------------------------------------------------------------------===// | |
| // | |
| // 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 |