Skip to content

Commit d98512f

Browse files
committed
Update on "[ET-VK] Introduce VulkanDelegateHeader to manage constant data and shader data"
## Context This changeset is essentially a mirror of #1523 in the XNNPACK delegate which is the first step to enabling constant weight data to be serialized outside the flatbuffer blob to speed up deserialization time for large models. `VulkanDelegateHeader` is introduced which will be used later on to help interpret what different sections of the serialized binary blob corresponds to. The primary difference compared to `XNNHeader` which was added for the XNNPACK delegate is that fields are added to support custom compute shaders that will be serialized with the model. Differential Revision: [D53957853](https://our.internmc.facebook.com/intern/diff/D53957853/) [ghstack-poisoned]
1 parent a590b77 commit d98512f

File tree

2 files changed

+31
-61
lines changed

2 files changed

+31
-61
lines changed

backends/vulkan/serialization/vulkan_graph_serialize.py

Lines changed: 14 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -44,23 +44,19 @@ class VulkanDelegateHeader:
4444
HEADER_SIZE_IX: ClassVar[slice] = slice(8, 10)
4545
FLATBUFFER_OFFSET_IX: ClassVar[slice] = slice(10, 14)
4646
FLATBUFFER_SIZE_IX: ClassVar[slice] = slice(14, 18)
47-
CONSTANTS_OFFSET_IX: ClassVar[slice] = slice(18, 22)
48-
CONSTANTS_SIZE_IX: ClassVar[slice] = slice(22, 30)
49-
SHADERS_OFFSET_IX: ClassVar[slice] = slice(30, 34)
50-
SHADERS_SIZE_IX: ClassVar[slice] = slice(34, 42)
47+
BYTES_OFFSET_IX: ClassVar[slice] = slice(18, 22)
48+
BYTES_SIZE_IX: ClassVar[slice] = slice(22, 30)
5149

5250
# magic bytes that should be at the beginning of the header
53-
EXPECTED_MAGIC: ClassVar[bytes] = b"VKDG"
51+
EXPECTED_MAGIC: ClassVar[bytes] = b"VH00"
5452
# The length of the header in bytes
55-
EXPECTED_LENGTH: ClassVar[int] = 42
53+
EXPECTED_LENGTH: ClassVar[int] = 30
5654

5755
# Instance attributes, @dataclass will turn these into constructor args
5856
flatbuffer_offset: int
5957
flatbuffer_size: int
60-
constants_offset: int
61-
constants_size: int
62-
shaders_offset: int
63-
shaders_size: int
58+
bytes_offset: int
59+
bytes_size: int
6460

6561
@staticmethod
6662
def from_bytes(data: bytes) -> "VulkanDelegateHeader":
@@ -90,37 +86,27 @@ def from_bytes(data: bytes) -> "VulkanDelegateHeader":
9086

9187
flatbuffer_offset_b: bytes = data[VulkanDelegateHeader.FLATBUFFER_OFFSET_IX]
9288
flatbuffer_size_b: bytes = data[VulkanDelegateHeader.FLATBUFFER_SIZE_IX]
93-
constants_offset_b: bytes = data[VulkanDelegateHeader.CONSTANTS_OFFSET_IX]
94-
constants_size_b: bytes = data[VulkanDelegateHeader.CONSTANTS_SIZE_IX]
95-
shaders_offset_b: bytes = data[VulkanDelegateHeader.SHADERS_OFFSET_IX]
96-
shaders_size_b: bytes = data[VulkanDelegateHeader.SHADERS_SIZE_IX]
89+
bytes_offset_b: bytes = data[VulkanDelegateHeader.BYTES_OFFSET_IX]
90+
bytes_size_b: bytes = data[VulkanDelegateHeader.BYTES_SIZE_IX]
9791

9892
return VulkanDelegateHeader(
9993
flatbuffer_offset=int.from_bytes(flatbuffer_offset_b, byteorder="little"),
10094
flatbuffer_size=int.from_bytes(flatbuffer_size_b, byteorder="little"),
101-
constants_offset=int.from_bytes(constants_offset_b, byteorder="little"),
102-
constants_size=int.from_bytes(constants_size_b, byteorder="little"),
103-
shaders_offset=int.from_bytes(shaders_offset_b, byteorder="little"),
104-
shaders_size=int.from_bytes(shaders_size_b, byteorder="little"),
95+
bytes_offset=int.from_bytes(bytes_offset_b, byteorder="little"),
96+
bytes_size=int.from_bytes(bytes_size_b, byteorder="little"),
10597
)
10698

