packages feed

hhlo-0.9.0.0: CHANGELOG.md

# Revision history for hhlo

## 0.1.0.0 -- 2026-04-22

* Initial release.
* Type-safe EDSL for StableHLO with 50+ ops.
* CPU execution via PJRT CPU plugin.
* GPU execution via PJRT CUDA plugin with device enumeration and selection.
* Multi-GPU concurrent inference scaling via `executeReplicas`.
* 115 CPU tests + 6 GPU integration tests.
* 29 executable examples including ResNet-18, AlexNet, Transformer, and UNet.

## 0.2.0.0 -- 2026-04-22

**BREAKING**: `Operation` AST changed from single-result to multi-result.
Any code using `opResult` / `opResultType` or pattern-matching on the
`Operation` constructor must update to `opResults` / `opResultTypes`.

* Multi-result `Operation` AST — `Operation` now supports `opResults :: [ValueId]`
  and `opResultTypes :: [TensorType]`, enabling ops with multiple outputs such as
  `stablehlo.rng_bit_generator`.
* Multi-value control flow — added `whileLoop2`, `conditional2`, `whileLoopN`,
  and `conditionalN` for carrying multiple typed tensors through loops and
  conditionals without manual packing.
* Random number generation — added `rngUniform`, `rngNormal`, and
  `rngBitGenerator` to the EDSL, wrapping `stablehlo.rng` and
  `stablehlo.rng_bit_generator`.
* PJRT CPU v1.16.0 parser compatibility fixes:
  * `stablehlo.compare` now emits generic form with enum attributes
    (`#stablehlo<comparison_direction LT>`) instead of custom form.
  * `stablehlo.rng` and `stablehlo.rng_bit_generator` emit generic form.
  * `func.return` for multi-result functions no longer wraps types in parentheses.
* New examples: `30-rng-uniform`, `31-rng-normal`, `32-rng-bit-generator`,
  `33-multi-value-loop`.
* Updated example `12-while` from print-only to fully executable.
* Test count: 124 CPU tests + 6 GPU integration tests.

## 0.3.0.0 -- 2026-04-25

**BREAKING**: `compare` and `lessThan` now return shape-preserving
`Tensor s 'Bool` instead of scalar `Tensor '[] 'Bool`. New exports
`sqrt`, `sin`, `cos`, `tan`, `floor`, `ceil` may conflict with Prelude.

* New primitive ops: `sqrt`, `rsqrt`, `sin`, `cos`, `tan`, `pow`, `log1p`, `floor`, `ceil`.
* New composite / convenience ops: `sigmoid`, `sumAll`, `pack2`, `pack3`, `slice1`.
* Fixed `compare` to return shape-preserving `Tensor s 'Bool` per StableHLO spec.
* New comparison wrappers: `equal`, `notEqual`, `greaterThan`, `lessThanOrEqual`, `greaterThanOrEqual`.
* Test count: 141 CPU tests + 6 GPU integration tests.

## 0.4.0.0 -- 2026-04-26

**BREAKING**: `HostType 'Bool` changed from `Bool` to `Word8` to match
PJRT's PRED buffer transfer semantics.

* **Convenience layer** — two new modules that eliminate boilerplate for
the common compile-and-run workflow:
  * `HHLO.ModuleBuilder` provides `buildModule @nIn @nOut`, a polymorphic
    entry point (via `TypeApplications`) that auto-generates `FuncArg`
    declarations and wires up `arg` calls. No more `natVal` or `FuncArg`
    boilerplate.
  * `HHLO.Session` provides `withCPU`, `withGPU`, `withGPUDevice`, `compile`,
    `run`, `runAsync`, and typed `HostTensor` host-device transfers.
    No more manual `render`, `toDeviceF32`, `fromDeviceF32`, or shape lists.
* `whileLoop3`–`whileLoop8` and `conditional3`–`conditional8` for carrying
  3–8 heterogeneous tensors through control flow.
