hbayesian-0.1.0.0: src/HBayesian/InferenceLoop.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
-- | Host-side inference loops for running compiled kernels.
--
-- Phase 2 uses a hybrid strategy: the kernel step is compiled to a PJRT
-- executable and executed repeatedly from Haskell IO. This avoids the
-- complexity of compiling the entire chain into a single XLA graph while
-- still running the heavy math on the device.
module HBayesian.InferenceLoop
( InferenceConfig (..)
, defaultInferenceConfig
, sampleChain
) where
import Data.Int (Int64)
import Data.Vector.Storable (Vector)
import qualified Data.Vector.Storable as V
import HHLO.Core.Types
import HHLO.EDSL.Ops
import HHLO.IR.AST (FuncArg(..), TensorType(..))
import HHLO.IR.Builder
import HHLO.IR.Pretty (render)
import qualified HHLO.Runtime.Buffer as RTBuf
import qualified HHLO.Runtime.Compile as RT
import qualified HHLO.Runtime.Execute as RTExec
import qualified HHLO.Runtime.PJRT.Plugin as RT
import HBayesian.Core
import HBayesian.HHLO.Compile
import HBayesian.HHLO.RNG ()
-- | Configuration for the inference loop.
data InferenceConfig = InferenceConfig
{ icNumWarmup :: Int -- ^ number of warmup (burn-in) steps
, icNumSamples :: Int -- ^ number of sampling steps
, icThinning :: Int -- ^ keep every N-th sample (1 = no thinning)
}
defaultInferenceConfig :: InferenceConfig
defaultInferenceConfig = InferenceConfig
{ icNumWarmup = 0
, icNumSamples = 1000
, icThinning = 1
}
-- | Run a single chain and collect samples.
--
-- This is a stub for Phase 2. A full implementation requires PJRT
-- plugin installation and buffer management. The function demonstrates
-- the intended API and will be completed when PJRT is available.
sampleChain :: forall s d state info.
(KnownShape s, KnownDType d)
=> InferenceConfig
-> Kernel s d state info
-> Key -- ^ initial PRNG key
-> Vector Double -- ^ initial position (host)
-> IO [Vector Double] -- ^ collected samples (host)
sampleChain config kernel key0 pos0 = do
-- NOTE: Full PJRT-based execution requires the PJRT CPU plugin.
-- For Phase 2, this function demonstrates the API shape.
-- When PJRT is available, the implementation will:
-- 1. Compile kernelInit and kernelStep to PJRT executables
-- 2. Transfer key and position to device buffers
-- 3. Run the warmup + sampling loop
-- 4. Read back samples to host vectors
putStrLn "sampleChain: PJRT-based execution not yet enabled in Phase 2"
return [pos0]