10799
def is_valid(self) -> bool:
108100
if self.flatbuffer_size <= 0:
109101
return False
110102

111103
expected_offset = self.flatbuffer_offset + self.flatbuffer_size
112-
if self.constants_offset < expected_offset:
104+
if self.bytes_offset < expected_offset:
113105
return False
114106

115-
if self.constants_size <= 0:
107+
if self.bytes_size < 0:
116108
return False
117109

118-
expected_offset = self.constants_offset + self.constants_size
119-
if self.shaders_offset < expected_offset:
120-
return False
121-
122-
# shaders_size can be 0
123-
124110
return True
125111

126112
def to_bytes(self) -> bytes:
@@ -135,10 +121,8 @@ def to_bytes(self) -> bytes:
135121
+ self.EXPECTED_LENGTH.to_bytes(2, byteorder="little")
136122
+ self.flatbuffer_offset.to_bytes(4, byteorder="little")
137123
+ self.flatbuffer_size.to_bytes(4, byteorder="little")
138-
+ self.constants_offset.to_bytes(4, byteorder="little")
139-
+ self.constants_size.to_bytes(8, byteorder="little")
140-
+ self.shaders_offset.to_bytes(4, byteorder="little")
141-
+ self.shaders_size.to_bytes(8, byteorder="little")
124+
+ self.bytes_offset.to_bytes(4, byteorder="little")
125+
+ self.bytes_size.to_bytes(8, byteorder="little")
142126
)
143127

144128
assert len(data) == VulkanDelegateHeader.EXPECTED_LENGTH

backends/vulkan/test/test_vulkan_delegate_header.py

Lines changed: 17 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,33 +12,27 @@
1212

1313
EXAMPLE_FLATBUFFER_OFFSET: int = 0x11223344
1414
EXAMPLE_FLATBUFFER_SIZE: int = 0x55667788
15-
EXAMPLE_CONSTANTS_OFFSET: int = EXAMPLE_FLATBUFFER_OFFSET + EXAMPLE_FLATBUFFER_SIZE
16-
EXAMPLE_CONSTANTS_SIZE: int = 0x99AABB
17-
EXAMPLE_SHADERS_OFFSET: int = EXAMPLE_CONSTANTS_OFFSET + EXAMPLE_CONSTANTS_SIZE
18-
EXAMPLE_SHADERS_SIZE: int = 0x11223344
15+
EXAMPLE_BYTES_OFFSET: int = EXAMPLE_FLATBUFFER_OFFSET + EXAMPLE_FLATBUFFER_SIZE
16+
EXAMPLE_BYTES_SIZE: int = 0x99AABBCC99AABBCC
1917

2018
# If header layout or magic changes, this test must change too.
2119
# The layout of the header is a contract, not an implementation detail
2220
EXAMPLE_HEADER_DATA: bytes = (
2321
# zeros
2422
b"\x00\x00\x00\x00"
2523
# magic
26-
+ b"VKDG"
24+
+ b"VH00"
2725
# All Values below are littl Endian
2826
# header length
29-
+ b"\x2A\x00"
27+
+ b"\x1E\x00"
3028
# Flatbuffer Offset
3129
+ b"\x44\x33\x22\x11"
3230
# Flatbuffer Size
3331
+ b"\x88\x77\x66\x55"
34-
# Constant Data Offset
32+
# Bytes Data Offset
3533
+ b"\xCC\xAA\x88\x66"
36-
# Constant Data Size
37-
+ b"\xBB\xAA\x99\x00\x00\x00\x00\x00"
38-
# Shader Offset
39-
+ b"\x87\x55\x22\x67"
40-
# Shader Size
41-
+ b"\x44\x33\x22\x11\x00\x00\x00\x00"
34+
# Bytes Data Size
35+
+ b"\xCC\xBB\xAA\x99\xCC\xBB\xAA\x99"
4236
)
4337

4438

