Tensor is a memoryview-backed object with NumPy-like metadata.
It is the central container for strided views, transpose, reshape, flatten, and axis reductions.
import numpy as npimport numkong as nkt = nk.Tensor(np.arange(12, dtype=np.float32).reshape(3, 4))print(t.shape, t.dtype, t.ndim, t.strides, t.itemsize, t.nbytes)print(np.asarray(t)) # zero-copy array view when layout allows itprint(t.T.shape) # transposed Tensor viewprint(t.reshape(2, 6).shape)print(t.flatten().shape)# Slicing — row, column, and scalar accessrow0 = t[0, :] # first row, shape (4,)col2 = t[:, 2] # third column, strided view, shape (3,)val = t[1, 2] # scalar element access → 6.0# Reductions compose with sliced viewsidx = col2.argmin() # index of the minimum in the third columnmn, i0, mx, i1 = col2.minmax()
The important layout rules are:
Tensor preserves shape and byte strides.
Transpose and slicing can produce non-contiguous views.
General reductions accept those views.
Matrix-style packed kernels require row-contiguous left operands.
Packed and symmetric outputs require C-contiguous out buffers.
Builds configured with -C cmake.define.NUMKONG_CUDA_ARCH=all or -C cmake.define.NUMKONG_ROCM_ARCH=all also carry the CUDA or ROCm kernels. nk.cuda_count_devices() counts the devices this process sees, zero without the runtime or its kernels, and nk.cuda_capabilities_enabled(0) reports the mask device 0 dispatches with, raising ValueError past the last. nk.cuda_capabilities_detected and nk.cuda_capabilities_compiled answer as their CPU twins do, nk.rocm_* and nk.metal_* do the same for the other vendors, and cpu_configure_thread is CPU only. nk.from_dlpack imports a CUDA or ROCm tensor without a copy and records its device.
Only dots_pack, the dots, angulars and euclideans _packed and _symmetric functions, and attention_pack, attention_packed and attention_packed_gradients run on it, with that device’s enabled capabilities.
The shape functions also take it for their outputs, running the mask their packs were copied with.
Element access, NumPy conversion, cdist, maxsim and every other CPU kernel raise BufferError rather than read device memory.
No verb allocates, so every GPU call writes into an out= its device reaches.
The dots and attention families take that as a Tensor on the same device, and mixing devices raises ValueError.
The shape functions take any memory the device reaches, a Tensor or a buffer over managed or pinned memory, which the runtime checks per call, raising BufferError for the rest.
Unified memory comes only from an explicit copy, as in nk.shapes_pack(clouds).copy(capabilities=gpu) and nk.zeros(shape).copy(capabilities=gpu), which frees with the tensor and its views and refuses resize() and reserve().
A GPU call queues one launch on stream=, an integer handle defaulting to 0, the legacy stream, and returns before it finishes, as PyTorch does, and nk.synchronize(capabilities, stream=stream) waits for it. nk.stream_init_cuda(ordinal) makes such a handle on any device by its ordinal, and nk.stream_free_cuda(stream) frees it once synchronized, with rocm_ and metal_ twins.
Metal tensors are host-readable and keep running on the CPU kernels, except the shape functions, which run on Metal over blocks of its allocator.
Supports NumPy-like properties and buffer protocol for interoperability.
Packed dtypes 'uint1', 'int4', 'uint4', and 'e2m1' count logical dimensions in shape;
the last dimension must be a multiple of the values per byte, and the buffer protocol,
__array_interface__, nbytes, and DLPack expose whole bytes.
TensorConstruct a Tensor by copying data from a buffer-protocol object; packed dtypes read its bytes.
Holds packed elements, per-block scales, and an optional per-tensor scale.
Produced by Tensor.astype('nvfp4'), Tensor.astype('mxfp4'), and similar block-scaled targets.
astypeMaterialize to a dense dtype, or transcode to another block-scaled dtype.
Accepts a PyCapsule named 'dltensor' or 'dltensor_versioned', or any object
with a __dlpack__ method (e.g. torch.Tensor, numpy.ndarray,
jax.Array). Only CPU tensors are supported.
emptyCreate an uninitialized Tensor of the given shape and dtype.
A supplied out must be writable, C-contiguous, have the exact input
shape and requested dtype, and must not overlap a. Returns out when
provided, otherwise a new Tensor.