## Name Strings

cl_intel_spirv_subgroups

## Contact

Ben Ashbaugh, Intel (ben 'dot' ashbaugh 'at' intel 'dot' com)

## Contributors

Ben Ashbaugh, Intel
Biju George, Intel
Michael Kinsner, Intel
Mariusz Merecki, Intel

Final Draft

## Version

Built On: 2019-10-23
Revision: 2

## Dependencies

This extension is written against the OpenCL SPIR-V Environment Specification Version 2.2, Revision v2.2-3.

This extension requires OpenCL support for SPIR-V, either via OpenCL 2.1 or via the cl_khr_il_program extension, and support for the cl_intel_subgroups extension.

This extension interacts with the cl_intel_subgroups_short extension.

## Overview

This extension defines how modules using the SPIR-V extension SPV_INTEL_subgroups may behave in an OpenCL environment.

This extension is a companion to the cl_intel_subgroups and cl_intel_subgroups_short OpenCL extensions, and the functionality described in this extension and SPV_INTEL_subgroups is sufficient to implement the built-in functions defined in the cl_intel_subgroups and cl_intel_subgroups_short extensions.

None.

None.

## Modifications to the OpenCL SPIR-V Environment Specification

### Add a new Section 7.1.X - cl_intel_spirv_subgroups

If the OpenCL environment supports the extension cl_intel_spirv_subgroups, then the environment must accept SPIR-V modules that declare use of the SPV_INTEL_subgroups extension via OpExtension.

If the OpenCL environment supports the extension cl_intel_spirv_subgroups and use of the SPV_INTEL_subgroups extension is declared in the module via OpExtension, then the environment must accept modules that declare the following SPIR-V capabilities:

• SubgroupShuffleINTEL

• SubgroupBufferBlockIOINTEL

• SubgroupImageBlockIOINTEL

Additionally, the environment must accept modules that use the following BuiltIns:

• SubgroupSize

• SubgroupMaxSize

• NumSubgroups

• SubgroupId

• SubgroupLocalInvocationId

For an OpenCL 2.0 or newer environment, the following BuiltIns must additionally be accepted:

• NumEnqueuedSubgroups

Additionally, the environment must accept the following instruction semantics:

For the control Barrier Instruction:

• OpControlBarrier:

• The Scope for Execution may be Subgroup.

• The Scope for Memory may be Subgroup.

For the Group Instructions:

• OpGroupAll

• OpGroupAny

• OpGroupFMin

• OpGroupUMin

• OpGroupSMin

• OpGroupFMax

• OpGroupUMax

• OpGroupSMax

• The Scope for Execution may be Subgroup.

### Add a new Section 7.1.X.1 - Shuffle Instructions

Because support for cl_intel_subgroups is required for cl_intel_spirv_subgroups, if the OpenCL environment supports the extension cl_intel_spirv_subgroups and use of the SPV_INTEL_subgroups extension is declared in the module via OpExtension, then the environment must accept the following types for 'Data' for the SubgroupShuffleINTEL instructions:

• Scalars and OpTypeVectors with 2, 3, 4, 8, or 16 Component Count components of the following Component Type types:

• OpTypeFloat with a Width of 32 bits (equivalent to float)

• OpTypeInt with a Width of 32 bits and Signedness of 0 (equivalent to int and uint)

• Scalars of OpTypeInt with a Width of 64 bits and Signedness of 0 (equivalent to long and ulong)

Additionally, if the Float16 capability is declared and supported:

• Scalars of OpTypeFloat with a Width of 16 bits (equivalent to half)

Additionally, if the Float64 capability is declared and supported:

• Scalars of OpTypeFloat with a Width of 64 bits (equivalent to double)

Additionally, if the OpenCL environment supports the extension cl_intel_subgroups_short:

• Scalars and OpTypeVectors with 2, 3, 4, 8, or 16 Component Count components of the following Component Type types:

• OpTypeInt with a Width of 16 bits and Signedness of 0 (equivalent to short and ushort)

### Add a new Section 7.1.X.2 - Block IO Instructions

Because support for cl_intel_subgroups is required for cl_intel_spirv_subgroups, if the OpenCL environment supports the extension cl_intel_spirv_subgroups and use of the SPV_INTEL_subgroups extension is declared in the module via OpExtension, then the environment must accept the following types for Result and Data for the SubgroupBufferBlockIOINTEL and SubgroupImageBlockIOINTEL instructions:

• Scalars and OpTypeVectors with 2, 4, or 8 Component Count components of the following Component Type types:

• OpTypeInt with a Width of 32 bits and Signedness of 0 (equivalent to int and uint)

Additionally, if the OpenCL environment supports the extension cl_intel_subgroups_short:

• Scalars and OpTypeVectors with 2, 4, or 8 Component Count components of the following Component Type types:

• OpTypeInt with a Width of 16 bits and Signedness of 0 (equivalent to short and ushort)

For Ptr, valid Storage Classes are:

• CrossWorkGroup (equivalent to the global address space)

For Image:

• Dim must be 2D

• Depth must be 0 (not a depth image)

