Skip to content

[SYCL] Added support for aspects and the has() function. #2237

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 5, 2020
Merged
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
1 change: 1 addition & 0 deletions sycl/include/CL/sycl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#pragma once

#include <CL/sycl/accessor.hpp>
#include <CL/sycl/aspects.hpp>
#include <CL/sycl/atomic.hpp>
#include <CL/sycl/backend.hpp>
#include <CL/sycl/buffer.hpp>
Expand Down
37 changes: 37 additions & 0 deletions sycl/include/CL/sycl/aspects.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//==-------------- aspects.hpp - SYCL Aspect Enums ------------*- C++ -*---==//
//
// 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 <CL/sycl/detail/defines.hpp>

__SYCL_INLINE_NAMESPACE(cl) {
namespace sycl {

enum class aspect {
host,
cpu,
gpu,
accelerator,
custom,
fp16,
fp64,
int64_base_atomics,
int64_extended_atomics,
image,
online_compiler,
online_linker,
queue_profiling,
usm_device_allocations,
usm_host_allocations,
usm_shared_allocations,
usm_restricted_shared_allocations,
usm_system_allocator
};

} // namespace sycl
} // __SYCL_INLINE_NAMESPACE(cl)
9 changes: 9 additions & 0 deletions sycl/include/CL/sycl/device.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#pragma once

#include <CL/sycl/aspects.hpp>
#include <CL/sycl/backend_types.hpp>
#include <CL/sycl/detail/common.hpp>
#include <CL/sycl/detail/export.hpp>
Expand Down Expand Up @@ -179,6 +180,14 @@ class __SYCL_EXPORT device {
return (typename interop<BackendName, device>::type)getNative();
}

/// Indicates if the SYCL device has the given feature.
///
/// \param Aspect is one of the values in Table 4.20 of the SYCL 2020
/// Provisional Spec.
///
/// \return true if the SYCL device has the given feature.
bool has(aspect Aspect) const;

private:
shared_ptr_class<detail::device_impl> impl;
device(shared_ptr_class<detail::device_impl> impl) : impl(impl) {}
Expand Down
10 changes: 10 additions & 0 deletions sycl/include/CL/sycl/platform.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,16 @@ class __SYCL_EXPORT platform {
getNative());
}

/// Indicates if all of the SYCL devices on this platform have the
/// given feature.
///
/// \param Aspect is one of the values in Table 4.20 of the SYCL 2020
/// Provisional Spec.
///
/// \return true if all of the SYCL devices on this platform have the
/// given feature.
bool has(aspect Aspect) const;

private:
pi_native_handle getNative() const;

