lstmBackward :: Int -> S.Vector Double -> S.Vector Double -> S.Vector Double -> S.Vector Double ->
                (S.Vector Double, S.Vector Double, S.Vector Double)
lstmBackward n ps store delta_h delta_y = unsafePerformIO $ do
  target_d_ws <- M.replicate (2*n) 0 :: IO (M.IOVector Double)
  target_d_hs <- M.replicate n 0 :: IO (M.IOVector Double)
  target_d_xs <- M.replicate (4*n) 0 :: IO (M.IOVector Double)
  S.unsafeWith ps $ \pbuf -> do
    S.unsafeWith store $ \sbuf -> do
      S.unsafeWith delta_h $ \dbuf -> do
        S.unsafeWith delta_y $ \dybuf -> do
          M.unsafeWith target_d_ws $ \dwbuf -> do
            M.unsafeWith target_d_hs $ \dhbuf -> do
              M.unsafeWith target_d_xs $ \dxbuf -> do
                lstmBackwardFFI (fromIntegral n) pbuf sbuf dbuf dybuf dwbuf dhbuf dxbuf
  d_ws <- V.unsafeFreeze target_d_ws
  d_hs <- V.unsafeFreeze target_d_hs
  d_xs <- V.unsafeFreeze target_d_xs
  return (d_ws, d_hs, d_xs)
lstmBackward :: Int -> S.Vector Double -> S.Vector Double -> S.Vector Double -> S.Vector Double ->
                (S.Vector Double, S.Vector Double, S.Vector Double)
lstmBackward n ps store delta_h delta_y = unsafePerformIO $ do
  target_d_ws <- M.replicate (2*n) 0 :: IO (M.IOVector Double)
  target_d_hs <- M.replicate n 0 :: IO (M.IOVector Double)
  target_d_xs <- M.replicate (4*n) 0 :: IO (M.IOVector Double)
  S.unsafeWith ps $ \pbuf -> do
    S.unsafeWith store $ \sbuf -> do
      S.unsafeWith delta_h $ \dbuf -> do
        S.unsafeWith delta_y $ \dybuf -> do
          M.unsafeWith target_d_ws $ \dwbuf -> do
            M.unsafeWith target_d_hs $ \dhbuf -> do
              M.unsafeWith target_d_xs $ \dxbuf -> do
                lstmBackwardFFI (fromIntegral n) pbuf sbuf dbuf dybuf dwbuf dhbuf dxbuf
  d_ws <- V.unsafeFreeze target_d_ws
  d_hs <- V.unsafeFreeze target_d_hs
  d_xs <- V.unsafeFreeze target_d_xs
  return (d_ws, d_hs, d_xs)
lstmBackward n ps store delta_h delta_y = unsafePerformIO $ do
  target_d_ws <- M.replicate (2*n) 0 :: IO (M.IOVector Double)
  target_d_hs <- M.replicate n 0 :: IO (M.IOVector Double)
  target_d_xs <- M.replicate (4*n) 0 :: IO (M.IOVector Double)
  S.unsafeWith ps $ \pbuf -> do
    S.unsafeWith store $ \sbuf -> do
      S.unsafeWith delta_h $ \dbuf -> do
        S.unsafeWith delta_y $ \dybuf -> do
          M.unsafeWith target_d_ws $ \dwbuf -> do
            M.unsafeWith target_d_hs $ \dhbuf -> do
              M.unsafeWith target_d_xs $ \dxbuf -> do
                lstmBackwardFFI (fromIntegral n) pbuf sbuf dbuf dybuf dwbuf dhbuf dxbuf
  d_ws <- V.unsafeFreeze target_d_ws
  d_hs <- V.unsafeFreeze target_d_hs
  d_xs <- V.unsafeFreeze target_d_xs
  return (d_ws, d_hs, d_xs)