Skip to content
Closed
Show file tree
Hide file tree
Changes from 4 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
17 changes: 15 additions & 2 deletions include/ur.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,18 @@ def __str__(self):
return hex(self.value)


###############################################################################
## @brief Extension name maximum length.
UR_MAX_EXTENSION_NAME_LENGTH = 256

###############################################################################
## @brief Extension type.
class ur_platform_extension_t(Structure):
_fields_ = [
("name", c_char_p), ## [in] null-terminated extension name.
("version", c_ulong) ## [in] version of the extension using ::UR_MAKE_VERSION.
]

###############################################################################
## @brief Supported platform info
class ur_platform_info_v(IntEnum):
Expand All @@ -282,8 +294,9 @@ class ur_platform_info_v(IntEnum):
## size of the info needs to be dynamically queried.
VERSION = 3 ## [char[]] The string denoting the version of the platform. The size of
## the info needs to be dynamically queried.
EXTENSIONS = 4 ## [char[]] The string denoting extensions supported by the platform. The
## size of the info needs to be dynamically queried.
EXTENSIONS = 4 ## [::ur_platform_extension_t[]] an array of ::ur_platform_extension_t
## which express which extensions supported by the platform.
## The size of the info needs to be dynamically queried.
PROFILE = 5 ## [char[]] The string denoting profile of the platform. The size of the
## info needs to be dynamically queried.
BACKEND = 6 ## [::ur_platform_backend_t] The backend of the platform. Identifies the
Expand Down
19 changes: 17 additions & 2 deletions include/ur_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,20 @@ urTearDown(
#if !defined(__GNUC__)
#pragma region platform
#endif
///////////////////////////////////////////////////////////////////////////////
#ifndef UR_MAX_EXTENSION_NAME_LENGTH
/// @brief Extension name maximum length.
#define UR_MAX_EXTENSION_NAME_LENGTH 256
#endif // UR_MAX_EXTENSION_NAME_LENGTH

///////////////////////////////////////////////////////////////////////////////
/// @brief Extension type.
typedef struct ur_platform_extension_t {
char *name; ///< [in] null-terminated extension name.
uint32_t version; ///< [in] version of the extension using ::UR_MAKE_VERSION.

} ur_platform_extension_t;

///////////////////////////////////////////////////////////////////////////////
/// @brief Retrieves all available platforms
///
Expand Down Expand Up @@ -398,8 +412,9 @@ typedef enum ur_platform_info_t {
///< size of the info needs to be dynamically queried.
UR_PLATFORM_INFO_VERSION = 3, ///< [char[]] The string denoting the version of the platform. The size of
///< the info needs to be dynamically queried.
UR_PLATFORM_INFO_EXTENSIONS = 4, ///< [char[]] The string denoting extensions supported by the platform. The
///< size of the info needs to be dynamically queried.
UR_PLATFORM_INFO_EXTENSIONS = 4, ///< [::ur_platform_extension_t[]] an array of ::ur_platform_extension_t
///< which express which extensions supported by the platform.
///< The size of the info needs to be dynamically queried.
UR_PLATFORM_INFO_PROFILE = 5, ///< [char[]] The string denoting profile of the platform. The size of the
///< info needs to be dynamically queried.
UR_PLATFORM_INFO_BACKEND = 6, ///< [::ur_platform_backend_t] The backend of the platform. Identifies the
Expand Down
108 changes: 108 additions & 0 deletions scripts/core/EXT.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<%
OneApi=tags['$OneApi']
x=tags['$x']
X=x.upper()
%>
==============
Extensions
==============

Objective
=========

Extensions allow for additional functionality to be added to the Unified Runtime specification
without affecting the core specification. Extensions may in future be promoted to the core specification
in a later version of Unified Runtime, when agreed upon by the Working Group. All extensions are
optional and are not required to be implemented by any particular adapter, but are expected to
be widely available and possibly be required in a future version of the specification. Adapters
must report which extensions are supported through the ${X}_PLATFORM_INFO_EXTENSIONS platform info query.
Each extension may also impose additional restrictions on when it can be used - i.e. a platform
or device query.

There are two types of extensions defined by this specification:

1. **Standard** - extension will be included into the current and all future version of the specification.
2. **Experimental** - extensions require additional experimentation and development, before becoming a standard extension.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will there be implementation or coverage requirements for when an extension should move from experimental to standard?

Applications should not rely on experimental extensions in production.

Requirements
============

- Extensions must use globally unique names for macros, enums, structures and functions
- Extensions must have globally unique extension names reported from ${X}_PLATFORM_INFO_EXTENSIONS platform info query
- All extensions must be defined in this specification
- Extensions must not break backwards compatibility of the core APIs

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this also include semantic breaks as well as interface breaks in the core APIs, i.e. does this forbid an extension from altering the behavior of an existing API?

Copy link
Contributor Author

@veselypeta veselypeta May 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think an extension can alter the behavour of an existing API. For example you might want to chain an additional structure to the input or use extension specific enums, but default usage should remain the same.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I'm not sure I'm so confortable with extensions that change semantics because we have no way to opt-out with this architecture. If we were able to enable extensions, like Vulkan, maybe I'd be more conformtable with that.

- Standard extension versions must be backwards compatible with prior versions
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I copied this from L0 extension scheme, but perhaps we could use semantic versioning with extensions with major/minor versions?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean that experimental extensions are permitted to break backwards compatibility?

Copy link
Contributor Author

@veselypeta veselypeta May 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I think that makes sense. Experimental extensions should have no ABI or backwards compatibility requirements.



Naming Convention
-----------------

The following naming conventions must be followed for **standard** extensions:
## --validate=off
- The extension name must begin with `${x}_ext`
- All extension functions must be postfixed with `Ext`
- All macros must use all caps `${X}_<NAME>_EXT` convention
- All structures, enumerations and other types must follow `${x}_<name>_ext_t` snake case convention
- All enumerator values must use all caps `${X}_ENUM_EXT_ETOR_NAME` convention
- All handle types must end with `ext_handle_t`
- All descriptor structures must end with `ext_desc_t`
- All property structures must end with `ext_properties_t`
- All flag enumerations must end with `ext_flags_t`
## --validate=on

The following naming conventions must be followed for **experimental** extensions:

## --validate=off
- The extension name must begin with `${x}_exp`
- Experimental extensions may be added and removed from the driver at any time.
- Experimental extensions are not guaranteed to be forward- or backward-compatible between versions.
- Experimental extensions are not guaranteed to be supported in production driver releases; and may appear and disappear from release to release.
- All extension functions must be postfixed with `Exp`
- All macros must use all caps `${X}_<NAME>_EXP` convention
- All structures, enumerations and other types must follow `${x}_<name>_exp_t` snake case convention
- All enumerator values must use all caps `${X}_ENUM_EXP_ETOR_NAME` convention
- All handle types must end with `exp_handle_t`
- All descriptor structures must end with `exp_desc_t`
- All property structures must end with `exp_properties_t`
- All flag enumerations must end with `exp_flags_t`
## --validate=on

Extending Enumerations
----------------------

Any existing enumeration may be extended by adding new enumerators. Enumerators must use the extensions naming
convention and values should be assigned to avoid future compatibility issues.


Extending Structures
--------------------

Any structure derived from `${x}_base_desc_t`` or `${x}_base_properties_t`` can be extended using a structure chain
by adding a pointer to the extended structure in `pNext` member variable. No other method of extending structures is allowed.

A structure chain can contain more than one extension structure, in any order. Therefore, extensions should not
be dependent on their order relative to other extensions and the implementation must be order agnostic. In addition,
the implementation will ignore extended structures that it does not support.

The extension must document the specific structures and functions that may be extended using the structure chain.

Adding an extension
===================

* Extend the specification with the functions, enumerations, macros, and structures required by the extension, ensuring that
all additions fully comply with the naming and ABI requirements detailed above.

* Document the extension in `EXT_<ext-name>.rst` file based on the `EXT_Template.rst`, ensuring it is added to the list of
extensions below.

* The extension will only be accepted if all conditions are met and its addition is agreed upon by the Working Group.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this refer to an extension becoming a standard extension?



List of Standard Extensions

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a thought, maybe these lists should also track the implementation status of the extensions, so whether they are implemented, and then which version of UR supports which version of the extension, particularly for the experimental extensions which may change, so high-level languages know what they can use when updating the UR interface.

===========================
// TODO - list all standard extensions

List of Experimental Extensions
===============================
// TODO - list all experimental extensions
42 changes: 42 additions & 0 deletions scripts/core/EXT_Template.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<%
import re
from templates import helper as th
%><%
OneApi=tags['$OneApi']
x=tags['$x']
X=x.upper()
%>
:orphan:

==================================
Unified Runtime Extension Template
==================================

API
---

* Enumerations


* List all enumerations defined by the extension.


* Structures


* List all structures defined by the extension.
* ...


* Functions


* List all functions defined by the extension.
* ...


Unified Runtime Extension Template
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In this section describe in detail the purpose of the extension, along with its
valid usage.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quite like it when extensions have a version history at the bottom, could we add that to the template?

Copy link
Contributor

@kbenzie kbenzie May 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is useful info, I do wonder if having the ability to view different extension versions side-by-side would also be useful though (other than looking at the git history)?

Copy link
Contributor Author

@veselypeta veselypeta May 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be really good. @kbenzie I've seen versioned docs before on the Zephyr project link - there is a dropdown in the bottom left where you can select the version of the API you want to view. I'm not really sure how this is implemented, but perhaps we can have something like that as well as a changelog (like ewan suggested).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the Zephyr page I think that's for the entire page rather than just the extension specs, my gut feeling is you'd need to have a separate Sphinx build for each extension to get something exapctly like that.

22 changes: 21 additions & 1 deletion scripts/core/platform.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,24 @@ type: header
desc: "Intel $OneApi Unified Runtime APIs for Platform"
ordinal: "1"
--- #--------------------------------------------------------------------------
type: macro
desc: "Extension name maximum length."
name: $X_MAX_EXTENSION_NAME_LENGTH
value: "256"
--- #--------------------------------------------------------------------------
type: struct
desc: "Extension type."
name: $x_platform_extension_t
class: $xPlatform
members:
# TODO - this should be char[], but haven't got it to work with generator yet
- type: char*
name: name
desc: "[in] null-terminated extension name."
- type: uint32_t
name: version
desc: "[in] version of the extension using $X_MAKE_VERSION."
--- #--------------------------------------------------------------------------
type: function
desc: "Retrieves all available platforms"
class: $xPlatform
Expand Down Expand Up @@ -57,7 +75,9 @@ etors:
desc: "[char[]] The string denoting the version of the platform. The size of the info needs to be dynamically queried."
- name: EXTENSIONS
value: "4"
desc: "[char[]] The string denoting extensions supported by the platform. The size of the info needs to be dynamically queried."
desc: |
[$x_platform_extension_t[]] an array of $x_platform_extension_t which express which extensions supported by the platform.
The size of the info needs to be dynamically queried.
todo: "document extensions names and their meaning"
- name: PROFILE
value: "5"
Expand Down
1 change: 1 addition & 0 deletions scripts/templates/index.rst.mako
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@

core/INTRO.rst
core/PROG.rst
core/EXT.rst
api.rst
32 changes: 30 additions & 2 deletions source/common/ur_params.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ inline std::ostream &operator<<(std::ostream &os,
const struct ur_rect_region_t params);
inline std::ostream &operator<<(std::ostream &os,
enum ur_device_init_flag_t value);
inline std::ostream &operator<<(std::ostream &os,
const struct ur_platform_extension_t params);
inline std::ostream &operator<<(std::ostream &os,
enum ur_platform_info_t value);
inline std::ostream &operator<<(std::ostream &os, enum ur_api_version_t value);
Expand Down Expand Up @@ -935,6 +937,22 @@ inline void serializeFlag_ur_device_init_flags_t(std::ostream &os,
}
}
} // namespace ur_params
inline std::ostream &operator<<(std::ostream &os,
const struct ur_platform_extension_t params) {
os << "(struct ur_platform_extension_t){";

os << ".name = ";

ur_params::serializePtr(os, (params.name));

os << ", ";
os << ".version = ";

os << (params.version);

os << "}";
return os;
}
inline std::ostream &operator<<(std::ostream &os,
enum ur_platform_info_t value) {
switch (value) {
Expand Down Expand Up @@ -1000,8 +1018,18 @@ serializeTaggedTyped_ur_platform_info_t(std::ostream &os, const void *ptr,

case UR_PLATFORM_INFO_EXTENSIONS: {

const char *tptr = (const char *)ptr;
serializePtr(os, tptr);
const ur_platform_extension_t *tptr =
(const ur_platform_extension_t *)ptr;
os << "[";
size_t nelems = size / sizeof(ur_platform_extension_t);
for (size_t i = 0; i < nelems; ++i) {
if (i != 0) {
os << ", ";
}

os << tptr[i];
}
os << "]";
} break;

case UR_PLATFORM_INFO_PROFILE: {
Expand Down
1 change: 1 addition & 0 deletions test/conformance/platform/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ add_conformance_test(platform
urInit.cpp
urPlatformGet.cpp
urPlatformGetBackendOption.cpp
# urPlatformGetExtensionProperties.cpp
urPlatformGetInfo.cpp
urTearDown.cpp)
27 changes: 27 additions & 0 deletions test/conformance/platform/urPlatformGetExtensionProperties.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (C) 2023 Intel Corporation
// SPDX-License-Identifier: MIT

#include "fixtures.h"

using urPlatformGetExtensionPropertiesTest = uur::platform::urPlatformTest;

TEST_F(urPlatformGetExtensionPropertiesTest, Success) {
uint32_t n_extensions = 0;
ASSERT_SUCCESS(
urPlatformGetExtensionProperties(platform, 0, nullptr, &n_extensions));

if (n_extensions == 0) {
GTEST_SKIP() << "Adapter does not support any extensions.\n";
}

std::vector<ur_extension_properties_t> extensions(n_extensions);
ASSERT_SUCCESS(urPlatformGetExtensionProperties(
platform, n_extensions, extensions.data(), nullptr));
}

TEST_F(urPlatformGetExtensionPropertiesTest, InvalidNullHandlePlatform) {
uint32_t n_extensions = 0;
ASSERT_EQ_RESULT(
UR_RESULT_ERROR_INVALID_NULL_HANDLE,
urPlatformGetExtensionProperties(nullptr, 0, nullptr, &n_extensions));
}
6 changes: 6 additions & 0 deletions test/conformance/platform/urPlatformGetInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ TEST_P(urPlatformGetInfoTest, Success) {
size_t size = 0;
ur_platform_info_t info_type = GetParam();
ASSERT_SUCCESS(urPlatformGetInfo(platform, info_type, 0, nullptr, &size));

// A platform that does not support any extensions can return a size of 0.
if (info_type == UR_PLATFORM_INFO_EXTENSIONS && size == 0) {
return;
}

ASSERT_NE(size, 0);
std::vector<char> name(size);
ASSERT_SUCCESS(
Expand Down