doBenchmark :: [String] -> IO ()
doBenchmark args =
    withArgs args $ do
    G.initializeGLUT False
    G.openWindowGLUT disp
    N.initializeCUDAGLCtx N.DeviceListAll
    repav2Gen   <- MR2.mandelbrotImageGenerator
    repav3Gen   <- MR3.mandelbrotImageGenerator
    nikolav2Gen <- MN2.mandelbrotImageGenerator
    nikolav3Gen <- MN3.mandelbrotImageGenerator
    nikolav4Gen <- MN4.mandelbrotImageGenerator
    nikolav5Gen <- MN5.mandelbrotImageGenerator
    let generateBitmapFrame :: Backend -> G.View -> Int -> Int -> IO (Bitmap F)
        generateBitmapFrame RepaV1 (G.View lowx lowy highx highy) size limit =
            MR1.mandelbrotImage lowx lowy highx highy size size limit

        generateBitmapFrame RepaV2 (G.View lowx lowy highx highy) size limit =
            repav2Gen lowx lowy highx highy size size limit

        generateBitmapFrame RepaV3 (G.View lowx lowy highx highy) size limit =
            repav3Gen lowx lowy highx highy size size limit

        generateBitmapFrame NikolaV1 (G.View lowx lowy highx highy) size limit =
            MN1.mandelbrotImage lowx lowy highx highy size size limit

        generateBitmapFrame NikolaV2 (G.View lowx lowy highx highy) size limit =
            nikolav2Gen lowx lowy highx highy size size limit

        generateBitmapFrame NikolaV3 (G.View lowx lowy highx highy) size limit =
            nikolav3Gen lowx lowy highx highy size size limit

        generateBitmapFrame NikolaV4 (G.View lowx lowy highx highy) size limit =
            nikolav4Gen lowx lowy highx highy size size limit

        generateBitmapFrame backend _ _ _ =
            fail $ "Cannot generate bitmap for" ++ show backend

    let generatePBOFrame :: Backend -> G.View -> Int -> Int -> IO GL.BufferObject
        generatePBOFrame NikolaV5 (G.View lowx lowy highx highy) size limit =
            nikolav5Gen lowx lowy highx highy size size limit

        generatePBOFrame backend _ _ _ =
            fail $ "Cannot generate PBO for" ++ show backend

    C.defaultMain
         [C.bench "Repa V1"   $ C.nfIO (generateBitmapFrame RepaV1   defaultView size limit)
         ,C.bench "Repa V2"   $ C.nfIO (generateBitmapFrame RepaV2   defaultView size limit)
         ,C.bench "Repa V3"   $ C.nfIO (generateBitmapFrame RepaV3   defaultView size limit)
         ,C.bench "Nikola V1" $ C.nfIO (generateBitmapFrame NikolaV1 defaultView size limit)
         ,C.bench "Nikola V2" $ C.nfIO (generateBitmapFrame NikolaV2 defaultView size limit)
         ,C.bench "Nikola V3" $ C.nfIO (generateBitmapFrame NikolaV3 defaultView size limit)
         ,C.bench "Nikola V4" $ C.nfIO (generateBitmapFrame NikolaV4 defaultView size limit)
         ,C.bench "Nikola V5" $ C.nfIO (generatePBOFrame    NikolaV5 defaultView size limit)
         ]
  where
    size  = 512
    limit = 255
    disp  = G.InWindow "Mandelbrot" (size, size) (10, 10)