* Boolean logic ops: `logicalAnd`, `logicalOr`, `logicalNot`.
* New dependency: `directory` (for plugin-path discovery in `withCPU`/`withGPU`).
* Test count: 155 CPU tests + 6 GPU integration tests.

## 0.5.0.0 -- 2026-04-27

* **Autograd** — reverse-mode automatic differentiation is now part of HHLO.
  New module `HHLO.Autograd` provides `grad` and `vjp` combinators that
  transform HHLO computation graphs into their gradients, producing new
  StableHLO modules that compile via PJRT. VJP rules cover ~25 ops including
  element-wise arithmetic, matmul, transpose, reshape, broadcast, reduce,
  slice, pad, concatenate, select, and more.
* New convenience ops:
  * `einsum` — Einstein summation via subscript strings (e.g. `"ij,jk->ik"`).
    Parses labels, computes batch/contracting dims, and emits the correct
    `stablehlo.dot_general` + optional `stablehlo.transpose`.
  * `split` — split a tensor into N equal parts along a dimension.
  * `stack` — stack N tensors along a new axis.
  * `productAll`, `productDim` — product reductions (mirrors `sumAll`/`reduceSumDim`).
  * `topK` — return top-K values along a dimension via `sort` + `slice`.
* Bug fix: `stablehlo.sort` now wraps its region in parentheses for PJRT
  v1.16.0 parser compatibility.
* Test count: 181 CPU tests + 6 GPU integration tests.

## 0.6.0.0 -- 2026-04-28
* **Convolution & pooling VJP rules** — autograd now supports backprop through
  `conv2d`, `transposeConvolution`, `maxPool`, and `avgPool`.
  * `vjpConvolution` / `vjpTransposeConvolution` emit backward input via
    flipped-kernel transposed conv and skip backward-kernel computation when
    the kernel is a constant (the common `gradModule` case).
  * `vjpReduceWindow` supports both sum-based (avgPool) and select-mask-based
    (maxPool) backward passes.
  * New primitive emitters: `bconvolution`, `breverse`.
  * PJRT parser compatibility: `stablehlo.reverse` custom pretty-printer and
    `batch_group_count` / `feature_group_count` attributes on backward convs.
  
## 0.7.0.0 -- 2026-04-28

* **Multi-parameter gradients** — `gradModule` is no longer limited to a single
  input. New combinators `gradModule2`, `gradModule3`, `grad2`, `grad3`
  differentiate w.r.t. multiple tensors natively.
* **ParamTree** — generic pack/unpack for structured parameter records.
  Derive via `GHC.Generics` and use `gradWithParams` to train models with
  dozens of weight tensors without manual offset math.
  ```haskell
  data MLPParams = MLPParams { w :: Tensor '[2,2] 'F32, b :: Tensor '[2] 'F32 }
      deriving (Generic)
  instance ParamTree MLPParams
  trainStep params x = gradWithParams loss params x
  ```

* New E2E autograd tests: `grad conv2d`, `grad maxPool`, `grad avgPool`,
  `grad2 multiply`, `gradWithParams`.
* New unit tests: `vjpConvolution`, `vjpTransposeConvolution`, `vjpReduceWindow`,
  `gradModule2`.
* Bug fix: `vjpSlice` padding value is now a 0D scalar (required by
  `stablehlo.pad`).
  
* **Comprehensive tutorial** — new document `doc/tutorial.md` (720 lines)
  providing a complete guided tour from `add` two scalars to multi-GPU
  distributed inference. Covers: shapes-as-types, the full EDSL, NN primitives,
  autograd (`grad`/`grad2`/`grad3`/ParamTree), control flow, async execution,
  and a deep-dive into the architecture and PJRT pipeline.
* Test count: 190 CPU tests + 6 GPU integration tests.

## 0.8.0.0 -- 2026-04-29