Expand Down
46 changes: 38 additions & 8 deletions sycl/source/detail/device_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@ device_impl::device_impl(pi_native_handle InteropDeviceHandle,

RT::PiDevice parent = nullptr;
// TODO catch an exception and put it to list of asynchronous exceptions
Plugin.call<PiApiKind::piDeviceGetInfo>(
MDevice, PI_DEVICE_INFO_PARENT_DEVICE, sizeof(RT::PiDevice), &parent, nullptr);
Plugin.call<PiApiKind::piDeviceGetInfo>(MDevice, PI_DEVICE_INFO_PARENT_DEVICE,
sizeof(RT::PiDevice), &parent,
nullptr);

MIsRootDevice = (nullptr == parent);
if (!MIsRootDevice && !InteroperabilityConstructor) {
Expand Down Expand Up @@ -181,13 +182,11 @@ device_impl::create_sub_devices(const vector_class<size_t> &Counts) const {
"Partitioning to subdevices of the host device is not implemented yet",
PI_INVALID_DEVICE);

if (!is_partition_supported(
info::partition_property::partition_by_counts)) {
if (!is_partition_supported(info::partition_property::partition_by_counts)) {
throw cl::sycl::feature_not_supported();
}
static const cl_device_partition_property P[] = {
CL_DEVICE_PARTITION_BY_COUNTS, CL_DEVICE_PARTITION_BY_COUNTS_LIST_END,
0};
CL_DEVICE_PARTITION_BY_COUNTS, CL_DEVICE_PARTITION_BY_COUNTS_LIST_END, 0};
vector_class<cl_device_partition_property> Properties(P, P + 3);
Properties.insert(Properties.begin() + 1, Counts.begin(), Counts.end());
return create_sub_devices(Properties.data(), Counts.size());
Expand All @@ -210,8 +209,7 @@ vector_class<device> device_impl::create_sub_devices(
const cl_device_partition_property Properties[3] = {
CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN,
(cl_device_partition_property)AffinityDomain, 0};
size_t SubDevicesCount =
get_info<info::device::partition_max_sub_devices>();
size_t SubDevicesCount = get_info<info::device::partition_max_sub_devices>();
Copy link
Contributor

Choose a reason for hiding this comment

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

It doesn't look like you've made any changes here and above in this file. Could you please preserve old formatting?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is not me, it is clang-format. I do not know why it suddenly changed these lines.

Copy link
Contributor

Choose a reason for hiding this comment

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

it is because clang-format was applied to the whole file. Please apply it only to the changes made in this PR.

return create_sub_devices(Properties, SubDevicesCount);
}

Expand All @@ -222,6 +220,38 @@ pi_native_handle device_impl::getNative() const {
return Handle;
}

bool device_impl::has(aspect Aspect) const {
switch (Aspect) {
case aspect::host:
return is_host();
case aspect::cpu:
return is_cpu();
case aspect::gpu:
return is_gpu();
case aspect::accelerator:
return is_accelerator();
case aspect::fp16:
return has_extension("cl_khr_fp16");
case aspect::fp64:
return has_extension("cl_khr_fp64");
case aspect::int64_base_atomics:
return has_extension("cl_khr_int64_base_atomics");
case aspect::int64_extended_atomics:
return has_extension("cl_khr_int64_extended_atomics");
case aspect::image:
return get_info<info::device::image_support>();
case aspect::online_compiler:
return get_info<info::device::is_compiler_available>();
case aspect::online_linker:
return get_info<info::device::is_linker_available>();
case aspect::queue_profiling:
return get_info<info::device::queue_profiling>();
default:
throw runtime_error("This device aspect has not been implemented yet.",
PI_INVALID_DEVICE);
}
}

} // namespace detail
} // namespace sycl
} // __SYCL_INLINE_NAMESPACE(cl)
9 changes: 9 additions & 0 deletions sycl/source/detail/device_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#pragma once

