triton.language.extra.cann.extension.index_put
- triton.language.extra.cann.extension.index_put(ptr: tensor, index: tensor, value: tensor, dim: int, index_boundary: int, end_offset: tuple, start_offset: tuple, dst_stride: tuple, _semantic=None)
Index put values from a tensor into a destination tensor.
Index put operation for different tensor ranks:
- 2D index scatter (0 <= dim < 1):
1.1 dim = 0 out[index[i]][start_offset[1]:end_offset[1]] = value[i][0:end_offset[1]-start_offset[1]]
- 3D index scatter (0 <= dim < 2):
- 2.1 dim = 0
- out[index[i]][start_offset[1]:end_offset[1]][start_offset[2]:end_offset[2]]
= value[i][0:end_offset[1]-start_offset[1]][0:end_offset[2]-start_offset[2]]
- 2.2 dim = 1
- out[start_offset[0]:end_offset[0]][index[j]][start_offset[2]:end_offset[2]]
= value[0:end_offset[0]-start_offset[0]][j][0:end_offset[2]-start_offset[2]]
- 参数:
ptr (pointer type) -- The destination tensor pointer (in GM).
index (tensor) -- An index to scatter (in UB).
value (tensor) -- A value to store (in UB).
dim (int) -- The dimension to scatter along.
index_boundary (int) -- The upper boundary for index values (must be a compile-time constant).
end_offset (tuple of int) -- The offsets of each dimension for the end of the scatter region.
start_offset (tuple of int) -- The offsets of each dimension for the start of the scatter region.
dst_stride -- The stride of each dimension of destination tensor.
Example
import torch import triton import triton.language as tl from triton.language.extra.cann.extension import index_put from triton.tools.get_ascend_devices import is_compile_on_910_95 @triton.jit def kernel(value_ptr, index_ptr, dst_ptr): """ Test index_put with a 2D value and 1D index: 1. Load index tensor from GM (shape [2]) 2. Load value tensor from GM (shape [2, 2]) 3. Scatter value rows into dst at positions given by index along dim=0 4. The operation: dst[index[i], :] = value[i, :] """ # index tile shape: [2] index_local = tl.arange(0, 2) x1_local = tl.arange(0, 2)[None, :] # shape=(1,2) index_tile = tl.load(index_ptr + index_local) value_tile = tl.load(value_ptr + index_local[:, None] * 2 + x1_local) index_put(ptr=dst_ptr, index=index_tile, value=value_tile, dim=0, index_boundary=4, end_offset=(2, 2), start_offset=(0, 0), dst_stride=(2, 1)) def test_index_put(): # dst: (4,2) of zeros dst = torch.zeros((4, 2), device='npu', dtype=torch.float32) # value = [[1., 2.], # [3., 4.]] value = torch.tensor([[1., 2.], [3., 4.]], device='npu') # index = [2, 0] index = torch.tensor([2, 0], device='npu') kernel[(1, )](value, index, dst) # Reference: dst[index[i], :] = value[i, :] # dst[2, :] = value[0, :] = [1., 2.] # dst[0, :] = value[1, :] = [3., 4.] # expected = [[3., 4.], # [0., 0.], # [1., 2.], # [0., 0.]] expected = torch.tensor([[3., 4.], [0., 0.], [1., 2.], [0., 0.]], device='cpu') assert torch.allclose(dst.cpu(), expected), \ f"Mismatch: expected {expected}, got {dst.cpu()}" if __name__ == "__main__": if not is_compile_on_910_95: print("index_put is only supported on Ascend 950, skipping test.") else: test_index_put()
Special Restrictions
Only supported on Ascend 950.
ptr.dtype: only supports float16, bfloat16, float32.ptrandvaluemust have the same rank.index: must be an integer tensor. Ifindex.rank!= 1, it will be reshaped to 1D.index.numel: must equalvalue.shape[dim].value: supports 2~5D tensors.dim: must satisfy 0 <= dim < rank(value) - 1.