Skip to content

[sycl-post-link] Generate spec constants device image property even for non-native spec constants #3561

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

Conversation

AlexeySachkov
Copy link
Contributor

@AlexeySachkov AlexeySachkov commented Apr 16, 2021

The main purpose of this change is to emit the same device image property SYCL/specialization constants not only when native spec constants are supported, but also when they are emulated.

This is needed to support SYCL 2020 specialization constants, design document can be found in: #3331.

The task is achieved by changing the way how SpecConstantsPass works with metadata: in order to provide info which should be put into device image properties, it was attached as metadata to __spirv_SpecConstant intrinsics and they are not generated if native spec constants are not available. New approach creates a single named metadata sycl.specialization-constants which contains a list of metadatas, corresponding to each specialization constant found in the module.

Such new representation makes it easier to generate metadata and more significantly, it should improve the speed of reading them, because we don't need to look over each call to __spirv_SpecConstant intrinsic.

@AlexeySachkov AlexeySachkov marked this pull request as ready for review April 19, 2021 14:21
@AlexeySachkov AlexeySachkov requested a review from kbobrovs as a code owner April 19, 2021 14:21
@AlexeySachkov AlexeySachkov requested a review from vmaksimo April 19, 2021 14:21
@AlexeySachkov AlexeySachkov requested a review from a team as a code owner April 21, 2021 15:41
// RUN: cat %t-split1_0.prop | FileCheck %s
// RUN: sycl-post-link %t.bc -spec-const=default -o %t-split2.txt
// RUN: cat %t-split2_0.prop | FileCheck %s
// RUN: llvm-spirv -o %t-split1_0.spv -spirv-max-version=1.1 -spirv-ext=+all %t-split1_0.bc
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like it is better to move the test to clang tests and implement some stub for SYCL RT classes to let it build.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, will move it there

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After thinking about this a bit more, I'm not sure that it will work there: clang doesn't have dependency on sycl-post-link and llvm-spirv, so it would be a significant change there, while SYCL LIT tests already depend on sycl-toolchain, which includes both tools.

Also, this seems like an integration test and I'm not sure that we have a better place for it. Note: it is not a complete E2E test, so I'm not sure that llvm-test-suite is a proper place for it either

Copy link
Contributor

@vmaksimo vmaksimo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM except small issues already mentioned above

@AlexeySachkov
Copy link
Contributor Author

@kbobrovs, could you please take a look?

Changed `SCMetadata` type from `StringMap` to `MapVector`, because
is needed to preserve the order in which specialization constants are
listed in `sycl.specialization-constants` metadata and therefore in
device image propertes.

Having them order as they appear is easier for DPC++ RT as no additional
sorting is needed.
@AlexeySachkov AlexeySachkov requested a review from mlychkov as a code owner April 27, 2021 18:16
#include <vector>

namespace llvm {
class StringRef;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not #include the header?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea is to minimize amount of includes and therefore speedup compilation.

I agree that in this particular case it probably doesn't make any difference, as the header is only used twice (by SpecConstants.cpp and sycl-post-link.cpp), but nevertheless, I just applied this approach here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. llvm::Module and llvm::PreservedAnalyses would have to also be handled in similar way, and this approach does not scale. But consider this a nit, I don't see any harm in this case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and this approach does not scale.

Yes, it indeed requires some effort

I see. llvm::Module and llvm::PreservedAnalyses would have to also be handled in similar way,

We can't do so, because they are passed by reference and therefore required to be fully defined.

Note, this is a common approach in LLVM project: llvm/llvm-project@43d6f9a, llvm/llvm-project@3caa03e

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, read LLVM's documentation - coding standards in particular.
https://llvm.org/docs/CodingStandards.html#minimal-list-of-includes

#include hurts compile time performance. Don’t do it unless you have to, especially in header files.

But wait! Sometimes you need to have the definition of a class to use it, or to inherit from it. In these cases go ahead and #include that header file. Be aware however that there are many cases where you don’t need to have the full definition of a class. If you are using a pointer or reference to a class, you don’t need the header file. If you are simply returning a class instance from a prototyped function or method, you don’t need it. In fact, for most cases, you simply don’t need the definition of a class. And not #includeing speeds up compilation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, read LLVM's documentation - coding standards in particular.
https://llvm.org/docs/CodingStandards.html#minimal-list-of-includes

Thanks! I was looking for it as well. It seems like my understanding about references is wrong, I will probably send some follow-up refactoring patches

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, then this still holds:

llvm::Module and llvm::PreservedAnalyses would have to also be handled in similar way

This, for example, compiles just fine, as there is no real use of the object:

class Foo;
void foo(Foo&);

@romanovvlad romanovvlad merged commit 528aa5c into intel:sycl Apr 29, 2021
@AlexeySachkov AlexeySachkov deleted the private/asachkov/spec-constants-properties-for-aot branch May 22, 2024 09:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants