Contributors
-
Ben Ashbaugh, Intel
-
Peter Cadey, Intel
-
Pawel Jurek, Intel
-
Piotr Kanclerz, Intel
-
Jianhui Li, Intel
-
Greg Lueck, Intel
-
Roland Schulz, Intel
Dependencies
This extension is written against the SPIR-V Specification, Version 1.6, Revision 7.
This extension requires SPIR-V 1.0.
Overview
This extension adds a special sub-group shuffle instruction to reinterpret vector or scalar source data as vector or scalar source data of a different type, and specifically as vector or scalar data with a different number of components.
Unlike the core SPIR-V OpBitcast instruction, which reinterprets the per-invocation source data as a different type, the OpSubgroupBitcastShuffleINTEL instruction added by this extension also re-assigns the data from one invocation in the subgroup to a different invocation in the subgroup. Although the re-assignment performed by OpSubgroupBitcastShuffleINTEL appears to be more complex than the core SPIR-V OpBitcast, the re-assignment is free for some hardware, and therefore can be more efficient than a traditional bitcast for applications performing element-wise operations or that can otherwise account for the re-assignment.
The OpSubgroupBitcastShuffleINTEL instruction added by this extension is especially useful for applications performing operations on the packed Matrix B data before passing it to the OpSubgroupMatrixMultiplyAccumulateINTEL instruction added by the SPV_INTEL_subgroup_matrix_multiply_accumulate extension.
Extension Name
To use this extension within a SPIR-V module, the appropriate OpExtension must be present in the module:
OpExtension "SPV_INTEL_subgroup_bitcast_shuffle"
Modifications to the SPIR-V Specification, Version 1.6
Capabilities
Modify Section 3.2.30, Capability, adding rows to the Capability table:
| Capability | Implicitly Declares | |
|---|---|---|
6207 |
SubgroupBitcastShuffleINTEL |
|
Instructions
Modify Section 3.3.21, Group and Subgroup Instructions, adding to the end of the list of instructions:
Performs a bit-preserving type conversion and shuffle of the source data among invocations in a subgroup. This instruction may execute more efficiently than a traditional bitcast. All invocations in the subgroup cooperate to perform this operation. Result Type defines the result of the operation and must be a scalar or vector of numerical type. Operand is the source data and must also be a scalar or vector of numerical type. It must have a different type than Result Type. If Result Type has the same number of components as the type of Operand, the behavior is the same as a traditional bitcast. Otherwise, when Result Type has a different number of components than the type of Operand, the total number of bits in Result Type must equal the total number of bits in Operand, and the bitcast and shuffle operation is performed as follows: Take the first component of the Operand source data for each invocation in the subgroup and concatenate the first components together, in order based on the subgroup local invocation ID. Then, repeat for the next component of the Operand source data for each invocation in the subgroup, until all Operand source data has been concatenated. This forms an M times N bit number, where M is the size in bits of each source Operand and N is the number of invocations in the subgroup. Now, take the first C bits of the concatenated number and assign them to the first component of the Result destination for the first invocation in the subgroup, where C is the size in bits of each component of Result Type when it is a vector type, or the size of the Result Type when it is a scalar type. Assign the next C bits to the first component of the Result destination for the next invocation in the subgroup, and so on, in order based on the subgroup local invocation ID. After C bits have been assigned to the first component for all invocations in the subgroup, repeat for the second component of the Result destination, and so on, until all bits have been assigned. Like a traditional bitcast, the bitcast and shuffle operation is reversible, so an OpSubgroupBitcastShuffleINTEL to one type followed another OpSubgroupBitcastShuffleINTEL back to the original type will result in the original source data. See Supported Types for the supported type combinations for this instruction. Behavior is undefined unless all invocations within the subgroup execute the same dynamic instance of this instruction. Additionally, behavior is undefined unless the SubgroupSize is equal to the SubgroupMaxSize; in other words, unless it is a full subgroup. |
Capability: |
|||
4 |
6208 |
<id> |
<id> |
<id> |
Examples
In the following examples:
-
A 32-bit number storing packed 16-bit data is described as
lowbits | highbits. -
A 32-bit number storing packed 8-bit data is described as
lowbits | ... | ... | highbits. -
A vector of two 16-bit numbers is described as
<first component, second component>. -
A vector of four 8-bit numbers is described as
<first component, ..., ..., fourth component>.
32-bit Scalar to Vector of 16-bit Data
Let the subgroup size be eight and let Operand equal:
| Invocation: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|---|
Operand: |
|
|
|
|
|
|
|
|
After the bitcast and shuffle operation, Result will be:
| Invocation: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|---|
Result: |
|
|
|
|
|
|
|
|
Vector of 16-bit Data to 32-bit Scalar
Let the subgroup size be eight and let Operand equal:
| Invocation: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|---|
Operand: |
|
|
|
|
|
|
|
|
After the bitcast and shuffle operation, Result will be:
| Invocation: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|---|
Result: |
|
|
|
|
|
|
|
|
Supported Types
The table below describes valid type combinations for the bitcast and shuffle operation. Each row in this table describes two type combinations, one where the first type is the source operand type and the second type is the destination result type, and another where the first type is the destination result type and the second type is the source operand type:
| First Type | Second Type |
|---|---|
16 bits: |
|
Vector of two 8-bit integers ( |
Scalar 16-bit Integer ( |
32 bits: |
|
Vector of four 8-bit Integers ( |
Vector of two 16-bit Integers ( |
Vector of four 8-bit Integers ( |
Scalar 32-bit Integer ( |
Vector of two 16-bit Integers ( |
Scalar 32-bit Integer ( |
64 bits: |
|
Vector of eight 8-bit Integers ( |
Vector of four 16-bit Integers ( |
Vector of eight 8-bit Integers ( |
Vector of two 32-bit Integers ( |
Vector of eight 8-bit Integers ( |
Scalar 64-bit Integer ( |
Vector of four 16-bit Integers ( |
Vector of two 32-bit Integers ( |
Vector of four 16-bit Integers ( |
Scalar 64-bit Integer ( |
Vector of two 32-bit Integers ( |
Scalar 64-bit Integer ( |
128 bits: |
|
Vector of sixteen 8-bit Integers ( |
Vector of eight 16-bit Integers ( |
Vector of sixteen 8-bit Integers ( |
Vector of four 32-bit Integers ( |
Vector of sixteen 8-bit Integers ( |
Vector of two 64-bit Integers ( |
Vector of eight 16-bit Integers ( |
Vector of four 32-bit Integers ( |
Vector of eight 16-bit Integers ( |
Vector of two 64-bit Integers ( |
Vector of four 32-bit Integers ( |
Vector of two 64-bit Integers ( |
256 bits: |
|
Vector of sixteen 16-bit Integers ( |
Vector of eight 32-bit Integers ( |
Vector of sixteen 16-bit Integers ( |
Vector of four 64-bit Integers ( |
Vector of eight 32-bit Integers ( |
Vector of four 64-bit Integers ( |
512 bits: |
|
Vector of sixteen 32-bit Integers ( |
Vector of eight 64-bit Integers ( |
Issues
-
What should this extension be called?
RESOLVED: The name of the extension is SPV_INTEL_subgroup_bitcast_shuffle. This name describes the key properties of the extension:
-
It is intended to reinterpret ("bitcast") source bits as bits of a different type.
-
It is exchanging ("shuffling") data among the invocations in a group, specifically a subgroup.
Although the shuffling will likely be used to bitcast to or from a "VNNI" packing, the same instruction could be used to perform other types of reinterpretation as well, such as reinterpreting a 64-bit value as two 32-bit values, or vice versa.
-