#include <CL/sycl/aspects.hpp>
#include <CL/sycl/detail/pi.hpp>
#include <CL/sycl/stl.hpp>
#include <detail/device_info.hpp>
Expand Down Expand Up @@ -203,6 +204,14 @@ class device_impl {
/// \return a native handle.
pi_native_handle getNative() const;

/// Indicates if the SYCL device has the given feature.
///
/// \param Aspect is one of the values in Table 4.20 of the SYCL 2020
/// Provisional Spec.
//
/// \return true if the SYCL device has the given feature.
bool has(aspect Aspect) const;

private:
explicit device_impl(pi_native_handle InteropDevice, RT::PiDevice Device,
PlatformImplPtr Platform, const plugin &Plugin);
Expand Down
10 changes: 10 additions & 0 deletions sycl/source/detail/platform_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,16 @@ platform_impl::get_info() const {
param>::get(this->getHandleRef(), getPlugin());
}

// All devices on the platform must have the given aspect.
bool platform_impl::has(aspect Aspect) const {
for (const auto &dev : get_devices()) {
if (dev.has(Aspect) == false) {
return false;
}
}
return true;
}

#define PARAM_TRAITS_SPEC(param_type, param, ret_type) \
template ret_type platform_impl::get_info<info::param_type::param>() const;

Expand Down
10 changes: 10 additions & 0 deletions sycl/source/detail/platform_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,16 @@ class platform_impl {
/// \return a native handle.
pi_native_handle getNative() const;

/// Indicates if all of the SYCL devices on this platform have the
/// given feature.
///
/// \param Aspect is one of the values in Table 4.20 of the SYCL 2020
/// Provisional Spec.
///
/// \return true all of the SYCL devices on this platform have the
/// given feature.
bool has(aspect Aspect) const;

private:
bool MHostPlatform = false;
RT::PiPlatform MPlatform = 0;
Expand Down
2 changes: 2 additions & 0 deletions sycl/source/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,5 +137,7 @@ device::get_info() const {

pi_native_handle device::getNative() const { return impl->getNative(); }

bool device::has(aspect Aspect) const { return impl->has(Aspect); }

} // namespace sycl
} // __SYCL_INLINE_NAMESPACE(cl)
2 changes: 2 additions & 0 deletions sycl/source/platform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ platform::get_info() const {

pi_native_handle platform::getNative() const { return impl->getNative(); }

bool platform::has(aspect Aspect) const { return impl->has(Aspect); }

#define PARAM_TRAITS_SPEC(param_type, param, ret_type) \
template __SYCL_EXPORT ret_type \
platform::get_info<info::param_type::param>() const;
Expand Down
2 changes: 2 additions & 0 deletions sycl/test/abi/sycl_symbols_linux.dump
Original file line number Diff line number Diff line change
Expand Up @@ -3922,6 +3922,7 @@ _ZNK2cl4sycl6device18create_sub_devicesILNS0_4info18partition_propertyE4230EEESt
_ZNK2cl4sycl6device18create_sub_devicesILNS0_4info18partition_propertyE4231EEESt6vectorIS1_SaIS1_EERKS5_ImSaImEE
_ZNK2cl4sycl6device18create_sub_devicesILNS0_4info18partition_propertyE4232EEESt6vectorIS1_SaIS1_EENS3_25partition_affinity_domainE
_ZNK2cl4sycl6device3getEv
_ZNK2cl4sycl6device3hasENS0_6aspectE
_ZNK2cl4sycl6device6is_cpuEv
_ZNK2cl4sycl6device6is_gpuEv
_ZNK2cl4sycl6device7is_hostEv
Expand Down Expand Up @@ -4066,6 +4067,7 @@ _ZNK2cl4sycl8platform11get_backendEv
_ZNK2cl4sycl8platform11get_devicesENS0_4info11device_typeE
_ZNK2cl4sycl8platform13has_extensionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
_ZNK2cl4sycl8platform3getEv
_ZNK2cl4sycl8platform3hasENS0_6aspectE
_ZNK2cl4sycl8platform7is_hostEv
_ZNK2cl4sycl8platform8get_infoILNS0_4info8platformE2304EEENS3_12param_traitsIS4_XT_EE11return_typeEv
_ZNK2cl4sycl8platform8get_infoILNS0_4info8platformE2305EEENS3_12param_traitsIS4_XT_EE11return_typeEv
Expand Down
72 changes: 72 additions & 0 deletions sycl/test/basic_tests/aspects.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// RUN: %clangxx %s -o %t.out -I %sycl_include -lsycl
// RUN: %t.out

//==--------------- aspects.cpp - SYCL device test ------------------------==//
//
// Returns the various aspects of a device and platform.
//
// 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 <CL/sycl.hpp>
#include <iostream>

using namespace cl::sycl;

// platform::has() calls device::has() for each device on the platform.

int main() {
bool failed = false;
int pltIdx = 0;
for (const auto &plt : platform::get_platforms()) {
pltIdx++;
if (plt.has(aspect::host)) {
std::cout << "Platform #" << pltIdx
Copy link
Contributor

Choose a reason for hiding this comment

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

Currently this test only checks that has() method can be called, but it doesn't check its result. Probably it is better to query same info using existing SYCL methods (like get_info) and compare it with the result of has().

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The aspect::has() function calls get_info() to see if the requested aspect is supported. Whether it is right or wrong, has() and get_info() will always agree.

<< " type: host supports:" << std::endl;
} else if (plt.has(aspect::cpu)) {
std::cout << "Platform #" << pltIdx
<< " type: cpu supports:" << std::endl;
} else if (plt.has(aspect::gpu)) {
std::cout << "Platform #" << pltIdx
<< " type: gpu supports:" << std::endl;
} else if (plt.has(aspect::accelerator)) {
std::cout << "Platform #" << pltIdx
<< " type: accelerator supports:" << std::endl;
} else {
failed = true;
std::cout << "Failed: platform #" << pltIdx << " type: unknown"
<< std::endl;
return 1;
}

if (plt.has(aspect::fp16)) {
std::cout << " fp16" << std::endl;
}
if (plt.has(aspect::fp64)) {
std::cout << " fp64" << std::endl;
}
if (plt.has(aspect::int64_base_atomics)) {
std::cout << " base atomic operations" << std::endl;
}
if (plt.has(aspect::int64_extended_atomics)) {
std::cout << " extended atomic operations" << std::endl;
}
if (plt.has(aspect::image)) {
std::cout << " images" << std::endl;
}
if (plt.has(aspect::online_compiler)) {
std::cout << " online compiler" << std::endl;
}
if (plt.has(aspect::online_linker)) {
std::cout << " online linker" << std::endl;
}
if (plt.has(aspect::queue_profiling)) {
std::cout << " queue profiling" << std::endl;
}
}
std::cout << "Passed." << std::endl;
return 0;
}