-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathreducer_client.py
89 lines (77 loc) · 3.3 KB
/
reducer_client.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import subprocess
import time
from abc import ABC
from abc import abstractmethod
from dataclasses import dataclass
from tempfile import NamedTemporaryFile
from spirvsmith_server_client import Client
from spirvsmith_server_client.api.queues import get_queues
from spirvsmith_server_client.api.shaders import get_next_mismatch
from spirvsmith_server_client.models.shader_data import ShaderData
from spirvsmith_server_client.types import Response
from src.shader_parser import parse_spirv_assembly_file
from src.shader_parser import parse_spirv_assembly_lines
from src.shader_utils import disassemble_spv_file
from src.shader_utils import SPIRVShader
@dataclass
class ReductionResult:
success: bool
reduced_shader: SPIRVShader
class ProgramReducer(ABC):
@abstractmethod
def reduce(self, shader: SPIRVShader) -> ReductionResult:
...
class SPIRVReducer(ProgramReducer):
@classmethod
def reduce(cls, shader_data: ShaderData) -> ReductionResult:
shader: SPIRVShader = parse_spirv_assembly_lines(
shader_data.shader_assembly.split("\n")
)
n_expected_reports: int = len(get_queues.sync(client=client).queues)
with NamedTemporaryFile(suffix=".spv") as spv_in_file:
with NamedTemporaryFile(suffix=".spv") as spv_out_file:
if not shader.assemble(spv_in_file.name):
return ReductionResult(False, shader)
reduce_process: subprocess.CompletedProcess = subprocess.run(
[
"spirv-reduce",
spv_in_file.name,
"-o",
spv_out_file.name,
"--",
f"./scripts/interestingness.sh",
shader.id,
str(n_expected_reports),
],
capture_output=False,
)
if reduce_process.returncode != 0:
return ReductionResult(False, shader)
with NamedTemporaryFile(
suffix=".spasm"
) as disassembled_reduced_spasm_file:
if not disassemble_spv_file(
spv_out_file.name,
disassembled_reduced_spasm_file.name,
):
return ReductionResult(False, shader)
parsed_shader: SPIRVShader = parse_spirv_assembly_file(
disassembled_reduced_spasm_file.name
)
return ReductionResult(True, parsed_shader)
if __name__ == "__main__":
client = Client(base_url="http://spirvsmith.hatout.dev")
while True:
response: Response[ShaderData] = get_next_mismatch.sync_detailed(client=client)
if response.status_code == 404:
time.sleep(2)
continue
shader_data: ShaderData = response.parsed
shader_id: str = shader_data.shader_id
print(f"Reducing shader {shader_id}")
reduction_result: ReductionResult = SPIRVReducer.reduce(shader_data)
if reduction_result.success:
print(f"Shader {shader_id} successfully reduced.")
reduction_result.reduced_shader.generate_assembly_file(
f"interesting_shaders/{shader_id}.spasm"
)