Skip to content

Commit 39368b9

Browse files
committed
Add source code and build / env documentation
1 parent 99dbe95 commit 39368b9

File tree

6 files changed

+115
-7
lines changed

6 files changed

+115
-7
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
.cache/
22
.vscode/
33
/build*
4-
/compile_commands.json
4+
/compile_commands.json
5+
/hdoc-output

README.md

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
<p align="center">
2-
<img src="resources/logo.png" alt="SimSYCL">
2+
<img src="resources/logo.svg" width="500px" alt="SimSYCL">
3+
<br/>
34
<i>“Technically correct is the best kind of correct”</i><br/>&nbsp;
45
</p>
56

6-
# What and why is this?
7-
87
SimSYCL is a single-threaded, synchronous, library-only implementation of the SYCL 2020 specification. It enables you to test your SYCL applications against simulated hardware of different characteristics and discover bugs with its extensive verification capabilities.
98

109
SimSYCL is in a very early stage of development - try it at your own risk!
1110

1211
## Requirements
1312

14-
SimSYCL requires the Boost `context` libary.
13+
SimSYCL requires CMake, a C++20 compiler and the Boost `context` libary to be installed.
1514

1615
## Supported Platforms
1716

@@ -25,6 +24,55 @@ The following platform and compiler combinations are currently tested in CI:
2524
Other platforms and compilers should also work, as long as they have sufficient C++20 support.
2625
Note that Clang versions prior to 17 do not currently work due to their incomplete CTAD support.
2726

27+
## Installing SimSYCL
28+
29+
To build SimSYCL and install it next to the source directory, run e.g.:
30+
31+
```sh
32+
cmake -B build -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$(pwd)-install
33+
cmake --build build --target install
34+
```
35+
36+
### Build Options
37+
38+
These can be set on the CMake command line via `-DOPTION=VALUE`.
39+
40+
| option | values | effect |
41+
|---|---|---|
42+
| `SIMSYCL_ANNOTATE_SYCL_DEPRECATIONS` | `OFF`,`ON` | Mark deprecated SYCL APIs with `[[deprecated]]` (default `ON`) |
43+
| `SIMSYCL_ENABLE_ASAN`| `OFF`,`ON` | Build SimSYCL and the user code with AddressSanitizer (default `OFF`) |
44+
| `SIMSYCL_CHECK_MODE` | `SIMSYCL_CHECK_{NONE,LOG,THROW,ABORT}` | How to report verification errors (default `ABORT`) |
45+
46+
## Using SimSYCL
47+
48+
To get started, simply copy the `examples` folder to a separate location and edit its files as you see fit. To build against SimSYCL installed as above:
49+
50+
```sh
51+
cmake -B build -DCMAKE_BUILD_TYPE=Debug -DCMAKE_PREFIX_PATH=/path/where/you/installed/SimSYCL
52+
cmake --build build
53+
```
54+
55+
### Environment Variables
56+
57+
These are available to all SimSYCL applications.
58+
59+
| variable | values | effect |
60+
|---|---|---|
61+
| `SIMSYCL_SYSTEM` | `system.json` | Simulate the system defined in `system.json` |
62+
| `SIMSYCL_SCHEDULE` | `rr`, `shuffle`, `shuffle:<seed>` | Choose a schedule for work item order in kernels |
63+
64+
### System Definition Files
65+
66+
Systems are defined by listing all devices, platforms and their runtime properties in a JSON file.
67+
As a starting point, you can export the built-in system definition via
68+
```c++
69+
simsycl::write_system_config("system.json", simsycl::builtin_system);
70+
```
71+
and then use your (modified) system definition via
72+
```sh
73+
SIMSYCL_SYSTEM=system.json build/matmul
74+
```
75+
2876
## Research
2977