doBenchmark :: [String] -> IO ()
doBenchmark args =
    withArgs args $ do
    G.initializeGLUT False
    G.openWindowGLUT disp
    N.initializeCUDAGLCtx N.DeviceListAll
    repav2Gen   <- MR2.mandelbrotImageGenerator
    repav3Gen   <- MR3.mandelbrotImageGenerator
    nikolav2Gen <- MN2.mandelbrotImageGenerator
    nikolav3Gen <- MN3.mandelbrotImageGenerator
    nikolav4Gen <- MN4.mandelbrotImageGenerator
    nikolav5Gen <- MN5.mandelbrotImageGenerator
    let generateBitmapFrame :: Backend -> G.View -> Int -> Int -> IO (Bitmap F)
        generateBitmapFrame RepaV1 (G.View lowx lowy highx highy) size limit =
            MR1.mandelbrotImage lowx lowy highx highy size size limit

        generateBitmapFrame RepaV2 (G.View lowx lowy highx highy) size limit =
            repav2Gen lowx lowy highx highy size size limit

        generateBitmapFrame RepaV3 (G.View lowx lowy highx highy) size limit =
            repav3Gen lowx lowy highx highy size size limit

        generateBitmapFrame NikolaV1 (G.View lowx lowy highx highy) size limit =
            MN1.mandelbrotImage lowx lowy highx highy size size limit

        generateBitmapFrame NikolaV2 (G.View lowx lowy highx highy) size limit =
            nikolav2Gen lowx lowy highx highy size size limit

        generateBitmapFrame NikolaV3 (G.View lowx lowy highx highy) size limit =
            nikolav3Gen lowx lowy highx highy size size limit

        generateBitmapFrame NikolaV4 (G.View lowx lowy highx highy) size limit =
            nikolav4Gen lowx lowy highx highy size size limit

        generateBitmapFrame backend _ _ _ =
            fail $ "Cannot generate bitmap for" ++ show backend

    let generatePBOFrame :: Backend -> G.View -> Int -> Int -> IO GL.BufferObject
        generatePBOFrame NikolaV5 (G.View lowx lowy highx highy) size limit =
            nikolav5Gen lowx lowy highx highy size size limit

        generatePBOFrame backend _ _ _ =
            fail $ "Cannot generate PBO for" ++ show backend

    C.defaultMain
         [C.bench "Repa V1"   $ C.nfIO (generateBitmapFrame RepaV1   defaultView size limit)
         ,C.bench "Repa V2"   $ C.nfIO (generateBitmapFrame RepaV2   defaultView size limit)
         ,C.bench "Repa V3"   $ C.nfIO (generateBitmapFrame RepaV3   defaultView size limit)
         ,C.bench "Nikola V1" $ C.nfIO (generateBitmapFrame NikolaV1 defaultView size limit)
         ,C.bench "Nikola V2" $ C.nfIO (generateBitmapFrame NikolaV2 defaultView size limit)
         ,C.bench "Nikola V3" $ C.nfIO (generateBitmapFrame NikolaV3 defaultView size limit)
         ,C.bench "Nikola V4" $ C.nfIO (generateBitmapFrame NikolaV4 defaultView size limit)
         ,C.bench "Nikola V5" $ C.nfIO (generatePBOFrame    NikolaV5 defaultView size limit)
         ]
  where
    size  = 512
    limit = 255
    disp  = G.InWindow "Mandelbrot" (size, size) (10, 10)
doBenchmark args =
    withArgs args $ do
    G.initializeGLUT False
    G.openWindowGLUT disp
    N.initializeCUDAGLCtx N.DeviceListAll
    repav2Gen   <- MR2.mandelbrotImageGenerator
    repav3Gen   <- MR3.mandelbrotImageGenerator
    nikolav2Gen <- MN2.mandelbrotImageGenerator
    nikolav3Gen <- MN3.mandelbrotImageGenerator
    nikolav4Gen <- MN4.mandelbrotImageGenerator
    nikolav5Gen <- MN5.mandelbrotImageGenerator
    let generateBitmapFrame :: Backend -> G.View -> Int -> Int -> IO (Bitmap F)
        generateBitmapFrame RepaV1 (G.View lowx lowy highx highy) size limit =
            MR1.mandelbrotImage lowx lowy highx highy size size limit

        generateBitmapFrame RepaV2 (G.View lowx lowy highx highy) size limit =
            repav2Gen lowx lowy highx highy size size limit

        generateBitmapFrame RepaV3 (G.View lowx lowy highx highy) size limit =
            repav3Gen lowx lowy highx highy size size limit

        generateBitmapFrame NikolaV1 (G.View lowx lowy highx highy) size limit =
            MN1.mandelbrotImage lowx lowy highx highy size size limit

        generateBitmapFrame NikolaV2 (G.View lowx lowy highx highy) size limit =
            nikolav2Gen lowx lowy highx highy size size limit

        generateBitmapFrame NikolaV3 (G.View lowx lowy highx highy) size limit =
            nikolav3Gen lowx lowy highx highy size size limit

        generateBitmapFrame NikolaV4 (G.View lowx lowy highx highy) size limit =
            nikolav4Gen lowx lowy highx highy size size limit

        generateBitmapFrame backend _ _ _ =
            fail $ "Cannot generate bitmap for" ++ show backend

    let generatePBOFrame :: Backend -> G.View -> Int -> Int -> IO GL.BufferObject
        generatePBOFrame NikolaV5 (G.View lowx lowy highx highy) size limit =
            nikolav5Gen lowx lowy highx highy size size limit

        generatePBOFrame backend _ _ _ =
            fail $ "Cannot generate PBO for" ++ show backend

    C.defaultMain
         [C.bench "Repa V1"   $ C.nfIO (generateBitmapFrame RepaV1   defaultView size limit)
         ,C.bench "Repa V2"   $ C.nfIO (generateBitmapFrame RepaV2   defaultView size limit)
         ,C.bench "Repa V3"   $ C.nfIO (generateBitmapFrame RepaV3   defaultView size limit)
         ,C.bench "Nikola V1" $ C.nfIO (generateBitmapFrame NikolaV1 defaultView size limit)
         ,C.bench "Nikola V2" $ C.nfIO (generateBitmapFrame NikolaV2 defaultView size limit)
         ,C.bench "Nikola V3" $ C.nfIO (generateBitmapFrame NikolaV3 defaultView size limit)
         ,C.bench "Nikola V4" $ C.nfIO (generateBitmapFrame NikolaV4 defaultView size limit)
         ,C.bench "Nikola V5" $ C.nfIO (generatePBOFrame    NikolaV5 defaultView size limit)
         ]
  where
    size  = 512
    limit = 255
    disp  = G.InWindow "Mandelbrot" (size, size) (10, 10)