Skip to content

Commit 79d8403

Browse files
committed
Improve fix by applying new review remarks
Signed-off-by: Mikhail Lychkov <[email protected]>
1 parent b478e9a commit 79d8403

File tree

10 files changed

+104
-43
lines changed

10 files changed

+104
-43
lines changed

sycl/include/CL/sycl/stream.hpp

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,26 @@ using GlobalOffsetAccessorT =
7373
cl::sycl::access::target::global_buffer,
7474
cl::sycl::access::placeholder::false_t>;
7575

76+
// Read first 2 bytes of flush buffer to get buffer offset.
77+
// TODO: Should be optimized to the following:
78+
// return *reinterpret_cast<uint16_t *>(&GlobalFlushBuf[WIOffset]);
79+
// when an issue with device code compilation using this optimization is fixed.
7680
inline unsigned GetFlushBufOffset(const GlobalBufAccessorT &GlobalFlushBuf,
7781
unsigned WIOffset) {
78-
return (((uint8_t)GlobalFlushBuf[WIOffset]) << 8) +
79-
(uint8_t)GlobalFlushBuf[WIOffset + 1];
82+
return ((static_cast<unsigned>(static_cast<uint8_t>(GlobalFlushBuf[WIOffset]))
83+
<< 8) +
84+
static_cast<uint8_t>(GlobalFlushBuf[WIOffset + 1]));
8085
}
8186

87+
// Write flush buffer's offset into first 2 bytes of that buffer.
88+
// TODO: Should be optimized to the following:
89+
// *reinterpret_cast<uint16_t *>(&GlobalFlushBuf[WIOffset]) =
90+
// static_cast<uint16_t>(Offset);
91+
// when an issue with device code compilation using this optimization is fixed.
8292
inline void SetFlushBufOffset(GlobalBufAccessorT &GlobalFlushBuf,
8393
unsigned WIOffset, unsigned Offset) {
84-
GlobalFlushBuf[WIOffset] = (Offset >> 8) & 0xff;
85-
GlobalFlushBuf[WIOffset + 1] = Offset & 0xff;
94+
GlobalFlushBuf[WIOffset] = static_cast<char>((Offset >> 8) & 0xff);
95+
GlobalFlushBuf[WIOffset + 1] = static_cast<char>(Offset & 0xff);
8696
}
8797

