Skip to content

Commit 29ea7a6

Browse files
authored
[SYCL][E2E][Docs] Update test-mode documentation (#16875)
Changes documentation of `build-only` mode to reflect the recent improvements in this mode.
1 parent c89165f commit 29ea7a6

File tree

1 file changed

+105
-93
lines changed

1 file changed

+105
-93
lines changed

sycl/test-e2e/README.md

Lines changed: 105 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
* [Marking tests as expected to fail](#marking-tests-as-expected-to-fail)
1313
* [Marking tests as unsupported](#marking-tests-as-unsupported)
1414
* [SYCL core header file](#sycl-core-header-file)
15+
* [Compiling and executing tests on separate systems](#compiling-and-executing-tests-on-separate-systems)
16+
* [Run only mode](#run-only-mode)
17+
* [Build only mode](#build-only-mode)
18+
* [Common Issues with separate build and run](#common-issues-with-separate-build-and-run)
1519

1620
## Overview
1721

@@ -393,109 +397,117 @@ machines. By default the `test-mode` parameter is set to `full`, indicating that
393397
both stages will run. This parameter can be set to `build-only`, or `run-only`,
394398
to only run the compilation stage, or the execution stage respectively.
395399
396-
**NOTE:** This feature is a work-in-progress and current limitations are
397-
expected to be addressed in the near future.
398-
399-
The modes work as follow:
400-
401-
* `--param test-mode=full`
402-
403-
This is the default mode tests run in. Tests are marked as unsupported if no
404-
device on the machine can fulfill the `REQUIRES`/`UNSUPPORTED` statements. In
405-
this mode all `RUN:` lines are executed normally, and two extra features are
406-
added: the `build-and-run-mode` and `run-mode`.
407-
408-
To make a test only run in `full` mode add a `REQUIRES: build-and-run-mode`
409-
line.
410-
411-
* `--param test-mode=build-only`
412-
413-
This mode can be used to compile all test binaries. To do this all
414-
`UNSUPPORTED` and `REQUIRES` statements are ignored unless they contain
415-
`UNSUPPORTED: true` or `REQUIRES: build-and-run-mode`. All `RUN:` lines within
416-
a test are ran in this mode unless they contain the following expansions:
417-
`%{run}`, `%{run-unfiltered-devices}`, or `%if run-mode`.
418-
419-
Currently, the only triple supported for `build-only` mode is `spir64`.
420-
421-
* `build-only` future work.
422-
423-
Note, the fact that `build-only` ignores general `UNSUPPORTED`/`REQUIRES`
424-
statements is a current limitation. The logic for taking into account the
425-
features that affect compilation, and ignoring those that are only relevant
426-
to the execution of the program is currently being worked on.
427-
428-
* `--param test-mode=run-only`
400+
#### Run only mode
401+
402+
Pass: `--param test-mode=run-only`
429403
430404
In this mode, tests will not be compiled, they will only run. To do this only
431-
the `RUN:` lines that contain `%{run}`, `%{run-unfiltered-devices}` or `%if
432-
run-mode` are executed. Tests are marked as unsupported in the same manner as
433-
`full` mode. Since tests are not compiled in this mode, for any test to pass
434-
the test binaries should already be in the `test_exec_root` directory, either
435-
by having ran `full` or `build-only` modes previously on the system, or having
436-
transferred the test binaries into that directory. The `run-mode` feature is
437-
added when in this mode.
438-
439-
#### Resolving common Issues with separate compilation and execution
405+
the `RUN:` lines that contain a "run" expansion will be executed (`%{run}`,
406+
`%{run-unfiltered-devices}`, or `%{run-aux}`). Since tests are not compiled in
407+
this mode, for any test to pass the test binaries should already be in the
408+
`test_exec_root` directory, either by having ran `full` or `build-only` modes
409+
previously on the system, or having transferred the test binaries into that
410+
directory. To mark a test as expected to fail at run-time the `XFAIL`
411+
expression should use runtime features, such as `run-mode` or device-specific
412+
features.
413+
414+
`%{run-aux}` is an empty expansion and executes a line as is, without
415+
expanding for each selected device and without using the `run_launcher`.
416+
417+
#### Build only mode
418+
419+
Pass: `--param test-mode=build-only`
420+
421+
This mode can be used to compile all test binaries that can be built on the
422+
system. To do this `REQUIRES`, and `UNSUPPORTED` statements are handled
423+
differently to accommodate for the fact that in `build-only` mode we do not
424+
have any devices, and as a result no device-specific features. Instead of
425+
considering these features as missing, we assign a third "unknown" value to
426+
them. When evaluating an expression it will result in an unknown value if its
427+
result could be changed by setting the unknown features to either true or
428+
false. i.e., `false || unknown = unknown` but `true || unknown = true`. If an
429+
expression's final value is unknown we consider it to have met the
430+
requirements. The list of device-agnostic features that are not considered
431+
unknown in `build-only` is found in the `E2EExpr.py`.
432+
433+
The triples to compile in this mode are set via the `sycl_build_targets` lit
434+
parameter. Valid build targets are: `spir`,`nvidia`, `amd`, `native_cpu`.
435+
These correspond to `spir64`, `nvptx64-nvidia-cuda`, `amdgcn-amd-amdhsa`, and
436+
`native_cpu` triples respectively. Each build target should be separated with
437+
a semicolon. This parameter is set to `all` by default, which enables
438+
autodetection for the available build targets. A test can be marked as
439+
requiring, or not supporting a particular triple via the `target-*` features.
440+
Build targets are selected if they are able to pass the test's requirements
441+
independent of the availability of other build targets. This is done to avoid
442+
having to deal with a boolean satisfiability problem. For example,
443+
`REQUIRES: target-spir && target-nvidia` will always be marked as unsupported
444+
since it requires multiple targets simultaneously. Instead we can use
445+
`any-target-is-*` features in this case, to check if a target is available in
446+
the current lit configuration.
447+
448+
When executing the test in `build-only`, all `RUN:` lines that do not have a
449+
run expansion will execute.
450+
451+
The `build-mode` feature is added when in this mode.
452+
453+
Some examples of `REQUIRES`/`UNSUPPORTED` in build-only:
454+
If `linux` and `zstd` are available, and `sycl_build_targets` is set to
455+
`spir;amd`
456+
* `REQUIRES: linux && zstd`: This would be supported, this is treated normally
457+
since both features are device-agnostic.
458+
* `REQUIRES: linux && sg-32`: Despite the `sg-32` feature not being available,
459+
this would be supported. Since the `sg-32` is a device-specific feature it is
460+
evaluated as unknown in this expression.
461+
* `REQUIRES: windows && sg-32`: This would be unsupported. `sg-32` would be
462+
evaluated as unknown, and `windows` would evaluate as false. The fact that we
463+
have an unknown value does not affect the end result, since the result of an
464+
`&&` expression where one sub-expression is false is always false.
465+
* `REQUIRES: windows || sg-32`: this would be supported. Here because the
466+
result of the `||` expression would change if we considered `sg-32` to be
467+
either true or false the overall expression evaluates to unknown.
468+
* `UNSUPPORTED: !sg-32`: this would be supported. `sg-32` is evaluated as
469+
unknown, and the negation of unknown is also unknown.
470+
* `REQUIRES: target-spir`: This will be supported, and only the `spir64`
471+
triple will be selected.
472+
* `REQUIRES: target-spir && target-amd`: This will not be supported. When
473+
checking if `target-spir` should be selected, `target-amd` will not be an
474+
available feature, and vice versa when checking `target-amd`.
475+
* `REQUIRES: target-spir && any-target-is-amd`: This will be supported, but
476+
only the `spir64` triple will be selected.
477+
478+
#### Common Issues with separate build and run
440479
441480
A number of extra considerations need to be taken to write tests that are able
442481
to be compiled and executed on separate machines.
443482
444483
* Tests that build and execute multiple binaries need to be written such that
445484
the output of each compilation has a different name. This way no files are
446485
overwritten, and all the necessary binaries can be transferred to the running
447-
system.
486+
system. For example, instead of setting the output of all compilation steps to
487+
a file named `%t.out`, we can number them `%t1.out`, `%t2.out`, and so on.
448488
449489
* Two scenarios need to be considered for tests that expectedly fail:
450490
* Tests that are expected to fail on compilation, and thus also during
451-
execution, need to be marked as `XFAIL` with a feature that is device
452-
agnostic, or with `XFAIL: *`. Device agnostic features are those which are
453-
added added through a method other than processing the output of sycl-ls, for
454-
example the OS, or the presence of a library. This needs to be done because
455-
sycl-ls is not ran in `build-only` mode.
491+
execution, need to be marked as `XFAIL` for a device-agnostic feature, or
492+
with `XFAIL: *`. This is due to the fact that there are no devices in
493+
`build-only` mode. For example if a test cannot compile for a triple, then it
494+
should be marked as `XFAIL` for the corresponding build target feature, rather
495+
than a backend feature.
456496
* If the expected failure occurs during run-time we will need to mark the test
457-
with `XFAIL` on a device specific feature (A feature that we add through
458-
processing sycl-ls output), or if its expected to always fail on run-time we
459-
can use `XFAIL: run-mode`. This is because otherwise the test would compile
460-
and pass on `build-only` mode and be reported as an `XPASS`.
461-
462-
* To separate compilation and execution of tests, we classify `RUN:` directives
463-
as being either build or run lines. If a line contains `%{run}`,
464-
`%{run-unfiltered-devices}` or `%if run-mode` it is classified as a run line,
465-
otherwise it is classified as a build line.
466-
* All `RUN:` lines that execute test binaries should be marked with either
467-
`%{run}` or `%{run-unfiltered-devices}`. Otherwise they will be incorrectly
468-
marked as a build line, likely causing a failure at the `build-only` stage as
469-
we try to execute the program without having the appropriate devices.
470-
* The vast majority of `RUN:` lines that do not execute the test binaries are
471-
needed to either set up files prior to compilation, or to compile the binary,
472-
as such `RUN:` lines are by default considered as build lines. In the case
473-
that we need to run a line on the `run-only` system, and it does not make
474-
sense to mark them with `%{run}` or `%{run-unfiltered-devices}`, we can mark a
475-
line with `%if run-mode` to specifically make the line a run line. This
476-
situation usually appears when we need to run a command in response to the
477-
execution of the test binary.
478-
479-
* Currently the `build-only` mode does not support logic to properly assess the
480-
features in `REQUIRES`/`UNSUPPORTED` to know if a test can be built in the
481-
system environment, or for `spir64`. Only tests that are marked with `REQUIRES:
482-
build-and-run-mode` or `UNSUPPORTED: true` are skipped. Thus if a test will fail
483-
building for the build environment we have on CI or for `spir64` we will need to
484-
mark this as `REQUIRES: build-and-run-mode`. This is only temporary solution,
485-
until further work is done to properly mark tests as unsupported on `build-only`
486-
based on features.
487-
488-
* CPU and FPGA AOT tests are currently expected to fail when compiling and
489-
executing on separate machines. These failures occur on the `run-only` side,
490-
because during compilation the host machine's CPU architecture is targeted,
491-
which may be different than that of the running machine. These tests are marked
492-
as `REQUIRES: build-and-run-mode` as a result, until they can be refactored to
493-
compile for the architectures that will be used on the run side.
494-
495-
#### Falling back to `full` testing mode on `run-only`
496-
497-
To not lose coverage of tests marked as `REQUIRES: build-and-run-mode` when
498-
using `run-only` mode, lit can be called using
499-
`--param fallback-to-build-if-requires-build-and-run=True`. When this option is
500-
enabled in `run-only` mode, tests marked as requiring `build-and-run-mode` will
501-
fallback to running on `full` mode, instead of being reported as unsupported.
497+
with `XFAIL` with an expression dependent on runtime features. If it is
498+
expected to fail for any device at run-time we can use `XFAIL: run-mode`,
499+
This must be done because otherwise the test would compile and pass on
500+
`build-only` mode and be reported as an `XPASS`.
501+
502+
* To separate compilation and execution of tests, `RUN:` lines are filtered in
503+
`build-only` and `run-only` mode based on the presence of "run" expansions.
504+
* Any line that is meant to execute the test binary should be marked with
505+
`%{run}` or `%{run-unfiltered-devices}` so that it is not ran in `build-only`,
506+
and the `run_launcher` substitution is properly employed.
507+
* The `%{run-aux}` expansion can be used if a `RUN:` line that does not
508+
execute a test binary needs to be ran in `run-only`.
509+
510+
* CPU AOT compilation will target the ISA of the host CPU, thus compiling
511+
these tests on a different system will lead to failures if the build system and
512+
run system support different ISAs. To accommodate this, these compilations
513+
should be delayed to the "run" stage by using the `%{run-aux}` markup.

0 commit comments

Comments
 (0)