Skip to content
This repository was archived by the owner on Dec 8, 2025. It is now read-only.

Commit e25b097

Browse files
Google Summer of Code 2021 Report - Mostafa Ashraf (#1157)
1 parent 0a46a4b commit e25b097

1 file changed

Lines changed: 292 additions & 0 deletions

File tree

Lines changed: 292 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,292 @@
1+
# Google Summer of Code 2021 Report - Mostafa Ashraf
2+
3+
###### Personal Links:
4+
###### [Github](https://github.com/Mostafa-ashraf19) - [Linkedin](https://www.linkedin.com/in/mostafa-ashraf-a62807142/)
5+
6+
###### Proposal:
7+
###### [Improving support for compute shaders in spirv-fuzz](https://summerofcode.withgoogle.com/projects/#6354411477008384)
8+
9+
###### Mentors:
10+
###### [Alastair Donaldson](https://github.com/afd), [Paul Thomson](https://github.com/paulthomson), [Vasyl Teliman](https://github.com/Vasniktel)
11+
12+
## Abstract
13+
14+
During the *Google Summer of Code 2021* program, I worked on the development of new *semantics-preserving transformations*, fuzzer passes and enhancements for the [*spirv-fuzz*](https://github.com/KhronosGroup/SPIRV-Tools) tool.
15+
Also, wrote some shaders in [shadertrap](https://github.com/google/shadertrap) and improve coverage of spirv-fuzz test suite in case of transformation code is not fully covered.
16+
17+
## Introduction
18+
Graphics drivers are the software components that allow operating systems and programs to use computer graphics hardware and communicate. The problem is there are cases when drivers do not work well due to driver bugs. These can lead to graphical glitches and application crashes. These bugs lead to a bad user experience and can be security-critical.
19+
20+
So our target is to eliminate or decrease these errors. How do this? Using testing, but when we think testing ideas is hard we need some things like the output we expected to compare with current output before rendering to help with this challenge, the [spirv-fuzz](https://github.com/KhronosGroup/SPIRV-Tools) tool employs a concept called metamorphic testing.
21+
22+
The metamorphic concept trying to make programs equivalent to the original program and moving them through the same operations on the original program then compares the output to check it passes or fails depends they have the same output or not.
23+
24+
In a `Spirv-fuzz` it works directly on the SPIR-V binary module and it automatically finds bugs in Vulkan drivers. Specifically the SPIR-V shader compiler component of the driver. The result is an input that when it runs on the Vulkan driver causes the driver to crash or more generally, "do the wrong thing"; e.g. render an incorrect image.
25+
26+
A `Spirv-fuzz` has limited support for compute shaders, it important because feature concurrent computation with multiple workgroups, the use of atomic operations to modify shared memory, barrier operations to synchronize threads, and operations to synchronize memory.
27+
28+
The metamorphic testing approach used by spirv-fuzz involves applying a series of semantics-preserving transformations to the shader to make it very different from the shader compiler's perspective, but to preserve the result that it produces. This means that bugs can be found by comparing the image rendered by an original shader and a transformed variant of that shader. And adding new transformations to `Spir-fuzz` tool to improve their support for compute shaders because the tool have limited support for compute shaders.
29+
30+
My objective is adding tranformations and fuzzer passes for atomic and barrier instructions, improve the implementation of the tooling and find bugs in existing graphics drivers.
31+
32+
### Improvements
33+
34+
- [#4295](https://github.com/KhronosGroup/SPIRV-Tools/pull/4295): Enhancing permute function variables and it's testing.
35+
- [#4289](https://github.com/KhronosGroup/SPIRV-Tools/pull/4289): Enhance test to improve lines covered in TransformationAddConstantScalar
36+
- [#4312](https://github.com/KhronosGroup/SPIRV-Tools/pull/4312): Improve TransformationAddBitInstructionSynonym to check integer signedness
37+
- [#4306](https://github.com/KhronosGroup/SPIRV-Tools/pull/4306): Achieve coverage of TransformationAddDeadBlock test
38+
- [#4349](https://github.com/KhronosGroup/SPIRV-Tools/pull/4349): Don't allow to use of non-constant operands in atomic operations
39+
- [#4348](https://github.com/KhronosGroup/SPIRV-Tools/pull/4348): Support atomic operations opcode and checks it's in operands signedness neutrality
40+
- [#4330](https://github.com/KhronosGroup/SPIRV-Tools/pull/4330): Support AtomicLoad
41+
- [#4440](https://github.com/KhronosGroup/SPIRV-Tools/pull/4440): Support AtomicStore
42+
43+
### Transformations and Fuzzer Passes
44+
- [#4248](https://github.com/KhronosGroup/SPIRV-Tools/pull/4248): Permute the order of variables at function scope
45+
- [#4455](https://github.com/KhronosGroup/SPIRV-Tools/pull/4455): Transformation and fuzzer pass for changing memory semantics
46+
- [#4483](https://github.com/KhronosGroup/SPIRV-Tools/pull/4483): Transformation and fuzzer pass for changing memory scope
47+
48+
- WIP transformations and fuzzer passes
49+
- [#4470](https://github.com/KhronosGroup/SPIRV-Tools/pull/4470): Transformation and fuzzer pass for adding atomic RMW instruction
50+
51+
- WIP issues
52+
- [#4484](https://github.com/KhronosGroup/SPIRV-Tools/issues/4484): Adding memory barrier instructions
53+
- [#4485](https://github.com/KhronosGroup/SPIRV-Tools/issues/4485): Adding control barrier instructions
54+
55+
The following are examples of SPIR-V code to demonstrate some transformations I proposed.
56+
- **Transformation and fuzzer pass for changing memory semantics:** its changes memory semantics for atomic or barrier instruction to stronger order
57+
<table>
58+
<tr>
59+
<th>
60+
Reference shader
61+
</th>
62+
<th>
63+
Variant shader
64+
</th>
65+
</tr>
66+
<tr>
67+
<td>
68+
<pre>
69+
<code>
70+
OpCapability Shader
71+
OpCapability Int8
72+
%1 = OpExtInstImport "GLSL.std.450"
73+
OpMemoryModel Logical GLSL450
74+
OpEntryPoint Fragment %4 "main"
75+
OpExecutionMode %4 OriginUpperLeft
76+
OpSource ESSL 320
77+
%2 = OpTypeVoid
78+
%3 = OpTypeFunction %2
79+
%6 = OpTypeInt 32 1
80+
%7 = OpTypeInt 8 1
81+
%9 = OpTypeInt 32 0
82+
%8 = OpTypeStruct %6
83+
%10 = OpTypePointer StorageBuffer %8
84+
%11 = OpVariable %10 StorageBuffer
85+
%18 = OpConstant %9 1
86+
%12 = OpConstant %6 0
87+
%13 = OpTypePointer StorageBuffer %6
88+
%15 = OpConstant %6 4
89+
%16 = OpConstant %6 7
90+
%17 = OpConstant %7 4
91+
%250 = OpConstant %6 66 ; Acquire | UniformMemory
92+
%26 = OpConstant %6 258 ; Acquire | WorkgroupMemory
93+
%27 = OpConstant %6 68 ; Release | UniformMemory
94+
%28 = OpConstant %6 80 ; SequentiallyConsistent | UniformMemory
95+
%29 = OpConstant %6 64 ; None | UniformMemory
96+
%30 = OpConstant %6 256 ; None | WorkgroupMemory
97+
%31 = OpConstant %6 72 ; AcquireRelease | UniformMemory
98+
%4 = OpFunction %2 None %3
99+
%5 = OpLabel
100+
%14 = OpAccessChain %13 %11 %12
101+
<strong>
102+
%21 = OpAtomicLoad %6 %14 %15 %250
103+
%22 = OpAtomicLoad %6 %14 %15 %29
104+
</strong>
105+
%23 = OpAtomicLoad %6 %14 %15 %27
106+
<strong>
107+
%32 = OpAtomicExchange %6 %14 %15 %31 %16
108+
%33 = OpAtomicCompareExchange %6 %14 %15 %28 %29 %16 %15
109+
</strong>
110+
%24 = OpAccessChain %13 %11 %12
111+
<strong>OpAtomicStore %14 %15 %27 %16</strong>
112+
OpReturn
113+
OpFunctionEnd
114+
</code>
115+
</pre>
116+
</td>
117+
<td>
118+
<pre>
119+
<code>
120+
OpCapability Shader
121+
OpCapability Int8
122+
%1 = OpExtInstImport "GLSL.std.450"
123+
OpMemoryModel Logical GLSL450
124+
OpEntryPoint Fragment %4 "main"
125+
OpExecutionMode %4 OriginUpperLeft
126+
OpSource ESSL 320
127+
%2 = OpTypeVoid
128+
%3 = OpTypeFunction %2
129+
%6 = OpTypeInt 32 1
130+
%7 = OpTypeInt 8 1
131+
%9 = OpTypeInt 32 0
132+
%8 = OpTypeStruct %6
133+
%10 = OpTypePointer StorageBuffer %8
134+
%11 = OpVariable %10 StorageBuffer
135+
%18 = OpConstant %9 1
136+
%12 = OpConstant %6 0
137+
%13 = OpTypePointer StorageBuffer %6
138+
%15 = OpConstant %6 4
139+
%16 = OpConstant %6 7
140+
%17 = OpConstant %7 4
141+
%250 = OpConstant %6 66 ; Acquire | UniformMemory
142+
%26 = OpConstant %6 258 ; Acquire | WorkgroupMemory
143+
%27 = OpConstant %6 68 ; Release | UniformMemory
144+
%28 = OpConstant %6 80 ; SequentiallyConsistent | UniformMemory
145+
%29 = OpConstant %6 64 ; None | UniformMemory
146+
%30 = OpConstant %6 256 ; None | WorkgroupMemory
147+
%31 = OpConstant %6 72 ; AcquireRelease | UniformMemory
148+
%4 = OpFunction %2 None %3
149+
%5 = OpLabel
150+
%14 = OpAccessChain %13 %11 %12
151+
<strong>
152+
%21 = OpAtomicLoad %6 %14 %15 %28
153+
%22 = OpAtomicLoad %6 %14 %15 %250</strong>
154+
%23 = OpAtomicLoad %6 %14 %15 %27
155+
<strong>
156+
%32 = OpAtomicExchange %6 %14 %15 %28 %16
157+
%33 = OpAtomicCompareExchange %6 %14 %15 %28 %28 %16 %15</strong>
158+
%24 = OpAccessChain %13 %11 %12
159+
<strong>
160+
OpAtomicStore %14 %15 %28 %16</strong>
161+
OpReturn
162+
OpFunctionEnd
163+
</code>
164+
</pre>
165+
</td>
166+
</tr>
167+
</table>
168+
169+
- **Support AtomicLoad:** Improve transformation(and fuzzer pass)load to support adding `OpAtomicLoad`
170+
171+
<table>
172+
<tr>
173+
<th>
174+
Reference shader
175+
</th>
176+
<th>
177+
Variant shader
178+
</th>
179+
</tr>
180+
<tr>
181+
<td>
182+
<pre>
183+
<code>
184+
OpCapability Shader
185+
OpCapability Int8
186+
%1 = OpExtInstImport "GLSL.std.450"
187+
OpMemoryModel Logical GLSL450
188+
OpEntryPoint Fragment %4 "main"
189+
OpExecutionMode %4 OriginUpperLeft
190+
OpSource ESSL 310
191+
%2 = OpTypeVoid
192+
%3 = OpTypeFunction %2
193+
%6 = OpTypeInt 32 1
194+
%26 = OpTypeFloat 32
195+
%27 = OpTypeInt 8 1
196+
%7 = OpTypeInt 32 0 ; 0 means unsigned
197+
%8 = OpConstant %7 0
198+
%17 = OpConstant %27 4
199+
%19 = OpConstant %26 0
200+
%9 = OpTypePointer Function %6
201+
%13 = OpTypeStruct %6
202+
%12 = OpTypePointer Workgroup %13
203+
%11 = OpVariable %12 Workgroup
204+
%14 = OpConstant %6 0
205+
%15 = OpTypePointer Function %6
206+
%51 = OpTypePointer Private %6
207+
%21 = OpConstant %6 4
208+
%23 = OpConstant %6 256
209+
%25 = OpTypePointer Function %7
210+
%50 = OpTypePointer Workgroup %6
211+
%34 = OpTypeBool
212+
%35 = OpConstantFalse %34
213+
%53 = OpVariable %51 Private
214+
%4 = OpFunction %2 None %3
215+
%5 = OpLabel
216+
OpSelectionMerge %37 None
217+
OpBranchConditional %35 %36 %37
218+
%36 = OpLabel
219+
%38 = OpAccessChain %50 %11 %14
220+
%40 = OpAccessChain %50 %11 %14
221+
OpBranch %37
222+
%37 = OpLabel
223+
OpReturn
224+
OpFunctionEnd
225+
</code>
226+
</pre>
227+
</td>
228+
<td>
229+
<pre>
230+
<code>
231+
OpCapability Shader
232+
OpCapability Int8
233+
%1 = OpExtInstImport "GLSL.std.450"
234+
OpMemoryModel Logical GLSL450
235+
OpEntryPoint Fragment %4 "main"
236+
OpExecutionMode %4 OriginUpperLeft
237+
OpSource ESSL 310
238+
%2 = OpTypeVoid
239+
%3 = OpTypeFunction %2
240+
%6 = OpTypeInt 32 1
241+
%26 = OpTypeFloat 32
242+
%27 = OpTypeInt 8 1
243+
%7 = OpTypeInt 32 0 ; 0 means unsigned
244+
%8 = OpConstant %7 0
245+
%17 = OpConstant %27 4
246+
%19 = OpConstant %26 0
247+
%9 = OpTypePointer Function %6
248+
%13 = OpTypeStruct %6
249+
%12 = OpTypePointer Workgroup %13
250+
%11 = OpVariable %12 Workgroup
251+
%14 = OpConstant %6 0
252+
%15 = OpTypePointer Function %6
253+
%51 = OpTypePointer Private %6
254+
%21 = OpConstant %6 4
255+
%23 = OpConstant %6 256
256+
%25 = OpTypePointer Function %7
257+
%50 = OpTypePointer Workgroup %6
258+
%34 = OpTypeBool
259+
%35 = OpConstantFalse %34
260+
%53 = OpVariable %51 Private
261+
%4 = OpFunction %2 None %3
262+
%5 = OpLabel
263+
OpSelectionMerge %37 None
264+
OpBranchConditional %35 %36 %37
265+
%36 = OpLabel
266+
%38 = OpAccessChain %50 %11 %14
267+
<strong>
268+
%60 = OpAtomicLoad %6 %38 %21 %23
269+
</strong>
270+
%40 = OpAccessChain %50 %11 %14
271+
OpBranch %37
272+
%37 = OpLabel
273+
OpReturn
274+
OpFunctionEnd
275+
</code>
276+
</pre>
277+
</td>
278+
</tr>
279+
</table>
280+
281+
282+
### Shadertrap Contributions
283+
- [#68](https://github.com/google/shadertrap/pull/68): Examples of computing a histogram of values
284+
285+
### Bug finding
286+
287+
- Using gfauto, I re-discovered a known bug in SwiftShader: [UNIMPLEMENTED_b_Function_block_instruction_Return](https://issuetracker.google.com/issues/141246700)
288+
- Using gfauto, I found a shader that crashes spirv-opt: OpPhis_incoming_basic_block_id_is_not_a_predecessor. This might be a known bug, as there are already a few similar, open GitHub issues in the SPIRV-Tools project.
289+
290+
### Conclusion
291+
It was a pleasure to participate in the Google Summer of Code 2021 program. I learned more about new tools, computer graphics, improved my coding skills, enhanced my git skills, and I'm looking for more. The plan is to continue contributing to the project after GSoC for finishing my role and I'm thinking to make a `Shadertrap formatting tool` and other works from my mentors' suggestions. Finally, I would like to thank my mentors, Alastair Donaldson, Paul Thomson, Vasyl Teliman, for the opportunity. GSoC gave me a high impact for continuously learning and some points of weakness I have and I will do my best to overcome them.
292+

0 commit comments

Comments
 (0)