• Arrayed must be 0 (non-arrayed content)

• MS must be 0 (single-sampled content)

• (equivalent to image2d_t)

For Coordinate, the following types are supported:

• OpTypeVectors with 2 Component Count components of Component Type OpTypeInt with a Width of 32 bits and Signedness of 0 (equivalent to int2)

### Add a new Section 7.1.X.3 - Notes and Restrictions

The SubgroupShuffleINTEL instructions may be placed within non-uniform control flow and hence do not have to be encountered by all invocations in the subgroup, however Data may only be shuffled among invocations encountering the SubgroupShuffleINTEL instruction. Shuffling Data from an invocation that does not encounter the SubgroupShuffleINTEL instruction will produce undefined results.

There is no defined behavior for out-of-range shuffle indices for the SubgroupShuffleINTEL instructions.

The SubgroupBufferBlockIOINTEL and SubgroupImageBlockIOINTEL instructions are only guaranteed to work correctly if placed strictly within uniform control flow within the subgroup. This ensures that if any invocation executes it, all invocations will execute it. If placed elsewhere, behavior is undefined.

There is no defined out-of-range behavior for the SubgroupBufferBlockIOINTEL instructions.

The SubgroupImageBlockIOINTEL instructions do support bounds checking, however they bounds-check to the image width in units of uints, not in units of image elements. This means:

• If the image has an Image Format size equal to the size of a uint (four bytes, for example Rgba8), the image will be correctly bounds-checked. In this case, out-of-bounds reads will return the edge image element (the equivalent of ClampToEdge), and out-of-bounds writes will be ignored.

• If the image has an Image Format size less than the size of a uint (such as R8), the entire image is addressable, however bounds checking will occur too late. For this reason, extra care should be taken to avoid out-of-bounds reads and writes, since out-of-bounds reads may return invalid data and out-of-bounds writes may corrupt other images or buffers unpredictably.

The following restrictions apply to the SubgroupBufferBlockIOINTEL instructions:

• The pointer Ptr must be 32-bit (4-byte) aligned for reads, and must be 128-bit (16-byte) aligned for writes.

• If the pointer Ptr is computed from a kernel argument that is a cl_mem that was created with CL_MEM_USE_HOST_PTR, then the host_ptr must be 32-bit (4-byte) aligned for reads, and must be 128-bit (16-byte) aligned for writes.

• If the pointer Ptr is computed from a kernel argument that is a cl_mem that is a sub-buffer, then the origin defining the sub-buffer offset into the buffer must be a multiple of 4 bytes for reads, and must be a multiple of 16 bytes for write, in addition to the CL_DEVICE_MEM_BASE_ADDR_ALIGN requirements. Additionally, if the buffer that the sub-buffer is created from was created with CL_MEM_USE_HOST_PTR, then the host_ptr for the buffer must be 32-bit (4-byte) aligned for reads, and must be 128-bit (16-byte) aligned for writes.

• If the pointer Ptr is computed from an SVM pointer kernel argument, then the SVM pointer kernel argument must be 32-bit (4-byte) aligned for reads, and must be 128-bit (16-byte) aligned for writes.

• Behavior is undefined if the SubgroupSize is smaller than SubgruopMaxSize; in other words, if this is a partial subgroup.

The following restrictions apply to the SubgroupImageBlockIOINTEL instructions:

• The behavior of the SubgroupImageBlockIOINTEL instructions is undefined for images with an element size greater than four bytes (such as Rgba32f).

• When reading or writing a 2D image created from a buffer with the SubgroupImageBlockIOINTEL instructions, the image row pitch is required to be a multiple of 64-bytes, in addition to the CL_DEVICE_IMAGE_PITCH_ALIGNMENT requirements.

• When reading or writing a 2D image created from a buffer with the SubgroupImageBlockIOINTEL instructions, if the buffer is a cl_mem that was created with CL_MEM_USE_HOST_PTR, then the host_ptr must be 256-bit (32-byte) aligned.

• When reading or writing a 2D image created from a buffer with the SubgroupImageBlockIOINTEL instructions, if the buffer is a cl_mem that is a sub-buffer, then the origin must be a multiple of 32-bytes. Additionally, if the buffer that the sub-buffer is created from was created with CL_MEM_USE_HOST_PTR, then the host_ptr for the buffer must be 256-bit (32-byte) aligned.

• Behavior is undefined if the SubgroupSize is smaller than SubgruopMaxSize; in other words, if this is a partial subgroup.

The following restrictions apply to the OpSubgroupImageBlockWriteINTEL instruction:

• Unlike the image block read instruction, which may read from any arbitrary byte offset, the x-component of the byte coordinate for the image block write instruction must be a multiple of four; in other words, the write must begin at a 32-bit boundary. There is no restriction on the y-component of the coordinate.

None.

## Revision History

Rev Date Author Changes

1

2018-10-29

Ben Ashbaugh

Initial revision

2

2019-09-17

Ben Ashbaugh

Added 3-component vector support for shuffles, restriction for block reads and writes and partial subgroups, and asciidoctor formatting fixes.