-
Notifications
You must be signed in to change notification settings - Fork 752
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SYCL][Fusion] JIT compiler kernel fusion passes #7661
[SYCL][Fusion] JIT compiler kernel fusion passes #7661
Conversation
This patch can be reviewed and merged independently of #7531. The tests are currently not yet run together with |
5e1613a
to
5451db0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, just the nitpick
5451db0
to
fae8208
Compare
Co-authored-by: Lukas Sommer <[email protected]> Co-authored-by: Victor Perez <[email protected]> Signed-off-by: Lukas Sommer <[email protected]>
fae8208
to
2021ae2
Compare
@intel/llvm-gatekeepers the PR is ready to be merged, AMD failure is unrelated to this patch AFAIK |
HIP failures reported in #7634. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some post-commit review
NF->copyAttributesFrom(F); | ||
// Drop masked-out attributes. | ||
SmallVector<AttributeSet> Attributes; | ||
const llvm::AttributeList PAL = NF->getAttributes(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: llvm::
namespace is used inconsistently: there is using namespace llvm;
, but in some places llvm::
is still used. For example, below on line 44 AttributeList
is referenced without llvm::
. This comment also applies to other files
|
||
{ | ||
// Copy metadata. | ||
SmallVector<std::pair<unsigned, MDNode *>> MDs; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit surprised that SmallVector
doesn't require a second argument, am I missing something? What is the point of using SmallVector
if we are not pre-allocating some storage on stack?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is actually recommended if there is no well motivated choice for N
:
In the absence of a well-motivated choice for the number of inlined elements N, it is recommended to use SmallVector (that is, omitting the N). This will choose a default number of inlined elements reasonable for allocation on the stack (for example, trying to keep sizeof(SmallVector) around 64 bytes).
From https://llvm.org/doxygen/classllvm_1_1SmallVector.html#details
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't know there is a default value for N
, thanks!
// Copy metadata. | ||
SmallVector<std::pair<unsigned, MDNode *>> MDs; | ||
F->getAllMetadata(MDs); | ||
for (auto MD : MDs) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unnecessary copy due to missing &
?
|
||
using namespace llvm; | ||
|
||
static FunctionType *createMaskedFunctionType(const BitVector &Mask, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not anonymous namespace?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My understanding so far was that there doesn't seem to be a big difference between static
and anonymous namespaces, also based on this.
Do you have a specific reason to prefer one over the other?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No strong reason, just making it more C++-y
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using static
in this case allows us to keep the static functions closer to their non-static users/callers without declaring multiple anonymous namespaces, so we stick with that for now.
auto *NewIndex = [&]() -> Value * { | ||
if (LocalSize == 1) { | ||
return Builder.getInt64(0); | ||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LLVM Coding Standard: Don't use else
after return
auto *FK = dyn_cast<MDString>(MDOp.get()); | ||
assert(FK && "Kernel should be given by its name as MDString"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to use dyn_cast
if you don't check the result. cast
already contains an assert
statement for you
if (StubFunction.hasMetadata(ParameterMDKind)) { | ||
llvm::MDNode *ParamMD = StubFunction.getMetadata(ParameterMDKind); | ||
for (const auto &Op : ParamMD->operands()) { | ||
auto *Tuple = dyn_cast<MDNode>(Op.get()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Once again, dyn_cast
-> cast
auto *ConstantMD = dyn_cast<ConstantAsMetadata>(MD); | ||
assert(ConstantMD && "Metadata not constant"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dyn_cast
-> cast
SmallVector<Value *> Indices; | ||
Indices.push_back(Builder.getInt32(0)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ArrayRef
is constructible from a single element: we should use that instead of performing an allocation on heap for a single pointer.
if (RetCode) { | ||
return std::move(RetCode); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Braces around single-line if
s can be omitted
@AlexeySachkov: Thank you for your feedback, I addressed your post-commit comments in #7719. |
Fix tests for kernel fusion passes in static builds by using correct library, loadable by `opt`, for tests. Also fixes post-commit feedback from @AlexeySachkov in #7661. Signed-off-by: Lukas Sommer <[email protected]>
This is the fourth patch in a series of patches to add an implementation of the kernel fusion extension. We have split the implementation into multiple patches to make them more easy to review.
This patch adds the LLVM passes that perform the kernel fusion and related optimizations:
The type of memory to use is currently specified by the user in the runtime.
The information is propagated from the SYCL runtime to the passes via LLVM metadata inserted by the JIT compiler frontend.
After and between the fusion passes, some standard LLVM optimization and transformation passes are executed to enable passes and optimize the fused kernel.
Co-authored-by: Lukas Sommer [email protected]
Co-authored-by: Victor Perez [email protected]
Signed-off-by: Lukas Sommer [email protected]