asc2.copy

asc2.copy(src: ~asc.language.tile.local_tensor.LocalTensor, offsets: ~typing.Iterable[~asc.language.core.ir_value.PlainValue | int] | None = None, shape: ~typing.Iterable[int] | None = None, location: ~asc._C.libpyasc.ir.TensorLocation = <TensorLocation.UB: 26>) LocalTensor

Copy a local tensor to a new local tensor, optionally reshaping and relocating.

Rationale: Unlike frameworks with simpler memory hierarchies (e.g., CUDA’s global/shared/registers), Ascend NPUs expose multiple local memory levels (L1, L0A, L0B, L0C, UB) where local-to-local transfers are common. copy_in and copy_out have clear directional semantics when one endpoint is global memory (“copy in = to local”, “copy out = to global”), but this breaks down for local-to-local transfers: the same L0C→L1 operation is a “copy out” from L0C’s perspective yet a “copy in” from L1’s. Local copy eliminates this ambiguity by providing a direction-agnostic operation that clearly expresses intent regardless of which memory level you’re reasoning from.

Parameters:
  • src – The source tensor to copy.

  • offsets – The offsets into the source tensor for each dimension. Default is zeros.

  • shape – The shape of the resulting tensor. If None, uses the source tensor’s shape. Must contain static values (e.g., ConstExpr or compile-time constants).

  • location – The memory location for the destination tensor. Default is TensorLocation.UB. Supported location transfers: L1 to L0A, L1 to L0B, L1 to BT, L0C to L1.

Returns:

A new tensor that is a copy of the source tensor

Return type:

LocalTensor

Raises:
  • TypeError – If src is not a LocalTensor or location is not a TensorLocation

  • RuntimeError – If shape is invalid, data alignment check fails, or offsets rank mismatch

Examples

Copy a tensor with the same shape:

src = asc2.copy_in(x_gm, [0], [128])
result = asc2.copy(src)

Copy a sub-tensor from a larger tensor with explicit shape and offsets:

src = asc2.copy_in(x_gm, [0, 0], [64, 64])
result = asc2.copy(src, [16, 16], [32, 32])

Copy a tensor to a different memory location (e.g., L0A for matrix multiplication):

a_l1 = asc2.copy_in(a_gm, [0, 0], [64, 128], asc2.TensorLocation.L1)
a_l0a = asc2.copy(a_l1, [0, 0], [64, 32], asc2.TensorLocation.L0A)
b_l0b = asc2.copy(b_l1, [0, 0], [32, 64], asc2.TensorLocation.L0B)

Copy accumulator result from L0C to L1:

acc = asc2.zeros_acc([64, 64], dtype=asc2.float32)
asc2.matmul_acc(acc, a_l0a, b_l0b)
result_l1 = asc2.copy(acc, location=asc2.TensorLocation.L1)