Tensor API
Tensor API
Pml\Tensor is the numeric core of the framework. It wraps a native C tensor and exposes fast vectorized operators, linear algebra, and zero-copy views.
Overview
The tensor API is designed for high-performance numeric work with a PHP-friendly wrapper.
The native C backend supports:
- dense tensor creation and views
- arithmetic and reductions
- BLAS-backed matrix multiplication
- convolution and attention primitives
- SafeTensors serialization and mmap-backed loading
- zero-copy dataset ingestion from CSV
API Signature
final class Tensor
Construction
public function __construct(array $shape = [], int $dtype = self::DTYPE_FLOAT32, ?\FFI\CData $arena = null)
public static function wrap(?\FFI\CData $ptr, ?self $parent = null): self
public static function fromArray(array $data, int $dtype = self::DTYPE_FLOAT32): self
public static function zeros(int ...$shape): self
public static function ones(int ...$shape): self
public static function randomNormal(array $shape, float $mean = 0.0, float $stddev = 1.0, ?\FFI\CData $arena = null): self
public static function randomUniform(array $shape, float $minVal = 0.0, float $maxVal = 1.0, ?\FFI\CData $arena = null): self
public static function range(float $start, float $end, float $step = 1.0): self
public static function linspace(float $start, float $end, int $steps): self
Metadata and shape
public function dtype(): int
public function shape(): array
public function size(): int
public function ndim(): int
public function isContiguous(): bool
public function contiguous(): self
Zero-copy views
public function view(): self
public function slice(int $axis, int $start, int $length): self
public function sliceStep(int $axis, int $start, int $end, int $step): self
public function row(int $row): self
public function col(int $col): self
Shape and layout operations
public function reshape(int ...$newShape): self
public function flatten(): self
public function expandDims(int $axis): self
public function squeeze(): self
public function transpose(): self
public function transposeNd(array $axes): self
public function swapaxes(int $axis1, int $axis2): self
Arithmetic
public function add(Tensor $b): self
public function sub(Tensor $b): self
public function mul(Tensor $b): self
public function div(Tensor $b): self
public function addScalar(float $val): self
public function mulScalar(float $val): self
public function pow(Tensor $b): self
public function clip(float $min, float $max): self
In-place arithmetic
public function addInplace(Tensor $b): self
public function subInplace(Tensor $b): self
public function mulInplace(Tensor $b): self
public function divInplace(Tensor $b): self
public function addScalarInplace(float $val): self
public function mulScalarInplace(float $val): self
Unary functions
public function sqrt(): self
public function square(): self
public function abs(): self
public function sign(): self
public function exp(): self
public function log(): self
public function log1p(): self
public function round(): self
public function floor(): self
public function ceil(): self
public function sigmoid(): self
public function tanh(): self
public function relu(): self
public function sin(): self
public function cos(): self
public function tan(): self
public function asin(): self
public function acos(): self
public function atan(): self
Logical operations
public function equal(Tensor $b): self
public function notEqual(Tensor $b): self
public function greater(Tensor $b): self
public function greaterEqual(Tensor $b): self
public function less(Tensor $b): self
public function lessEqual(Tensor $b): self
public function logicalNot(): self
NaN / Inf handling
public function isNan(): self
public function isInf(): self
public function nanToNumInplace(float $nan_val = 0.0, float $posinf = 1e38, float $neginf = -1e38): self
public function any(): bool
public function all(): bool
Indexing and selection
public function where(Tensor $x, Tensor $y): self
public function booleanIndex(Tensor $mask): self
public function take(Tensor $indices, int $axis): self
public function unique(): self
public function bincount(): self
Concatenation and padding
public static function concat(array $tensors, int $axis): self
public function pad(array $padWidth, float $constantValue = 0.0): self
Sorting and aggregation
public function argsort(int $axis = -1): self
public function sort(int $axis = -1): self
public function topk(int $k, int $axis = -1): self
public function sum(): float
public function product(): float
public function mean(): float
public function min(): float
public function max(): float
public function argmin(): int
public function argmax(): int
public function variance(): float
public function std(): float
public function median(): float
public function sumAxis(int $axis): self
public function meanAxis(int $axis): self
public function maxAxis(int $axis): self
public function minAxis(int $axis): self
public function cumsum(int $axis): self
public function sumMulti(array $axes): self
public function meanMulti(array $axes): self
public function maxMulti(array $axes): self
Normalization
public function normalize(): self
public function standardize(): self
public function normalizeInplace(): self
public function standardizeInplace(): self
Linear algebra
public function dot(Tensor $b): float
public function trace(): float
public function matmul(Tensor $b, bool $transA = false, bool $transB = false): self
public function matmulInto(Tensor $A, Tensor $B, bool $transA = false, bool $transB = false): void
public function sumAxisInto(Tensor $A, int $axis): void
public function bmm(Tensor $b): self
public function inverse(): self
public function pinv(): self
public function solve(Tensor $B): self
public function cholesky(): self
public function lu(): array
public function svd(): array
public function eigenSym(): array
public function ref(): self
public function rref(): self
Deep learning primitives
public function linear(Tensor $W, ?Tensor $bias = null): self
public function addRelu(Tensor $b): self
public function mulAdd(Tensor $B, Tensor $C): self
public function im2col(int $kernel_h, int $kernel_w, int $stride_h, int $stride_w, int $pad_h, int $pad_w): self
public function col2im(int $batch, int $channels, int $height, int $width, int $kernel_h, int $kernel_w, int $stride_h, int $stride_w, int $pad_h, int $pad_w): self
public function conv2d(Tensor $W, ?Tensor $bias = null, int $stride_h = 1, int $stride_w = 1, int $pad_h = 0, int $pad_w = 0): self
public function conv2dBackward(Tensor $X, Tensor $W, int $stride_h = 1, int $stride_w = 1, int $pad_h = 0, int $pad_w = 0): array
public function embeddingLookup(Tensor $weights): self
Transformer and attention primitives
public function rmsnorm(float $eps = 1e-5): void
public function applyRope(Tensor $k, int $headDim, int $pos, float $baseFreq = 10000.0, float $scale = 1.0): void
public function softmaxInplace(): void
public function attention(Tensor $k, Tensor $v): self
public function attentionKV(KVCache $cache): self
Persistence and I/O
public function save(string $filepath): void
public static function load(string $filepath): self
public static function saveSafetensors(string $filepath, string $jsonHeader, array $tensors): int
public static function datasetFromCsv(string $filepath, int $labelCol = -1, bool $hasHeader = true): array
public static function fromMmap(string $filepath, int $byteOffset, array $shape, int $dtype = 0): self
public function mmapFree(): void
public function copyFrom(Tensor $src): void
public function toFlatArray(): array
public function buffer(): \FFI\CData
Advanced utilities
public static function configureThreading(int $ompThreads, int $blasThreads = 1): void
What it does
Tensor wraps the native TensorC pointer and offers a PHP-friendly API for high-performance numeric operations. Most methods call C kernels and return new tensors with C-managed data.
When to use it
- Use
Tensorfor matrix math and neural network computation. - Use zero-copy views for slicing and batching.
- Use
fromArray()to convert small PHP arrays into native tensors. - Use
toFlatArray()only for final export or debugging.
Parameters
| Parameter | Type | Description |
|---|---|---|
shape |
array |
Tensor dimensions, e.g. [2, 3]. |
dtype |
int |
One of Tensor::DTYPE_FLOAT32, DTYPE_INT32, DTYPE_INT64. |
axis |
int |
Axis index for slicing or aggregation. |
indices |
Tensor |
Tensor of integer positions. |
mask |
Tensor |
Boolean mask tensor. |
padWidth |
array |
Padding width per axis. |
k |
int |
Number of top elements to select. |
Return values
- Most operations return a new
Tensorobject backed by native C memory. - In-place methods return the same tensor instance.
sum(),mean(), and similar aggregations return scalars.lu()andsvd()return arrays of tensors.
Example Usage
use Pml\Tensor;
$x = Tensor::fromArray([[1.0, 2.0], [3.0, 4.0]]);
$w = Tensor::ones(2, 2);
$y = $x->matmul($w)->relu();
$view = $y->slice(0, 0, 1); // first row, zero-copy
print_r($view->toFlatArray());
$z = $y->sumAxis(0);
var_export($z->toFlatArray());
Performance notes
Tensor::fromArray()packs the PHP values into a binary string and performs a singleFFI::memcpy.- Views such as
slice()retain a parent reference to avoid freeing shared memory. configureThreading()controls OpenMP and BLAS so you can prevent CPU oversubscription.saveSafetensors()writes tensor bytes via the native kernel rather than through PHP.
Common mistakes
- Calling
toFlatArray()inside the training loop forces a full copy. - Forgetting to retain the parent reference for view tensors can lead to use-after-free bugs;
Tensorhandles that internally. - Assuming
reshape()modifies the tensor in-place; it returns a new view. - Passing
Tensorobjects of mismatched dtype to operations that require the same dtype.