8898
inline void write(GlobalBufAccessorT &GlobalFlushBuf, size_t FlushBufferSize,
@@ -719,6 +729,7 @@ inline __width_manipulator__ setw(int Width) {
719729
/// \ingroup sycl_api
720730
class __SYCL_EXPORT stream {
721731
public:
732+
// Throws exception in case of invalid input parameters
722733
stream(size_t BufferSize, size_t MaxStatementSize, handler &CGH);
723734

724735
size_t get_size() const;
@@ -841,6 +852,10 @@ class __SYCL_EXPORT stream {
841852
// overhead on FPGA target. That is why use global atomic variable to
842853
// calculate offsets.
843854
WIOffset = GlobalOffset[1].fetch_add(FlushBufferSize);
855+
856+
// Initialize flush subbuffer's offset for each work item on device.
857+
// Initialization on host device is performed via submition of additional
858+
// host task.
844859
SetFlushBufOffset(GlobalFlushBuf, WIOffset, 0);
845860
}
846861

sycl/source/detail/scheduler/scheduler.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <detail/global_handler.hpp>
1212
#include <detail/queue_impl.hpp>
1313
#include <detail/scheduler/scheduler.hpp>
14+
#include <detail/scheduler/scheduler_helpers.hpp>
1415
#include <detail/stream_impl.hpp>
1516

1617
#include <chrono>
@@ -75,10 +76,12 @@ EventImplPtr Scheduler::addCG(std::unique_ptr<detail::CG> CommandGroup,
7576

7677
if (IsKernel) {
7778
Streams = ((CGExecKernel *)CommandGroup.get())->getStreams();
79+
// Stream's flush buffer memeory is mainly initialized in stream's __init
80+
// method. However, this method is not available on host device.
81+
// Initializing stream's flush buffer on the host side in a separate task.
7882
if (Queue->is_host()) {
79-
// Initializing stream's flush buffer on the host side.
80-
for (auto StreamImplPtr : Streams) {
81-
StreamImplPtr->fill(Queue);
83+
for (const StreamImplPtr &Stream : Streams) {
84+
initStream(Stream, Queue);
8285
}
8386
}
8487
}

sycl/source/detail/scheduler/scheduler.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,7 @@ class Scheduler {
764764
};
765765

766766
friend class stream_impl;
767+
friend void initStream(StreamImplPtr, QueueImplPtr);
767768

768769
// Protects stream buffers pool
769770
std::recursive_mutex StreamBuffersPoolMutex;
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//==---------- scheduler_helpers.hpp - SYCL standard header file -----------==//
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+
#pragma once
10+
11+
#include <CL/sycl/queue.hpp>
12+
#include <detail/scheduler/scheduler.hpp>
13+
14+
__SYCL_INLINE_NAMESPACE(cl) {
15+
namespace sycl {
16+
namespace detail {
17+
18+
void initStream(StreamImplPtr Stream, QueueImplPtr Queue) {
19+
auto StreamBuf =
20+
Scheduler::getInstance().StreamBuffersPool.find(Stream.get());
21+
assert((StreamBuf != Scheduler::getInstance().StreamBuffersPool.end()) &&
22+
"Stream is unexpectedly not found in pool.");
23+
24+
auto &FlushBuf = StreamBuf->second->FlushBuf;
25+
// Only size of buffer_impl object has been resized.
26+
// Value of Range field of FlushBuf instance is still equal to
27+
// MaxStatementSize only.
28+
size_t FlushBufSize = getSyclObjImpl(FlushBuf)->get_count();
29+
30+
auto Q = createSyclObjFromImpl<queue>(Queue);
31+
Q.submit([&](handler &cgh) {
32+
auto FlushBufAcc = FlushBuf.get_access<access::mode::discard_write,
33+
access::target::host_buffer>(
34+
cgh, range<1>(FlushBufSize), id<1>(0));
35+
cgh.codeplay_host_task([=] {
36+
char *FlushBufPtr = FlushBufAcc.get_pointer();
37+
std::memset(FlushBufPtr, 0, FlushBufAcc.get_size());
38+
});
39+
});
40+
}
41+
42+
} // namespace detail
43+
} // namespace sycl
44+
} // __SYCL_INLINE_NAMESPACE(cl)

sycl/source/detail/stream_impl.cpp

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -61,29 +61,6 @@ size_t stream_impl::get_size() const { return BufferSize_; }
6161

6262
size_t stream_impl::get_max_statement_size() const { return MaxStatementSize_; }
6363

64-
void stream_impl::fill(QueueImplPtr Queue) {
65-
auto Q = detail::createSyclObjFromImpl<queue>(Queue);
66-
Q.submit([&](handler &cgh) {
67-
auto StreamBuf =
68-
detail::Scheduler::getInstance().StreamBuffersPool.find(this);
69-
assert((StreamBuf !=
70-
detail::Scheduler::getInstance().StreamBuffersPool.end()) &&
71-
"Stream is unexpectedly not found in pool");
72-
auto &FlushBuf = StreamBuf->second->FlushBuf;
73-
// Only size of buffer_impl object has been resized.
74-
// Value of Range field of FlushBuf instance is still equal to
75-
// MaxStatementSize only.
76-
size_t FlushBufSize = detail::getSyclObjImpl(FlushBuf)->get_count();
77-
auto FlushBufAcc = FlushBuf.get_access<access::mode::read_write,
78-
access::target::global_buffer>(
79-
cgh, range<1>(FlushBufSize), id<1>(0));
80-
cgh.codeplay_host_task([=] {
81-
char *FlushBufPtr = FlushBufAcc.get_pointer();
82-
std::memset(FlushBufPtr, 0, FlushBufAcc.get_size());
83-
});
84-
});
85-
}
86-
8764
void stream_impl::flush() {
8865
// We don't want stream flushing to be blocking operation that is why submit a
8966
// host task to print stream buffer. It will fire up as soon as the kernel

sycl/source/detail/stream_impl.hpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@ class __SYCL_EXPORT stream_impl {
3737
// buffer and offset in the flush buffer
3838
GlobalOffsetAccessorT accessGlobalOffset(handler &CGH);
3939

40-
void fill(QueueImplPtr Queue);
41-
4240
// Enqueue task to copy stream buffer to the host and print the contents
4341
void flush();
4442

sycl/source/stream.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9+
//#include <CL/sycl/exception.hpp>
910
#include <CL/sycl/stream.hpp>
1011
#include <detail/queue_impl.hpp>
1112
#include <detail/stream_impl.hpp>
@@ -25,8 +26,12 @@ stream::stream(size_t BufferSize, size_t MaxStatementSize, handler &CGH)
2526
// Allocate the flush buffer, which contains space for each work item
2627
GlobalFlushBuf(impl->accessGlobalFlushBuf(CGH)),
2728
FlushBufferSize(MaxStatementSize + detail::FLUSH_BUF_OFFSET_SIZE) {
28-
assert((MaxStatementSize <= MAX_STATEMENT_SIZE) &&
29-
"Maximum statement size too large.");
29+
if (MaxStatementSize > MAX_STATEMENT_SIZE) {
30+
throw invalid_parameter_error("Maximum statement size exceeds limit of " +
31+
std::to_string(MAX_STATEMENT_SIZE) +
32+
" bytes.",
33+
PI_INVALID_VALUE);
34+
}
3035

3136
// Save stream implementation in the handler so that stream will be alive
3237
// during kernel execution

sycl/test/abi/sycl_symbols_linux.dump

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3725,7 +3725,6 @@ _ZN2cl4sycl6detail11buffer_impl11allocateMemESt10shared_ptrINS1_12context_implEE
37253725
_ZN2cl4sycl6detail11stream_impl15accessGlobalBufERNS0_7handlerE
37263726
_ZN2cl4sycl6detail11stream_impl18accessGlobalOffsetERNS0_7handlerE
37273727
_ZN2cl4sycl6detail11stream_impl20accessGlobalFlushBufERNS0_7handlerE
3728-
_ZN2cl4sycl6detail11stream_impl4fillESt10shared_ptrINS1_10queue_implEE
37293728
_ZN2cl4sycl6detail11stream_impl5flushEv
37303729
_ZN2cl4sycl6detail11stream_implC1EmmRNS0_7handlerE
37313730
_ZN2cl4sycl6detail11stream_implC2EmmRNS0_7handlerE

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

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,6 @@
44
// RUN: %GPU_RUN_ON_LINUX_PLACEHOLDER %t.out %GPU_CHECK_ON_LINUX_PLACEHOLDER
55
// RUN: %ACC_RUN_PLACEHOLDER %t.out %ACC_CHECK_PLACEHOLDER
66

7-
//==-- stream_copies_buffer_sync.cpp - SYCL stream flush buffer sync test --==//
8-
//
9-
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
10-
// See https://llvm.org/LICENSE.txt for license information.
11-
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
12-
//
13-
//===----------------------------------------------------------------------===//
14-
157
#include <CL/sycl.hpp>
168

179
using namespace cl::sycl;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out
2+
// RUN: env SYCL_DEVICE_TYPE=HOST %t.out | FileCheck %s
3+
// RUN: %CPU_RUN_PLACEHOLDER %t.out %CPU_CHECK_PLACEHOLDER
4+
// RUN: %GPU_RUN_ON_LINUX_PLACEHOLDER %t.out %GPU_CHECK_ON_LINUX_PLACEHOLDER
5+
// RUN: %ACC_RUN_PLACEHOLDER %t.out %ACC_CHECK_PLACEHOLDER
6+
7+
#include <CL/sycl.hpp>
8+
9+
#include <cassert>
10+
11+
using namespace cl;
12+
13+
int main() {
14+
sycl::queue Queue;
15+
try {
16+
Queue.submit([&](sycl::handler &cgh) {
17+
sycl::stream Out(100, 65536, cgh);
18+
cgh.single_task<class test_max_stmt_exceed>(
19+
[=]() { Out << "Hello world!" << sycl::endl; });
20+
});
21+
Queue.wait();
22+
} catch (sycl::exception &ExpectedException) {
23+
// CHECK: Maximum statement size exceeds limit of 65535 bytes
24+
std::cout << ExpectedException.what() << std::endl;
25+
}
26+
return 0;
27+
}

0 commit comments

Comments
 (0)