Skip to content

Commit

Permalink
feat(fuzzer): implement usage of OpExtension, OpExtInstImport and OpE…
Browse files Browse the repository at this point in the history
…xtInst; modify fuzzer logic to include the GLSL extension
  • Loading branch information
rayanht committed Apr 19, 2022
1 parent 91f867e commit 6cba185
Show file tree
Hide file tree
Showing 13 changed files with 272 additions and 153 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,9 @@ void main () {

|OpCode| Status |
|--|--|
| OpExtension | :red_circle: |
| OpExtInstImport | :red_circle: |
| OpExtInst | :red_circle: |
| OpExtension | :white_check_mark: |
| OpExtInstImport | :white_check_mark: |
| OpExtInst | :white_check_mark: |

</details>

Expand All @@ -177,7 +177,7 @@ void main () {
| OpMemoryModel | :white_check_mark: |
| OpEntryPoint | :white_check_mark: |
| OpExecutionMode | :white_check_mark: |
| OpCapability | :red_circle: |
| OpCapability | :white_check_mark: |
| OpExecutionModeId | :red_circle: |

</details>
Expand Down Expand Up @@ -376,7 +376,7 @@ void main () {
| OpSNegate | :white_check_mark: |
| OpFNegate | :white_check_mark: |
| OpIAdd | :white_check_mark: |
| OpFAdd |:white_check_mark: |
| OpFAdd | :white_check_mark: |
| OpISub | :white_check_mark: |
| OpFSub | :white_check_mark: |
| OpIMul | :white_check_mark: |
Expand Down
5 changes: 5 additions & 0 deletions src/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import hashlib
import inspect
import pickle
from abc import ABC
from dataclasses import field
Expand Down Expand Up @@ -105,8 +106,12 @@ def fuzz(_: "Context") -> list["OpCode"]:
return []

def resolve_attribute_spasm(self, attr, context) -> str:
if self.__class__.__name__ == "OpDecorate":
pass
if attr.__class__.__name__ == "Context" or attr is None:
return ""
elif inspect.isclass(attr) and issubclass(attr, OpCode):
attr_spasm = f" {attr.__name__}"
elif isinstance(attr, OpCode):
if isinstance(attr, (Type, Constant)):
attr_spasm = f" %{context.tvc[attr]}"
Expand Down
7 changes: 4 additions & 3 deletions src/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,10 @@ def fuzz(self, context: "Context") -> list[OpCode]:
for _ in range(len(self.type)):
column_values = OpConstantComposite()
column_values.type = column_type
column_values.constituents = tuple(
column_values.fuzz_constituents(context)
)
constituents = column_values.fuzz_constituents(context)
if not constituents:
return []
column_values.constituents = tuple(constituents)
self.constituents.append(column_values)
else:
self.constituents = self.fuzz_constituents(context)
Expand Down
26 changes: 20 additions & 6 deletions src/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,15 @@

class Context:
id: UUID
symbol_table: dict["OpCode", str]
symbol_table: list["OpCode"]
function: Optional["OpFunction"]
parent_context: Optional["Context"]
tvc: dict["OpCode", str]
annotations: list[Annotation]
execution_model: ExecutionModel
config: "SPIRVSmithConfig"
monitor: Monitor
extension_sets: dict[str, "OpCode"]

def __init__(
self,
Expand All @@ -59,12 +60,13 @@ def __init__(
monitor: Monitor,
) -> None:
self.id = uuid4()
self.symbol_table = dict()
self.symbol_table = []
self.function = function
self.annotations = annotations
self.parent_context = parent_context
self.execution_model = execution_model
self.tvc = dict()
self.extension_sets = dict()
self.config = config
self.monitor = monitor

Expand Down Expand Up @@ -117,6 +119,7 @@ def make_child_context(self, function: OpTypeFunction = None):
self.monitor,
)
context.tvc = self.tvc
context.extension_sets = self.extension_sets
return context

def add_to_tvc(self, opcode: "OpCode"):
Expand Down Expand Up @@ -227,19 +230,30 @@ def gen_global_variables(self):
variable = self.create_on_demand_variable(StorageClass.StorageBuffer)
if len(self.tvc) != n:
self.add_annotation(
OpDecorate(None, variable.type.type, Decoration.Block)
OpDecorate(target=variable.type.type, decoration=Decoration.Block)
)
self.add_annotation(
OpDecorate(None, variable, Decoration.DescriptorSet, (0,))
OpDecorate(
target=variable,
decoration=Decoration.DescriptorSet,
extra_operands=(0,),
)
)
self.add_annotation(
OpDecorate(None, variable, Decoration.Binding, (i,))
OpDecorate(
target=variable,
decoration=Decoration.Binding,
extra_operands=(i,),
)
)
offset = 0
for j, t in enumerate(variable.type.type.types):
self.add_annotation(
OpMemberDecorate(
None, variable.type.type, j, Decoration.Offset, (offset,)
target_struct=variable.type.type,
member=j,
decoration=Decoration.Offset,
extra_operands=(offset,),
)
)
offset += t.width
Expand Down
31 changes: 24 additions & 7 deletions src/extension.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,33 @@
from typing import TYPE_CHECKING

from src import OpCode
from src import ReparametrizationError
from src import Statement
from src import Type
from src import VoidOp
from utils.patched_dataclass import dataclass

if TYPE_CHECKING:
from src.context import Context


class OpExtension(OpCode):
name: str
@dataclass
class OpExtension(OpCode, VoidOp):
name: str = None


@dataclass
class OpExtInstImport(OpCode):
name: str = None


# @dataclass
# class OpExtInst(OpCode):
# name: str
# def get_required_capabilities(self) -> list[Capability]:
# return []
@dataclass
class OpExtInst(Statement):
type: Type = None
extension_set: OpExtInstImport = None
instruction: OpCode = None
operands: tuple[Statement] = None

def fuzz(self, context: "Context") -> list[OpCode]:
Statement.set_zero_probability(self.__class__)
raise ReparametrizationError
3 changes: 2 additions & 1 deletion src/function.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from src import VoidOp
from src.enums import FunctionControlMask
from src.enums import SelectionControlMask
from src.extension import OpExtInst

if TYPE_CHECKING:
from src.context import Context
Expand Down Expand Up @@ -190,7 +191,7 @@ def fuzz_block(context: "Context", exit_label: Optional[OpLabel]) -> tuple[OpCod
nested_block = True
break
if isinstance(statement, Statement) and not nested_block:
block_context.symbol_table[statement] = statement.id
block_context.symbol_table.append(statement)
if not isinstance(statement, (OpVariable, OpReturn)):
instructions.append(statement)
if isinstance(statement, OpVariable):
Expand Down
10 changes: 9 additions & 1 deletion src/fuzzing_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from src.enums import ExecutionModel
from src.enums import MemoryModel
from src.enums import StorageClass
from src.extension import OpExtInstImport
from src.misc import OpCapability
from src.misc import OpEntryPoint
from src.misc import OpExecutionMode
Expand All @@ -29,6 +30,7 @@
from src.monitor import Monitor
from src.operators.memory.memory_access import OpVariable
from src.recondition import recondition
from src.types.concrete_types import OpTypeFloat

if TYPE_CHECKING:
from run_local import SPIRVSmithConfig
Expand Down Expand Up @@ -127,6 +129,9 @@ def export(self):
for capability in self.capabilities:
f.write(capability.to_spasm(self.context))
f.write("\n")
for ext in self.context.extension_sets.values():
f.write(ext.to_spasm(self.context))
f.write("\n")
f.write(self.memory_model.to_spasm(self.context))
f.write("\n")
f.write(self.entry_point.to_spasm(self.context))
Expand Down Expand Up @@ -241,7 +246,6 @@ def start(self):
target=upload_shader_data_to_GCS_and_notify_amber_clients,
args=(publisher, topic_path, bucket, shader, self.monitor),
).start()

if paused:
self.monitor.info(event=Event.PAUSED)

Expand Down Expand Up @@ -337,6 +341,8 @@ def gen_shader(self) -> SPIRVShader:
context = Context.create_global_context(
execution_model, self.config, self.monitor
)
if self.config.strategy.enable_ext_glsl_std_450:
context.extension_sets["GLSL"] = OpExtInstImport(name="GLSL.std.450")
# Generate random types and constants to be used by the program
context.gen_types()
context.gen_constants()
Expand All @@ -349,6 +355,8 @@ def gen_shader(self) -> SPIRVShader:

# Remap IDs
id_gen = id_generator()
for ext in context.extension_sets.values():
ext.id = next(id_gen)
new_tvc = {}
for tvc in context.tvc.keys():
tvc.id = next(id_gen)
Expand Down
23 changes: 23 additions & 0 deletions src/operators/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,16 @@
from src import Statement
from src.constants import OpConstantComposite
from src.context import Context
from src.extension import OpExtInst
from src.types.concrete_types import OpTypeVector

Operand = Statement | Constant


class GLSLExtensionOperator:
...


class UnaryOperatorFuzzMixin:
def fuzz(self, context: "Context") -> list[OpCode]:
(
Expand Down Expand Up @@ -51,6 +56,15 @@ def fuzz(self, context: "Context") -> list[OpCode]:
else:
self.type = operand.type
self.operand = operand
if isinstance(self, GLSLExtensionOperator):
return [
OpExtInst(
type=self.type,
extension_set=context.extension_sets["GLSL"],
instruction=self.__class__,
operands=tuple([self.operand]),
)
]
return [self]

def __str__(self) -> str:
Expand Down Expand Up @@ -105,6 +119,15 @@ def fuzz(self, context: "Context") -> list[OpCode]:
self.type = operand1.type
self.operand1 = operand1
self.operand2 = operand2
if isinstance(self, GLSLExtensionOperator):
return [
OpExtInst(
type=self.type,
extension_set=context.extension_sets["GLSL"],
instruction=self.__class__,
operands=tuple([self.operand1, self.operand2]),
)
]
return [self]

def __str__(self) -> str:
Expand Down
Loading

0 comments on commit 6cba185

Please sign in to comment.