packages feed

hanalyze-0.1.0.0: bench/haskell/BenchRFFOOM.hs

{-# LANGUAGE BangPatterns #-}
-- | OOM regression bench for Phase 11b
-- (RFF.medianPairwiseDist + rbfKernelMat).
--
-- Pre-fix: n>=768 OOM-killed WSL2 (~7 GB+) inside maximizeMarginalLikRBFMV
-- because both internals built O(n²) Haskell-list intermediates with
-- @rows !! i@ index walks. Post-fix expectation:
--
--   * n=200  : sub-second, ~10 MB alloc
--   * n=400  : ~1 s,        ~50 MB alloc
--   * n=768  : few seconds, ~200 MB alloc (grid evals dominate; was OOM)
--
-- @maximizeMarginalLikRBFMV@ exercises both fixed paths heavily:
--
--   * 'medianPairwiseDist' once for the @ℓ@ centre.
--   * 'rbfKernelMat' inside @logMarginalLikRBFMV@ for every grid point.
module Main where

import qualified Numeric.LinearAlgebra as LA
import qualified Hanalyze.Model.RFF    as RFF
import           Data.Time.Clock        (getCurrentTime, diffUTCTime)
import           System.IO              (hSetBuffering, BufferMode (..), stdout)
import           System.Environment     (getArgs)

mkX :: Int -> Int -> LA.Matrix Double
mkX n p =
  LA.reshape p
    (LA.fromList [ sin (fromIntegral (i * 31 + j * 7)) / 3
                 | i <- [0 .. n - 1], j <- [0 .. p - 1] ])

-- Tiny grid (3,2,2) so we evaluate logMarginalLikRBFMV / rbfKernelMat
-- only 24 times — enough to surface OOM behaviour but not enough to drown
-- the timing.
benchOne :: Int -> IO ()
benchOne n = do
  let x = mkX n 8
      y = LA.fromList [ sin (fromIntegral i / 5) | i <- [0 .. n - 1] ]
  t0 <- getCurrentTime
  let !r = RFF.maximizeMarginalLikRBFMV x y (Just (3, 2, 2))
  t1 <- getCurrentTime
  putStrLn $ "  n=" ++ show n
          ++ "  ml=" ++ show (RFF.mlLogMlik r)
          ++ "  ell=" ++ show (RFF.mlEll r)
          ++ "  elapsed=" ++ show (diffUTCTime t1 t0)

main :: IO ()
main = do
  hSetBuffering stdout NoBuffering
  args <- getArgs
  let ns = case args of
             [] -> [50, 100, 200]
             _  -> map read args
  putStrLn "=== maximizeMarginalLikRBFMV (Stage1+2 with tiny grid 3*2*2) ==="
  mapM_ benchOne ns