Skip to content

Commit 5d948a2

Browse files
committed
Rewrite stream init dependence LIT test as unit test
Signed-off-by: Mikhail Lychkov <[email protected]>
1 parent cd71a1c commit 5d948a2

File tree

8 files changed

+200
-71
lines changed

8 files changed

+200
-71
lines changed

sycl/include/CL/sycl/handler.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ template <typename T_Src, int Dims_Src, cl::sycl::access::mode AccessMode_Src,
6565
cl::sycl::access::placeholder IsPlaceholder_Dst>
6666
class __copyAcc2Acc;
6767

68+
// For unit testing purposes
69+
class MockHandler;
70+
6871
__SYCL_INLINE_NAMESPACE(cl) {
6972
namespace sycl {
7073

@@ -1951,6 +1954,8 @@ class __SYCL_EXPORT handler {
19511954
friend void detail::associateWithHandler(handler &,
19521955
detail::AccessorBaseHost *,
19531956
access::target);
1957+
1958+
friend class ::MockHandler;
19541959
};
19551960
} // namespace sycl
19561961
} // __SYCL_INLINE_NAMESPACE(cl)

sycl/source/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ set(SYCL_SOURCES
134134
"detail/scheduler/commands.cpp"
135135
"detail/scheduler/leaves_collection.cpp"
136136
"detail/scheduler/scheduler.cpp"
137+
"detail/scheduler/scheduler_helpers.cpp"
137138
"detail/scheduler/graph_processor.cpp"
138139
"detail/scheduler/graph_builder.cpp"
139140
"detail/spec_constant_impl.cpp"
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
//==-- scheduler_helpers.cpp - SYCL Scheduler helper functions --*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include <CL/sycl/queue.hpp>
10+
#include <detail/queue_impl.hpp>
11+
#include <detail/scheduler/scheduler.hpp>
12+
#include <detail/scheduler/scheduler_helpers.hpp>
13+
#include <detail/stream_impl.hpp>
14+
15+
__SYCL_INLINE_NAMESPACE(cl) {
16+
namespace sycl {
17+
namespace detail {
18+
19+
void initStream(StreamImplPtr Stream, QueueImplPtr Queue) {
20+
Scheduler::StreamBuffers *StrBufs{};
21+
22+
{
23+
std::lock_guard<std::recursive_mutex> lock(
24+
Scheduler::getInstance().StreamBuffersPoolMutex);
25+
26+
auto StreamBuf =
27+
Scheduler::getInstance().StreamBuffersPool.find(Stream.get());
28+
assert((StreamBuf != Scheduler::getInstance().StreamBuffersPool.end()) &&
29+
"Stream is unexpectedly not found in pool.");
30+
31+
StrBufs = StreamBuf->second;
32+
}
33+
34+
assert(StrBufs && "No buffers for a stream.");
35+
36+
// Real size of full flush buffer is saved only in buffer_impl field of
37+
// FlushBuf object.
38+
size_t FlushBufSize = getSyclObjImpl(StrBufs->FlushBuf)->get_count();
39+
40+
auto Q = createSyclObjFromImpl<queue>(Queue);
41+
Q.submit([&](handler &cgh) {
42+
auto FlushBufAcc =
43+
StrBufs->FlushBuf.get_access<access::mode::discard_write,
44+
access::target::host_buffer>(
45+
cgh, range<1>(FlushBufSize), id<1>(0));
46+
cgh.codeplay_host_task([=] {
47+
char *FlushBufPtr = FlushBufAcc.get_pointer();
48+
std::memset(FlushBufPtr, 0, FlushBufAcc.get_size());
49+
});
50+
});
51+
}
52+
53+
} // namespace detail
54+
} // namespace sycl
55+
} // __SYCL_INLINE_NAMESPACE(cl)

sycl/source/detail/scheduler/scheduler_helpers.hpp

Lines changed: 10 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -8,46 +8,21 @@
88

99
#pragma once
1010

11-
#include <CL/sycl/queue.hpp>
12-
#include <detail/scheduler/scheduler.hpp>
11+
#include <CL/sycl/detail/defines_elementary.hpp>
12+
13+
#include <memory>
1314

1415
__SYCL_INLINE_NAMESPACE(cl) {
1516
namespace sycl {
1617
namespace detail {
1718

18-
void initStream(StreamImplPtr Stream, QueueImplPtr Queue) {
19-
Scheduler::StreamBuffers *StrBufs{};
20-
21-
{
22-
std::lock_guard<std::mutex> lock(
23-
Scheduler::getInstance().StreamBuffersPoolMutex);
24-
25-
auto StreamBuf =
26-
Scheduler::getInstance().StreamBuffersPool.find(Stream.get());
27-
assert((StreamBuf != Scheduler::getInstance().StreamBuffersPool.end()) &&
28-
"Stream is unexpectedly not found in pool.");
29-
30-
StrBufs = StreamBuf->second;
31-
}
32-
33-
assert(StrBufs && "No buffers for a stream.");
34-
35-
// Real size of full flush buffer is saved only in buffer_impl field of
36-
// FlushBuf object.
37-
size_t FlushBufSize = getSyclObjImpl(StrBufs->FlushBuf)->get_count();
38-
39-
auto Q = createSyclObjFromImpl<queue>(Queue);
40-
Q.submit([&](handler &cgh) {
41-
auto FlushBufAcc =
42-
StrBufs->FlushBuf.get_access<access::mode::discard_write,
43-
access::target::host_buffer>(
44-
cgh, range<1>(FlushBufSize), id<1>(0));
45-
cgh.codeplay_host_task([=] {
46-
char *FlushBufPtr = FlushBufAcc.get_pointer();
47-
std::memset(FlushBufPtr, 0, FlushBufAcc.get_size());
48-
});
49-
});
50-
}
19+
class stream_impl;
20+
class queue_impl;
21+
22+
using StreamImplPtr = std::shared_ptr<detail::stream_impl>;
23+
using QueueImplPtr = std::shared_ptr<detail::queue_impl>;
24+
25+
void initStream(StreamImplPtr Stream, QueueImplPtr Queue);
5126

5227
} // namespace detail
5328
} // namespace sycl

sycl/test/on-device/basic_tests/stream/stream_flush_buf_init_dep.cpp

Lines changed: 0 additions & 36 deletions
This file was deleted.

sycl/unittests/scheduler/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@ add_sycl_unittest(SchedulerTests OBJECT
99
LinkedAllocaDependencies.cpp
1010
LeavesCollection.cpp
1111
NoUnifiedHostMemory.cpp
12+
StreamInitDependencyOnHost.cpp
1213
utils.cpp
1314
)

sycl/unittests/scheduler/SchedulerTestUtils.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,12 @@ class MockScheduler : public cl::sycl::detail::Scheduler {
130130
const cl::sycl::detail::QueueImplPtr &Queue) {
131131
return MGraphBuilder.insertMemoryMove(Record, Req, Queue);
132132
}
133+
134+
cl::sycl::detail::Command *
135+
addCG(std::unique_ptr<cl::sycl::detail::CG> CommandGroup,
136+
cl::sycl::detail::QueueImplPtr Queue) {
137+
return MGraphBuilder.addCG(std::move(CommandGroup), Queue);
138+
}
133139
};
134140

135141
void addEdge(cl::sycl::detail::Command *User, cl::sycl::detail::Command *Dep,
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
//==------ LinkedAllocaDependencies.cpp --- Scheduler unit tests -----------==//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "SchedulerTest.hpp"
10+
#include "SchedulerTestUtils.hpp"
11+
12+
#include <detail/scheduler/scheduler_helpers.hpp>
13+
14+
using namespace cl::sycl;
15+
16+
class MockHandler : public sycl::handler {
17+
public:
18+
MockHandler(shared_ptr_class<detail::queue_impl> Queue, bool IsHost)
19+
: sycl::handler(Queue, IsHost) {}
20+
21+
void setType(detail::CG::CGTYPE Type) {
22+
static_cast<sycl::handler *>(this)->MCGType = Type;
23+
}
24+
25+
void addStream(const detail::StreamImplPtr &Stream) {
26+
sycl::handler::addStream(Stream);
27+
}
28+
29+
unique_ptr_class<detail::CG> finalize() {
30+
auto CGH = static_cast<sycl::handler *>(this);
31+
unique_ptr_class<detail::CG> CommandGroup;
32+
switch (CGH->MCGType) {
33+
case detail::CG::KERNEL:
34+
case detail::CG::RUN_ON_HOST_INTEL: {
35+
CommandGroup.reset(new detail::CGExecKernel(
36+
std::move(CGH->MNDRDesc), std::move(CGH->MHostKernel),
37+
std::move(CGH->MKernel), std::move(CGH->MArgsStorage),
38+
std::move(CGH->MAccStorage), std::move(CGH->MSharedPtrStorage),
39+
std::move(CGH->MRequirements), std::move(CGH->MEvents),
40+
std::move(CGH->MArgs), std::move(CGH->MKernelName),
41+
std::move(CGH->MOSModuleHandle), std::move(CGH->MStreamStorage),
42+
CGH->MCGType, CGH->MCodeLoc));
43+
break;
44+
}
45+
default:
46+
throw runtime_error("Unhandled type of command group",
47+
PI_INVALID_OPERATION);
48+
}
49+
50+
return CommandGroup;
51+
}
52+
};
53+
54+
using CmdTypeTy = cl::sycl::detail::Command::CommandType;
55+
56+
static bool ValidateDepCommandsTree(const detail::Command *Cmd,
57+
std::queue<CmdTypeTy> DepCmdsTypes,
58+
const detail::SYCLMemObjI *MemObj) {
59+
if (DepCmdsTypes.empty())
60+
return true;
61+
else if (!Cmd)
62+
return false;
63+
64+
CmdTypeTy DepCmdType = DepCmdsTypes.front();
65+
DepCmdsTypes.pop();
66+
67+
for (const detail::DepDesc &Dep : Cmd->MDeps) {
68+
if (Dep.MDepCommand && (Dep.MDepCommand->getType() == DepCmdType) &&
69+
Dep.MDepRequirement && (Dep.MDepRequirement->MSYCLMemObj == MemObj) &&
70+
ValidateDepCommandsTree(Dep.MDepCommand, DepCmdsTypes, MemObj))
71+
return true;
72+
}
73+
74+
return false;
75+
}
76+
77+
TEST_F(SchedulerTest, StreamInitDependencyOnHost) {
78+
cl::sycl::queue HQueue(host_selector{});
79+
detail::QueueImplPtr HQueueImpl = detail::getSyclObjImpl(HQueue);
80+
81+
// Emulating processing of command group function
82+
MockHandler MockCGH(HQueueImpl, true);
83+
MockCGH.setType(detail::CG::KERNEL);
84+
85+
// Emulating construction of stream object inside command group
86+
detail::StreamImplPtr StreamImpl =
87+
std::make_shared<detail::stream_impl>(1024, 200, MockCGH);
88+
detail::GlobalBufAccessorT FlushBufAcc =
89+
StreamImpl->accessGlobalFlushBuf(MockCGH);
90+
MockCGH.addStream(StreamImpl);
91+
92+
detail::SYCLMemObjI *FlushBufMemObjPtr =
93+
detail::getSyclObjImpl(FlushBufAcc)->MSYCLMemObj;
94+
ASSERT_TRUE(!!FlushBufMemObjPtr)
95+
<< "Memory object for stream flush buffer not initialized";
96+
97+
unique_ptr_class<detail::CG> MainCG = MockCGH.finalize();
98+
99+
// Emulate call of Scheduler::addCG
100+
vector_class<detail::StreamImplPtr> Streams =
101+
static_cast<detail::CGExecKernel *>(MainCG.get())->getStreams();
102+
ASSERT_EQ(Streams.size(), 1u) << "Invalid number of stream objects";
103+
104+
initStream(Streams[0], HQueueImpl);
105+
106+
MockScheduler MS;
107+
detail::Command *NewCmd = MS.addCG(std::move(MainCG), HQueueImpl);
108+
ASSERT_TRUE(!!NewCmd) << "Failed to add command group into scheduler";
109+
ASSERT_GT(NewCmd->MDeps.size(), 0u)
110+
<< "No deps appeared in the new exec kernel command";
111+
112+
// Searching in dependencies for CG execution command that initializes flush
113+
// buffer of a stream that is supposed to be used inside NewCmd's CG.
114+
// Tree of dependencies should look like:
115+
// [MAIN_CG] -> [EMPTY_NODE {FlushBufMemObj}] -> [FILL_CG {FlushBufMemObj}] ->
116+
// [[ALLOC_TASK {FlushBufMemObj}]
117+
std::queue<CmdTypeTy> DepCmdsTypes({CmdTypeTy::EMPTY_TASK,
118+
CmdTypeTy::RUN_CG, // FILL_CG
119+
CmdTypeTy::ALLOCA});
120+
ASSERT_TRUE(ValidateDepCommandsTree(NewCmd, DepCmdsTypes, FlushBufMemObjPtr))
121+
<< "Dependency on stream flush buffer initialization not found";
122+
}

0 commit comments

Comments
 (0)