@@ -47,10 +41,8 @@ def test_to_bytes(self) -> None:
4741
header = VulkanDelegateHeader(
4842
EXAMPLE_FLATBUFFER_OFFSET,
4943
EXAMPLE_FLATBUFFER_SIZE,
50-
EXAMPLE_CONSTANTS_OFFSET,
51-
EXAMPLE_CONSTANTS_SIZE,
52-
EXAMPLE_SHADERS_OFFSET,
53-
EXAMPLE_SHADERS_SIZE,
44+
EXAMPLE_BYTES_OFFSET,
45+
EXAMPLE_BYTES_SIZE,
5446
)
5547
self.assertEqual(header.to_bytes(), EXAMPLE_HEADER_DATA)
5648
self.assertTrue(header.is_valid())
@@ -59,40 +51,36 @@ def test_from_bytes(self) -> None:
5951
header = VulkanDelegateHeader.from_bytes(EXAMPLE_HEADER_DATA)
6052
self.assertEqual(header.flatbuffer_offset, EXAMPLE_FLATBUFFER_OFFSET)
6153
self.assertEqual(header.flatbuffer_size, EXAMPLE_FLATBUFFER_SIZE)
62-
self.assertEqual(header.constants_offset, EXAMPLE_CONSTANTS_OFFSET)
63-
self.assertEqual(header.constants_size, EXAMPLE_CONSTANTS_SIZE)
64-
self.assertEqual(header.shaders_offset, EXAMPLE_SHADERS_OFFSET)
65-
self.assertEqual(header.shaders_size, EXAMPLE_SHADERS_SIZE)
54+
self.assertEqual(header.bytes_offset, EXAMPLE_BYTES_OFFSET)
55+
self.assertEqual(header.bytes_size, EXAMPLE_BYTES_SIZE)
6656

6757
def test_invalid_metadata(self) -> None:
6858
WRONG_MAGIC_DATA = EXAMPLE_HEADER_DATA[0:4] + b"YT01" + EXAMPLE_HEADER_DATA[8:]
6959
with self.assertRaisesRegex(
7060
ValueError,
71-
"Expected magic bytes to be b'VKDG', but got b'YT01'",
61+
"Expected magic bytes to be b'VH00', but got b'YT01'",
7262
):
7363
VulkanDelegateHeader.from_bytes(WRONG_MAGIC_DATA)
7464

7565
WRONG_LENGTH_DATA = (
7666
EXAMPLE_HEADER_DATA[0:8] + b"\x1D\x00" + EXAMPLE_HEADER_DATA[10:]
7767
)
7868
with self.assertRaisesRegex(
79-
ValueError, "Expected header to be 42 bytes, but got 29 bytes."
69+
ValueError, "Expected header to be 30 bytes, but got 29 bytes."
8070
):
8171
VulkanDelegateHeader.from_bytes(WRONG_LENGTH_DATA)
8272

8373
with self.assertRaisesRegex(
84-
ValueError, "Expected header to be 42 bytes, but got 43 bytes."
74+
ValueError, "Expected header to be 30 bytes, but got 31 bytes."
8575
):
8676
VulkanDelegateHeader.from_bytes(EXAMPLE_HEADER_DATA + b"\x00")
8777

8878
def test_invalid_flatbuffer_size(self) -> None:
8979
header = VulkanDelegateHeader(
9080
EXAMPLE_FLATBUFFER_OFFSET,
9181
0,
92-
EXAMPLE_CONSTANTS_OFFSET,
93-
EXAMPLE_CONSTANTS_SIZE,
94-
EXAMPLE_SHADERS_OFFSET,
95-
EXAMPLE_SHADERS_SIZE,
82+
EXAMPLE_BYTES_OFFSET,
83+
EXAMPLE_BYTES_SIZE,
9684
)
9785

9886
with self.assertRaises(ValueError):
@@ -103,9 +91,7 @@ def test_invalid_constants_offset(self) -> None:
10391
EXAMPLE_FLATBUFFER_OFFSET,
10492
EXAMPLE_FLATBUFFER_SIZE,
10593
EXAMPLE_FLATBUFFER_OFFSET + EXAMPLE_FLATBUFFER_SIZE - 1,
106-
EXAMPLE_CONSTANTS_SIZE,
107-
EXAMPLE_SHADERS_OFFSET,
108-
EXAMPLE_SHADERS_SIZE,
94+
EXAMPLE_BYTES_SIZE,
10995
)
11096

11197
with self.assertRaises(ValueError):

0 commit comments

Comments
 (0)