Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
9 changes: 6 additions & 3 deletions sycl/source/detail/graph_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -730,10 +730,13 @@ void executable_command_graph::finalizeImpl() {
info::graph_support_level::native;

#if FORCE_EMULATION_MODE
// Above query should still succeed in emulation mode, but ignore the
// result and use emulation.
CmdBufSupport = false;
setEmulationModeForced(true);
#endif
if (impl->isEmulationModeForced()) {
// Above query should still succeed in emulation mode, but ignore the
// result and use emulation.
CmdBufSupport = false;
}

if (CmdBufSupport) {
impl->createCommandBuffers(Device);
Expand Down
26 changes: 26 additions & 0 deletions sycl/source/detail/graph_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,16 @@ class graph_impl {
if (PropList.has_property<property::graph::no_cycle_check>()) {
MSkipCycleChecks = true;
}
if (SyclDevice.get_info<
ext::oneapi::experimental::info::device::graph_support>() ==
info::graph_support_level::unsupported) {
std::stringstream Stream;
Stream << SyclDevice.get_backend();
std::string BackendString = Stream.str();
throw sycl::exception(
sycl::make_error_code(errc::invalid),
BackendString + " backend is not supported by SYCL Graph extension.");
}
}

/// Insert node into list of root nodes.
Expand Down Expand Up @@ -582,6 +592,14 @@ class graph_impl {
void makeEdge(std::shared_ptr<node_impl> Src,
std::shared_ptr<node_impl> Dest);

/// Force to use an emulated backend
/// @param Forced true force to use an emulated backend
/// false enable the use of non-emulatated backend
void setEmulationModeForced(bool Forced) { MEmulationModeForced = Forced; }
/// Get the status of MEmulationModeForced member
/// @return true is bakced is forced to emulation
bool getEmulationModeForced() { return MEmulationModeForced; }

private:
/// Iterate over the graph depth-first and run \p NodeFunc on each node.
/// @param NodeFunc A function which receives as input a node in the graph to
Expand Down Expand Up @@ -620,6 +638,9 @@ class graph_impl {
/// Controls whether we skip the cycle checks in makeEdge, set by the presence
/// of the no_cycle_check property on construction.
bool MSkipCycleChecks = false;

/// Force to use an emulated backend
bool MEmulationModeForced = false;
};

/// Class representing the implementation of command_graph<executable>.
Expand Down Expand Up @@ -692,6 +713,11 @@ class exec_graph_impl {
return false;
}

/// @return true if emulated backend has been forced
bool isEmulationModeForced() const {
return MGraphImpl->getEmulationModeForced();
}

private:
/// Create a command-group for the node and add it to command-buffer by going
/// through the scheduler.
Expand Down
35 changes: 35 additions & 0 deletions sycl/test-e2e/Graph/exception_unsupported_backend.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// RUN: %{build} -o %t.out
// RUN: %{run} %t.out

// Tests the ability to finalize a empty command graph
// The test checks that invalid exception is thrown
// when trying to create a graph with an unsupported backend.

#include "graph_common.hpp"

int GetUnsupportedBackend(const sycl::device &Dev) {
// Return 1 if the device backend is unsupported or 0 else.
// 0 does not prevent another device to be picked as a second choice
return Dev.get_info<
ext::oneapi::experimental::info::device::graph_support>() ==
ext::oneapi::experimental::info::graph_support_level::unsupported;
}

int main() {
sycl::device Dev{GetUnsupportedBackend};
queue Queue{Dev};

if (Dev.get_info<ext::oneapi::experimental::info::device::graph_support>() !=
ext::oneapi::experimental::info::graph_support_level::unsupported)
return 0;

std::error_code ExceptionCode = make_error_code(sycl::errc::success);
try {
exp_ext::command_graph Graph{Queue.get_context(), Dev};
} catch (exception &Exception) {
ExceptionCode = Exception.code();
}
assert(ExceptionCode == sycl::errc::invalid);

return 0;
}
31 changes: 30 additions & 1 deletion sycl/unittests/Extensions/CommandGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,22 @@
using namespace sycl;
using namespace sycl::ext::oneapi;

namespace {
void forceEmulatedBackend(
experimental::command_graph<experimental::graph_state::modifiable> Graph) {
auto GraphImpl = sycl::detail::getSyclObjImpl(Graph);
GraphImpl->setEmulationModeForced(true);
}
} // anonymous namespace

class CommandGraphTest : public ::testing::Test {
public:
CommandGraphTest()
: Mock{}, Plat{Mock.getPlatform()}, Dev{Plat.get_devices()[0]},
Queue{Dev}, Graph{Queue.get_context(), Dev} {}
Queue{Dev}, Graph{Queue.get_context(), Dev} {
// We need to disable backend for unitests as backends are not loaded
forceEmulatedBackend(Graph);
}

protected:
void SetUp() override {}
Expand Down Expand Up @@ -282,6 +293,9 @@ TEST_F(CommandGraphTest, SubGraph) {
ASSERT_EQ(sycl::detail::getSyclObjImpl(Node2MainGraph)->MPredecessors.size(),
1lu);

// We need to disable backend for unitests as backends are not loaded
forceEmulatedBackend(MainGraph);

// Finalize main graph and check schedule
auto MainGraphExec = MainGraph.finalize();
auto MainGraphExecImpl = sycl::detail::getSyclObjImpl(MainGraphExec);
Expand Down Expand Up @@ -325,6 +339,9 @@ TEST_F(CommandGraphTest, RecordSubGraph) {
});
MainGraph.end_recording(Queue);

// We need to disable backend for unitests as backends are not loaded
forceEmulatedBackend(MainGraph);

// Finalize main graph and check schedule
auto MainGraphExec = MainGraph.finalize();
auto MainGraphExecImpl = sycl::detail::getSyclObjImpl(MainGraphExec);
Expand Down Expand Up @@ -407,6 +424,9 @@ TEST_F(CommandGraphTest, InOrderQueue) {

InOrderGraph.end_recording(InOrderQueue);

// We need to disable backend for unitests as backends are not loaded
forceEmulatedBackend(InOrderGraph);

// Finalize main graph and check schedule
auto GraphExec = InOrderGraph.finalize();
auto GraphExecImpl = sycl::detail::getSyclObjImpl(GraphExec);
Expand Down Expand Up @@ -466,6 +486,9 @@ TEST_F(CommandGraphTest, InOrderQueueWithEmpty) {

InOrderGraph.end_recording(InOrderQueue);

// We need to disable backend for unitests as backends are not loaded
forceEmulatedBackend(InOrderGraph);

// Finalize main graph and check schedule
// Note that empty nodes are not scheduled
auto GraphExec = InOrderGraph.finalize();
Expand Down Expand Up @@ -523,6 +546,9 @@ TEST_F(CommandGraphTest, InOrderQueueWithEmptyFirst) {

InOrderGraph.end_recording(InOrderQueue);

// We need to disable backend for unitests as backends are not loaded
forceEmulatedBackend(InOrderGraph);

// Finalize main graph and check schedule
// Note that empty nodes are not scheduled
auto GraphExec = InOrderGraph.finalize();
Expand Down Expand Up @@ -580,6 +606,9 @@ TEST_F(CommandGraphTest, InOrderQueueWithEmptyLast) {

InOrderGraph.end_recording(InOrderQueue);

// We need to disable backend for unitests as backends are not loaded
forceEmulatedBackend(InOrderGraph);

// Finalize main graph and check schedule
// Note that empty nodes are not scheduled
auto GraphExec = InOrderGraph.finalize();
Expand Down
2 changes: 1 addition & 1 deletion sycl/unittests/helpers/PiMockPlugin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ inline pi_result mock_piDeviceGetInfo(pi_device device,
size_t *param_value_size_ret) {
constexpr char MockDeviceName[] = "Mock device";
constexpr char MockSupportedExtensions[] =
"cl_khr_fp64 cl_khr_fp16 cl_khr_il_program";
"cl_khr_fp64 cl_khr_fp16 cl_khr_il_program ur_exp_command_buffer";
switch (param_name) {
case PI_DEVICE_INFO_TYPE: {
// Act like any device is a GPU.
Expand Down