|
14 | 14 | #ifndef SPIRV_NON_UNIFORM_OPS
|
15 | 15 | #define SPIRV_NON_UNIFORM_OPS
|
16 | 16 |
|
| 17 | +class SPV_GroupNonUniformArithmeticOp<string mnemonic, Type type, |
| 18 | + list<OpTrait> traits = []> : SPV_Op<mnemonic, traits> { |
| 19 | + |
| 20 | + let availability = [ |
| 21 | + MinVersion<SPV_V_1_3>, |
| 22 | + MaxVersion<SPV_V_1_5>, |
| 23 | + Extension<[]>, |
| 24 | + Capability<[SPV_C_GroupNonUniformArithmetic, |
| 25 | + SPV_C_GroupNonUniformClustered, |
| 26 | + SPV_C_GroupNonUniformPartitionedNV]> |
| 27 | + ]; |
| 28 | + |
| 29 | + let arguments = (ins |
| 30 | + SPV_ScopeAttr:$execution_scope, |
| 31 | + SPV_GroupOperationAttr:$group_operation, |
| 32 | + SPV_ScalarOrVectorOf<type>:$value, |
| 33 | + SPV_Optional<SPV_Integer>:$cluster_size |
| 34 | + ); |
| 35 | + |
| 36 | + let results = (outs |
| 37 | + SPV_ScalarOrVectorOf<type>:$result |
| 38 | + ); |
| 39 | + |
| 40 | + let parser = [{ return parseGroupNonUniformArithmeticOp(parser, result); }]; |
| 41 | + let printer = [{ printGroupNonUniformArithmeticOp(getOperation(), p); }]; |
| 42 | + let verifier = [{ return ::verifyGroupNonUniformArithmeticOp(getOperation()); }]; |
| 43 | + |
| 44 | +} |
| 45 | + |
17 | 46 | // -----
|
18 | 47 |
|
19 | 48 | def SPV_GroupNonUniformBallotOp : SPV_Op<"GroupNonUniformBallot", []> {
|
@@ -120,7 +149,110 @@ def SPV_GroupNonUniformElectOp : SPV_Op<"GroupNonUniformElect", []> {
|
120 | 149 |
|
121 | 150 | // -----
|
122 | 151 |
|
123 |
| -def SPV_GroupNonUniformIAddOp : SPV_Op<"GroupNonUniformIAdd", []> { |
| 152 | +def SPV_GroupNonUniformFAddOp : |
| 153 | + SPV_GroupNonUniformArithmeticOp<"GroupNonUniformFAdd", SPV_Float, []> { |
| 154 | + let summary = [{ |
| 155 | + A floating point add group operation of all Value operands contributed |
| 156 | + by active invocations in the group. |
| 157 | + }]; |
| 158 | + |
| 159 | + let description = [{ |
| 160 | + Result Type must be a scalar or vector of floating-point type. |
| 161 | + |
| 162 | + Execution must be Workgroup or Subgroup Scope. |
| 163 | + |
| 164 | + The identity I for Operation is 0. If Operation is ClusteredReduce, |
| 165 | + ClusterSize must be specified. |
| 166 | + |
| 167 | + The type of Value must be the same as Result Type. The method used to |
| 168 | + perform the group operation on the contributed Value(s) from active |
| 169 | + invocations is implementation defined. |
| 170 | + |
| 171 | + ClusterSize is the size of cluster to use. ClusterSize must be a scalar |
| 172 | + of integer type, whose Signedness operand is 0. ClusterSize must come |
| 173 | + from a constant instruction. ClusterSize must be at least 1, and must be |
| 174 | + a power of 2. If ClusterSize is greater than the declared SubGroupSize, |
| 175 | + executing this instruction results in undefined behavior. |
| 176 | + |
| 177 | + ### Custom assembly form |
| 178 | + |
| 179 | + ``` |
| 180 | + scope ::= `"Workgroup"` | `"Subgroup"` |
| 181 | + operation ::= `"Reduce"` | `"InclusiveScan"` | `"ExclusiveScan"` | ... |
| 182 | + float-scalar-vector-type ::= float-type | |
| 183 | + `vector<` integer-literal `x` float-type `>` |
| 184 | + non-uniform-fadd-op ::= ssa-id `=` `spv.GroupNonUniformFAdd` scope operation |
| 185 | + ssa-use ( `cluster_size` `(` ssa_use `)` )? |
| 186 | + `:` float-scalar-vector-type |
| 187 | + ``` |
| 188 | + |
| 189 | + For example: |
| 190 | + |
| 191 | + ``` |
| 192 | + %four = spv.constant 4 : i32 |
| 193 | + %scalar = ... : f32 |
| 194 | + %vector = ... : vector<4xf32> |
| 195 | + %0 = spv.GroupNonUniformFAdd "Workgroup" "Reduce" %scalar : f32 |
| 196 | + %1 = spv.GroupNonUniformFAdd "Subgroup" "ClusteredReduce" %vector cluster_size(%four) : vector<4xf32> |
| 197 | + ``` |
| 198 | + }]; |
| 199 | +} |
| 200 | + |
| 201 | +// ----- |
| 202 | + |
| 203 | +def SPV_GroupNonUniformFMulOp : |
| 204 | + SPV_GroupNonUniformArithmeticOp<"GroupNonUniformFMul", SPV_Float, []> { |
| 205 | + let summary = [{ |
| 206 | + A floating point multiply group operation of all Value operands |
| 207 | + contributed by active invocations in the group. |
| 208 | + }]; |
| 209 | + |
| 210 | + let description = [{ |
| 211 | + Result Type must be a scalar or vector of floating-point type. |
| 212 | + |
| 213 | + Execution must be Workgroup or Subgroup Scope. |
| 214 | + |
| 215 | + The identity I for Operation is 1. If Operation is ClusteredReduce, |
| 216 | + ClusterSize must be specified. |
| 217 | + |
| 218 | + The type of Value must be the same as Result Type. The method used to |
| 219 | + perform the group operation on the contributed Value(s) from active |
| 220 | + invocations is implementation defined. |
| 221 | + |
| 222 | + ClusterSize is the size of cluster to use. ClusterSize must be a scalar |
| 223 | + of integer type, whose Signedness operand is 0. ClusterSize must come |
| 224 | + from a constant instruction. ClusterSize must be at least 1, and must be |
| 225 | + a power of 2. If ClusterSize is greater than the declared SubGroupSize, |
| 226 | + executing this instruction results in undefined behavior. |
| 227 | + |
| 228 | + ### Custom assembly form |
| 229 | + |
| 230 | + ``` |
| 231 | + scope ::= `"Workgroup"` | `"Subgroup"` |
| 232 | + operation ::= `"Reduce"` | `"InclusiveScan"` | `"ExclusiveScan"` | ... |
| 233 | + float-scalar-vector-type ::= float-type | |
| 234 | + `vector<` integer-literal `x` float-type `>` |
| 235 | + non-uniform-fmul-op ::= ssa-id `=` `spv.GroupNonUniformFMul` scope operation |
| 236 | + ssa-use ( `cluster_size` `(` ssa_use `)` )? |
| 237 | + `:` float-scalar-vector-type |
| 238 | + ``` |
| 239 | + |
| 240 | + For example: |
| 241 | + |
| 242 | + ``` |
| 243 | + %four = spv.constant 4 : i32 |
| 244 | + %scalar = ... : f32 |
| 245 | + %vector = ... : vector<4xf32> |
| 246 | + %0 = spv.GroupNonUniformFMul "Workgroup" "Reduce" %scalar : f32 |
| 247 | + %1 = spv.GroupNonUniformFMul "Subgroup" "ClusteredReduce" %vector cluster_size(%four) : vector<4xf32> |
| 248 | + ``` |
| 249 | + }]; |
| 250 | +} |
| 251 | + |
| 252 | +// ----- |
| 253 | + |
| 254 | +def SPV_GroupNonUniformIAddOp : |
| 255 | + SPV_GroupNonUniformArithmeticOp<"GroupNonUniformIAdd", SPV_Integer, []> { |
124 | 256 | let summary = [{
|
125 | 257 | An integer add group operation of all Value operands contributed active
|
126 | 258 | by invocations in the group.
|
@@ -164,24 +296,55 @@ def SPV_GroupNonUniformIAddOp : SPV_Op<"GroupNonUniformIAdd", []> {
|
164 | 296 | %1 = spv.GroupNonUniformIAdd "Subgroup" "ClusteredReduce" %vector cluster_size(%four) : vector<4xi32>
|
165 | 297 | ```
|
166 | 298 | }];
|
| 299 | +} |
167 | 300 |
|
168 |
| - let availability = [ |
169 |
| - MinVersion<SPV_V_1_3>, |
170 |
| - MaxVersion<SPV_V_1_5>, |
171 |
| - Extension<[]>, |
172 |
| - Capability<[SPV_C_GroupNonUniformArithmetic, SPV_C_GroupNonUniformClustered, SPV_C_GroupNonUniformPartitionedNV]> |
173 |
| - ]; |
| 301 | +// ----- |
174 | 302 |
|
175 |
| - let arguments = (ins |
176 |
| - SPV_ScopeAttr:$execution_scope, |
177 |
| - SPV_GroupOperationAttr:$group_operation, |
178 |
| - SPV_ScalarOrVectorOf<SPV_Integer>:$value, |
179 |
| - SPV_Optional<SPV_Integer>:$cluster_size |
180 |
| - ); |
| 303 | +def SPV_GroupNonUniformIMulOp : |
| 304 | + SPV_GroupNonUniformArithmeticOp<"GroupNonUniformIMul", SPV_Integer, []> { |
| 305 | + let summary = [{ |
| 306 | + An integer multiply group operation of all Value operands contributed by |
| 307 | + active invocations in the group. |
| 308 | + }]; |
181 | 309 |
|
182 |
| - let results = (outs |
183 |
| - SPV_ScalarOrVectorOf<SPV_Integer>:$result |
184 |
| - ); |
| 310 | + let description = [{ |
| 311 | + Result Type must be a scalar or vector of integer type. |
| 312 | + |
| 313 | + Execution must be Workgroup or Subgroup Scope. |
| 314 | + |
| 315 | + The identity I for Operation is 1. If Operation is ClusteredReduce, |
| 316 | + ClusterSize must be specified. |
| 317 | + |
| 318 | + The type of Value must be the same as Result Type. |
| 319 | + |
| 320 | + ClusterSize is the size of cluster to use. ClusterSize must be a scalar |
| 321 | + of integer type, whose Signedness operand is 0. ClusterSize must come |
| 322 | + from a constant instruction. ClusterSize must be at least 1, and must be |
| 323 | + a power of 2. If ClusterSize is greater than the declared SubGroupSize, |
| 324 | + executing this instruction results in undefined behavior. |
| 325 | + |
| 326 | + ### Custom assembly form |
| 327 | + |
| 328 | + ``` |
| 329 | + scope ::= `"Workgroup"` | `"Subgroup"` |
| 330 | + operation ::= `"Reduce"` | `"InclusiveScan"` | `"ExclusiveScan"` | ... |
| 331 | + integer-scalar-vector-type ::= integer-type | |
| 332 | + `vector<` integer-literal `x` integer-type `>` |
| 333 | + non-uniform-imul-op ::= ssa-id `=` `spv.GroupNonUniformIMul` scope operation |
| 334 | + ssa-use ( `cluster_size` `(` ssa_use `)` )? |
| 335 | + `:` integer-scalar-vector-type |
| 336 | + ``` |
| 337 | + |
| 338 | + For example: |
| 339 | + |
| 340 | + ``` |
| 341 | + %four = spv.constant 4 : i32 |
| 342 | + %scalar = ... : i32 |
| 343 | + %vector = ... : vector<4xi32> |
| 344 | + %0 = spv.GroupNonUniformIMul "Workgroup" "Reduce" %scalar : i32 |
| 345 | + %1 = spv.GroupNonUniformIMul "Subgroup" "ClusteredReduce" %vector cluster_size(%four) : vector<4xi32> |
| 346 | + ``` |
| 347 | + }]; |
185 | 348 | }
|
186 | 349 |
|
187 | 350 | // -----
|
|
0 commit comments