Float32Array - Opaque Type Implementation #
High-performance Float32 array with zero-copy GPU interop and in-place mutations.
Key Advantages #
- Zero Copy: Direct pointer passing to WebGPU (no conversion overhead)
- Memory Efficient: Native C++
std::vector<float>, not boxed Lean objects - In-Place Updates: Mutable operations in IO monad (no array copying)
- 2x Memory Savings: vs Float64 (4 bytes/element vs 8 bytes/element)
- Better SIMD: AVX2 8 floats/op vs 4 doubles/op, NEON 4 vs 2
Implementation Pattern #
- Lean Side: Opaque type (contents invisible to Lean)
- C++ Side:
std::vector<float>allocated on heap - FFI Boundary: Lean holds pointer via
Lean.Externalwith finalizer - GPU Interop: Pass raw pointer via
ptr()forwgpuQueueWriteBuffer
Usage #
-- Create array of 1000 elements (allocated in C++ heap)
let arr ← Float32Array.create 1000
-- Set values (in-place mutation, no copying!)
arr.set 0 3.14
arr.set 1 2.71
-- Get values (converts f32 → f64 only when reading)
let val ← arr.get 0 -- returns Float (f64)
-- Pass to GPU (zero-copy!)
let ptr ← arr.ptr
let size ← arr.byteSize
-- Use ptr with wgpuQueueWriteBuffer(queue, buffer, 0, ptr, size)
Type Definition #
Opaque type representing a C++ std::vector<float>. Contents are invisible to Lean - all operations go through FFI.
Float32 array type (opaque to Lean, managed by C++)
Instances For
Creation and Destruction #
Create a new Float32Array with the specified number of elements. All elements are initialized to 0.0f.
C++ Implementation: new std::vector<float>(size, 0.0f)
Element Access #
Set a value at the specified index (in-place mutation). Value is converted from Float64 to Float32.
Safety: Out-of-bounds access will return error. Performance: O(1), in-place update (no array copy).
Get a value at the specified index. Value is converted from Float32 to Float64.
Safety: Out-of-bounds access will return error. Performance: O(1).
Array Properties #
Get the number of Float32 elements in the array.
Performance: O(1) - calls vec.size().
Get the size in bytes (for GPU buffer allocation).
GPU Interop (Zero-Copy Pointer Access) #
Get the raw pointer to the underlying data for GPU operations.
UNSAFE: This returns a raw pointer (size_t) to vec.data().
The pointer is only valid while the Float32Array object is alive.
Use Case: Pass to wgpuQueueWriteBuffer for zero-copy uploads:
let ptr ← arr.ptr
let size ← arr.byteSize
-- C++: wgpuQueueWriteBuffer(queue, buffer, 0, (void*)ptr, size)
Safety: Caller must ensure:
- Float32Array stays alive during GPU operation
- No concurrent modifications while GPU reads
Conversions #
Create Float32Array from Lean's native Array Float.
Performance: O(n) - each Float64 is converted to Float32. Use Case: Initial data preparation from Lean computations.
Convert Float32Array to Lean's native Array Float.
Performance: O(n) - each Float32 is converted to Float64. Use Case: Reading results back into Lean for verification/analysis.
SIMD Operations #
SIMD element-wise addition: result[i] = a[i] + b[i]
Hardware Acceleration:
- x86_64: AVX2 (8 floats/operation)
- ARM64: NEON (4 floats/operation)
Safety: Arrays must have same size, returns error otherwise. Performance: ~8x faster than scalar on AVX2, ~4x on NEON.
SIMD element-wise multiplication: result[i] = a[i] * b[i]
Utilities #
String representation for debugging (shows first 8 elements)
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- Hesper.Core.instToStringFloat32Array = { toString := fun (_arr : Hesper.Core.Float32Array) => toString "Float32Array[size=?] (use arr.toString for details)" }