-
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][E2E] Add logic to react to REQUIRED
/UNSUPPORTED
in build-only
#16725
Conversation
This pr is the logic from #16637, but only with support for |
sycl/test-e2e/TriStateExpr.py
Outdated
self.assertTrue( | ||
E2EExpr.evaluate("!rt_feature", {"rt_feature"}, True, True) | ||
) | ||
self.assertTrue( | ||
E2EExpr.evaluate("!!rt_feature", {"rt_feature"}, True, True) | ||
) |
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.
IMO, there are far too many tests with {"rt_feature"}
when run time features are to be ignored. We don't expect the set of "set" features to contain them, so why are we testing that scenario mostly?
I can understand having a couple of tests for completeness/to document behavior, but having too many is counterproductive and might confuse the reader about the purpose of this class.
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.
Instead of deleting these, I just made the available features list empty. Does that work? otherwise I can delete them.
My intention with these was to show that ignore values propagate up the expression.
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.
quick initial review, will look more indepth once andrei's feedback is addressed
sycl/test-e2e/format.py
Outdated
if self.getMissingRequiredFeaturesFromList(features, test.requires, build_only_mode=True): | ||
continue | ||
if self.getMatchedFromList(features, test.unsupported, build_only_mode=True): |
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.
these functions are called get
but are being used as has
it seems, should we rename?
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.
hasMissingRequiredFeatures
and hasUnsupportedFeatures
? or what were you thinking. One thing to note that brought some confusion in the past is the fact that these dont report the specific features that were missing to pass the expression, rather it returns the clauses that did not pass.
Also should note that getMissingRequiredFeaturesFromList
is named after a function of the same name in the lit implementation. As for getMatchedFromList
that one doesnt have an exact corresponding function, but there is getUnsupportedFeatures
which is similar, but does not have an argument to pass in the features available.
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.
do we ever use the return value's contents or is it just empty or not? if its only empty or not i think we should rename to has...
, otherwise current is fine
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.
One small caveat, the getMatchedFromList
function is also used for determining XFAILs, so im not entirely sure hasUnsupportedFeatures
would be entirely accurate.
This
False
implies that we're processingUNSUPPORTED
, we need to modify the name of this function to indicate that now. Doeslit.Test
have some name that we can copy?
@aelovikov-intel tagging you here, because I think these comments are asking for the same thing, going to mark the other as resolved and we can continue discussion here
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.
IMO, keeping it close to lit.Test
or whatever the names came from is more important than renaming just because we don't use the result.
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.
One small caveat, the getMatchedFromList function is also used for determining XFAILs, so im not entirely sure hasUnsupportedFeatures would be entirely accurate.
In this case, I'd avoid hardcoding False
in the body and pass it as an additional parameter. Yes, it's kind of useless, but it would make interface more consistent.
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.
yeah im not super familiar with the implementation of lit so if the function names are standard then its fine
sycl/test-e2e/lit.cfg.py
Outdated
target = config.backend_to_target[be] | ||
features.add(target) | ||
config.sycl_triples.add(target) |
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.
Backend is the underlying runtime that sycl is implemented on, right? Isn't it possible to have the same backend support multiple targets?. For example using OpenCL on AMD or NVIDIA (theoretically of course since practically they would have to support the extensions sycl requires).
I think if backend_to_target
would be backend_default_target
then it leaves the design open to add an override via some option like --param backend_targets_<be>=<target1>,<target2>
.
Or maybe this is what architectures
is for?
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 think if
backend_to_target
would bebackend_default_target
then it leaves the design open to add an override via some option like--param backend_targets_<be>=<target1>,<target2>
.
Or maybe this is whatarchitectures
is for?
Yeah, something like that could be possible to do by overriding/changing the dictionary used for the mappings. Although I do still prefer the x_to_y
naming scheme for these mapping dictionaries, since it groups them together with consistent naming, and I don't think it necessarily stops us from redefining them in the future through parameters like you suggest.
sycl/test-e2e/lit.cfg.py
Outdated
config.target_to_triple = { | ||
"target-spir": "spir64", | ||
"target-nvidia":"nvptx64-nvidia-cuda", | ||
"target-amd":"amdgcn-amd-amdhsa", | ||
"target-native_cpu":"native_cpu", | ||
} | ||
config.triple_to_target = {v:k for k,v in config.target_to_triple.items()} |
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.
What's the difference between a "target" and the "triple" it corresponds to, given there's a 1:1 mapping between them? Is target just a short name for the triple? Is it an alias to allow changing the target triples without updating all the tests that refer to it?
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.
Short name was part of the motivation (at least for me). Also, Nick mentioned that there is some work to have two different spir triples (spir64 and spirv, I think).
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.
IMO, we it's good to be merged as-is. Any updates fixes can (and probably should) be done in subsequent PRs.
Hi @Maetveis, thank you for your comments and concerns. If you had any more concerns related to this I am going to continue to work on this after this pr, so I will be ready to work with you to address any other concerns in the post-commit. Also wanted to check in with @uditagarwal97 to ask if you are good to continue with these changes as well. |
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.
Changes looks reasonable to me.
… tests (#16787) As of #16725 tests that do not build for `spir64` do not need to be marked as exceptions for split build/run with `REQUIRES: build-and-run-mode`, instead we can mark them as `REQUIRES: target-<nvidia/amd>`. This patch replaces the `REQUIRES: build-and-run-mode` directives in Matrix tests with `REQUIRES: target-amd` or `REQUIRES: target-nvidia`.
…nd `Adapters` tests (#16795) As of #16725 tests can properly react to features that affect compilation on build-only mode (i.e., libraries or OS), additionally we can also mark if a test should only be built for a specific triple using the `target-*` features. This pr removes `REQUIRES: build-and-run-mode` from syclcompat and Adapters tests, and either lets the test be marked as unsupported due to requiring a missing build feature (`windows` or `cuda_dev_kit`), or the test is marked as unsupported for `spir` by requiring `target-nvidia`
Adds logic for evaluating
REQUIRES
/UNSUPPORTED
statements onbuild-only
mode by "ignoring" features in these statements that do not affect the compilation (Everything other than OS, triple, and SDK/libraries).More precisely, the ability to ignore features is implemented by extending the boolean expressions to use a third boolean state -
ignore
. If a particular sub-expression includes anignore
, and if its result could be changed by setting thatignore
to eithertrue
orfalse
, then the result of that sub-expression is set toignore
. For exampleignore || true = true
, butignore || false = ignore
, this is because in the first example there would be no way to set the ignore such that the result is anything other thantrue
, while in the second example the result is dependent on the "actual" value of theignore
.If the resulting value of a
REQUIRES
predicate isignore
we interpret that astrue
(The requirements were met), on the other hand forUNSUPPORTED
predicates we would interpretignore
asfalse
instead (The unsupported criteria was not met).The triples that can be used for a given test are then selected by evaluating the
REQUIRES
/UNSUPPORTED
with the set of features + the target feature corresponding to each triple (mirroring the way we select devices), while ignoring all features that do not affect compilation.The target features available are the following:
target-spir
,target-amd
,target-nvidia
, andtarget-native_cpu
. Each of these map to a triple.Similarly to how
XFAIL
is handled when using multiple devices if we are compiling for multiple triples, and a single triple is marked asXFAIL
, then it is treated as unsupported instead.The available target triples in
build-only
mode is determined through the use of thesycl_build_targets
lit param (i.e.,--param sycl_build_targets=spir;amd
). This is currently set to onlyspir
, as the changes in test markup included in this pr do not take into account building fornvptx
andamdgcn
triples. Inrun-only
andfull
mode the available triples are determined via the available devices.