3078
For a detailed introduction and evaluation of SimSYCL, please refer to the [the IWOCL'24 paper](https://dl.acm.org/doi/pdf/10.1145/3648115.3648136).

include/simsycl/detail/lock.hh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77

88
namespace simsycl::detail {
99

10+
/// SimSYCL can be used from multiple threads simultaneously, but will serialize all actual SYCL work as well as access
11+
/// to structures with reference semantics using the (singleton) system lock. It is safe to lock recursively from within
12+
/// a single thread.
1013
class system_lock {
1114
public:
1215
system_lock();
@@ -18,6 +21,8 @@ class system_lock {
1821
std::lock_guard<std::recursive_mutex> m_lock;
1922
};
2023

24+
/// Mutable state that is potentially shared between threads should be wrapped in a `shared_value` to ensure it can only
25+
/// be accessed when a `system_lock` is in scope.
2126
template<typename T>
2227
class shared_value {
2328
public:

include/simsycl/schedule.hh

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77

88
namespace simsycl {
99

10+
/// A schedule generates execution orders for work items within the constraints of group synchronization.
11+
///
12+
/// The kernel function is invoked once for each work item as prescribed by the schedule. For ND-range kernels, they can
13+
/// be suspended and resumed multiple times around group collective functions, in which case the schedule can instruct a
14+
/// different order for each iteration.
1015
class cooperative_schedule {
1116
public:
1217
using state = uint64_t;
@@ -18,16 +23,29 @@ class cooperative_schedule {
1823
cooperative_schedule &operator=(cooperative_schedule &&) = delete;
1924
virtual ~cooperative_schedule() = default;
2025

26+
/// Fill a vector of linear work item indices for the initial round of kernel invocations.
27+
///
28+
/// The retured `state` is to be carried into the first invocation of `update()`, if any.
2129
[[nodiscard]] virtual state init(std::vector<size_t> &order) const = 0;
30+
31+
/// After work items have been suspended on an ND-range kernel collective function, fill the index vector with the
32+
/// next sequence of work item indices.
33+
///
34+
/// The retured `state` is to be carried into the next invocation of `update()`.
2235
[[nodiscard]] virtual state update(state state_before, std::vector<size_t> &order) const = 0;
2336
};
2437

38+
/// A schedule executing threads in-order by linear thread id.
2539
class round_robin_schedule final : public cooperative_schedule {
2640
public:
2741
[[nodiscard]] state init(std::vector<size_t> &order) const override;
2842
[[nodiscard]] state update(state state_before, std::vector<size_t> &order) const override;
2943
};
3044

45+
/// A schedule executing threads in randomly shuffled order. After each collective barrier, indices are re-shuffled.
46+
///
47+
/// SYCL programs need to ensure their kernels are correct under any order of thread items, so using a
48+
/// `shuffle_schedule` (potentially with multiple seeds) allows fuzzing that assumption.
3149
class shuffle_schedule final : public cooperative_schedule {
3250
public:
3351
shuffle_schedule() = default;
@@ -40,8 +58,12 @@ class shuffle_schedule final : public cooperative_schedule {
4058
uint64_t m_seed = 1234567890;
4159
};
4260

43-
// effect is thread-local
61+
/// Return the thread-locally active schedule.
4462
const cooperative_schedule &get_cooperative_schedule();
63+
64+
/// Set the thread-locally active schedule for future kernel invocations.
65+
///
66+
/// Must not be called from within a kernel.
4567
void set_cooperative_schedule(std::shared_ptr<const cooperative_schedule> schedule);
4668

4769
} // namespace simsycl

include/simsycl/system.hh

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,15 @@ namespace simsycl {
1212

1313
class cooperative_schedule;
1414

15+
/// Identifier for `sycl::platform`s within a `system_config`.
1516
using platform_id = std::string;
17+
18+
/// Identifier for `sycl::device`s within a `system_config`.
1619
using device_id = std::string;
17-
using system_id = std::string;
1820

21+
/// Configuration for a single `sycl::device`.
22+
///
23+
/// All data members will be reflected in the `sycl::info::device` properties of the created device.
1924
struct device_config {
2025
sycl::info::device_type device_type{};
2126
uint32_t vendor_id{};
@@ -97,6 +102,9 @@ struct device_config {
97102
sycl::info::partition_affinity_domain partition_type_affinity_domain{};
98103
};
99104

105+
/// Configuration for a single `sycl::platform`.
106+
///
107+
/// All data members will be reflected in the `sycl::info::platform` properties of the created platform.
100108
struct platform_config {
101109
std::string profile{};
102110
std::string version{};
@@ -105,20 +113,44 @@ struct platform_config {
105113
std::vector<std::string> extensions{};
106114
};
107115

116+
/// Configuration for the entire system simulated by SimSYCL.
108117
struct system_config {
118+
/// All platforms returned by `sycl::platform::get_platforms()`, in order.
119+
///
120+
/// The `platform_id` is only relevant as a reference within this struct.
109121
std::unordered_map<platform_id, platform_config> platforms{};
122+
123+
/// All devices returned by `sycl::device::get_devices()`, in order.
124+
///
125+
/// The `device_id` is only relevant as a reference within this struct.
110126
std::unordered_map<device_id, device_config> devices{};
111127
};
112128

129+
/// Configuration of the builtin platform as returned through `sycl::platform::get_platforms()` by default.
113130
extern const platform_config builtin_platform;
131+
132+
/// Configuration of the builtin device as returned through `sycl::device::get_devices()` by default.
114133
extern const device_config builtin_device;
134+
135+
/// Default system configuration when not overriden by the environment.
115136
extern const system_config builtin_system;
116137

138+
/// Return the system configuration specified by the environment via `SIMSYCL_SYSTEM=system.json`, or `builtin_system`
139+
/// as a fallback.
117140
const system_config &get_default_system_config();
141+
142+
/// Read a `system_config` from a JSON file.
118143
system_config read_system_config(const std::string &path_to_json_file);
144+
145+
/// Write a `system_config` to a JSON file.
119146
void write_system_config(const std::string &path_to_json_file, const system_config &config);
147+
148+
/// Replace the active `system_config` so that all future calls to device and platform selection functions return
149+
/// members of this configuration.
120150
void configure_system(const system_config &system);
121151

152+
/// Return the schedule for threads of a kernel specified by the environment via `SIMSYCL_SCHEDULE`, or a
153+
/// `round_robin_schedule` as a fallback.
122154
std::shared_ptr<const cooperative_schedule> get_default_cooperative_schedule();
123155

124156
} // namespace simsycl

resources/logo.png

-185 KB
Binary file not shown.

0 commit comments

Comments
 (0)