Download pascal/ffi/tensor_abi.pas from Snapkitty/sparse-router-formal: direct link, hf CLI and curl.
- Browser
- Download file 9.64 kB
-
https://huggingface.co/Snapkitty/sparse-router-formal/resolve/main/pascal/ffi/tensor_abi.pas
- Command line
-
hf download hf://Snapkitty/sparse-router-formal/pascal/ffi/tensor_abi.pas
-
curl -L -o tensor_abi.pas https://huggingface.co/Snapkitty/sparse-router-formal/resolve/main/pascal/ffi/tensor_abi.pas
9.64 kB
| { SPDX-License-Identifier: LicenseRef-Sovereign-Leviathan-SL-AGPL3-001 | |
| Licensing: see LICENSE in the repository root. } | |
| { ============================================================================ | |
| NraayTensor FFI ABI Bindings for Free Pascal | |
| Provides Pascal-idiomatic bindings to the Rust tensor FFI layer. | |
| All operations are thin wrappers around C FFI calls into tensor_ffi.rs. | |
| The Pascal implementation remains independent for validation. | |
| These bindings allow Pascal to invoke Rust tensor operations for | |
| conformance testing and oracle comparison. | |
| ============================================================================ } | |
| unit TensorABI; | |
| interface | |
| uses | |
| Classes, SysUtils, TypInfo; | |
| type | |
| { ======================================================================== | |
| Tensor Descriptor — mirrors C ABI | |
| ======================================================================== } | |
| TTensorDescriptorC = packed record | |
| buffer_id: UInt64; | |
| base_addr: UInt64; | |
| offset: UInt64; | |
| rank: UInt32; | |
| element_count: UInt64; | |
| shape_ptr: UInt64; | |
| stride_ptr: UInt64; | |
| governance: Byte; | |
| ownership: Byte; | |
| materialized: Byte; | |
| state: Byte; | |
| generation: UInt64; | |
| end; | |
| PTensorDescriptorC = ^TTensorDescriptorC; | |
| { ======================================================================== | |
| Result Structure | |
| ======================================================================== } | |
| TTensorResultC = packed record | |
| success: Int32; | |
| error_code: UInt32; | |
| error_msg: array[0..255] of AnsiChar; | |
| end; | |
| { ======================================================================== | |
| Operation Result | |
| ======================================================================== } | |
| TTensorOpResultC = packed record | |
| descriptor: TTensorDescriptorC; | |
| result: TTensorResultC; | |
| end; | |
| { ======================================================================== | |
| Ownership State Enumeration | |
| ======================================================================== } | |
| TOwnershipState = ( | |
| OWNERSHIP_OWNED = 0, | |
| OWNERSHIP_SHARED = 1, | |
| OWNERSHIP_EXCLUSIVE = 2 | |
| ); | |
| { ======================================================================== | |
| Governance State Enumeration | |
| ======================================================================== } | |
| TGovernanceState = ( | |
| GOVERNANCE_SHARED = 0, { B=0: shared/non-canonical } | |
| GOVERNANCE_CANONICAL = 1 { B=1: canonical/contiguous } | |
| ); | |
| { ============================================================================ | |
| FFI Declarations — map to Rust tensor_ffi.rs | |
| ============================================================================ } | |
| { External C function declarations } | |
| function tensor_allocate( | |
| rank: UInt32; | |
| shape: PUInt64; | |
| element_size: UInt64 | |
| ): TTensorOpResultC; cdecl; external; | |
| function tensor_deallocate( | |
| desc: PTensorDescriptorC | |
| ): TTensorResultC; cdecl; external; | |
| function tensor_view( | |
| source: PTensorDescriptorC; | |
| start_indices: PUInt64; | |
| end_indices: PUInt64 | |
| ): TTensorOpResultC; cdecl; external; | |
| function tensor_materialize( | |
| source: PTensorDescriptorC | |
| ): TTensorOpResultC; cdecl; external; | |
| function tensor_validate_generation( | |
| desc: PTensorDescriptorC | |
| ): TTensorResultC; cdecl; external; | |
| function tensor_load( | |
| desc: PTensorDescriptorC; | |
| indices: PUInt64; | |
| out_value: PSingle | |
| ): TTensorResultC; cdecl; external; | |
| function tensor_store( | |
| desc: PTensorDescriptorC; | |
| indices: PUInt64; | |
| value: Single | |
| ): TTensorResultC; cdecl; external; | |
| function tensor_info( | |
| desc: PTensorDescriptorC; | |
| out_buffer: PByte; | |
| out_len: SizeInt | |
| ): TTensorResultC; cdecl; external; | |
| { ============================================================================ | |
| Pascal Wrapper Functions (idiomatic error handling) | |
| ============================================================================ } | |
| type | |
| EFTensorError = class(Exception); | |
| { Allocate tensor, raise exception on failure } | |
| procedure FTensorAllocate( | |
| out Desc: TTensorDescriptorC; | |
| Rank: UInt32; | |
| const Shape: array of UInt64; | |
| ElementSize: UInt64 = 4 | |
| ); | |
| { Deallocate tensor, raise exception on failure } | |
| procedure FTensorDeallocate(const Desc: TTensorDescriptorC); | |
| { Create view, raise exception on failure } | |
| procedure FTensorView( | |
| out ViewDesc: TTensorDescriptorC; | |
| const Source: TTensorDescriptorC; | |
| const StartIndices, EndIndices: array of UInt64 | |
| ); | |
| { Materialize view, raise exception on failure } | |
| procedure FTensorMaterialize( | |
| out MatDesc: TTensorDescriptorC; | |
| const Source: TTensorDescriptorC | |
| ); | |
| { Validate generation (stale descriptor check) } | |
| function FTensorValidateGeneration(const Desc: TTensorDescriptorC): Boolean; | |
| { Load element value } | |
| function FTensorLoad( | |
| const Desc: TTensorDescriptorC; | |
| const Indices: array of UInt64 | |
| ): Single; | |
| { Store element value } | |
| procedure FTensorStore( | |
| const Desc: TTensorDescriptorC; | |
| const Indices: array of UInt64; | |
| Value: Single | |
| ); | |
| { Get info string (for debugging) } | |
| function FTensorInfo(const Desc: TTensorDescriptorC): String; | |
| { Helper: check result and raise on error } | |
| procedure CheckFTensorResult(const Result: TTensorResultC; const Context: String); | |
| implementation | |
| procedure CheckFTensorResult(const Result: TTensorResultC; const Context: String); | |
| var | |
| ErrorMsg: String; | |
| begin | |
| if Result.success = 0 then | |
| begin | |
| SetLength(ErrorMsg, 256); | |
| ErrorMsg := PAnsiChar(@Result.error_msg[0]); | |
| raise EFTensorError.Create( | |
| Format('[%s] Error %d: %s', [Context, Result.error_code, ErrorMsg]) | |
| ); | |
| end; | |
| end; | |
| procedure FTensorAllocate( | |
| out Desc: TTensorDescriptorC; | |
| Rank: UInt32; | |
| const Shape: array of UInt64; | |
| ElementSize: UInt64 = 4 | |
| ); | |
| var | |
| OpResult: TTensorOpResultC; | |
| ShapeArray: array of UInt64; | |
| I: Integer; | |
| begin | |
| if Rank = 0 then | |
| raise EFTensorError.Create('Rank must be > 0'); | |
| if Rank <> High(Shape) + 1 then | |
| raise EFTensorError.Create('Shape array length mismatch'); | |
| { Copy shape to heap } | |
| SetLength(ShapeArray, Rank); | |
| for I := Low(Shape) to High(Shape) do | |
| ShapeArray[I] := Shape[I]; | |
| { Call FFI } | |
| OpResult := tensor_allocate(Rank, @ShapeArray[0], ElementSize); | |
| CheckFTensorResult(OpResult.result, 'tensor_allocate'); | |
| Desc := OpResult.descriptor; | |
| end; | |
| procedure FTensorDeallocate(const Desc: TTensorDescriptorC); | |
| var | |
| LocalDesc: TTensorDescriptorC; | |
| Result: TTensorResultC; | |
| begin | |
| LocalDesc := Desc; | |
| Result := tensor_deallocate(@LocalDesc); | |
| CheckFTensorResult(Result, 'tensor_deallocate'); | |
| end; | |
| procedure FTensorView( | |
| out ViewDesc: TTensorDescriptorC; | |
| const Source: TTensorDescriptorC; | |
| const StartIndices, EndIndices: array of UInt64 | |
| ); | |
| var | |
| OpResult: TTensorOpResultC; | |
| SrcCopy: TTensorDescriptorC; | |
| StartArray, EndArray: array of UInt64; | |
| I: Integer; | |
| begin | |
| if High(StartIndices) <> High(EndIndices) then | |
| raise EFTensorError.Create('Index array length mismatch'); | |
| if High(StartIndices) + 1 <> Source.rank then | |
| raise EFTensorError.Create('Index count mismatch with tensor rank'); | |
| SetLength(StartArray, Source.rank); | |
| SetLength(EndArray, Source.rank); | |
| for I := Low(StartIndices) to High(StartIndices) do | |
| begin | |
| StartArray[I] := StartIndices[I]; | |
| EndArray[I] := EndIndices[I]; | |
| end; | |
| SrcCopy := Source; | |
| OpResult := tensor_view(@SrcCopy, @StartArray[0], @EndArray[0]); | |
| CheckFTensorResult(OpResult.result, 'tensor_view'); | |
| ViewDesc := OpResult.descriptor; | |
| end; | |
| procedure FTensorMaterialize( | |
| out MatDesc: TTensorDescriptorC; | |
| const Source: TTensorDescriptorC | |
| ); | |
| var | |
| OpResult: TTensorOpResultC; | |
| SrcCopy: TTensorDescriptorC; | |
| begin | |
| SrcCopy := Source; | |
| OpResult := tensor_materialize(@SrcCopy); | |
| CheckFTensorResult(OpResult.result, 'tensor_materialize'); | |
| MatDesc := OpResult.descriptor; | |
| end; | |
| function FTensorValidateGeneration(const Desc: TTensorDescriptorC): Boolean; | |
| var | |
| LocalDesc: TTensorDescriptorC; | |
| Result: TTensorResultC; | |
| begin | |
| LocalDesc := Desc; | |
| Result := tensor_validate_generation(@LocalDesc); | |
| Exit(Result.success <> 0); | |
| end; | |
| function FTensorLoad( | |
| const Desc: TTensorDescriptorC; | |
| const Indices: array of UInt64 | |
| ): Single; | |
| var | |
| LocalDesc: TTensorDescriptorC; | |
| IndicesArray: array of UInt64; | |
| Value: Single; | |
| Result: TTensorResultC; | |
| I: Integer; | |
| begin | |
| if High(Indices) + 1 <> Desc.rank then | |
| raise EFTensorError.Create('Index count mismatch'); | |
| SetLength(IndicesArray, Desc.rank); | |
| for I := Low(Indices) to High(Indices) do | |
| IndicesArray[I] := Indices[I]; | |
| LocalDesc := Desc; | |
| Result := tensor_load(@LocalDesc, @IndicesArray[0], @Value); | |
| CheckFTensorResult(Result, 'tensor_load'); | |
| Exit(Value); | |
| end; | |
| procedure FTensorStore( | |
| const Desc: TTensorDescriptorC; | |
| const Indices: array of UInt64; | |
| Value: Single | |
| ); | |
| var | |
| LocalDesc: TTensorDescriptorC; | |
| IndicesArray: array of UInt64; | |
| Result: TTensorResultC; | |
| I: Integer; | |
| begin | |
| if High(Indices) + 1 <> Desc.rank then | |
| raise EFTensorError.Create('Index count mismatch'); | |
| SetLength(IndicesArray, Desc.rank); | |
| for I := Low(Indices) to High(Indices) do | |
| IndicesArray[I] := Indices[I]; | |
| LocalDesc := Desc; | |
| Result := tensor_store(@LocalDesc, @IndicesArray[0], Value); | |
| CheckFTensorResult(Result, 'tensor_store'); | |
| end; | |
| function FTensorInfo(const Desc: TTensorDescriptorC): String; | |
| var | |
| LocalDesc: TTensorDescriptorC; | |
| Buffer: array[0..511] of AnsiChar; | |
| Result: TTensorResultC; | |
| begin | |
| FillChar(Buffer, SizeOf(Buffer), 0); | |
| LocalDesc := Desc; | |
| Result := tensor_info(@LocalDesc, PByte(@Buffer), SizeOf(Buffer)); | |
| CheckFTensorResult(Result, 'tensor_info'); | |
| Exit(String(PAnsiChar(@Buffer))); | |
| end; | |
| end. | |