Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion llvm/include/llvm/SYCLLowerIR/DeviceConfigFile.td
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ def AspectExt_oneapi_cuda_cluster_group : Aspect<"ext_oneapi_cuda_cluster_group"
def AspectExt_intel_fpga_task_sequence : Aspect<"ext_intel_fpga_task_sequence">;
def AspectExt_oneapi_atomic16 : Aspect<"ext_oneapi_atomic16">;
def AspectExt_oneapi_virtual_functions : Aspect<"ext_oneapi_virtual_functions">;
def AspectExt_oneapi_async_memory_alloc : Aspect<"ext_oneapi_async_memory_alloc">;
// Deprecated aspects
def AspectInt64_base_atomics : Aspect<"int64_base_atomics">;
def AspectInt64_extended_atomics : Aspect<"int64_extended_atomics">;
Expand Down Expand Up @@ -150,7 +151,8 @@ def : TargetInfo<"__TestAspectList",
AspectExt_oneapi_queue_profiling_tag, AspectExt_oneapi_virtual_mem, AspectExt_oneapi_cuda_cluster_group,
AspectExt_intel_fpga_task_sequence,
AspectExt_oneapi_atomic16,
AspectExt_oneapi_virtual_functions],
AspectExt_oneapi_virtual_functions,
AspectExt_oneapi_async_memory_alloc],
[]>;
// This definition serves the only purpose of testing whether the deprecated aspect list defined in here and in SYCL RT
// match.
Expand Down
19 changes: 19 additions & 0 deletions sycl/include/sycl/context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <sycl/detail/owner_less_base.hpp> // for OwnerLessBase
#include <sycl/platform.hpp> // for platform
#include <sycl/property_list.hpp> // for property_list
#include <sycl/usm/usm_enums.hpp> // for usm::alloc
#include <ur_api.h> // for ur_native_handle_t

