This document is relevant for: Trn2, Trn3
nki.isa.NkiScalar#
- class nki.isa.NkiScalar(state, dtype=None, is_comparison=False)[source]#
NkiScalar is the core scalar type in NKI. It holds one integer, computed on device, and can be used as an operand of arithmetic, as the
scalar_offsetof an access pattern, and as a bound ofnki.language.fori_loop().NkiScalars are instantiated from values in a NkiTensor where dtype is either
nl.int32ornl.int64, vianki.isa.scalar_load().A NkiScalar can be used almost anywhere a Python
intliteral is used, and the other operand of an arithmetic operator may be a Pythonintor another NkiScalar so long as the dtypes match. Every operator returns a new NkiScalar.Width is fixed at creation. A 32-bit scalar is never widened, so arithmetic that outgrows 32 bits wraps rather than promoting:
100000 * 100000yields1410065408, and adding 1 to the largestnl.int32yields the smallest. Load from annl.int64tile when a value needs more range.Not every operation exists at both widths. At 64 bits only addition, subtraction and multiplication are available:
Operation
nl.int32nl.int64+,-(binary and unary),*Supported
Supported
<,<=,>,>=,==,!=Traced, but the result cannot be used
Rejected at compile time
Bound of
nki.language.fori_loop()Supported, including an arithmetic expression
Not supported; the trip-count comparison has no 64-bit form
scalar_offseton an HBM access patternSupported
Supported, including offsets beyond 4GB
scalar_offseton an SBUF or PSUM access patternSupported
Not supported; an on-chip offset must be 32 bits
A scalar has no Python value.
bool(s),int(s),float(s), using a scalar as a Python index (range(s),some_list[s]), and using one in anif,while, orassertcondition are all rejected, under the CPU simulator as well as the tracer, because the value arrives only when the kernel runs. Indexing a tensor with a scalar works throughnki.language.ds():t[nl.ds(s, 8)]andselect()both take one, as doesscalar_offset. A slice bound cannot be a scalar, because a slice needs both bounds while the kernel is built.nki.language.fori_loop()takes a scalar bound directly.Choosing a width for addressing.
scalar_offsetcounts elements of the access pattern’s indirect dimension, not bytes, and neuronx-cc scales that count by the dimension’s stride when it forms the address, so a 32-bit index reaches well past 4GB: rows of 512nl.float32values are 2KB apart, so2**31of them span roughly 4TB. Annl.int64offset is needed when the index value itself passes2**31– when element-indexing a tensor of more than2**31elements, for instance.Create scalars via
nki.isa.scalar_load(). See NKI Scalar Values for a walkthrough with runnable examples.Methods
Attributes
The NKI dtype name, e.g.
- property dtype#
The NKI dtype name, e.g.
"int32".
This document is relevant for: Trn2, Trn3