diff --git a/adoc/chapters/architecture.adoc b/adoc/chapters/architecture.adoc index 499038ca..0da52a07 100644 --- a/adoc/chapters/architecture.adoc +++ b/adoc/chapters/architecture.adoc @@ -3,36 +3,25 @@ [[architecture]] = SYCL architecture -This chapter describes the structure of a SYCL application, and how the SYCL -generic programming model lays out on top of a number of <>s. +This chapter describes the structure of a SYCL application and its programming +model. == Overview SYCL is an open industry standard for programming a heterogeneous system. The design of SYCL allows standard {cpp} source code to be written such that it -can run on either an heterogeneous device or on the <>. - -The terminology used for SYCL inherits historically from OpenCL with some -SYCL-specific additions. -However SYCL is a generic {cpp} programming model that can be laid out on top of -other heterogeneous APIs apart from OpenCL. -SYCL implementations can provide <>s for various heterogeneous APIs, -implementing the SYCL general specification on top of them. -We refer to this heterogeneous API as the <>. -The SYCL general specification defines the behavior that all SYCL -implementations must expose to SYCL users for a SYCL application to behave as -expected. - -A function object that can execute on a <> exposed by a <> -is called a <>. - -To ensure maximum interoperability with different <>s, software -developers can access the <> alongside the SYCL general API -whenever they include the <> interoperability headers. -However, interoperability is a <>-specific feature. -An application that uses interoperability does not conform to the SYCL general -application model, since it is not portable across backends. +can run on either an heterogeneous device such as a GPU or on a general purpose +CPU. + +Some terminology from SYCL derives from OpenCL. +However, OpenCL is not a prerequisite for implementing SYCL. +A SYCL implementation may layer on top of a heterogeneous programming API such +as OpenCL, but this is not necessary. +It is also possible to implement SYCL directly on hardware. + +A function object that can execute on a <> is called a +<>. // Note below I leave the reference to OpenCL intentionally @@ -194,8 +183,8 @@ An implementation may also expose empty <> that do not contain any <>. A SYCL <> is constructed, either directly by the user or implicitly -when creating a <>, to hold all the runtime information required by the -SYCL runtime and the <> to operate on a device, or group of devices. +when creating a <>, to hold all the runtime information required to +operate on a device, or group of devices. When a group of devices can be grouped together on the same context, they have some visibility of each other's memory objects. The SYCL runtime can assume that memory is visible across all devices in the @@ -204,26 +193,23 @@ Not all devices exposed from the same <> can be grouped together in the same <>. A SYCL application executes on the host as a standard {cpp} program. -<> are exposed through different <> to -the SYCL application. +The <> exposes <> to the application. The SYCL application submits <> to <>. -Each <> enables execution on a given device. +function objects>> to <>, and each <> enables execution on +a given device. The <> then extracts operations from the <>, e.g. an explicit copy operation or a <>. -When the operation is a <>, the <> uses a -<>-specific mechanism to extract the device binary from the SYCL +When the operation is a <>, the <> uses an +implementation-specific mechanism to extract the device binary from the SYCL application and pass it to the heterogeneous API for execution on the <>. A SYCL <> is divided into one or more compute units (CUs) which are each divided into one or more processing elements (PEs). Computations on a device occur within the processing elements. -How computation is mapped to PEs is <> and <> specific. -Two devices exposed via two different backends can map computations differently -to the same device. +How computation is mapped to PEs is specific to the implementation. When a SYCL application contains <> objects, the SYCL implementation must provide an offline compilation mechanism that enables the @@ -233,29 +219,36 @@ as SPIR-V, that will be finalized during execution or a final device ISA. A device may expose special purpose functionality as a _built-in_ function. The SYCL API exposes functions to query and dispatch said _built-in_ functions. -Some <> and <> may not support -programmable kernels, and only support _built-in_ functions. +Some <> may not support programmable kernels, and only support +_built-in_ functions. // TODO: Conformance of these custom-devices? == The SYCL backend model -SYCL is a generic programming model for the {cpp} language that can target -multiple heterogeneous APIs, such as OpenCL. - -SYCL implementations enable these target APIs by implementing <>. -For a SYCL implementation to be conformant on said <>, it must execute -the SYCL generic programming model on the backend. -All SYCL implementations must provide at least one backend. - -The present document covers the SYCL generic interface available to all -<>. -How the SYCL generic interface maps to a particular <> is defined -either by a separate <> specification document, provided by the Khronos -SYCL group, or by the SYCL implementation documentation. -Whenever there is a <> specification document, this takes precedence -over SYCL implementation documentation. +A SYCL implementation may expose devices by layering on top of a heterogeneous +API such as OpenCL or it may expose devices in some other way. +An implementation may even combine these methods, exposing devices through +several different heterogeneous APIs or through other mechanisms. +Regardless of how the devices are exposed, they must implement the semantics of +the SYCL APIs defined in this document. + +When a SYCL implementation layers on top of a heterogeneous API such as OpenCL, +we refer to this as a <>. +In this case, the implementation may choose to document how the backend APIs +correlate to SYCL and provide interoperation APIs that allow a SYCL application +to make calls to both the SYCL APIs and the backend APIs. +However, applications that make use of this ability are no longer conformant to +the <> and may not be portable to other implementations of SYCL. + +In order to aid with this sort of backend interoperation, SYCL provides the +[code]#backend# enumeration, and most SYCL objects provide a member function +[code]#get_backend#. +If a SYCL implementation wants to expose backend interoperation, it must define +one or more enumerators in the [code]#backend# enumeration, and each of those +enumerators must have a corresponding backend interoperation specification. +These enumerators and specifications may be defined either by the Khronos SYCL +group or by the vendor of the SYCL implementation. When a SYCL user builds their SYCL application, she decides which of the <> will be used to build the SYCL application. @@ -306,22 +299,21 @@ across <>. USM allocations are subject to the limitations described in <>. -When a SYCL application runs on any number of <> without -relying on any <>-specific behavior or interoperability, it is said to -be a SYCL general application, and it is expected to run in any SYCL-conformant +When a SYCL application runs without relying on any <>-specific +behavior or interoperability, it is expected to run on any SYCL-conformant implementation that supports the required features for the application. === Platform mixed version support -The SYCL generic programming model exposes a number of <>, -each of them either empty or exposing a number of <>. -Each <> is bound to a certain <>. -SYCL <> associated with said <> are associated with -that <>. +The SYCL programming model exposes a number of <>, each of +them either empty or exposing a number of <>. +Each platform is bound to no more than one <>. +If the platform is bound to a backend, the devices associated with that platform +are associated with that backend. -Although the APIs in the SYCL generic programming model are defined according to -this specification and their version is indicated by the macro +Although most APIs in the SYCL programming model are defined according to this +specification and their version is indicated by the macro [code]#SYCL_LANGUAGE_VERSION#, this does not apply to APIs exposed by the <>. Each <> provides its own document that defines its APIs, and that @@ -1608,13 +1600,13 @@ queue constructor. Device topology may be cached by the <>, but this is not required. Device discovery will return all <> from all -<> exposed by all the supported <>. +<>. === Interfacing with the SYCL backend API There are two styles of developing a SYCL application: -. writing a pure SYCL generic application; +. writing a SYCL application that works with any <>; . writing a SYCL application that relies on some <> specific behavior. When users follow 1., there is no assumption about what <> will be used @@ -1622,8 +1614,8 @@ during compilation or execution of the SYCL application. Therefore, the <> is not assumed to be available to the developer. Only standard {cpp} types and interfaces are assumed to be available, as described in <>. -Users only need to include the [code]## header to write a SYCL -generic application. +Users only need to include the [code]## header to write such an +application. On the other hand, when users follow 2., they must know what <>s they are using. diff --git a/adoc/chapters/device_compiler.adoc b/adoc/chapters/device_compiler.adoc index 5b89c137..469e573e 100644 --- a/adoc/chapters/device_compiler.adoc +++ b/adoc/chapters/device_compiler.adoc @@ -676,13 +676,13 @@ associated with an aspect that is not listed in the attribute. == Address-space deduction {cpp} has no type-level support to represent address spaces. -As a consequence, the SYCL generic programming model does not directly affect -the {cpp} type of unannotated pointers and references. +As a consequence, the SYCL programming model does not directly affect the {cpp} +type of unannotated pointers and references. -Source level guarantees about address spaces in the SYCL generic programming -model can only be achieved using pointer classes (instances of -[code]#multi_ptr#), which are regular classes that represent pointers to data -stored in the corresponding address spaces. +Source level guarantees about address spaces in the SYCL programming model can +only be achieved using pointer classes (instances of [code]#multi_ptr#), which +are regular classes that represent pointers to data stored in the corresponding +address spaces. In SYCL, the address space of pointer and references are derived from: diff --git a/adoc/chapters/host_backend.adoc b/adoc/chapters/host_backend.adoc index 24a871b1..a30b04d4 100644 --- a/adoc/chapters/host_backend.adoc +++ b/adoc/chapters/host_backend.adoc @@ -49,7 +49,7 @@ kernel execution model. Kernel math library functions on the host must conform to OpenCL math precision requirements. The SYCL host device needs to be queried for the capabilities it provides. -This ensures consistency when executing any SYCL general application. +This ensures consistency when executing any SYCL application. The <> must report as supporting images and therefore support the minimum image formats. diff --git a/adoc/chapters/opencl_backend.adoc b/adoc/chapters/opencl_backend.adoc index 37bc993c..13b13113 100644 --- a/adoc/chapters/opencl_backend.adoc +++ b/adoc/chapters/opencl_backend.adoc @@ -4,10 +4,10 @@ [[chapter:opencl-backend]] = OpenCL backend specification -This chapter describes how the SYCL general programming model is mapped on top -of OpenCL, and how the SYCL generic interoperability interface must be -implemented by vendors providing SYCL for OpenCL implementations to ensure SYCL -applications written for the OpenCL backend are interoperable. +This chapter describes how the SYCL programming model is mapped on top of +OpenCL, and how the SYCL interoperability interface must be implemented by +vendors providing SYCL for OpenCL implementations to ensure SYCL applications +written for the OpenCL backend are interoperable. [[sec:opencl:native-interop-application]] @@ -669,8 +669,8 @@ bool has_extension(const sycl::device& syclDevice, const std::string& extension) === Reference counting Most OpenCL objects are reference counted. -The SYCL general programming model doesn't require that native objects are -reference counted. +The SYCL programming model doesn't require that native objects are reference +counted. However, for convenience, the following function is provided in the [code]#sycl::opencl# namespace. diff --git a/adoc/chapters/programming_interface.adoc b/adoc/chapters/programming_interface.adoc index c7e06bd0..337a5fce 100644 --- a/adoc/chapters/programming_interface.adoc +++ b/adoc/chapters/programming_interface.adoc @@ -24,24 +24,24 @@ indicates a values for the enumerator. [[sec:backends]] == Backends -The <> that can be supported by a SYCL implementation -are identified using the [code]#enum class backend#. +The [code]#backend# enumerator defines the <> (if any) +that an application may interoperate with. [source,,linenums] ---- include::{header_dir}/backends.h[lines=4..-1] ---- -The [code]#enum class backend# is implementation-defined and must be populated -with a unique identifier for each <> that the SYCL implementation can -support. -Note that the <> listed in the [code]#enum class -backend# are not guaranteed to be available in a given installation. +The enumerator value [code]#backend::none# is used to identify a SYCL object +that does not correspond to any backend. +If the implementation provides interoperation with any backends, it must define +one additional enumerator for each of these backends, and these enumerators must +each have an associated backend interoperation specification. -Each named <> enumerated in the [code]#enum class backend# must be -associated with a <> specification. -Many sections of this specification will refer to the associated <> -specification. +Even if an implementation defines a backend enumerator, this is not a guarantee +that the backend is available when the application runs. +A backend is only guaranteed to be available if some SYCL object returns the +associated enumerator from its [code]#get_backend# member function. [[sec:backend-macros]] @@ -60,21 +60,9 @@ See <> for the name of the macro if the vendor defines the If a backend listed in the [code]#enum class backend# is not available, the associated macro must be left undefined. -[[sec:generic-vs-non-generic]] -== Generic vs non-generic SYCL - -The SYCL programming API is split into two categories; generic SYCL and -non-generic SYCL. -Almost everything in the SYCL programming API is considered generic SYCL. -However any usage of the [code]#enum class backend# is considered non-generic -SYCL and should only be used for <> specialized code paths, as the -identifiers defined in [code]#backend# are implementation-defined. - -In any non-generic SYCL application code where the [code]#backend# enum class is -used, the expression must be guarded with a preprocessor [code]#{hash}ifdef# -guard using the associated preprocessor macro to ensure that the SYCL -application will compile even if the SYCL implementation does not support that -<> being specialized for. +Any usage of the [code]#enum class backend# should appear only in code paths +specialized for a specific <> that are guarded by a preprocessor +directive using the macro associated with that backend. [[sec:headers-and-namespaces]] @@ -186,8 +174,6 @@ available outside of that scope. Support for <> interoperability is optional and therefore not required to be provided by a SYCL implementation. -A SYCL application using <> interoperability is considered to be -non-generic SYCL. Details on the interoperability for a given <> are available on the <> specification document for that <>. @@ -745,9 +731,8 @@ and returning a value that is implicitly convertible to [code]#int#. At any point where the <> needs to select a SYCL [code]#device# using a <>, the system queries all <> from all <> in the system, calls the -<> on each device and selects the one which returns the highest -score. +devices>> from all platforms in the system, calls the <> on +each device and selects the one which returns the highest score. If the highest value is strictly negative no device is selected. In places where only one device has to be picked and the high score is obtained @@ -770,7 +755,7 @@ a@ ---- default_selector_v ---- - a@ Select a SYCL [code]#device# from any supported <> + a@ Select a SYCL [code]#device# from one of the platforms based on an implementation-defined heuristic. Since all implementations must support at least one device, this selector must always return a device. @@ -787,7 +772,7 @@ a@ ---- gpu_selector_v ---- - a@ Select a SYCL [code]#device# from any supported <> + a@ Select a SYCL [code]#device# from one of the platforms for which the device type is [code]#info::device_type::gpu#. The SYCL class constructor using it must throw an [code]#exception# @@ -799,7 +784,7 @@ a@ ---- accelerator_selector_v ---- - a@ Select a SYCL [code]#device# from any supported <> + a@ Select a SYCL [code]#device# from one of the platforms for which the device type is [code]#info::device_type::accelerator#. The SYCL class constructor using it must throw an [code]#exception# @@ -811,7 +796,7 @@ a@ ---- cpu_selector_v ---- - a@ Select a SYCL [code]#device# from any supported <> + a@ Select a SYCL [code]#device# from one of the platforms for which the device type is [code]#info::device_type::cpu#. The SYCL class constructor using it must throw an [code]#exception# @@ -832,7 +817,7 @@ template __unspecified_callable__ aspect_selector(); ---- a@ The free function [code]#aspect_selector# has several overloads, each of which returns a selector object that selects a -SYCL [code]#device# from any supported <> +SYCL [code]#device# from one of the platforms which contains all the requested aspects, i.e. for the specific device [code]#dev# and each aspect [code]#devAspect# from [code]#aspectList# @@ -951,10 +936,11 @@ to resolve some ambiguity in constructors with default parameters. The SYCL [code]#platform# class encapsulates a single SYCL platform on which SYCL kernel functions may be executed. -A SYCL platform must be associated with a single <>. +A SYCL platform must be associated with no more than one <>. -A SYCL [code]#platform# is also associated with any number of SYCL -[code]#devices# associated with the same <>. +A platform is also associated with any number of SYCL devices. +If the platform is associated with a backend, each of these devices must be +associated with that same backend. A platform may contain no devices. All member functions of the [code]#platform# class are synchronous and errors @@ -1028,8 +1014,10 @@ a@ ---- backend get_backend() const noexcept ---- - a@ Returns a [code]#backend# identifying the <> associated - with this [code]#platform#. + a@ Returns the backend (if any) that underlies this object. + When the backend is not [code]#backend::none#, backend interoperation is + available for this object as defined by the corresponding SYCL backend + specification. a@ [source] @@ -1099,7 +1087,7 @@ a@ static std::vector get_platforms() ---- a@ Returns a [code]#std::vector# containing all SYCL - [code]#platforms# from all <> available in the system. + [code]#platforms# available in the system. |==== @@ -1170,8 +1158,8 @@ Returns the extensions supported by this [code]#platform#. Returns an empty list === Context class The <> class represents a SYCL <>. -A <> represents the runtime data structures and state required by a -<> API to interact with a group of devices associated with a platform. +A <> represents the runtime data structures and state required to +interact with a group of devices associated with a platform. The SYCL [code]#context# class provides the common reference semantics (see <>). @@ -1191,9 +1179,9 @@ All member functions of the <> class are synchronous and errors are handled by throwing synchronous SYCL exceptions. All constructors of the SYCL <> class will construct an instance -associated with a particular <>, determined by the constructor -parameters or, in the case of the default constructor, the SYCL [code]#device# -produced by the [code]#default_selector_v#. +associated with a particular platform, determined by the constructor parameters +or, in the case of the default constructor, the SYCL [code]#device# produced by +the [code]#default_selector_v#. A SYCL [code]#context# can optionally be constructed with an [code]#async_handler# parameter. @@ -1257,8 +1245,10 @@ a@ ---- backend get_backend() const noexcept ---- - a@ Returns a [code]#backend# identifying the <> associated - with this [code]#context#. + a@ Returns the backend (if any) that underlies this object. + When the backend is not [code]#backend::none#, backend interoperation is + available for this object as defined by the corresponding SYCL backend + specification. a@ [source] @@ -1448,8 +1438,8 @@ A SYCL [code]#device# can be partitioned into multiple SYCL devices, by calling the [code]#create_sub_devices()# member function template. The resulting SYCL [code]#devices# are considered sub devices, and it is valid to partition these sub devices further. -The range of support for this feature is <> and device specific and can -be queried for through [code]#get_info()#. +The range of support for this feature can be queried for through +[code]#device::get_info()#. The SYCL [code]#device# class provides the common reference semantics (see <>). @@ -1507,8 +1497,10 @@ a@ ---- backend get_backend() const noexcept ---- - a@ Returns a [code]#backend# identifying the <> associated - with this [code]#device#. + a@ Returns the backend (if any) that underlies this object. + When the backend is not [code]#backend::none#, backend interoperation is + available for this object as defined by the corresponding SYCL backend + specification. a@ [source] @@ -1692,7 +1684,7 @@ static std::vector get_devices(info::device_type deviceType = info::device_type::all) ---- a@ Returns a [code]#std::vector# containing all the - <> from all <> + <> from all platforms available in the system which have the device type encapsulated by [code]#deviceType#. @@ -3109,8 +3101,10 @@ a@ ---- backend get_backend() const noexcept ---- -a@ Returns a [code]#backend# identifying the <> associated -with this [code]#queue#. +a@ Returns the backend (if any) that underlies this object. +When the backend is not [code]#backend::none#, backend interoperation is +available for this object as defined by the corresponding SYCL backend +specification. a@ [source] @@ -3794,9 +3788,8 @@ event() Waiting on this [code]#event# will return immediately and querying its status will return [code]#info::event_command_status::complete#. -The event is constructed as though it was created from a default-constructed -[code]#queue#. Therefore, its backend is the same as the backend from the -default device. +The backend (if any) that is associated with this event is implementation +defined. |==== @@ -3812,8 +3805,10 @@ a@ ---- backend get_backend() const noexcept ---- - a@ Returns a [code]#backend# identifying the <> associated - with this [code]#event#. + a@ Returns the backend (if any) that underlies this object. + When the backend is not [code]#backend::none#, backend interoperation is + available for this object as defined by the corresponding SYCL backend + specification. a@ [source] @@ -9088,7 +9083,7 @@ parameters are the same. In SYCL, there are five different address spaces: global, local, constant, private and generic. -In a SYCL generic implementation, types are not affected by the address spaces. +The type of a pointer is not typically affected by its address space. However, there are situations where users need to explicitly carry address spaces in the type. For example: @@ -14705,8 +14700,10 @@ include::{header_dir}/hostTask/classInteropHandle/constructors.h[lines=4..-1] include::{header_dir}/hostTask/classInteropHandle/getbackend.h[lines=4..-1] ---- - . _Returns:_ Returns a [code]#backend# identifying the <> associated - with the <> associated with this [code]#interop_handle#. + . _Returns:_ The backend (if any) that underlies the queue that is associated + with this [code]#interop_handle#. + When the backend is not [code]#backend::none#, backend interoperation is + available as defined by the corresponding SYCL backend specification. [[subsec:interfaces.hosttask.interophandle.getnative]] ==== Template member functions [code]#get_native_*# @@ -15692,7 +15689,10 @@ _Returns:_ [code]#true# only if the kernel bundle contains no device images. backend get_backend() const noexcept; ---- -_Returns:_ The backend that is associated with the kernel bundle. +_Returns:_ The backend (if any) that underlies this object. +When the backend is not [code]#backend::none#, backend interoperation is +available for this object as defined by the corresponding SYCL backend +specification. [source] ---- @@ -15935,7 +15935,10 @@ The following member functions provide various queries for a <>. backend get_backend() const noexcept; ---- -_Returns:_ The backend associated with this kernel. +_Returns:_ The backend (if any) that underlies this object. +When the backend is not [code]#backend::none#, backend interoperation is +available for this object as defined by the corresponding SYCL backend +specification. [source] ---- diff --git a/adoc/headers/backends.h b/adoc/headers/backends.h index 953eb8d8..c4f0577e 100644 --- a/adoc/headers/backends.h +++ b/adoc/headers/backends.h @@ -3,6 +3,7 @@ namespace sycl { enum class backend : /* unspecified */ { + none, /* see below */ }; } // namespace sycl