* **Nested ParamTree** — `ParamTree` now supports arbitrarily nested records
  via an overlapping `GParamTree (K1 R a)` instance. Fields can be other
  `ParamTree` records, not just bare `Tensor`s.
  ```haskell
  data LayerParams = LayerParams { w :: Tensor '[2] 'F32, b :: Tensor '[2] 'F32 }
      deriving (Generic)
  instance ParamTree LayerParams

  data ModelParams = ModelParams { layer1 :: LayerParams, layer2 :: LayerParams }
      deriving (Generic)
  instance ParamTree ModelParams
  ```
* New E2E autograd test: `gradWithParams nested`.
* Massive GPU test expansion — from 6 to 82 GPU integration tests.
  * New shared GPU test harness (`Test.Runtime.GPUResource`) using `tasty`
    `withResource` for a single PJRT client shared across all GPU tests.
  * GPU counterparts for nearly all CPU EndToEnd test categories:
    Arithmetic (15), Shape (8), Matmul (6), NN (7), Reductions (5),
    DataMovement (15), MultiValue (6), Autograd (10), Session (4).
  * New typed GPU helpers: `toDeviceF32On`, `toDevicePredOn`, `toDeviceS64On`.
  * Total: 191 CPU tests + 82 GPU tests = 273 tests.
* New `sessionFrom` constructor in `HHLO.Session` — create a `Session` from an
  existing PJRT API/client/device without loading a new plugin.
* Fixed `CUDA_ERROR_OUT_OF_MEMORY` warnings during GPU tests by converting
  `SessionGPU` tests to reuse the shared PJRT client (was creating 4 separate
  clients via `withGPU`, each contending for the same GPU memory).
* Moved `getPluginPath` from `HHLO.Session` to `HHLO.Runtime.PJRT.Plugin`.
  `withPJRTCPU` and `withPJRTGPU` now resolve plugin paths via the
  `HHLO_PJRT_CPU_PLUGIN` / `HHLO_PJRT_GPU_PLUGIN` environment variables
  (falling back to `deps/pjrt/`), so downstream libraries no longer need to
  reimplement plugin discovery.

## 0.9.0.0 -- 2026-04-20

* **Fixed-length configuration vectors** — rank-polymorphic EDSL ops now use
  `vector-sized` to tie config vector lengths to tensor ranks at compile time.
  This eliminates the class of bugs where wrong-length config silently produces
  invalid StableHLO.
  * Phase 1 (2D NN primitives): `conv2dWithPadding`, `maxPool`, `avgPool`,
    `transposeConvolution` accept `V2 Int64` / `P2`.
  * Phase 2+ (rank-polymorphic ops): `transpose`, `slice`, `pad`,
    `dynamicSlice`, `reduceWindow`, and `dotGeneral` now accept
    `Vector (Length s) Int64` or separate `Vector n Int64` type parameters
    instead of raw `[Int64]`.
  ```haskell
  -- BEFORE (could silently miscompile)
  transpose [1, 0] x
  slice x [1] [3] [1]
  dotGeneral [] [] [1] [0] x y

  -- AFTER (type-safe)
  transpose (v2 1 0) x
  slice x (v1 1) (v1 3) (v1 1)
  dotGeneral VS.empty VS.empty (v1 1) (v1 0) x y
  ```
  New exports in `HHLO.Core.Types`: `Length` type family, `V`, `V1`, `V2`,
  `V3`, `V4`, `Padding`, `P2`, plus smart constructors `v1`, `v2`, `v3`, `v4`,
  `p2`.
* New dependency: `vector-sized >= 1.5 && < 1.6`.
* Fix `transposeConvolution` lhs_dilation bug — passing a 2-element spatial
  dilation list no longer drops the second element.
* `gather` and `scatter` kept as `[Int64]` for now. Their config vector lengths
  depend on complex relationships between operand / indices / result ranks, so
  a clean type-safe design requires a separate future phase.