Skip to content
This repository was archived by the owner on Mar 28, 2023. It is now read-only.

[PI][OpenCL] Test support for exposing compute slices #1530

Open
wants to merge 2 commits into
base: intel
Choose a base branch
from
Open
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
162 changes: 162 additions & 0 deletions SYCL/Basic/subsubdevice_cslice.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out
// RUN: %CPU_RUN_PLACEHOLDER %t.out
// RUN: %GPU_RUN_PLACEHOLDER %t.out
// RUN: %ACC_RUN_PLACEHOLDER %t.out

//==----- subsubdevice_cslice.cpp - SYCL subsubdevice basic 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
//
// This test tries to identify devices at all levels of hierarchy.
//===----------------------------------------------------------------------===//

#if 1 // __STANDALONE_TESTING__
// unnamed namespace for standalone testing
#include <cstdlib>
#include <cstring>
namespace {
void readEnvStringWithDefault(const char *name, char *value, const char *def) {
char *tmp = std::getenv(name);

Choose a reason for hiding this comment

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

We don't set any env variable in RUN lines, so I don't see how it is applicable to this test.

if (!tmp)
std::strcpy(value, def);
else
std::strcpy(value, tmp);
}
} // namespace
#else
void readEnvStringWithDefault(const char *, char *, const char *);
#endif

#if __clang_major__ > 15
#include <sycl/sycl.hpp>
#else
#include <CL/sycl.hpp>
inline namespace cl {
using namespace sycl;
}
namespace sycl = ::cl::sycl;
#endif
Comment on lines +32 to +40

Choose a reason for hiding this comment

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

We don't do that - the test-suite is tied with the compiler.


#include <atomic>
#include <exception>
#include <map>
#include <thread>
#include <vector>

static auto exception_handler = [](sycl::exception_list list) {
for (std::exception_ptr const &e : list) {
try {
std::rethrow_exception(e);
} catch (std::exception const &e) {
std::cout << "Exception: " << e.what() << std::endl;
std::fflush(stdout);
Comment on lines +53 to +54

Choose a reason for hiding this comment

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

https://en.cppreference.com/w/cpp/io/manip/endl

Inserts a newline character into the output sequence os and flushes it as if by calling os.put(os.widen('\n')) followed by os.flush().

throw;
// std::terminate();
}
}
};

int identify_devices() {
std::vector<sycl::device> devices;
int verbose = 0;
try {
std::vector<sycl::device> all_devices = sycl::device::get_devices();
char variable_name[255];

readEnvStringWithDefault("XPU_USE_SUBDEVICES", variable_name, "1");
auto use_subdevices = std::atoi(variable_name);
int split_streams = 0;
if (use_subdevices) {
readEnvStringWithDefault("XPU_SPLIT_STREAMS", variable_name, "1");
split_streams = std::atoi(variable_name);
}

readEnvStringWithDefault("XPU_VERBOSE", variable_name, "1");
verbose = std::atoi(variable_name);

readEnvStringWithDefault("XPU_DEVICE_NAME", variable_name, "Graphics");

if (verbose) {
std::cout << "XPU_DEVICE_NAME=" << variable_name << std::endl;
std::cout << "Devices found:" << std::endl;
}
std::cout << "Number of root devices = " << all_devices.size() << std::endl;
for (auto &device : all_devices) {
if (verbose) {
std::cout << "* Device: " << device.get_info<sycl::info::device::name>()
<< ", Backend: " << device.get_platform().get_backend()
<< std::endl;
}

if (device.get_info<sycl::info::device::name>().find(variable_name) !=
std::string::npos) {
// Select devices with the same backend only
if (devices.empty() ||
(!devices.empty() && devices[0].get_platform().get_backend() ==
device.get_platform().get_backend())) {
// Select subdevices if any
auto device_partition_properties =
device.get_info<sycl::info::device::partition_properties>();
if (!use_subdevices || device_partition_properties.empty()) {
devices.push_back(device);
} else {
for (int i = 0; i < device_partition_properties.size(); i++) {
if (device_partition_properties[i] ==
sycl::info::partition_property::
partition_by_affinity_domain) {
auto subdevices =
device.create_sub_devices<sycl::info::partition_property::
partition_by_affinity_domain>(
sycl::info::partition_affinity_domain::numa);
std::cout << "Number of subdevices = " << subdevices.size()
<< "\n";
for (int j = 0; j < subdevices.size(); j++) {
auto subdevice_partition_properties =
subdevices[j]
.get_info<sycl::info::device::partition_properties>();
if (!split_streams ||
subdevice_partition_properties.empty()) {
devices.push_back(subdevices[j]);
} else {
for (int i = 0; i < subdevice_partition_properties.size();
i++) {
if (subdevice_partition_properties[i] ==
sycl::info::partition_property::
ext_intel_partition_by_cslice) {
Comment on lines +125 to +127

Choose a reason for hiding this comment

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

I don't see how the test fails without the OpenCL plugin implementation.

auto streams =
subdevices[j]
.create_sub_devices<
sycl::info::partition_property::
ext_intel_partition_by_cslice>();
std::cout
<< "Number of compute slices = " << streams.size()
<< "\n";
for (int j = 0; j < streams.size(); j++) {
devices.push_back(streams[j]);
}
break;
}
}
}
}
break;
} else {
devices.push_back(device);
}
}
}
}
}
}
Comment on lines +140 to +152

Choose a reason for hiding this comment

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

Can we somehow restructure the code to avoid this?

return 0;
} catch (sycl::exception &e) {
std::cout << "Sync sycl exception in initialize_queues(): " << e.what()
<< std::endl;
std::fflush(stdout);
return 1;
}
}

int main() { return identify_devices(); }