|
| 1 | +# Test plan for [`sycl_ext_oneapi_work_group_memory`][spec-link] extension |
| 2 | + |
| 3 | +## Testing scope |
| 4 | + |
| 5 | +### Device coverage |
| 6 | + |
| 7 | +Functionality provided by the extension is not guarded by any aspects and |
| 8 | +should be supported on every device supported by an implementation. |
| 9 | + |
| 10 | +Therefore, those tests should be launched on every supported device |
| 11 | +configuration that we have. |
| 12 | + |
| 13 | +### Type coverage |
| 14 | + |
| 15 | +New APIs for allocating local memory described by the extension take data type |
| 16 | +as a template argument and therefore tests should be repeated for different |
| 17 | +data types to ensure that everything works correctly. |
| 18 | + |
| 19 | +List of data types which should be covered: |
| 20 | +- some basic C++ data types of different sizes: `char`, `int16_t`, `int`, |
| 21 | + `double` |
| 22 | +- `half` |
| 23 | +- pointers |
| 24 | +- user-defined types such as `struct`, `union` |
| 25 | +- SYCL-provided data types such as `vec`, `marray` |
| 26 | +- arrays (both bounded and unbounded) of the types listed above |
| 27 | + |
| 28 | +**TODO**: the spec doesn't seem to disallow references and cv-qualified types to |
| 29 | +be used with `work_group_memory` which is likely a bug in the spec. |
| 30 | + |
| 31 | +**TODO**: it would not be possible or reasonable to repeat absolutely every test |
| 32 | +with every data type. Should the specification of which tests should be repeated |
| 33 | +for which data types be a part of the test plan, or should it be an |
| 34 | +implementation detail of the said test plan? |
| 35 | + |
| 36 | +## Tests |
| 37 | + |
| 38 | +### Unit tests |
| 39 | + |
| 40 | +#### Interface tests |
| 41 | + |
| 42 | +These tests are intended to check that all classes and methods defined by the |
| 43 | +extension have correct implementation, i.e.: right signatures, right return |
| 44 | +types, all necessary constraints are checked/enforced, etc. |
| 45 | + |
| 46 | +Those tests are expected to be compile-only tests which doesn't require |
| 47 | +execution of compiled code. |
| 48 | + |
| 49 | +Things which we need to check here: |
| 50 | + |
| 51 | +- that diagnostic is emitted if `PropertyListT` argument is set to anything |
| 52 | + else than `empty_properties_t` |
| 53 | +- that `value_type` type alias is properly defined |
| 54 | +- that `work_group_memory` is default-constructible, copy-constructible and |
| 55 | + copy-assignable |
| 56 | +- that constructors accepting `handler` are also properly defined by the |
| 57 | + implementation, including type restrictions they have |
| 58 | +- that conversion operators are properly defined |
| 59 | +- that `operator=(const DataT&)` is properly defined, including its type |
| 60 | + restrictions |
| 61 | +- that `get_multi_ptr` is properly defined and its `IsDecorated` template |
| 62 | + argument is handled correctly |
| 63 | +- that methods documented as `const` are indeed defined in the implementation |
| 64 | + as `const` |
| 65 | + |
| 66 | +Tests in this category may not perform some useful actions to exercise the |
| 67 | +extension functionality in full, but instead they are focused on making sure |
| 68 | +that all APIs are consistent with respect to other APIs. |
| 69 | + |
| 70 | +#### Runtime diagnostics on misuse |
| 71 | + |
| 72 | +`work_group_memory` objects can only be used in `parallel_for(nd_range)` |
| 73 | +kernels, so the test should ensure that we throw a synchronious `exception` |
| 74 | +with the `errc::kernel_argument` error code if `work_group_memory` was used by |
| 75 | +other types of kernels (`single_task` and `parallel_for(range)`). |
| 76 | + |
| 77 | +#### Consistency of address-taking operations |
| 78 | + |
| 79 | +The test need to check that `operator&()` and `get_multi_ptr().get_raw()` both |
| 80 | +return the same address. |
| 81 | + |
| 82 | +#### Copy constructors and assignment operator |
| 83 | + |
| 84 | +The test need to check that `operator&()` and `get_multi_ptr().get_raw()` both |
| 85 | +return correct address after `work_group_memory` was copy-constructed, or |
| 86 | +copy-assigned from another `work_group_memory` object. |
| 87 | + |
| 88 | +#### Operations on different types |
| 89 | + |
| 90 | +This test should check that an object of `work_group_memory` class behaves like |
| 91 | +an object of a type `work_group_memory` is templated on, i.e. all operations |
| 92 | +possible on an underlying type can also be performed on `work_group_memory` |
| 93 | +object and produce correct results. |
| 94 | + |
| 95 | +#### Number of kernel arguments produced by `work_group_memory` objects |
| 96 | + |
| 97 | +One of the main reasons behind the extension is to provide a lightweight |
| 98 | +alternative to `local_accessor`. To make sure that the implementation is indeed |
| 99 | +lightweight, there should be a test which ensures that every `work_group_memory` |
| 100 | +object results in a single kernel argument generated by the compiler. |
| 101 | + |
| 102 | +### End-to-end tests |
| 103 | + |
| 104 | +Tests in this category perform some meaningful actions with the extension to |
| 105 | +see that the extension works in a scenarios which mimic real-life usage of the |
| 106 | +extension. |
| 107 | + |
| 108 | +#### Basic usage |
| 109 | + |
| 110 | +This test is intended to check that memory provided through `work_group_memory` |
| 111 | +is indeed shared between work-items within a work-group and can be properly |
| 112 | +accessed for reading-writing to it. |
| 113 | + |
| 114 | +A test should allocate an array of integers through `work_group_memory` and |
| 115 | +submit a single (for simplicity) work-group where every work-item would store |
| 116 | +an element from a global buffer into that allocated local array which |
| 117 | +corresponds to its local id. |
| 118 | + |
| 119 | +Then, a single work-item should perform a reduction of that local array, i.e. |
| 120 | +compute sum of its elements. The result should be communicated back to host and |
| 121 | +verified there. |
| 122 | + |
| 123 | +Some of the operations performed on `work_group_memory` object should be done in |
| 124 | +a separate helper function to check that we can pass `work_group_memory` objects |
| 125 | +to functions and correctcly access data they reference there. |
| 126 | + |
| 127 | +#### Use of multiple `work_group_memory` objects |
| 128 | + |
| 129 | +This test is similar to the one above, but a kernel should operate on more than |
| 130 | +one `work_group_memory` object. For example, the second `work_group_memory` |
| 131 | +object could be used to broadcast reduction value to all work-items in a |
| 132 | +work-group. |
| 133 | + |
| 134 | +#### Use of `work_group_memory` with `atomic_ref` |
| 135 | + |
| 136 | +The test should check that `work_group_memory` objects could be used together |
| 137 | +with `atomic_ref`: a scalar `work_group_memory` object could be used to |
| 138 | +construct an `atomic_ref` object and the latter should be used to perform a |
| 139 | +reduction (compute a sum, for exmple) of values in a global buffer. |
| 140 | + |
| 141 | +#### Use of `work_group_memory` with free function kernel |
| 142 | + |
| 143 | +One of important use cases which we anticipate is usage of `work_group_memory` |
| 144 | +in kernels defined as free functions. |
| 145 | + |
| 146 | +Basic usage test should be repeated with kernels defined as free functions. |
| 147 | + |
| 148 | +[spec-link]: https://github.com/intel/llvm/blob/sycl/sycl/doc/extensions/proposed/sycl_ext_oneapi_work_group_memory.asciidoc |
0 commit comments