HABQT-0.1.0.0: libHABQT/LibHABQT.hs
{-# LANGUAGE ForeignFunctionInterface #-}
module LibHABQT where
import Control.Monad.State.Lazy
import Data.IORef
import Data.Validation
import Foreign
import Foreign.C
import ForeignHABQT
import HABQTlib.Data
import HABQTlib.Data.Particle
import HABQTlib.UnsafeAPI
import qualified System.IO as IO
import qualified System.Random.MWC as MWC
type TomForegin
= Ptr CDouble -- measurement SV real
-> Ptr CDouble -- measurement SV imag
-> Ptr CDouble -- estimate dm real
-> Ptr CDouble -- estimate dm imag
-> Ptr CDouble -- next POVM real
-> Ptr CDouble -- next POVM imag
-> IO ()
type ArgStorage = (QBitNum, OutputVerb, MHMCiter, OptIter, MWC.GenIO)
type Storage = IORef (ArgStorage, (ParticleHierarchy, [PureStateVector]))
type InitFun = CInt -> CInt -> CInt -> CInt -> CInt -> IO (StablePtr Storage)
foreign export ccall "tomography_init" tomInit :: InitFun
tomInit :: InitFun
tomInit qn' pc' mi' oi' verb' = do
let inp = validateInputs qn' pc' mi' oi' verb'
gen <- MWC.createSystemRandom
case inp of
Failure errs -> do
IO.hSetBuffering IO.stderr IO.LineBuffering
IO.hPutStrLn IO.stderr (unlines errs)
IO.hPutStrLn
IO.stderr
"Free the resulting pointer using tomography_free and re-initialise with valid inputs"
IO.hFlush IO.stderr
ph <- initialiseParticleHierarchy 2 1
mem <- newIORef ((1, NoOutput, 1, 1, gen), (ph, []))
newStablePtr mem
Success (qn, pc, mi, oi, verb) -> do
let dim = 2 ^ qn
out =
case verb of
0 -> NoOutput
1 -> FullOutput
ph <- initialiseParticleHierarchy dim pc
mem <- newIORef ((qn, out, mi, oi, gen), (ph, []))
newStablePtr mem
foreign export ccall "tomography" foreignTomFun
:: StablePtr Storage -> TomForegin
foreignTomFun :: StablePtr Storage -> TomForegin
foreignTomFun strPtr svrPtr sviPtr dmrPtr dmiPtr povmrPtr povmiPtr = do
mem <- deRefStablePtr strPtr
((qn, out, mi, oi, gen), s) <- readIORef mem
let dim = 2 ^ qn
sv <- unmarshallSV dim svrPtr sviPtr
case validSV sv of
Success _ -> do
((dm, nextPOVM), sn) <- runStateT (tomographyFun' qn mi oi out gen sv) s
writeIORef mem ((qn, out, mi, oi, gen), sn)
marshallDM dm dmrPtr dmiPtr
marshallPOVM nextPOVM povmrPtr povmiPtr
Failure [msg] -> do
IO.hSetBuffering IO.stderr IO.LineBuffering
IO.hPutStrLn IO.stderr $ msg ++ " Doing nothing."
IO.hFlush IO.stderr
foreign export ccall "tomography_free" tomFree :: StablePtr Storage -> IO ()
tomFree :: StablePtr Storage -> IO ()
tomFree = freeStablePtr
validateInputs ::
CInt
-> CInt
-> CInt
-> CInt
-> CInt
-> Validation [String] (QBitNum, NumberOfParticles, MHMCiter, OptIter, Int)
validateInputs qn' pn' mi' oi' verb' =
let qn = fromIntegral qn'
pn = fromIntegral pn'
verb = fromIntegral verb'
mi = fromIntegral mi'
oi = fromIntegral oi'
qnM = ["Number of quantum bits must be a positive integer."]
pnM = ["Number of particles per rank must be a positive integer."]
vM =
[ "Verbosity level must be an integer equal to 0 (no output) or 1 (full output)."
]
miM = ["Number of MHMC iterations must be a positive integer."]
vQn = validate qnM (> 0) qn
vPn = validate pnM (> 0) pn
vVerb = validate vM ((||) <$> (== 0) <*> (== 1)) verb
vMi = validate miM (> 0) mi
vOi = validOptIter oi
in (,,,,) <$> vQn <*> vPn <*> vMi <*> vOi <*> vVerb