Skip to content

Commit 992ef06

Browse files
zibaiwansherry-yuanrho180
authored
[SYCL] Host pipe runtime implementation (#7468)
Disclaimer: This work is a continuation of a previous approved Sherry's PR: #5766 and her draft work #5894. We are implementing Hostpipes based on the Spec [here](https://github.com/rho180/llvm/blob/rho180-pipe-design/sycl/doc/design/HostPipes.md). OpenCL spec is [here](https://github.com/intel-sandbox/ip-authoring-specs/blob/MJ_ChangeDocs4/Pipe/Spec/cl_intel_host_pipe_symbol.asciidoc). The following is the outline of the design. 1. The host pipe properties need to be added to the device image (probably similar to the previous change here a9ad3af) 2.The frontend calls the [registration of device image, maybe similar to this code](https://github.com/intel/llvm/blob/af858c74e4be95b2163ce6ba545ce588ff0aca4c/sycl/source/detail/program_manager/program_manager.cpp#L2014): which is where the host pipe information is available. This is where the mapping from host pipe name to host pipe pointer is extracted. 3. The frontend also calls `host_pipe_map::add` to register/initialize the host pipes. This is the new function. We are not sure about the ordering of registration of device image / registration of host pipe. for which ever one that comes later, it need to initialize the remaining attribute of host pipe (such as its properties). 4. The opencl runtime will need to get a cl_program object, which is typically not available until the first kernel launch. To get a program object early on, the host pipe name/pointer to device image mapping is cached during registration. And when the specific host pipe is needed, build the program and get its ocl runtime representation. This is done in the first couple commits. 5. Since a host pipe read/write need to depend on other write operation finishing before it (including the inter kernel write). This means the pipe needs to know the dependency of kernel execution. For this reason, the host pipe read and write ocl function cannot be called with no dep event. therefore, it is implemented with handler , which is aware of the event that it is supposed to wait upon. This is done in the "Register new command group .." commit. 6. Unit test - mock a fake device image. - register the fake device image - register fake pipe with some name you specified - fake the opencl functionality, this can be done with unittest::PiMock::redefine --------- Co-authored-by: Sherry Yuan <[email protected]> Co-authored-by: Ho, Robert <[email protected]>
1 parent 6b2d66b commit 992ef06

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1595
-47
lines changed

buildbot/dependency.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ def do_dependency(args):
5858

5959
# Checkout fixed version to avoid unexpected issues coming from upstream
6060
# Specific version can be uplifted as soon as such need arise
61-
checkout_cmd = ["git", "checkout", "23710f1b99186065c1768fc3098ba681adc0f253"]
61+
checkout_cmd = ["git", "checkout", "9ddb236e6eb3cf844f9e2f81677e1045f9bf838e"]
6262
subprocess.check_call(checkout_cmd, cwd=ocl_header_dir)
6363

6464
# fetch and build OpenCL ICD loader
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
//===------- HostPipes.h - get required info about FPGA Host Pipes --------===//
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+
// The file contains a number of functions to extract corresponding attributes
10+
// of the host pipe global variables and save them as a property set for the
11+
// runtime.
12+
//===----------------------------------------------------------------------===//
13+
14+
#pragma once
15+
16+
#include "llvm/ADT/MapVector.h"
17+
18+
#include <cstdint>
19+
#include <vector>
20+
21+
namespace llvm {
22+
23+
class GlobalVariable;
24+
class Module;
25+
class StringRef;
26+
27+
// Represents a host pipe variable - at SYCL RT level host pipe
28+
// variables are being represented as a byte-array.
29+
struct HostPipeProperty {
30+
HostPipeProperty(uint32_t Size) : Size(Size) {}
31+
32+
// Encodes size of the underlying type T of the host pipe variable.
33+
uint32_t Size;
34+
};
35+
36+
using HostPipePropertyMapTy =
37+
MapVector<StringRef, std::vector<HostPipeProperty>>;
38+
39+
/// Return \c true if the variable @GV is a host pipe variable.
40+
///
41+
/// The function checks whether the variable has the LLVM IR attribute \c
42+
/// sycl-host-pipe
43+
/// @param GV [in] A variable to test.
44+
///
45+
/// @return \c true if the variable is a host pipe variable, \c false
46+
/// otherwise.
47+
bool isHostPipeVariable(const GlobalVariable &GV);
48+
49+
/// Searches given module for occurrences of host pipe variable-specific
50+
/// metadata and builds "host pipe variable name" ->
51+
/// vector<"variable properties"> map.
52+
///
53+
/// @param M [in] LLVM Module.
54+
///
55+
/// @returns the "host pipe variable name" -> vector<"variable properties">
56+
/// map.
57+
HostPipePropertyMapTy collectHostPipeProperties(const Module &M);
58+
59+
} // end namespace llvm

llvm/include/llvm/SYCLLowerIR/SYCLUtils.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ namespace llvm {
2222
namespace sycl {
2323
namespace utils {
2424
constexpr char ATTR_SYCL_MODULE_ID[] = "sycl-module-id";
25-
constexpr StringRef SYCL_HOST_PIPE_ATTR = "sycl-host-pipe";
2625

2726
using CallGraphNodeAction = ::std::function<void(Function *)>;
2827
using CallGraphFunctionFilter =
@@ -117,10 +116,6 @@ inline bool isSYCLExternalFunction(const Function *F) {
117116
return F->hasFnAttribute(ATTR_SYCL_MODULE_ID);
118117
}
119118

120-
inline bool isHostPipeVariable(const GlobalVariable &GV) {
121-
return GV.hasAttribute(SYCL_HOST_PIPE_ATTR);
122-
}
123-
124119
} // namespace utils
125120
} // namespace sycl
126121
} // namespace llvm

llvm/include/llvm/Support/PropertySetIO.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ class PropertySetRegistry {
197197
static constexpr char SYCL_EXPORTED_SYMBOLS[] = "SYCL/exported symbols";
198198
static constexpr char SYCL_DEVICE_GLOBALS[] = "SYCL/device globals";
199199
static constexpr char SYCL_DEVICE_REQUIREMENTS[] = "SYCL/device requirements";
200+
static constexpr char SYCL_HOST_PIPES[] = "SYCL/host pipes";
200201

201202
// Function for bulk addition of an entire property set under given category
202203
// (property set name).

llvm/lib/SYCLLowerIR/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ add_llvm_component_library(LLVMSYCLLowerIR
5757
ESIMD/LowerESIMDVecArg.cpp
5858
ESIMD/LowerESIMDVLoadVStore.cpp
5959
ESIMD/LowerESIMDSlmReservation.cpp
60+
HostPipes.cpp
6061
LowerInvokeSimd.cpp
6162
LowerKernelProps.cpp
6263
LowerWGLocalMemory.cpp

llvm/lib/SYCLLowerIR/CompileTimePropertiesPass.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
#include "llvm/SYCLLowerIR/CompileTimePropertiesPass.h"
1212
#include "llvm/SYCLLowerIR/DeviceGlobals.h"
13-
#include "llvm/SYCLLowerIR/SYCLUtils.h"
13+
#include "llvm/SYCLLowerIR/HostPipes.h"
1414

1515
#include "llvm/ADT/APInt.h"
1616
#include "llvm/ADT/StringMap.h"
@@ -343,7 +343,7 @@ PreservedAnalyses CompileTimePropertiesPass::run(Module &M,
343343
HostAccessDecorValue, VarName));
344344
}
345345

346-
if (sycl::utils::isHostPipeVariable(GV)) {
346+
if (isHostPipeVariable(GV)) {
347347
auto VarName = getGlobalVariableUniqueId(GV);
348348
MDOps.push_back(buildSpirvDecorMetadata(Ctx, SPIRV_HOST_ACCESS_DECOR,
349349
SPIRV_HOST_ACCESS_DEFAULT_VALUE,

llvm/lib/SYCLLowerIR/DeviceGlobals.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,19 +72,19 @@ bool hasDeviceImageScopeProperty(const GlobalVariable &GV) {
7272
return hasProperty(GV, SYCL_DEVICE_IMAGE_SCOPE_ATTR);
7373
}
7474

75-
/// Returns the unique id for the device global variable.
75+
/// Returns the unique id for the device global or host pipe variable.
7676
///
7777
/// The function gets this value from the LLVM IR attribute \c
7878
/// sycl-unique-id.
7979
///
80-
/// @param GV [in] Device Global variable.
80+
/// @param GV [in] Device Global or Hostpipe variable.
8181
///
82-
/// @returns the unique id of the device global variable represented
83-
/// in the LLVM IR by \c GV.
82+
/// @returns the unique id of the device global or hostpipe variable
83+
/// represented in the LLVM IR by \c GV.
8484
StringRef getGlobalVariableUniqueId(const GlobalVariable &GV) {
8585
assert(GV.hasAttribute(SYCL_UNIQUE_ID_ATTR) &&
8686
"a 'sycl-unique-id' string must be associated with every device "
87-
"global variable");
87+
"global or hostpipe variable");
8888
return GV.getAttribute(SYCL_UNIQUE_ID_ATTR).getValueAsString();
8989
}
9090

llvm/lib/SYCLLowerIR/HostPipes.cpp

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
//===------------- HostPipes.cpp - SYCL Host Pipes Pass -------------------===//
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+
// See comments in the header.
9+
//===----------------------------------------------------------------------===//
10+
11+
#include "llvm/SYCLLowerIR/HostPipes.h"
12+
#include "llvm/SYCLLowerIR/CompileTimePropertiesPass.h"
13+
#include "llvm/SYCLLowerIR/DeviceGlobals.h"
14+
15+
#include "llvm/ADT/STLExtras.h"
16+
#include "llvm/ADT/StringRef.h"
17+
#include "llvm/IR/Module.h"
18+
19+
#include <cassert>
20+
21+
using namespace llvm;
22+
23+
namespace {
24+
25+
constexpr StringRef SYCL_HOST_PIPE_ATTR = "sycl-host-pipe";
26+
constexpr StringRef SYCL_HOST_PIPE_SIZE_ATTR = "sycl-host-pipe-size";
27+
28+
/// Returns the size (in bytes) of the type \c T of the host
29+
/// pipe variable.
30+
///
31+
/// The function gets this value from the LLVM IR attribute \c
32+
/// sycl-host-pipe-size.
33+
///
34+
/// @param GV [in] Host Pipe variable.
35+
///
36+
/// @returns the size (int bytes) of the underlying type \c T of the
37+
/// host pipe variable represented in the LLVM IR by @GV.
38+
uint32_t getHostPipeTypeSize(const GlobalVariable &GV) {
39+
assert(GV.hasAttribute(SYCL_HOST_PIPE_SIZE_ATTR) &&
40+
"The host pipe variable must have the 'sycl-host-pipe-size' "
41+
"attribute that must contain a number representing the size of the "
42+
"underlying type T of the host pipe variable");
43+
return getAttributeAsInteger<uint32_t>(GV, SYCL_HOST_PIPE_SIZE_ATTR);
44+
}
45+
46+
} // anonymous namespace
47+
48+
namespace llvm {
49+
50+
/// Return \c true if the variable @GV is a host pipe variable.
51+
///
52+
/// The function checks whether the variable has the LLVM IR attribute \c
53+
/// sycl-host-pipe.
54+
/// @param GV [in] A variable to test.
55+
///
56+
/// @return \c true if the variable is a host pipe variable, \c false
57+
/// otherwise.
58+
bool isHostPipeVariable(const GlobalVariable &GV) {
59+
return GV.hasAttribute(SYCL_HOST_PIPE_ATTR);
60+
}
61+
62+
HostPipePropertyMapTy collectHostPipeProperties(const Module &M) {
63+
HostPipePropertyMapTy HPM;
64+
auto HostPipeNum = count_if(M.globals(), isHostPipeVariable);
65+
if (HostPipeNum == 0)
66+
return HPM;
67+
68+
HPM.reserve(HostPipeNum);
69+
70+
for (auto &GV : M.globals()) {
71+
if (!isHostPipeVariable(GV))
72+
continue;
73+
74+
HPM[getGlobalVariableUniqueId(GV)] = {getHostPipeTypeSize(GV)};
75+
}
76+
77+
return HPM;
78+
}
79+
80+
} // namespace llvm

llvm/lib/Support/PropertySetIO.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ constexpr char PropertySetRegistry::SYCL_ASSERT_USED[];
203203
constexpr char PropertySetRegistry::SYCL_EXPORTED_SYMBOLS[];
204204
constexpr char PropertySetRegistry::SYCL_DEVICE_GLOBALS[];
205205
constexpr char PropertySetRegistry::SYCL_DEVICE_REQUIREMENTS[];
206+
constexpr char PropertySetRegistry::SYCL_HOST_PIPES[];
206207

207208
} // namespace util
208209
} // namespace llvm

llvm/test/SYCLLowerIR/CompileTimePropertiesPass/host-pipes/basic.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ $_ZN4sycl3_V13ext5intel12experimental9host_pipeI9D2HPipeIDiNS1_6oneapi12experime
1414
@_ZN4sycl3_V13ext5intel12experimental9host_pipeI9D2HPipeIDiNS1_6oneapi12experimental10propertiesISt5tupleIJEEEEE6__pipeE = linkonce_odr dso_local addrspace(1) constant %struct.BasicKernel zeroinitializer, comdat, align 1 #0
1515
; CHECK-IR: @_ZN4sycl3_V13ext5intel12experimental9host_pipeI9D2HPipeIDiNS1_6oneapi12experimental10propertiesISt5tupleIJEEEEE6__pipeE = linkonce_odr dso_local addrspace(1) constant %struct.BasicKernel zeroinitializer, comdat, align 1, !spirv.Decorations ![[#MN0:]]
1616

17-
attributes #0 = { "sycl-host-pipe" "sycl-unique-id"="_ZN4sycl3_V13ext5intel12experimental9host_pipeI9H2DPipeIDiNS1_6oneapi12experimental10propertiesISt5tupleIJEEEEE6__pipeE" }
17+
attributes #0 = { "sycl-host-pipe" "sycl-host-pipe-size"="4" "sycl-unique-id"="_ZN4sycl3_V13ext5intel12experimental9host_pipeI9H2DPipeIDiNS1_6oneapi12experimental10propertiesISt5tupleIJEEEEE6__pipeE" }
1818

1919
; Ensure that the generated metadata nodes are correct
2020
; CHECK-IR-DAG: ![[#MN0]] = !{![[#MN1:]]}

llvm/tools/sycl-post-link/sycl-post-link.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "llvm/Passes/PassBuilder.h"
3838
#include "llvm/SYCLLowerIR/DeviceGlobals.h"
3939
#include "llvm/SYCLLowerIR/ESIMD/LowerESIMD.h"
40+
#include "llvm/SYCLLowerIR/HostPipes.h"
4041
#include "llvm/SYCLLowerIR/LowerInvokeSimd.h"
4142
#include "llvm/SYCLLowerIR/LowerKernelProps.h"
4243
#include "llvm/Support/CommandLine.h"
@@ -466,6 +467,11 @@ std::string saveModuleProperties(module_split::ModuleDesc &MD,
466467
PropSet.add(PropSetRegTy::SYCL_DEVICE_GLOBALS, DevGlobalPropertyMap);
467468
}
468469

470+
auto HostPipePropertyMap = collectHostPipeProperties(M);
471+
if (!HostPipePropertyMap.empty()) {
472+
PropSet.add(PropSetRegTy::SYCL_HOST_PIPES, HostPipePropertyMap);
473+
}
474+
469475
std::error_code EC;
470476
std::string SCFile = makeResultFileName(".prop", I, Suff);
471477
raw_fd_ostream SCOut(SCFile, EC);

opencl/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ set(OCL_LOADER_REPO
2020

2121
# Repo tags/hashes
2222

23-
set(OCL_HEADERS_TAG dcd5bede6859d26833cd85f0d6bbcee7382dc9b3)
23+
set(OCL_HEADERS_TAG 9ddb236e6eb3cf844f9e2f81677e1045f9bf838e)
2424
set(OCL_LOADER_TAG 9a3e962f16f5097d2054233ad8b6dad51b6f41b7)
2525

2626
# OpenCL Headers

sycl/include/sycl/detail/cg.hpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ class CG {
7474
Memset2DUSM = 18,
7575
CopyToDeviceGlobal = 19,
7676
CopyFromDeviceGlobal = 20,
77+
ReadWriteHostPipe = 21,
7778
};
7879

7980
CG(CGTYPE Type, std::vector<std::vector<char>> ArgsStorage,
@@ -495,6 +496,36 @@ class CGMemset2DUSM : public CG {
495496
char getValue() const { return MValue; }
496497
};
497498

499+
/// "ReadWriteHostPipe" command group class.
500+
class CGReadWriteHostPipe : public CG {
501+
std::string PipeName;
502+
bool Blocking;
503+
void *HostPtr;
504+
size_t TypeSize;
505+
bool IsReadOp;
506+
507+
public:
508+
CGReadWriteHostPipe(const std::string &Name, bool Block, void *Ptr,
509+
size_t Size, bool Read,
510+
std::vector<std::vector<char>> ArgsStorage,
511+
std::vector<detail::AccessorImplPtr> AccStorage,
512+
std::vector<std::shared_ptr<const void>> SharedPtrStorage,
513+
std::vector<AccessorImplHost *> Requirements,
514+
std::vector<detail::EventImplPtr> Events,
515+
detail::code_location loc = {})
516+
: CG(ReadWriteHostPipe, std::move(ArgsStorage), std::move(AccStorage),
517+
std::move(SharedPtrStorage), std::move(Requirements),
518+
std::move(Events), std::move(loc)),
519+
PipeName(Name), Blocking(Block), HostPtr(Ptr), TypeSize(Size),
520+
IsReadOp(Read) {}
521+
522+
std::string getPipeName() { return PipeName; }
523+
void *getHostPtr() { return HostPtr; }
524+
size_t getTypeSize() { return TypeSize; }
525+
bool isBlocking() { return Blocking; }
526+
bool isReadHostPipe() { return IsReadOp; }
527+
};
528+
498529
/// "Copy to device_global" command group class.
499530
class CGCopyToDeviceGlobal : public CG {
500531
void *MSrc;

sycl/include/sycl/detail/pi.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,9 @@ _PI_API(piextUSMEnqueueMemcpy)
131131
_PI_API(piextUSMEnqueuePrefetch)
132132
_PI_API(piextUSMEnqueueMemAdvise)
133133
_PI_API(piextUSMGetMemAllocInfo)
134+
// Host pipes
135+
_PI_API(piextEnqueueReadHostPipe)
136+
_PI_API(piextEnqueueWriteHostPipe)
134137

135138
_PI_API(piextKernelSetArgMemObj)
136139
_PI_API(piextKernelSetArgSampler)

0 commit comments

Comments
 (0)