diff --git a/llvm/include/llvm/SYCLLowerIR/DeviceConfigFile.td b/llvm/include/llvm/SYCLLowerIR/DeviceConfigFile.td index b4f7c71af7d9f..839db6cfc3717 100644 --- a/llvm/include/llvm/SYCLLowerIR/DeviceConfigFile.td +++ b/llvm/include/llvm/SYCLLowerIR/DeviceConfigFile.td @@ -97,6 +97,7 @@ def Aspectext_oneapi_exportable_device_mem : Aspect<"ext_oneapi_exportable_devic def Aspectext_oneapi_clock_sub_group : Aspect<"ext_oneapi_clock_sub_group">; def Aspectext_oneapi_clock_work_group : Aspect<"ext_oneapi_clock_work_group">; def Aspectext_oneapi_clock_device : Aspect<"ext_oneapi_clock_device">; +def Aspectext_oneapi_is_integrated_gpu : Aspect<"ext_oneapi_is_integrated_gpu">; // Deprecated aspects def AspectInt64_base_atomics : Aspect<"int64_base_atomics">; @@ -174,7 +175,8 @@ def : TargetInfo<"__TestAspectList", Aspectext_oneapi_exportable_device_mem, Aspectext_oneapi_clock_sub_group, Aspectext_oneapi_clock_work_group, - Aspectext_oneapi_clock_device], + Aspectext_oneapi_clock_device, + Aspectext_oneapi_is_integrated_gpu], []>; // This definition serves the only purpose of testing whether the deprecated aspect list defined in here and in SYCL RT // match. diff --git a/sycl/doc/extensions/proposed/sycl_ext_oneapi_device_is_integrated_gpu.asciidoc b/sycl/doc/extensions/experimental/sycl_ext_oneapi_device_is_integrated_gpu.asciidoc similarity index 86% rename from sycl/doc/extensions/proposed/sycl_ext_oneapi_device_is_integrated_gpu.asciidoc rename to sycl/doc/extensions/experimental/sycl_ext_oneapi_device_is_integrated_gpu.asciidoc index e48ef4ba40ca1..92325fb9c56d6 100644 --- a/sycl/doc/extensions/proposed/sycl_ext_oneapi_device_is_integrated_gpu.asciidoc +++ b/sycl/doc/extensions/experimental/sycl_ext_oneapi_device_is_integrated_gpu.asciidoc @@ -44,11 +44,12 @@ the SYCL specification refer to that revision. == Status -This is a proposed extension specification, intended to gather community -feedback. Interfaces defined in this specification may not be implemented yet -or may be in a preliminary state. The specification itself may also change in -incompatible ways before it is finalized. *Shipping software products should -not rely on APIs defined in this specification.* +This is an experimental extension specification, intended to provide early +access to features and gather community feedback. Interfaces defined in this +specification are implemented in {dpcpp}, but they are not finalized and may +change incompatibly in future versions of {dpcpp} without prior notice. +*Shipping software products should not rely on APIs defined in this +specification.* == Overview diff --git a/sycl/include/sycl/info/aspects.def b/sycl/include/sycl/info/aspects.def index d3e97a47a0248..4c5cb0a3ec8b2 100644 --- a/sycl/include/sycl/info/aspects.def +++ b/sycl/include/sycl/info/aspects.def @@ -83,3 +83,4 @@ __SYCL_ASPECT(ext_oneapi_exportable_device_mem, 90) __SYCL_ASPECT(ext_oneapi_clock_sub_group, 91) __SYCL_ASPECT(ext_oneapi_clock_work_group, 92) __SYCL_ASPECT(ext_oneapi_clock_device, 93) +__SYCL_ASPECT(ext_oneapi_is_integrated_gpu, 94) diff --git a/sycl/source/detail/device_impl.hpp b/sycl/source/detail/device_impl.hpp index 7958f384c09f3..13c5f5c16ce3c 100644 --- a/sycl/source/detail/device_impl.hpp +++ b/sycl/source/detail/device_impl.hpp @@ -1592,6 +1592,11 @@ class device_impl : public std::enable_shared_from_this { return get_info_impl_nocheck() .value_or(0); } + CASE(ext_oneapi_is_integrated_gpu) { + return is_gpu() && + get_info_impl_nocheck().value_or( + 0); + } else { return false; // This device aspect has not been implemented yet. } diff --git a/sycl/source/detail/ur_device_info_ret_types.inc b/sycl/source/detail/ur_device_info_ret_types.inc index 11336b2ff4e8c..9c7a12379efdc 100644 --- a/sycl/source/detail/ur_device_info_ret_types.inc +++ b/sycl/source/detail/ur_device_info_ret_types.inc @@ -196,4 +196,5 @@ MAP(UR_DEVICE_INFO_MEMORY_EXPORT_EXPORTABLE_DEVICE_MEM_EXP, ur_bool_t) MAP(UR_DEVICE_INFO_CLOCK_SUB_GROUP_SUPPORT_EXP, ur_bool_t) MAP(UR_DEVICE_INFO_CLOCK_WORK_GROUP_SUPPORT_EXP, ur_bool_t) MAP(UR_DEVICE_INFO_CLOCK_DEVICE_SUPPORT_EXP, ur_bool_t) +MAP(UR_DEVICE_INFO_IS_INTEGRATED_GPU, ur_bool_t) // clang-format on diff --git a/sycl/source/feature_test.hpp.in b/sycl/source/feature_test.hpp.in index a641ae79b65e6..f89754b9cb465 100644 --- a/sycl/source/feature_test.hpp.in +++ b/sycl/source/feature_test.hpp.in @@ -121,6 +121,7 @@ inline namespace _V1 { #define SYCL_KHR_QUEUE_EMPTY_QUERY 1 #define SYCL_EXT_ONEAPI_MEMORY_EXPORT 1 #define SYCL_EXT_ONEAPI_CLOCK 1 +#define SYCL_EXT_ONEAPI_DEVICE_IS_INTEGRATED_GPU 1 // In progress yet #define SYCL_EXT_ONEAPI_ATOMIC16 0 #define SYCL_KHR_DEFAULT_CONTEXT 1 diff --git a/sycl/test-e2e/DeviceIsIntegratedGPU/device_is_cpu.cpp b/sycl/test-e2e/DeviceIsIntegratedGPU/device_is_cpu.cpp new file mode 100644 index 0000000000000..9882a1cf04396 --- /dev/null +++ b/sycl/test-e2e/DeviceIsIntegratedGPU/device_is_cpu.cpp @@ -0,0 +1,28 @@ +//==--- device_is_cpu.cpp - sycl_ext_oneapi_device_is_integrated_gpu test --==// +// +// 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 +// +//===----------------------------------------------------------------------===// +// REQUIRES: cpu +// RUN: %{build} -o %t.out +// RUN: %{run} %t.out + +// Test checks that aspect::ext_oneapi_is_integrated_gpu is false if device is +// not GPU (e.g., CPU). + +#include + +using namespace sycl; + +int main() { + queue Queue; + auto dev = Queue.get_device(); + + if (!dev.has(aspect::ext_oneapi_is_integrated_gpu)) + return 0; + + assert(false && "aspect::ext_oneapi_is_integrated_gpu must be false"); + return 1; +} diff --git a/sycl/test-e2e/DeviceIsIntegratedGPU/device_is_integrated_gpu.cpp b/sycl/test-e2e/DeviceIsIntegratedGPU/device_is_integrated_gpu.cpp new file mode 100644 index 0000000000000..55f097720d0de --- /dev/null +++ b/sycl/test-e2e/DeviceIsIntegratedGPU/device_is_integrated_gpu.cpp @@ -0,0 +1,29 @@ +//==- device_is_integrated_gpu.cpp - sycl_ext_oneapi_device_is_integrated_gpu +// test -==// +// +// 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 +// +//===----------------------------------------------------------------------===// +// REQUIRES: gpu-intel-gen12 +// RUN: %{build} -o %t.out +// RUN: %{run} %t.out + +// Test checks that aspect::ext_oneapi_is_integrated_gpu is true if GPU device +// is integrated. + +#include + +using namespace sycl; + +int main() { + queue Queue; + auto dev = Queue.get_device(); + + if (dev.has(aspect::ext_oneapi_is_integrated_gpu)) + return 0; + + assert(false && "aspect::ext_oneapi_is_integrated_gpu must be true"); + return 1; +} diff --git a/sycl/test-e2e/DeviceIsIntegratedGPU/device_is_not_integrated_gpu.cpp b/sycl/test-e2e/DeviceIsIntegratedGPU/device_is_not_integrated_gpu.cpp new file mode 100644 index 0000000000000..517cdd856099a --- /dev/null +++ b/sycl/test-e2e/DeviceIsIntegratedGPU/device_is_not_integrated_gpu.cpp @@ -0,0 +1,29 @@ +//==- device_is_not_integrated_gpu.cpp - +// sycl_ext_oneapi_device_is_integrated_gpu test -==// +// +// 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 +// +//===----------------------------------------------------------------------===// +// REQUIRES: arch-intel_gpu_pvc || arch-intel_gpu_bmg_g21 +// RUN: %{build} -o %t.out +// RUN: %{run} %t.out + +// Test checks that aspect::ext_oneapi_is_integrated_gpu is false if GPU device +// is discrete. + +#include + +using namespace sycl; + +int main() { + queue Queue; + auto dev = Queue.get_device(); + + if (!dev.has(aspect::ext_oneapi_is_integrated_gpu)) + return 0; + + assert(false && "aspect::ext_oneapi_is_integrated_gpu must be false"); + return 1; +} diff --git a/sycl/unittests/Extensions/CMakeLists.txt b/sycl/unittests/Extensions/CMakeLists.txt index 311b411985a40..db0bc0120e8db 100644 --- a/sycl/unittests/Extensions/CMakeLists.txt +++ b/sycl/unittests/Extensions/CMakeLists.txt @@ -3,6 +3,7 @@ set(CMAKE_CXX_EXTENSIONS OFF) add_sycl_unittest(ExtensionsTests OBJECT CurrentDevice.cpp DefaultContext.cpp + DeviceIsIntegratedGPU.cpp FPGADeviceSelectors.cpp DeviceArchitecture.cpp USMMemcpy2D.cpp diff --git a/sycl/unittests/Extensions/DeviceIsIntegratedGPU.cpp b/sycl/unittests/Extensions/DeviceIsIntegratedGPU.cpp new file mode 100644 index 0000000000000..4dfc077b87ef4 --- /dev/null +++ b/sycl/unittests/Extensions/DeviceIsIntegratedGPU.cpp @@ -0,0 +1,73 @@ +//==--- DeviceIsIntegratedGPU.cpp - oneapi_device_is_integrated_gpu test ---==// +// +// 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/platform.hpp" +#include +#include + +#include + +#include + +namespace { +template +static ur_result_t redefinedDeviceGetInfoAfter(void *pParams) { + auto params = *static_cast(pParams); + if (*params.ppropName == UR_DEVICE_INFO_IS_INTEGRATED_GPU) { + auto *Result = reinterpret_cast(*params.ppPropValue); + *Result = IsIntegratedGPU; + } + + if (*params.ppropName == UR_DEVICE_INFO_TYPE) { + auto *Result = reinterpret_cast(*params.ppPropValue); + *Result = URDeviceType; + } + + return UR_RESULT_SUCCESS; +} +} // namespace + +TEST(DeviceIsIntegratedGPU, DeviceIsNotIntegratedGPUOnGPUDevice) { + sycl::unittest::UrMock<> Mock; + mock::getCallbacks().set_after_callback( + "urDeviceGetInfo", &redefinedDeviceGetInfoAfter); + sycl::device Device = sycl::platform().get_devices()[0]; + ASSERT_FALSE(Device.has(sycl::aspect::ext_oneapi_is_integrated_gpu)); +} + +TEST(DeviceIsIntegratedGPU, DeviceIsIntegratedGPUOnGPUDevice) { + sycl::unittest::UrMock<> Mock; + mock::getCallbacks().set_after_callback( + "urDeviceGetInfo", &redefinedDeviceGetInfoAfter); + sycl::device Device = sycl::platform().get_devices()[0]; + ASSERT_TRUE(Device.has(sycl::aspect::ext_oneapi_is_integrated_gpu)); +} + +TEST(DeviceIsIntegratedGPU, DeviceIsNotIntegratedGPUOnCPUDevice) { + sycl::unittest::UrMock<> Mock; + mock::getCallbacks().set_after_callback( + "urDeviceGetInfo", &redefinedDeviceGetInfoAfter); + sycl::device Device = sycl::platform().get_devices()[0]; + ASSERT_FALSE(Device.has(sycl::aspect::ext_oneapi_is_integrated_gpu)); +} + +TEST(DeviceIsIntegratedGPU, DeviceIsIntegratedGPUOnCPUDevice) { + sycl::unittest::UrMock<> Mock; + // Not much sense here but if for some reason UR_DEVICE_INFO_IS_INTEGRATED_GPU + // is true on CPU device, we check that + // sycl::aspect::ext_oneapi_is_integrated_gpu must be false as stated in the + // extension spec. + mock::getCallbacks().set_after_callback( + "urDeviceGetInfo", &redefinedDeviceGetInfoAfter); + sycl::device Device = sycl::platform().get_devices()[0]; + ASSERT_FALSE(Device.has(sycl::aspect::ext_oneapi_is_integrated_gpu)); +} diff --git a/sycl/unittests/helpers/UrMock.hpp b/sycl/unittests/helpers/UrMock.hpp index 642ed8b401782..b3b2a0d78b846 100644 --- a/sycl/unittests/helpers/UrMock.hpp +++ b/sycl/unittests/helpers/UrMock.hpp @@ -212,6 +212,7 @@ inline ur_result_t mock_urDeviceGetInfo(void *pParams) { case UR_DEVICE_INFO_AVAILABLE: case UR_DEVICE_INFO_LINKER_AVAILABLE: case UR_DEVICE_INFO_COMPILER_AVAILABLE: + case UR_DEVICE_INFO_IS_INTEGRATED_GPU: case UR_DEVICE_INFO_COMMAND_BUFFER_SUPPORT_EXP: { if (*params->ppPropValue) *static_cast(*params->ppPropValue) = true; diff --git a/unified-runtime/include/ur_api.h b/unified-runtime/include/ur_api.h index 736060f3ab721..5c87df648297c 100644 --- a/unified-runtime/include/ur_api.h +++ b/unified-runtime/include/ur_api.h @@ -2438,6 +2438,8 @@ typedef enum ur_device_info_t { /// [::ur_bool_t] returns true if the device supports sampling values from /// the device clock. UR_DEVICE_INFO_CLOCK_DEVICE_SUPPORT_EXP = 0x2062, + /// [::ur_bool_t] returns true if the device is integrated GPU. + UR_DEVICE_INFO_IS_INTEGRATED_GPU = 0x2070, /// [::ur_bool_t] Returns true if the device supports the USM P2P /// experimental feature. UR_DEVICE_INFO_USM_P2P_SUPPORT_EXP = 0x4000, diff --git a/unified-runtime/include/ur_print.hpp b/unified-runtime/include/ur_print.hpp index 9d7bef35061fd..b3de6c166ca31 100644 --- a/unified-runtime/include/ur_print.hpp +++ b/unified-runtime/include/ur_print.hpp @@ -3130,6 +3130,9 @@ inline std::ostream &operator<<(std::ostream &os, enum ur_device_info_t value) { case UR_DEVICE_INFO_CLOCK_DEVICE_SUPPORT_EXP: os << "UR_DEVICE_INFO_CLOCK_DEVICE_SUPPORT_EXP"; break; + case UR_DEVICE_INFO_IS_INTEGRATED_GPU: + os << "UR_DEVICE_INFO_IS_INTEGRATED_GPU"; + break; case UR_DEVICE_INFO_USM_P2P_SUPPORT_EXP: os << "UR_DEVICE_INFO_USM_P2P_SUPPORT_EXP"; break; @@ -5307,6 +5310,19 @@ inline ur_result_t printTagged(std::ostream &os, const void *ptr, os << ")"; } break; + case UR_DEVICE_INFO_IS_INTEGRATED_GPU: { + const ur_bool_t *tptr = (const ur_bool_t *)ptr; + if (sizeof(ur_bool_t) > size) { + os << "invalid size (is: " << size + << ", expected: >=" << sizeof(ur_bool_t) << ")"; + return UR_RESULT_ERROR_INVALID_SIZE; + } + os << (const void *)(tptr) << " ("; + + os << *tptr; + + os << ")"; + } break; case UR_DEVICE_INFO_USM_P2P_SUPPORT_EXP: { const ur_bool_t *tptr = (const ur_bool_t *)ptr; if (sizeof(ur_bool_t) > size) { diff --git a/unified-runtime/scripts/core/EXP-DEVICE-IS-INTEGRATED-GPU.rst b/unified-runtime/scripts/core/EXP-DEVICE-IS-INTEGRATED-GPU.rst new file mode 100644 index 0000000000000..b346a6b17e165 --- /dev/null +++ b/unified-runtime/scripts/core/EXP-DEVICE-IS-INTEGRATED-GPU.rst @@ -0,0 +1,58 @@ +<% + OneApi=tags['$OneApi'] + x=tags['$x'] + X=x.upper() +%> + +.. _experimental-device-is-integrated-gpu: + +================================================================================ +Device is integrated GPU +================================================================================ + +.. warning:: + + Experimental features: + + * May be replaced, updated, or removed at any time. + * Do not require maintaining API/ABI stability of their own additions over + time. + * Do not require conformance testing of their own additions. + + +Motivation +-------------------------------------------------------------------------------- +This experimental extension enables the sycl_ext_oneapi_device_is_integrated_gpu +feature: +http://github.com/intel/llvm/blob/sycl/sycl/doc/extensions/experimental/sycl_ext_oneapi_device_is_integrated_gpu.asciidoc. +It introduces descriptor to query if device is integrated GPU. + +API +-------------------------------------------------------------------------------- + +Enums +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +* ${x}_device_info_t + * ${X}_DEVICE_INFO_IS_INTEGRATED_GPU + +Changelog +-------------------------------------------------------------------------------- + ++-----------+------------------------+ +| Revision | Changes | ++===========+========================+ +| 1.0 | Initial Draft | ++-----------+------------------------+ + + +Support +-------------------------------------------------------------------------------- + +Adapters which support this experimental feature *must* return ${X}_RESULT_SUCCESS +from the ${x}DeviceGetInfo call with this new ${X}_DEVICE_INFO_IS_INTEGRATED_GPU +device descriptor. + +Contributors +-------------------------------------------------------------------------------- + +* Vodopyanov, Dmitry `dmitry.vodopyanov@intel.com `_ diff --git a/unified-runtime/scripts/core/exp-device-is-integrated-gpu.yml b/unified-runtime/scripts/core/exp-device-is-integrated-gpu.yml new file mode 100644 index 0000000000000..b0b07ac4269d6 --- /dev/null +++ b/unified-runtime/scripts/core/exp-device-is-integrated-gpu.yml @@ -0,0 +1,25 @@ +# +# Copyright (C) 2025 Intel Corporation +# +# Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM +# Exceptions. +# See LICENSE.TXT +# +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +# See YaML.md for syntax definition +# +--- #-------------------------------------------------------------------------- +type: header +desc: "Intel $OneApi Unified Runtime Experimental APIs for quering if device is integrated GPU" +ordinal: "99" +--- #-------------------------------------------------------------------------- +type: enum +extend: true +typed_etors: true +desc: "Extension enums for $x_device_info_t to support quering if device is integrated GPU." +name: $x_device_info_t +etors: + - name: IS_INTEGRATED_GPU + value: "0x2070" + desc: "[$x_bool_t] returns true if the device is integrated GPU." diff --git a/unified-runtime/source/adapters/level_zero/device.cpp b/unified-runtime/source/adapters/level_zero/device.cpp index 40ab701312292..5b117e62a42b0 100644 --- a/unified-runtime/source/adapters/level_zero/device.cpp +++ b/unified-runtime/source/adapters/level_zero/device.cpp @@ -1461,6 +1461,8 @@ ur_result_t urDeviceGetInfo( case UR_DEVICE_INFO_CLOCK_DEVICE_SUPPORT_EXP: // Currently GPUs only support sub-group clock. return ReturnValue(false); + case UR_DEVICE_INFO_IS_INTEGRATED_GPU: + return ReturnValue(static_cast(Device->isIntegrated() != 0)); default: UR_LOG(ERR, "Unsupported ParamName in urGetDeviceInfo"); UR_LOG(ERR, "ParamNameParamName={}(0x{})", ParamName, diff --git a/unified-runtime/source/adapters/opencl/device.cpp b/unified-runtime/source/adapters/opencl/device.cpp index eac2c9fe0bf2c..736b9c0b9fa1b 100644 --- a/unified-runtime/source/adapters/opencl/device.cpp +++ b/unified-runtime/source/adapters/opencl/device.cpp @@ -1510,6 +1510,18 @@ UR_APIEXPORT ur_result_t UR_APICALL urDeviceGetInfo(ur_device_handle_t hDevice, } return ReturnValue(Supported); } + case UR_DEVICE_INFO_IS_INTEGRATED_GPU: { + cl_bool CLValue; + + // TODO: use stable API instead of deprecated CL_DEVICE_HOST_UNIFIED_MEMORY. + // Currently CL_DEVICE_HOST_UNIFIED_MEMORY is deprecated by OpenCL 2.0, but + // still was not removed even from Intel implementations of OpenCL 3.0. + CL_RETURN_ON_FAILURE(clGetDeviceInfo(hDevice->CLDevice, + CL_DEVICE_HOST_UNIFIED_MEMORY, + sizeof(cl_bool), &CLValue, nullptr)); + + return ReturnValue(static_cast(CLValue)); + } // TODO: We can't query to check if these are supported, they will need to be // manually updated if support is ever implemented. case UR_DEVICE_INFO_KERNEL_SET_SPECIALIZATION_CONSTANTS: diff --git a/unified-runtime/tools/urinfo/urinfo.hpp b/unified-runtime/tools/urinfo/urinfo.hpp index 3407c57f847d7..41999350f9edf 100644 --- a/unified-runtime/tools/urinfo/urinfo.hpp +++ b/unified-runtime/tools/urinfo/urinfo.hpp @@ -456,6 +456,8 @@ inline void printDeviceInfos(ur_device_handle_t hDevice, std::cout << prefix; printDeviceInfo(hDevice, UR_DEVICE_INFO_CLOCK_DEVICE_SUPPORT_EXP); std::cout << prefix; + printDeviceInfo(hDevice, UR_DEVICE_INFO_IS_INTEGRATED_GPU); + std::cout << prefix; printDeviceInfo(hDevice, UR_DEVICE_INFO_USM_P2P_SUPPORT_EXP); std::cout << prefix; printDeviceInfo(hDevice,