(* ======================================================================== * SOVEREIGN LEVIATHAN NODE LICENSE * License-ID: SL-AGPL3-001 | Covenant-Version: 1.0 * Copyright (C) 2026 SnapKittyWest. Ahmad Ali Parr, Bel Esprit D'Accord Irrevocable Trust. * ======================================================================== * * This file is a covered work under the GNU Affero General Public License, * version 3, together with the Sovereign Leviathan additional terms. * * Hark, though this node be but a spark, * Its covenant endureth through the dark. * * Ignorantia juris non excusat. * ======================================================================== *) unit TensorCore; {$mode objfpc}{$H+} interface uses SysUtils, Math; const TENSORCORE_LINE_BUDGET = 250; type TFloatArray = array of Double; TIntArray = array of Integer; { Explicit tensor record. Data is row-major and Shape contains each dimension. } TTensor = record Data: TFloatArray; Shape: TIntArray; end; function TensorCreate(const Shape: array of Integer): TTensor; function TensorScalar(const Value: Double): TTensor; function TensorVector(const Values: array of Double): TTensor; function TensorMatrix(const Rows, Cols: Integer): TTensor; function TensorRank(const T: TTensor): Integer; function TensorSize(const T: TTensor): Integer; function TensorDim(const T: TTensor; const Axis: Integer): Integer; procedure TensorFill(var T: TTensor; const Value: Double); procedure TensorZeros(var T: TTensor); procedure TensorOnes(var T: TTensor); function TensorClone(const T: TTensor): TTensor; function TensorGet(const T: TTensor; const Index: Integer): Double; procedure TensorSet(var T: TTensor; const Index: Integer; const Value: Double); function TensorOffset2D( const T: TTensor; const Row, Col: Integer ): Integer; function TensorOffset3D( const T: TTensor; const A, B, C: Integer ): Integer; function TensorGet2D( const T: TTensor; const Row, Col: Integer ): Double; procedure TensorSet2D( var T: TTensor; const Row, Col: Integer; const Value: Double ); function TensorGet3D( const T: TTensor; const A, B, C: Integer ): Double; procedure TensorSet3D( var T: TTensor; const A, B, C: Integer; const Value: Double ); function TensorAdd( const A, B: TTensor ): TTensor; function TensorSub( const A, B: TTensor ): TTensor; function TensorScale( const A: TTensor; const S: Double ): TTensor; function TensorHadamard( const A, B: TTensor ): TTensor; function TensorAddInPlace( var A: TTensor; const B: TTensor ): Boolean; function TensorScaleInPlace( var A: TTensor; const S: Double ): Boolean; function TensorMatMul( const A, B: TTensor ): TTensor; function TensorTranspose2D( const A: TTensor ): TTensor; function TensorTranspose( const A: TTensor; const Axis0, Axis1: Integer ): TTensor; function TensorReshape( const A: TTensor; const NewShape: array of Integer ): TTensor; function TensorFlatten( const A: TTensor ): TTensor; function TensorDot( const A, B: TTensor ): Double; function TensorSum( const A: TTensor ): Double; function TensorMean( const A: TTensor ): Double; function TensorMax( const A: TTensor ): Double; function TensorArgMax( const A: TTensor ): Integer; procedure TensorRandomSeed( const Seed: Integer ); function TensorRandomUniform( const Shape: array of Integer; const MinValue, MaxValue: Double ): TTensor; function TensorRandomNormal( const Shape: array of Integer; const Mean, StdDev: Double ): TTensor; function TensorXavierUniform( const Rows, Cols: Integer ): TTensor; function TensorXavierNormal( const Rows, Cols: Integer ): TTensor; function TensorIsFinite( const A: TTensor ): Boolean; function TensorMaxAbs( const A: TTensor ): Double; function TensorL2Norm( const A: TTensor ): Double; function TensorSameShape( const A, B: TTensor ): Boolean; function TensorShapeString( const A: TTensor ): string; procedure TensorSave( const FileName: string; const A: TTensor ); function TensorLoad( const FileName: string ): TTensor; procedure TensorAssert( const Condition: Boolean; const Message: string ); implementation function ProductOfShape( const Shape: array of Integer ): Integer; var I: Integer; begin Result := 1; for I := Low(Shape) to High(Shape) do begin if Shape[I] <= 0 then raise EArgumentException.Create( 'Tensor dimensions must be positive' ); Result := Result * Shape[I]; end; end; function ProductOfShapeArray( const Shape: TIntArray ): Integer; var I: Integer; begin Result := 1; for I := Low(Shape) to High(Shape) do begin if Shape[I] <= 0 then raise EArgumentException.Create( 'Tensor dimensions must be positive' ); Result := Result * Shape[I]; end; end; procedure CheckSameShape( const A, B: TTensor ); begin if not TensorSameShape(A, B) then raise EArgumentException.Create( 'Tensor shape mismatch: ' + TensorShapeString(A) + ' versus ' + TensorShapeString(B) ); end; procedure Check2D( const T: TTensor; const Name: string ); begin if TensorRank(T) <> 2 then raise EArgumentException.Create( Name + ' must be rank 2' ); end; function TensorCreate( const Shape: array of Integer ): TTensor; var I: Integer; begin SetLength(Result.Shape, Length(Shape)); for I := Low(Shape) to High(Shape) do Result.Shape[I] := Shape[I]; SetLength( Result.Data, ProductOfShape(Shape) ); TensorZeros(Result); end; function TensorScalar( const Value: Double ): TTensor; begin Result := TensorCreate([1]); Result.Data[0] := Value; end; function TensorVector( const Values: array of Double ): TTensor; var I: Integer; begin Result := TensorCreate([Length(Values)]); for I := Low(Values) to High(Values) do Result.Data[I] := Values[I]; end; function TensorMatrix( const Rows, Cols: Integer ): TTensor; begin Result := TensorCreate([Rows, Cols]); end; function TensorRank( const T: TTensor ): Integer; begin Result := Length(T.Shape); end; function TensorSize( const T: TTensor ): Integer; begin Result := Length(T.Data); end; function TensorDim( const T: TTensor; const Axis: Integer ): Integer; begin if (Axis < 0) or (Axis >= TensorRank(T)) then raise EArgumentOutOfRangeException.Create( 'Tensor axis out of range' ); Result := T.Shape[Axis]; end; procedure TensorFill( var T: TTensor; const Value: Double ); var I: Integer; begin for I := 0 to High(T.Data) do T.Data[I] := Value; end; procedure TensorZeros( var T: TTensor ); begin TensorFill(T, 0.0); end; procedure TensorOnes( var T: TTensor ); begin TensorFill(T, 1.0); end; function TensorClone( const T: TTensor ): TTensor; begin Result.Shape := Copy( T.Shape, 0, Length(T.Shape) ); Result.Data := Copy( T.Data, 0, Length(T.Data) ); end; function TensorGet( const T: TTensor; const Index: Integer ): Double; begin if (Index < 0) or (Index >= Length(T.Data)) then raise EArgumentOutOfRangeException.Create( 'Tensor data index out of range' ); Result := T.Data[Index]; end; procedure TensorSet( var T: TTensor; const Index: Integer; const Value: Double ); begin if (Index < 0) or (Index >= Length(T.Data)) then raise EArgumentOutOfRangeException.Create( 'Tensor data index out of range' ); T.Data[Index] := Value; end; function TensorOffset2D( const T: TTensor; const Row, Col: Integer ): Integer; begin Check2D(T, 'Tensor'); if (Row < 0) or (Row >= T.Shape[0]) or (Col < 0) or (Col >= T.Shape[1]) then raise EArgumentOutOfRangeException.Create( '2D tensor index out of range' ); Result := Row * T.Shape[1] + Col; end; function TensorOffset3D( const T: TTensor; const A, B, C: Integer ): Integer; begin if TensorRank(T) <> 3 then raise EArgumentException.Create( 'Tensor must be rank 3' ); if (A < 0) or (A >= T.Shape[0]) or (B < 0) or (B >= T.Shape[1]) or (C < 0) or (C >= T.Shape[2]) then raise EArgumentOutOfRangeException.Create( '3D tensor index out of range' ); Result := (A * T.Shape[1] * T.Shape[2]) + (B * T.Shape[2]) + C; end; function TensorGet2D( const T: TTensor; const Row, Col: Integer ): Double; begin Result := T.Data[ TensorOffset2D(T, Row, Col) ]; end; procedure TensorSet2D( var T: TTensor; const Row, Col: Integer; const Value: Double ); begin T.Data[ TensorOffset2D(T, Row, Col) ] := Value; end; function TensorGet3D( const T: TTensor; const A, B, C: Integer ): Double; begin Result := T.Data[ TensorOffset3D(T, A, B, C) ]; end; procedure TensorSet3D( var T: TTensor; const A, B, C: Integer; const Value: Double ); begin T.Data[ TensorOffset3D(T, A, B, C) ] := Value; end; function TensorAdd( const A, B: TTensor ): TTensor; var I: Integer; begin CheckSameShape(A, B); Result := TensorClone(A); for I := 0 to High(Result.Data) do Result.Data[I] := A.Data[I] + B.Data[I]; end; function TensorSub( const A, B: TTensor ): TTensor; var I: Integer; begin CheckSameShape(A, B); Result := TensorClone(A); for I := 0 to High(Result.Data) do Result.Data[I] := A.Data[I] - B.Data[I]; end; function TensorScale( const A: TTensor; const S: Double ): TTensor; var I: Integer; begin Result := TensorClone(A); for I := 0 to High(Result.Data) do Result.Data[I] := A.Data[I] * S; end; function TensorHadamard( const A, B: TTensor ): TTensor; var I: Integer; begin CheckSameShape(A, B); Result := TensorClone(A); for I := 0 to High(Result.Data) do Result.Data[I] := A.Data[I] * B.Data[I]; end; function TensorAddInPlace( var A: TTensor; const B: TTensor ): Boolean; var I: Integer; begin Result := False; if not TensorSameShape(A, B) then Exit; for I := 0 to High(A.Data) do A.Data[I] := A.Data[I] + B.Data[I]; Result := True; end; function TensorScaleInPlace( var A: TTensor; const S: Double ): Boolean; var I: Integer; begin for I := 0 to High(A.Data) do A.Data[I] := A.Data[I] * S; Result := True; end; function TensorMatMul( const A, B: TTensor ): TTensor; var M, K, N: Integer; I, J, P: Integer; Sum: Double; begin Check2D(A, 'A'); Check2D(B, 'B'); M := A.Shape[0]; K := A.Shape[1]; if B.Shape[0] <> K then raise EArgumentException.Create( 'MatMul inner dimensions do not match' ); N := B.Shape[1]; Result := TensorMatrix(M, N); for I := 0 to M - 1 do for J := 0 to N - 1 do begin Sum := 0.0; for P := 0 to K - 1 do Sum := Sum + A.Data[I * K + P] * B.Data[P * N + J]; Result.Data[I * N + J] := Sum; end; end; function TensorTranspose2D( const A: TTensor ): TTensor; var I, J: Integer; begin Check2D(A, 'Tensor'); Result := TensorMatrix( A.Shape[1], A.Shape[0] ); for I := 0 to A.Shape[0] - 1 do for J := 0 to A.Shape[1] - 1 do Result.Data[ J * A.Shape[0] + I ] := A.Data[ I * A.Shape[1] + J ]; end; function TensorTranspose( const A: TTensor; const Axis0, Axis1: Integer ): TTensor; var R, I, J, K: Integer; NewShape: TIntArray; SourceIndex, TargetIndex: Integer; StrideSource, StrideTarget: TIntArray; begin R := TensorRank(A); if (Axis0 < 0) or (Axis0 >= R) or (Axis1 < 0) or (Axis1 >= R) then raise EArgumentOutOfRangeException.Create( 'Transpose axis out of range' ); NewShape := Copy(A.Shape, 0, R); NewShape[Axis0] := A.Shape[Axis1]; NewShape[Axis1] := A.Shape[Axis0]; Result := TensorCreate(NewShape); SetLength( StrideSource, R ); SetLength( StrideTarget, R ); StrideSource[R - 1] := 1; StrideTarget[R - 1] := 1; for I := R - 2 downto 0 do begin StrideSource[I] := StrideSource[I + 1] * A.Shape[I + 1]; StrideTarget[I] := StrideTarget[I + 1] * Result.Shape[I + 1]; end; for I := 0 to TensorSize(A) - 1 do begin SourceIndex := I; TargetIndex := 0; for J := 0 to R - 1 do begin K := SourceIndex div StrideSource[J]; SourceIndex := SourceIndex mod StrideSource[J]; if J = Axis0 then TargetIndex := TargetIndex + K * StrideTarget[Axis1] else if J = Axis1 then TargetIndex := TargetIndex + K * StrideTarget[Axis0] else TargetIndex := TargetIndex + K * StrideTarget[J]; end; Result.Data[TargetIndex] := A.Data[I]; end; end; function TensorReshape( const A: TTensor; const NewShape: array of Integer ): TTensor; var NewSize: Integer; begin NewSize := ProductOfShape(NewShape); if NewSize <> TensorSize(A) then raise EArgumentException.Create( 'Reshape changes tensor element count' ); Result.Shape := Copy( NewShape, 0, Length(NewShape) ); Result.Data := Copy( A.Data, 0, Length(A.Data) ); end; function TensorFlatten( const A: TTensor ): TTensor; begin Result := TensorReshape( A, [TensorSize(A)] ); end; function TensorDot( const A, B: TTensor ): Double; var I: Integer; begin CheckSameShape(A, B); Result := 0.0; for I := 0 to High(A.Data) do Result := Result + A.Data[I] * B.Data[I]; end; function TensorSum( const A: TTensor ): Double; var I: Integer; begin Result := 0.0; for I := 0 to High(A.Data) do Result := Result + A.Data[I]; end; function TensorMean( const A: TTensor ): Double; begin if TensorSize(A) = 0 then raise EArgumentException.Create( 'Mean of empty tensor' ); Result := TensorSum(A) / TensorSize(A); end; function TensorMax( const A: TTensor ): Double; var I: Integer; begin if TensorSize(A) = 0 then raise EArgumentException.Create( 'Maximum of empty tensor' ); Result := A.Data[0]; for I := 1 to High(A.Data) do if A.Data[I] > Result then Result := A.Data[I]; end; function TensorArgMax( const A: TTensor ): Integer; var I: Integer; begin if TensorSize(A) = 0 then raise EArgumentException.Create( 'ArgMax of empty tensor' ); Result := 0; for I := 1 to High(A.Data) do if A.Data[I] > A.Data[Result] then Result := I; end; procedure TensorRandomSeed( const Seed: Integer ); begin RandSeed := Seed; end; function RandomUnit: Double; begin Result := Random; end; function RandomGaussian: Double; var U1, U2: Double; begin U1 := RandomUnit; if U1 <= 1E-12 then U1 := 1E-12; U2 := RandomUnit; Result := Sqrt( -2.0 * Ln(U1) ) * Cos( 2.0 * Pi * U2 ); end; function TensorRandomUniform( const Shape: array of Integer; const MinValue, MaxValue: Double ): TTensor; var I: Integer; begin Result := TensorCreate(Shape); for I := 0 to High(Result.Data) do Result.Data[I] := MinValue + RandomUnit * (MaxValue - MinValue); end; function TensorRandomNormal( const Shape: array of Integer; const Mean, StdDev: Double ): TTensor; var I: Integer; begin Result := TensorCreate(Shape); for I := 0 to High(Result.Data) do Result.Data[I] := Mean + StdDev * RandomGaussian; end; function TensorXavierUniform( const Rows, Cols: Integer ): TTensor; var Limit: Double; begin Limit := Sqrt( 6.0 / (Rows + Cols) ); Result := TensorRandomUniform( [Rows, Cols], -Limit, Limit ); end; function TensorXavierNormal( const Rows, Cols: Integer ): TTensor; var StdDev: Double; begin StdDev := Sqrt( 2.0 / (Rows + Cols) ); Result := TensorRandomNormal( [Rows, Cols], 0.0, StdDev ); end; function TensorIsFinite( const A: TTensor ): Boolean; var I: Integer; begin Result := True; for I := 0 to High(A.Data) do if IsNan(A.Data[I]) or IsInfinite(A.Data[I]) then Exit(False); end; function TensorMaxAbs( const A: TTensor ): Double; var I: Integer; V: Double; begin Result := 0.0; for I := 0 to High(A.Data) do begin V := Abs(A.Data[I]); if V > Result then Result := V; end; end; function TensorL2Norm( const A: TTensor ): Double; var I: Integer; SumSquares: Double; begin SumSquares := 0.0; for I := 0 to High(A.Data) do SumSquares := SumSquares + A.Data[I] * A.Data[I]; Result := Sqrt(SumSquares); end; function TensorSameShape( const A, B: TTensor ): Boolean; var I: Integer; begin Result := TensorRank(A) = TensorRank(B); if not Result then Exit; for I := 0 to TensorRank(A) - 1 do if A.Shape[I] <> B.Shape[I] then Exit(False); end; function TensorShapeString( const A: TTensor ): string; var I: Integer; begin Result := '['; for I := 0 to High(A.Shape) do begin if I > 0 then Result := Result + 'x'; Result := Result + IntToStr(A.Shape[I]); end; Result := Result + ']'; end; procedure TensorSave( const FileName: string; const A: TTensor ); var F: TFileStream; Rank: Integer; DataCount: Integer; begin F := TFileStream.Create( FileName, fmCreate ); try Rank := TensorRank(A); DataCount := TensorSize(A); F.WriteBuffer( Rank, SizeOf(Rank) ); if Rank > 0 then F.WriteBuffer( A.Shape[0], Rank * SizeOf(Integer) ); F.WriteBuffer( DataCount, SizeOf(DataCount) ); if DataCount > 0 then F.WriteBuffer( A.Data[0], DataCount * SizeOf(Double) ); finally F.Free; end; end; function TensorLoad( const FileName: string ): TTensor; var F: TFileStream; Rank: Integer; DataCount: Integer; I: Integer; begin F := TFileStream.Create( FileName, fmOpenRead or fmShareDenyWrite ); try F.ReadBuffer( Rank, SizeOf(Rank) ); if Rank < 0 then raise EInvalidData.Create( 'Invalid tensor rank' ); SetLength( Result.Shape, Rank ); if Rank > 0 then F.ReadBuffer( Result.Shape[0], Rank * SizeOf(Integer) ); for I := 0 to Rank - 1 do if Result.Shape[I] <= 0 then raise EInvalidData.Create( 'Invalid tensor dimension' ); F.ReadBuffer( DataCount, SizeOf(DataCount) ); if DataCount <> ProductOfShapeArray(Result.Shape) then raise EInvalidData.Create( 'Tensor data count does not match shape' ); SetLength( Result.Data, DataCount ); if DataCount > 0 then F.ReadBuffer( Result.Data[0], DataCount * SizeOf(Double) ); finally F.Free; end; end; procedure TensorAssert( const Condition: Boolean; const Message: string ); begin if not Condition then raise EAssertionFailed.Create( Message ); end; end.