Skip to content

Commit 1f7d77f

Browse files
committed
[SYCL][UNITTEST] Unit testing host pipe functionality
This test mocks the following: 1. host pipe registration 2. device image registration 3. opencl function calls This aims to test: assuming the host pipe registration is correct the host pipe read and write should behave correctly, in this case, read and write the right data into the global variables.
1 parent c2fc28d commit 1f7d77f

File tree

6 files changed

+168
-4
lines changed

6 files changed

+168
-4
lines changed

sycl/include/CL/sycl.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,5 @@
7272
#include <sycl/ext/oneapi/sub_group.hpp>
7373
#include <sycl/ext/oneapi/sub_group_mask.hpp>
7474

75+
#include <sycl/ext/intel/experimental/host_pipes.hpp>
7576
#include <sycl/ext/intel/experimental/pipe_properties.hpp>

sycl/include/sycl/ext/intel/experimental/host_pipes.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ class
7373
? _propertiesT::template get_property<min_capacity_key>().value
7474
: 0;
7575

76+
static const void *get_host_ptr() { return &__pipe; }
77+
7678
// Blocking pipes
7779
static _dataT read(queue & q, memory_order order = memory_order::seq_cst);
7880
static void write(queue & q, const _dataT &data,

sycl/source/detail/host_pipe.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,8 @@ host_pipe<_name, _dataT, _propertiesT,
3333
detail::HostPipeMapEntry *hostPipeEntry =
3434
detail::ProgramManager::getInstance().getHostPipeEntry(HostPipePtr);
3535
const std::string pipe_name = hostPipeEntry->MUniqueId;
36-
size_t size = 4;
3736
event e = q.submit([=](handler &CGH) {
38-
CGH.read_write_host_pipe(pipe_name, (void *)(&data), (size_t)size, false,
37+
CGH.read_write_host_pipe(pipe_name, (void *)(&data), sizeof(_dataT), false,
3938
true /* read */);
4039
});
4140
e.wait();
@@ -60,9 +59,8 @@ void host_pipe<
6059
detail::ProgramManager::getInstance().getHostPipeEntry(HostPipePtr);
6160
const std::string pipe_name = hostPipeEntry->MUniqueId;
6261
const void *data_ptr = &data;
63-
size_t size = 4;
6462
event e = q.submit([=](handler &CGH) {
65-
CGH.read_write_host_pipe(pipe_name, (void *)data_ptr, (size_t)size, false,
63+
CGH.read_write_host_pipe(pipe_name, (void *)data_ptr, sizeof(_dataT), false,
6664
false /* write */);
6765
});
6866
e.wait();

sycl/unittests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ add_subdirectory(scheduler)
4040
add_subdirectory(stream)
4141
add_subdirectory(SYCL2020)
4242
add_subdirectory(thread_safety)
43+
add_subdirectory(pipes)
4344
add_subdirectory(program_manager)
4445
add_subdirectory(assert)
4546
add_subdirectory(Extensions)

sycl/unittests/pipes/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
set(CMAKE_CXX_EXTENSIONS OFF)
2+
3+
add_sycl_unittest(PipeTests OBJECT
4+
host_pipe_registration.cpp
5+
)
6+
7+
add_dependencies(PipeTests sycl)
8+
target_include_directories(PipeTests PRIVATE SYSTEM ${sycl_inc_dir})
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
//==-------------- host_pipe_registration.cpp - Host pipe 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 <CL/sycl.hpp>
10+
#include <cstring>
11+
12+
#include <gtest/gtest.h>
13+
#include <helpers/CommonRedefinitions.hpp>
14+
#include <helpers/PiImage.hpp>
15+
#include <helpers/PiMock.hpp>
16+
17+
namespace {
18+
using namespace cl::sycl;
19+
using pipe_prop = decltype(ext::oneapi::experimental::properties(
20+
ext::intel::experimental::min_capacity<5>));
21+
22+
template <unsigned ID> struct pipe_id {
23+
static constexpr unsigned id = ID;
24+
};
25+
26+
class test_data_type {
27+
public:
28+
int num;
29+
};
30+
31+
using test_host_pipe =
32+
ext::intel::experimental::host_pipe<pipe_id<0>, test_data_type, pipe_prop>;
33+
34+
pi_device_binary_struct generate_device_binary() {
35+
std::vector<unsigned char> Bin{0, 1, 2, 3, 4, 5}; // Random data
36+
unittest::PiArray<unittest::PiOffloadEntry> Entries =
37+
unittest::makeEmptyKernels({"TestKernel"});
38+
unittest::PiPropertySet PropSet;
39+
pi_device_binary_struct MBinaryDesc = pi_device_binary_struct{
40+
PI_DEVICE_BINARY_VERSION,
41+
PI_DEVICE_BINARY_OFFLOAD_KIND_SYCL,
42+
PI_DEVICE_BINARY_TYPE_SPIRV,
43+
__SYCL_PI_DEVICE_BINARY_TARGET_SPIRV64,
44+
"",
45+
"",
46+
nullptr,
47+
nullptr,
48+
&*Bin.begin(),
49+
(&*Bin.begin()) + Bin.size(),
50+
Entries.begin(),
51+
Entries.end(),
52+
PropSet.begin(),
53+
PropSet.end(),
54+
};
55+
return MBinaryDesc;
56+
}
57+
pi_event READ = reinterpret_cast<pi_event>(0);
58+
pi_event WRITE = reinterpret_cast<pi_event>(1);
59+
static constexpr test_data_type PipeReadVal = {8};
60+
static test_data_type PipeWriteVal = {0};
61+
pi_result redefinedEnqueueReadHostPipe(pi_queue, pi_program, const char *,
62+
pi_bool, void *ptr, size_t, pi_uint32,
63+
const pi_event *, pi_event *event) {
64+
*(((test_data_type *)ptr)) = PipeReadVal;
65+
*event = READ;
66+
return PI_SUCCESS;
67+
}
68+
pi_result redefinedEnqueueWriteHostPipe(pi_queue, pi_program, const char *,
69+
pi_bool, void *ptr, size_t, pi_uint32,
70+
const pi_event *, pi_event *event) {
71+
test_data_type tmp = {9};
72+
PipeWriteVal = tmp;
73+
*event = WRITE;
74+
return PI_SUCCESS;
75+
}
76+
77+
bool preparePiMock(platform &Plt) {
78+
if (Plt.is_host()) {
79+
std::cout << "Not run on host - no PI events created in that case"
80+
<< std::endl;
81+
return false;
82+
}
83+
84+
unittest::PiMock Mock{Plt};
85+
Mock.redefine<detail::PiApiKind::piextEnqueueReadHostPipe>(
86+
redefinedEnqueueReadHostPipe);
87+
Mock.redefine<detail::PiApiKind::piextEnqueueWriteHostPipe>(
88+
redefinedEnqueueWriteHostPipe);
89+
return true;
90+
}
91+
92+
class PipeTest : public ::testing::Test {
93+
protected:
94+
void SetUp() override {
95+
platform Plt{default_selector()};
96+
if (!preparePiMock(Plt))
97+
return;
98+
context Ctx{Plt.get_devices()[0]};
99+
queue Q{Ctx, default_selector()};
100+
plat = Plt;
101+
ctx = Ctx;
102+
q = Q;
103+
104+
// Fake registration of host pipes
105+
sycl::detail::host_pipe_map::add(test_host_pipe::get_host_ptr(),
106+
"test_host_pipe_unique_id");
107+
// Fake registration of device image
108+
static constexpr size_t NumberOfImages = 1;
109+
pi_device_binary_struct MNativeImages[NumberOfImages];
110+
MNativeImages[0] = generate_device_binary();
111+
MAllBinaries = pi_device_binaries_struct{
112+
PI_DEVICE_BINARIES_VERSION,
113+
NumberOfImages,
114+
MNativeImages,
115+
nullptr, // not used, put here for compatibility with OpenMP
116+
nullptr, // not used, put here for compatibility with OpenMP
117+
};
118+
__sycl_register_lib(&MAllBinaries);
119+
}
120+
121+
void TearDown() override { __sycl_unregister_lib(&MAllBinaries); }
122+
123+
platform plat;
124+
context ctx;
125+
queue q;
126+
pi_device_binaries_struct MAllBinaries;
127+
};
128+
129+
TEST_F(PipeTest, Basic) {
130+
const void *HostPipePtr = test_host_pipe::get_host_ptr();
131+
detail::HostPipeMapEntry *hostPipeEntry =
132+
detail::ProgramManager::getInstance().getHostPipeEntry(HostPipePtr);
133+
const std::string pipe_name = hostPipeEntry->MUniqueId;
134+
test_data_type host_pipe_read_data = {};
135+
void *data_ptr = &host_pipe_read_data;
136+
event e = q.submit([=](handler &CGH) {
137+
CGH.read_write_host_pipe(pipe_name, data_ptr, sizeof(test_data_type), false,
138+
true /* read */);
139+
});
140+
e.wait();
141+
// auto host_pipe_read_data = test_host_pipe::read(q);
142+
assert(host_pipe_read_data.num == PipeReadVal.num);
143+
test_data_type tmp = {9};
144+
data_ptr = &tmp;
145+
event e_write = q.submit([=](handler &CGH) {
146+
CGH.read_write_host_pipe(pipe_name, data_ptr, sizeof(test_data_type), false,
147+
false /* write */);
148+
});
149+
e_write.wait();
150+
// test_host_pipe::write(q, tmp);
151+
assert(PipeWriteVal.num == 9);
152+
}
153+
154+
} // namespace

0 commit comments

Comments
 (0)