#ifdef __SYCL_INTERNAL_API
Expand All @@ -36,6 +37,10 @@ inline namespace _V1 {
class device;
class platform;

namespace ext::oneapi::experimental {
class memory_pool;
} // namespace ext::oneapi::experimental

namespace detail {
class context_impl;
}
Expand Down Expand Up @@ -245,6 +250,20 @@ class __SYCL_EXPORT context : public detail::OwnerLessBase<context> {
/// \return a vector of valid SYCL device instances.
std::vector<device> get_devices() const;

/// Gets default memory pool associated with a device and context.
///
/// \return a memory pool for a particular device and context.
sycl::ext::oneapi::experimental::memory_pool
ext_oneapi_get_default_memory_pool(const device &dev,
const sycl::usm::alloc &kind) const;

/// Gets default memory pool associated with the context -- with the
/// allocation kind usm::alloc::host.
///
/// \return a memory pool associated with this context.
sycl::ext::oneapi::experimental::memory_pool
ext_oneapi_get_default_memory_pool() const;

private:
/// Constructs a SYCL context object from a valid context_impl instance.
context(std::shared_ptr<detail::context_impl> Impl);
Expand Down
2 changes: 2 additions & 0 deletions sycl/include/sycl/detail/cg_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ enum class CGType : unsigned int {
SemaphoreSignal = 25,
ProfilingTag = 26,
EnqueueNativeCommand = 27,
AsyncAlloc = 28,
AsyncFree = 29,
};

template <typename, typename T> struct check_fn_signature {
Expand Down
8 changes: 6 additions & 2 deletions sycl/include/sycl/detail/property_helper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,10 @@ enum DataLessPropKind {
GraphDependOnAllLeaves = 24,
GraphUpdatable = 25,
GraphEnableProfiling = 26,
MemPoolReadOnly = 27,
MemPoolZeroInit = 28,
// Indicates the last known dataless property.
LastKnownDataLessPropKind = 26,
LastKnownDataLessPropKind = 28,
// Exceeding 32 may cause ABI breaking change on some of OSes.
DataLessPropKindSize = 32
};
Expand All @@ -67,7 +69,9 @@ enum PropWithDataKind {
AccPropBufferLocation = 5,
QueueComputeIndex = 6,
GraphNodeDependencies = 7,
PropWithDataKindSize = 8
MemPoolInitialThreshold = 8,
MemPoolMaximumSize = 9,
PropWithDataKindSize = 10
};

// Base class for dataless properties, needed to check that the type of an
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
//==----------- async_alloc.hpp --- SYCL asynchronous allocation -----------==//
//
// 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
//
//===----------------------------------------------------------------------===//

#pragma once
#include <sycl/detail/common.hpp> // for code_location
#include <sycl/ext/oneapi/experimental/async_alloc/memory_pool.hpp> // for memory_pool
#include <sycl/handler.hpp> // for handler
#include <sycl/queue.hpp> // for queue
#include <sycl/usm/usm_enums.hpp> // for usm::alloc

namespace sycl {
inline namespace _V1 {
namespace ext::oneapi::experimental {

/**
* @brief Asynchronousy allocate memory from a default pool.
*
* @param q The queue with which to enqueue the asynchronous allocation.
* @param kind The kind of memory pool allocation - device, host, shared, etc.
* @param size The size in bytes to allocate.
*
* @return Generic pointer to allocated USM memory.
*/
__SYCL_EXPORT void *async_malloc(const sycl::queue &q, sycl::usm::alloc kind,
size_t size,
const sycl::detail::code_location &CodeLoc =
sycl::detail::code_location::current());

/**
* @brief Asynchronously allocate memory from a default pool.
*
* @param h The handler with which to enqueue the asynchronous allocation.
* @param kind The kind of memory pool allocation - device, host, shared, etc.
* @param size The size in bytes to allocate.
*
* @return Generic pointer to allocated USM memory.
*/
__SYCL_EXPORT void *async_malloc(sycl::handler &h, sycl::usm::alloc kind,
size_t size);

/**
* @brief Asynchronously allocate memory from a specified pool.
*
* @param q The queue with which to enqueue the asynchronous allocation.
* @param size The size in bytes to allocate.
* @param pool The pool with which to allocate from.
*
* @return Generic pointer to allocated USM memory.
*/
__SYCL_EXPORT void *
async_malloc_from_pool(const sycl::queue &q, size_t size, memory_pool &pool,
const sycl::detail::code_location &CodeLoc =
sycl::detail::code_location::current());

/**
* @brief Asynchronously allocate memory from a specified pool.
*
* @param h The handler with which to enqueue the asynchronous allocation.
* @param size The size in bytes to allocate.
* @param pool The pool with which to allocate from.
*
* @return Generic pointer to allocated USM memory.
*/
__SYCL_EXPORT void *async_malloc_from_pool(sycl::handler &h, size_t size,
memory_pool &pool);

/**
* @brief Asynchronously free memory.
*
* @param q The queue with which to enqueue the asynchronous free.
* @param ptr The generic pointer to be freed.
*/
__SYCL_EXPORT void async_free(const sycl::queue &q, void *ptr,
const sycl::detail::code_location &CodeLoc =
sycl::detail::code_location::current());

/**
* @brief Asynchronously free memory.
*
* @param h The handler with which to enqueue the asynchronous free.
* @param ptr The generic pointer to be freed.
*/
__SYCL_EXPORT void async_free(sycl::handler &h, void *ptr);

} // namespace ext::oneapi::experimental
} // namespace _V1
} // namespace sycl
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
//==----------- memory_pool.hpp --- SYCL asynchronous allocation -----------==//
//
// 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
//
//===----------------------------------------------------------------------===//

#pragma once
#include <sycl/context.hpp> // for context
#include <sycl/device.hpp> // for device
#include <sycl/queue.hpp> // for queue
#include <sycl/usm/usm_enums.hpp> // for usm::alloc

namespace sycl {
inline namespace _V1 {
namespace ext::oneapi::experimental {
namespace property {

// Property that determines the initial threshold of a memory pool.
struct initial_threshold : public sycl::detail::PropertyWithData<
sycl::detail::MemPoolInitialThreshold> {
public:
initial_threshold(size_t initialThreshold)
: initialThreshold(initialThreshold) {};
size_t get_initial_threshold() { return initialThreshold; }

private:
size_t initialThreshold;
};

// Property that determines the maximum size of a memory pool.
struct maximum_size
: public sycl::detail::PropertyWithData<sycl::detail::MemPoolMaximumSize> {
public:
maximum_size(size_t maxSize) : maxSize(maxSize) {};
size_t get_maximum_size() { return maxSize; }

private:
size_t maxSize;
};

// Property that provides a performance hint that all allocations from this pool
// will only be read from within SYCL kernel functions.
struct read_only
: public sycl::detail::DataLessProperty<sycl::detail::MemPoolReadOnly> {
public:
read_only() = default;
};

// Property that initial allocations to a pool (not subsequent allocations from
// prior frees) are iniitialised to zero.
struct zero_init
: public sycl::detail::DataLessProperty<sycl::detail::MemPoolZeroInit> {
public:
zero_init() = default;
};
} // namespace property

namespace detail {
class memory_pool_impl {
public:
memory_pool_impl(const sycl::context &ctx, const sycl::device &dev,
const sycl::usm::alloc kind, const property_list &props);
memory_pool_impl(const sycl::context &ctx, const sycl::device &dev,
const sycl::usm::alloc kind, ur_usm_pool_handle_t poolHandle,
const bool isDefaultPool, const property_list &props);

~memory_pool_impl();

memory_pool_impl(const memory_pool_impl &) = delete;
memory_pool_impl &operator=(const memory_pool_impl &) = delete;

ur_usm_pool_handle_t get_handle() const { return poolHandle; }
sycl::device get_device() const { return syclDevice; }
sycl::context get_context() const { return syclContext; }
sycl::usm::alloc get_alloc_kind() const { return kind; }
const property_list &getPropList() const { return propList; }

// Returns backend specific values.
size_t get_max_size() const;
size_t get_threshold() const;
void set_new_threshold(size_t newThreshold);

private:
sycl::context syclContext;
sycl::device syclDevice;
sycl::usm::alloc kind;
ur_usm_pool_handle_t poolHandle{0};
bool isDefaultPool = false;
property_list propList;
};
} // namespace detail

/// Memory pool
class __SYCL_EXPORT memory_pool {

public:
memory_pool(const sycl::context &ctx, const property_list &props = {});

memory_pool(const sycl::context &ctx, const sycl::device &dev,
const sycl::usm::alloc kind, const property_list &props = {});

memory_pool(const sycl::queue &q, const sycl::usm::alloc kind,
const property_list &props = {});

memory_pool(const sycl::context &ctx, const void *ptr, size_t size,
const property_list &props = {});

~memory_pool() = default;

// Copy constructible/assignable, move constructible/assignable.
memory_pool(const memory_pool &) = default;
memory_pool(memory_pool &&) = default;
memory_pool &operator=(const memory_pool &) = default;
memory_pool &operator=(memory_pool &&) = default;

// Equality comparison.
bool operator==(const memory_pool &rhs) const { return impl == rhs.impl; }
bool operator!=(const memory_pool &rhs) const { return !(*this == rhs); }

// Impl handles getters and setters.
sycl::context get_context() const { return impl->get_context(); }
sycl::device get_device() const { return impl->get_device(); }
sycl::usm::alloc get_alloc_kind() const { return impl->get_alloc_kind(); }

size_t get_max_size() const;
size_t get_threshold() const;
void set_new_threshold(size_t newThreshold);

// Property getters.
template <typename propertyT> bool has_property() const noexcept {
return getPropList().template has_property<propertyT>();
}
template <typename propertyT> propertyT get_property() const {
return getPropList().template get_property<propertyT>();
}

protected:
std::shared_ptr<detail::memory_pool_impl> impl;

template <class Obj>
friend const decltype(Obj::impl) &
sycl::detail::getSyclObjImpl(const Obj &SyclObject);

template <class T>
friend T sycl::detail::createSyclObjFromImpl(decltype(T::impl) ImplObj);

const property_list &getPropList() const;

memory_pool(std::shared_ptr<detail::memory_pool_impl> Impl) : impl(Impl) {}
};

} // namespace ext::oneapi::experimental

template <>
struct is_property<sycl::ext::oneapi::experimental::property::initial_threshold>
: std::true_type {};

template <>
struct is_property<sycl::ext::oneapi::experimental::property::maximum_size>
: std::true_type {};

template <>
struct is_property<sycl::ext::oneapi::experimental::property::read_only>
: std::true_type {};

template <>
struct is_property<sycl::ext::oneapi::experimental::property::zero_init>
: std::true_type {};
} // namespace _V1
} // namespace sycl

namespace std {
template <> struct hash<sycl::ext::oneapi::experimental::memory_pool> {
size_t operator()(
const sycl::ext::oneapi::experimental::memory_pool &mem_pool) const {
return hash<std::shared_ptr<
sycl::ext::oneapi::experimental::detail::memory_pool_impl>>()(
sycl::detail::getSyclObjImpl(mem_pool));
}
};
} // namespace std
17 changes: 17 additions & 0 deletions sycl/include/sycl/handler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,11 @@ namespace ext ::oneapi ::experimental {
template <typename, typename>
class work_group_memory;
struct image_descriptor;
__SYCL_EXPORT void async_free(handler &h, void *ptr);
__SYCL_EXPORT void *async_malloc(sycl::handler &h, sycl::usm::alloc kind,
size_t size);
__SYCL_EXPORT void *async_malloc_from_pool(sycl::handler &h, size_t size,
memory_pool &pool);
} // namespace ext::oneapi::experimental

namespace ext::oneapi::experimental::detail {
Expand Down Expand Up @@ -3882,6 +3887,18 @@ class __SYCL_EXPORT handler {

friend class detail::HandlerAccess;

// Friend free-functions for asynchronous allocation and freeing.
__SYCL_EXPORT friend void
ext::oneapi::experimental::async_free(sycl::handler &h, void *ptr);

__SYCL_EXPORT friend void *
ext::oneapi::experimental::async_malloc(sycl::handler &h,
sycl::usm::alloc kind, size_t size);

__SYCL_EXPORT friend void *ext::oneapi::experimental::async_malloc_from_pool(
sycl::handler &h, size_t size,
ext::oneapi::experimental::memory_pool &pool);

protected:
/// Registers event dependencies in this command group.
void depends_on(const detail::EventImplPtr &Event);
Expand Down
Loading
Loading