diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,19 @@
+The MIT License (MIT)
+Copyright (c) 2016-2017 Tao He
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/mxnet.cabal b/mxnet.cabal
new file mode 100644
--- /dev/null
+++ b/mxnet.cabal
@@ -0,0 +1,30 @@
+name:                       mxnet
+version:                    0.1.0.0
+synopsis:                   MXNet interface in Haskell.
+description:                MXNet interface in Haskell via CFFI.
+homepage:                   http://github.com/sighingnow/mxnet-haskell#readme
+license:                    MIT
+license-file:               LICENSE
+author:                     Tao He
+maintainer:                 sighingnow@gmail.com
+copyright:                  Copyright: (c) 2016-2017 Tao He
+category:                   Machine Learning
+build-type:                 Simple
+cabal-version:              >= 1.10
+
+Library
+    exposed-modules:
+        MXNet.Core.Base
+        MXNet.Core.NDArray
+        MXNet.Core.Predict.Base
+    other-modules:
+        MXNet.Core.Internal.Types.Raw
+        MXNet.Core.Base.Internal.Raw
+        MXNet.Core.Predict.Internal.Raw
+    hs-source-dirs:         src
+    build-tools:            c2hs
+    ghc-options:            -Wall
+    default-language:       Haskell2010
+    build-depends:          base >= 4.7 && < 5.0
+                          , c2hs-extra >= 0.1
+    extra-libraries:        mxnet
diff --git a/src/MXNet/Core/Base.hs b/src/MXNet/Core/Base.hs
new file mode 100644
--- /dev/null
+++ b/src/MXNet/Core/Base.hs
@@ -0,0 +1,154 @@
+-----------------------------------------------------------
+-- |
+-- module:                      MXNet.Core.Base
+-- copyright:                   (c) 2016 Tao He
+-- license:                     MIT
+-- maintainer:                  sighingnow@gmail.com
+--
+-- Interfaces in core module of MXNet.
+--
+module MXNet.Core.Base (
+      -- * Data type definitions
+      -- ** Type alias
+      MXUInt
+    , MXFloat
+      -- ** Handlers and Creators
+    , NDArrayHandle
+    , FunctionHandle
+    , AtomicSymbolCreator
+    , SymbolHandle
+    , AtomicSymbolHandle
+    , ExecutorHandle
+    , DataIterCreator
+    , DataIterHandle
+    , KVStoreHandle
+    , RecordIOHandle
+    , RtcHandle
+      -- ** Callback types
+    , ExecutorMonitorCallback
+    , CustomOpPropCreator
+    , MXKVStoreUpdater
+    , MXKVStoreServerController
+      -- * Error handling.
+    , mxGetLastError
+      -- * Global State setups
+    , mxRandomSeed
+    , mxNotifyShutdown
+    , mxSetProfilerConfig
+    , mxSetProfilerState
+    , mxDumpProfile
+      -- * NDArray creation and deletion
+    , mxNDArrayCreateNone
+    , mxNDArrayCreate
+    , mxNDArrayCreateEx
+    , mxNDArrayLoadFromRawBytes
+    , mxNDArraySaveRawBytes
+    , mxNDArraySave
+    , mxNDArrayLoad
+    , mxNDArraySyncCopyFromCPU
+    , mxNDArraySyncCopyToCPU
+    , mxNDArrayWaitToRead
+    , mxNDArrayWaitToWrite
+    , mxNDArrayWaitAll
+    , mxNDArrayFree
+    , mxNDArraySlice
+    , mxNDArrayAt
+    , mxNDArrayReshape
+    , mxNDArrayGetShape
+    , mxNDArrayGetData
+    , mxNDArrayGetDType
+    , mxNDArrayGetContext
+      -- * Functions on NDArray
+    , mxListFunctions
+    , mxGetFunction
+    , mxFuncGetInfo
+    , mxFuncDescribe
+    , mxFuncInvoke
+    , mxFuncInvokeEx
+    , mxImperativeInvoke
+      -- * Symbolic configuration generation
+    , mxSymbolListAtomicSymbolCreators
+    , mxSymbolGetAtomicSymbolName
+    , mxSymbolGetAtomicSymbolInfo
+    , mxSymbolCreateAtomicSymbol
+    , mxSymbolCreateVariable
+    , mxSymbolCreateGroup
+    , mxSymbolCreateFromFile
+    , mxSymbolCreateFromJSON
+    , mxSymbolSaveToFile
+    , mxSymbolSaveToJSON
+    , mxSymbolFree
+    , mxSymbolCopy
+    , mxSymbolPrint
+    , mxSymbolGetName
+    , mxSymbolGetAttr
+    , mxSymbolSetAttr
+    , mxSymbolListAttr
+    , mxSymbolListAttrShallow
+    , mxSymbolListArguments
+    , mxSymbolListOutputs
+    , mxSymbolGetInternals
+    , mxSymbolGetOutput
+    , mxSymbolListAuxiliaryStates
+    , mxSymbolCompose
+    , mxSymbolGrad
+    , mxSymbolInferShape
+    , mxSymbolInferShapePartial
+    , mxSymbolInferType
+      -- * Executor interface
+    , mxExecutorFree
+    , mxExecutorPrint
+    , mxExecutorForward
+    , mxExecutorBackward
+    , mxExecutorOutputs
+    , mxExecutorBind
+    , mxExecutorBindX
+    , mxExecutorBindEX
+    , mxExecutorSetMonitorCallback
+      -- * IO Interface
+    , mxListDataIters
+    , mxDataIterCreateIter
+    , mxDataIterGetIterInfo
+    , mxDataIterFree
+    , mxDataIterNext
+    , mxDataIterBeforeFirst
+    , mxDataIterGetData
+    , mxDataIterGetIndex
+    , mxDataIterGetPadNum
+    , mxDataIterGetLabel
+      -- * Basic KVStore interface
+    , mxInitPSEnv
+    , mxKVStoreCreate
+    , mxKVStoreFree
+    , mxKVStoreInit
+    , mxKVStorePush
+    , mxKVStorePull
+    , mxKVStoreSetUpdater
+    , mxKVStoreGetType
+      -- * Advanced KVStore for multi-machines
+    , mxKVStoreGetRank
+    , mxKVStoreGetGroupSize
+    , mxKVStoreIsWorkerNode
+    , mxKVStoreIsServerNode
+    , mxKVStoreIsSchedulerNode
+    , mxKVStoreBarrier
+    , mxKVStoreSetBarrierBeforeExit
+    , mxKVStoreRunServer
+    , mxKVStoreSendCommmandToServers
+    , mxKVStoreGetNumDeadNode
+    , mxRecordIOWriterCreate
+    , mxRecordIOWriterFree
+    , mxRecordIOWriterWriteRecord
+    , mxRecordIOWriterTell
+    , mxRecordIOReaderCreate
+    , mxRecordIOReaderFree
+    , mxRecordIOReaderReadRecord
+    , mxRecordIOReaderSeek
+    , mxRtcCreate
+    , mxRtcPush
+    , mxRtcFree
+    , mxCustomOpRegister
+    ) where
+
+import MXNet.Core.Internal.Types.Raw
+import MXNet.Core.Base.Internal.Raw
diff --git a/src/MXNet/Core/Base/Internal/Raw.chs b/src/MXNet/Core/Base/Internal/Raw.chs
new file mode 100644
--- /dev/null
+++ b/src/MXNet/Core/Base/Internal/Raw.chs
@@ -0,0 +1,1103 @@
+-----------------------------------------------------------
+-- |
+-- module:                      MXNet.Core.Base.Internal.Raw
+-- copyright:                   (c) 2016 Tao He
+-- license:                     MIT
+-- maintainer:                  sighingnow@gmail.com
+--
+-- Direct C FFI bindings for <mxnet/c_api.h>.
+--
+#if __GLASGOW_HASKELL__ >= 709
+{-# LANGUAGE Safe #-}
+#elif __GLASGOW_HASKELL__ >= 701
+{-# LANGUAGE Trustworthy #-}
+#endif
+{-# LANGUAGE ForeignFunctionInterface #-}
+
+module MXNet.Core.Base.Internal.Raw where
+
+import Foreign.C.Types
+import Foreign.Marshal.Alloc
+import Foreign.Marshal.Array
+import Foreign.Ptr
+import Foreign.Storable
+
+import C2HS.C.Extra.Marshal
+
+{#import MXNet.Core.Internal.Types.Raw #}
+
+#include <mxnet/c_api.h>
+
+-- | Handle size_t type.
+{#typedef size_t CSize#}
+
+-- | Get the string message of last error.
+{#fun MXGetLastError as mxGetLastError
+    {
+    } -> `String' #}
+
+-------------------------------------------------------------------------------
+
+-- | Seed the global random number generators in mxnet.
+{#fun MXRandomSeed as mxRandomSeed
+    { `Int'
+    } -> `Int' #}
+
+-- | Notify the engine about a shutdown.
+{#fun MXNotifyShutdown as mxNotifyShutdown
+    {
+    } -> `Int' #}
+
+-- | Set up configuration of profiler.
+{#fun MXSetProfilerConfig as mxSetProfilerConfig
+    { `Int'         -- ^ Mode, indicate the working mode of profiler, record anly symbolic
+                    -- operator when mode == 0, record all operator when mode == 1.
+    , `String'      -- ^ Filename, where to save trace file.
+    } -> `Int' #}
+
+-- | Set up state of profiler.
+{#fun MXSetProfilerState as mxSetProfilerState
+    { `Int'         -- ^ State, indicate the working state of profiler, profiler not running
+                    -- when state == 0, profiler running when state == 1.
+    } -> `Int' #}
+
+-- | Save profile and stop profiler.
+{#fun MXDumpProfile as mxDumpProfile
+    {
+    } -> `Int' #}
+
+-------------------------------------------------------------------------------
+
+-- | Create a NDArray handle that is not initialized.
+{#fun MXNDArrayCreateNone as mxNDArrayCreateNone
+    { alloca- `NDArrayHandle' peek*
+    } -> `Int' -- ^ The returned NDArrayHandle.
+    #}
+
+-- | Create a NDArray with specified shape.
+{#fun MXNDArrayCreate as mxNDArrayCreate
+    { withArray* `[MXUInt]'         -- ^ The shape of NDArray.
+    , id `MXUInt'                   -- ^ The dimension of the shape.
+    , `Int'                         -- ^ Device type, specify device we want to take.
+    , `Int'                         -- ^ The device id of the specific device.
+    , `Int'                         -- ^ Whether to delay allocation until.
+    , alloca- `NDArrayHandle' peek*
+    } -> `Int' -- ^ The returing handle.
+    #}
+
+-- | Create a NDArray with specified shape and data type.
+{#fun MXNDArrayCreateEx as mxNDArrayCreateEx
+    { withArray* `[MXUInt]'
+    , id `MXUInt'
+    , `Int'                         -- ^ Device type, specify device we want to take.
+    , `Int'                         -- ^ The device id of the specific device.
+    , `Int'                         -- ^ Whether to delay allocation until.
+    , `Int'                         -- ^ Data type of created array.
+    , alloca- `NDArrayHandle' peek*
+    } -> `Int' -- ^ The returing handle.
+    #}
+
+-- | Create a NDArray handle that is loaded from raw bytes.
+{#fun MXNDArrayLoadFromRawBytes as mxNDArrayLoadFromRawBytes
+    { id `Ptr ()'                   -- ^ The head of the raw bytes.
+    , `CSize'                       -- ^ Size of the raw bytes.
+    , alloca- `NDArrayHandle' peek*
+    } -> `Int' #}
+
+-- | Save the NDArray into raw bytes.
+{#fun MXNDArraySaveRawBytes as mxNDArraySaveRawBytes
+    { id `NDArrayHandle'        -- ^ The NDArray handle.
+    , alloca- `CSize' peek*     -- ^ Size of the raw bytes.
+    , alloca- `Ptr CChar' peek* -- ^ The head of returning memory bytes.
+    } -> `Int' #}
+
+-- | Save list of narray into the file.
+{#fun MXNDArraySave as mxNDArraySave
+    { `String'                      -- ^ Name of the file.
+    , id `MXUInt'                   -- ^ Number of arguments to save.
+    , withArray* `[NDArrayHandle]'  -- ^ the array of NDArrayHandles to be saved.
+    , withStringArray* `[String]'   -- ^ names of the NDArrays to save.
+    } -> `Int' #}
+
+{#fun MXNDArrayLoad as mxNDArrayLoadImpl
+    { `String'                      -- ^ Name of the file.
+    , alloca- `MXUInt' peek*
+    , alloca- `Ptr NDArrayHandle' peek*
+    , alloca- `MXUInt' peek*
+    , alloca- `Ptr (Ptr CChar)' peek*
+    } -> `Int' #}
+
+-- | Load list of narray from the file.
+mxNDArrayLoad :: String                         -- ^ Name of the file.
+              -> IO (Int,
+                     MXUInt, [NDArrayHandle],
+                     MXUInt, [String])          -- ^ The size of ndarray handles, ndarray
+                                                -- handles the number of names and the
+                                                -- returned names.
+mxNDArrayLoad fname = do
+    (res, c1, p1, c2, p2) <- mxNDArrayLoadImpl fname
+    handles <- peekArray (fromIntegral c1) p1
+    names <- peekStringArray c2 p2
+    return (res, c1, handles, c2, names)
+
+-- | Perform a synchronize copy from a continugous CPU memory region.
+-- This is useful to copy data from existing memory region that are
+-- not wrapped by NDArray (thus dependency not being tracked).
+{#fun MXNDArraySyncCopyFromCPU as mxNDArraySyncCopyFromCPU
+    { id `NDArrayHandle'    -- ^ The NDArrayHandle.
+    , id `Ptr ()'           -- ^ The raw data source to copy from.
+    , `CSize'               -- ^ The memory size want to copy from.
+    } -> `Int' #}
+
+-- | Perform a synchronize copy to a continugous CPU memory region.
+{#fun MXNDArraySyncCopyToCPU as mxNDArraySyncCopyToCPU
+    { id `NDArrayHandle'    -- ^ The NDArrayHandle.
+    , id `Ptr ()'           -- ^ The raw data source to copy into.
+    , `CSize'               -- ^ The memory size want to copy into.
+    } -> `Int' #}
+
+-- | Wait until all the pending writes with respect NDArray are finished.
+{#fun MXNDArrayWaitToRead as mxNDArrayWaitToRead
+    { id `NDArrayHandle'
+    } -> `Int' #}
+
+-- | Wait until all the pending read/write with respect NDArray are finished.
+{#fun MXNDArrayWaitToWrite as mxNDArrayWaitToWrite
+    { id `NDArrayHandle'
+    } -> `Int' #}
+
+-- | Wait until all delayed operations in the system is completed.
+{#fun MXNDArrayWaitAll as mxNDArrayWaitAll
+    {
+    } -> `Int' #}
+
+-- | Free the narray handle.
+{#fun MXNDArrayFree as mxNDArrayFree
+    { id `NDArrayHandle'
+    } -> `Int' #}
+
+-- | Slice the NDArray along axis 0.
+{#fun MXNDArraySlice as mxNDArraySlice
+    { id `NDArrayHandle'            -- ^ The handle to the NDArray.
+    , id `MXUInt'                   -- ^ The beginning index of slice.
+    , id `MXUInt'                   -- ^ The ending index of slice.
+    , alloca- `NDArrayHandle' peek*
+    } -> `Int' -- ^ The NDArrayHandle of sliced NDArray.
+    #}
+
+-- | Index the NDArray along axis 0.
+{#fun MXNDArrayAt as mxNDArrayAt
+    { id `NDArrayHandle'            -- ^ The handle to the NDArray.
+    , id `MXUInt'                   -- ^ The index.
+    , alloca- `NDArrayHandle' peek*
+    } -> `Int' -- ^ The NDArrayHandle of output NDArray.
+    #}
+
+-- | Reshape the NDArray.
+{#fun MXNDArrayReshape as mxNDArrayReshape
+    { id `NDArrayHandle'            -- ^ The handle to the NDArray.
+    , `Int'                         -- ^ Number of dimensions of new shape.
+    , withIntegralArray* `[Int]'    -- ^ New sizes of every dimension.
+    , alloca- `NDArrayHandle' peek*
+    } -> `Int' -- ^ The new shape data and the NDArrayHandle of reshaped NDArray.
+    #}
+
+{#fun MXNDArrayGetShape as mxNDArrayGetShapeImpl
+    { id `NDArrayHandle'
+    , alloca- `MXUInt' peek*
+    , alloca- `Ptr MXUInt' peek*
+    } -> `Int' #}
+
+-- Get the shape of the array.
+mxNDArrayGetShape :: NDArrayHandle
+                  -> IO (Int, MXUInt, [MXUInt]) -- ^ The output dimension and it's shape.
+mxNDArrayGetShape handle = do
+    (res, d, p) <- mxNDArrayGetShapeImpl handle
+    shapes <- peekArray (fromIntegral d) p
+    return (res, d, shapes)
+
+-- | Get the content of the data in NDArray.
+{#fun MXNDArrayGetData as mxNDArrayGetData
+    { id `NDArrayHandle'            -- ^ The NDArray handle.
+    , alloca- `Ptr MXFloat' peek*
+    } -> `Int' -- ^ Pointer holder to get pointer of data.
+    #}
+
+-- | Get the type of the data in NDArray
+{#fun MXNDArrayGetDType as mxNDArrayGetDType
+    { id `NDArrayHandle'            -- ^ The NDArray handle.
+    , alloca- `Int' peekIntegral*
+    } -> `Int' -- ^ The type of data in this NDArray handle.
+    #}
+
+-- | Get the context of the NDArray.
+{#fun MXNDArrayGetContext as mxNDArrayGetContext
+    { id `NDArrayHandle'          -- ^ The NDArray handle.
+    , alloca- `Int' peekIntegral*
+    , alloca- `Int' peekIntegral*
+    } -> `Int' -- ^ The device type and device id.
+    #}
+
+-------------------------------------------------------------------------------
+
+{#fun MXListFunctions as mxListFunctionsImpl
+    { alloca- `MXUInt' peek*
+    , alloca- `Ptr FunctionHandle' peek*
+    } -> `Int' #}
+
+-- | List all the available functions handles.
+mxListFunctions :: IO (Int, MXUInt, [FunctionHandle]) -- ^ The output function handle array.
+mxListFunctions = do
+    (res, c, p) <- mxListFunctionsImpl
+    fs <- peekArray (fromIntegral c) p
+    return (res, c, fs)
+
+-- | Get the function handle by name.
+{#fun MXGetFunction as mxGetFunction
+    { `String'                          -- ^ The name of the function.
+    , alloca- `FunctionHandle' peek*
+    } -> `Int' -- ^ The corresponding function handle.
+    #}
+
+{#fun MXFuncGetInfo as mxFuncGetInfoImpl
+    { id `FunctionHandle'
+    , alloca- `String' peekString*
+    , alloca- `String' peekString*
+    , alloca- `MXUInt' peek*
+    , alloca- `Ptr (Ptr CChar)' peek*
+    , alloca- `Ptr (Ptr CChar)' peek*
+    , alloca- `Ptr (Ptr CChar)' peek*
+    , alloca- `String' peekString*
+    } -> `Int' #}
+
+-- | Get the information of the function handle.
+mxFuncGetInfo :: FunctionHandle                     -- ^ The target function handle.
+              -> IO (Int,
+                     String, String,
+                     MXUInt,
+                     [String], [String], [String],
+                     String)                        -- ^ The name of returned function,
+                                                    -- it's description, the number of it's
+                                                    -- arguments, argument name, type and
+                                                    -- descriptions, as well as the return
+                                                    -- type of this function.
+mxFuncGetInfo handle = do
+    (res, name, desc, argc, argv, argtype, argdesc, rettype) <- mxFuncGetInfoImpl handle
+    argv' <- peekStringArray argc argv
+    argtype' <- peekStringArray argc argtype
+    argdesc' <- peekStringArray argc argdesc
+    return (res, name, desc, argc, argv', argtype', argdesc', rettype)
+
+-- | Get the argument requirements of the function.
+{#fun MXFuncDescribe as mxFuncDescribe
+    { id `FunctionHandle'
+    , alloca- `MXUInt' peek*
+    , alloca- `MXUInt' peek*
+    , alloca- `MXUInt' peek*
+    , alloca- `Int' peekIntegral*
+    } -> `Int' -- ^ The number of NDArrays, scalar variables and mutable NDArrays to be
+               -- passed in, and the type mask of this function.
+    #}
+
+-- | Invoke a function, the array size of passed in arguments must match the values in the
+-- @fun@ function.
+{#fun MXFuncInvoke as mxFuncInvoke
+    { id `FunctionHandle'           -- ^ The function to invoke.
+    , withArray* `[NDArrayHandle]'  -- ^ The normal NDArrays arguments.
+    , withArray* `[MXFloat]'        -- ^ The scalar arguments.
+    , withArray* `[NDArrayHandle]'  -- ^ The mutable NDArrays arguments.
+    } -> `Int' #}
+
+-- | Invoke a function, the array size of passed in arguments must match the values in the
+-- @fun@ function.
+{#fun MXFuncInvokeEx as mxFuncInvokeEx
+    { id `FunctionHandle'           -- ^ The function to invoke.
+    , withArray* `[NDArrayHandle]'  -- ^ The normal NDArrays arguments.
+    , withArray* `[MXFloat]'        -- ^ The scalar arguments.
+    , withArray* `[NDArrayHandle]'  -- ^ The mutable NDArrays arguments.
+    , `Int'                         -- ^ Number of keyword parameters.
+    , withStringArray* `[String]'   -- ^ Keys for keyword parameters.
+    , withStringArray* `[String]'   -- ^ Values for keyword parameters.
+    } -> `Int' #}
+
+-- | Invoke a nnvm op and imperative function. FIXME
+mxImperativeInvoke = undefined
+
+-------------------------------------------------------------------------------
+
+{#fun MXSymbolListAtomicSymbolCreators as mxSymbolListAtomicSymbolCreatorsImpl
+    { alloca- `MXUInt' peek*
+    , alloca- `Ptr AtomicSymbolCreator' peek*
+    } -> `Int' #}
+
+-- | List all the available @AtomicSymbolCreator@.
+mxSymbolListAtomicSymbolCreators
+    :: IO (Int, MXUInt, [AtomicSymbolCreator])  -- ^ The number of atomic symbol creators and
+                                                -- the atomic symbol creators list.
+mxSymbolListAtomicSymbolCreators = do
+    (res, n, p) <- mxSymbolListAtomicSymbolCreatorsImpl
+    ss <- peekArray (fromIntegral n) p
+    return (res, n, ss)
+
+-- | Get the name of an atomic symbol.
+{#fun MXSymbolGetAtomicSymbolName as mxSymbolGetAtomicSymbolName
+    { id `AtomicSymbolCreator'
+    , alloca- `String' peekString*
+    } -> `Int' -- ^ Name of the target atomic symbol.
+    #}
+
+{#fun MXSymbolGetAtomicSymbolInfo as mxSymbolGetAtomicSymbolInfoImpl
+    { id `AtomicSymbolCreator'
+    , alloca- `String' peekString*
+    , alloca- `String' peekString*
+    , alloca- `MXUInt' peek*
+    , alloca- `Ptr (Ptr CChar)' peek*
+    , alloca- `Ptr (Ptr CChar)' peek*
+    , alloca- `Ptr (Ptr CChar)' peek*
+    , withStringArray* `[String]'
+    , alloca- `String' peekString*
+    } -> `Int' #}
+
+-- | Get the detailed information about atomic symbol.
+mxSymbolGetAtomicSymbolInfo
+    :: AtomicSymbolCreator
+    -> [String]                             -- ^ TODO document for this argument.
+                                            -- The keyword arguments for specifying variable
+                                            -- number of arguments.
+    -> IO (Int, String, String, MXUInt,
+           [String], [String], [String],
+           String)                          -- ^ Return the name and description of the symbol,
+                                            -- the name, type and description of it's arguments,
+                                            -- as well as the return type of this symbol.
+mxSymbolGetAtomicSymbolInfo creator kargs = do
+    (res, name, desc, argc, argv, argtype, argdesc, rettype) <- mxSymbolGetAtomicSymbolInfoImpl creator kargs
+    argv' <- peekStringArray argc argv
+    argtype' <- peekStringArray argc argtype
+    argdesc' <- peekStringArray argc argdesc
+    return (res, name, desc, argc, argv', argtype', argdesc', rettype)
+
+-- | Create an AtomicSymbol.
+{#fun MXSymbolCreateAtomicSymbol as mxSymbolCreateAtomicSymbol
+    { id `AtomicSymbolCreator'      -- ^ The atomic symbol creator.
+    , id `MXUInt'                   -- ^ The number of parameters.
+    , withStringArray* `[String]'   -- ^ The keys of the parameters.
+    , withStringArray* `[String]'   -- ^ The values of the parameters.
+    , alloca- `SymbolHandle' peek*
+    } -> `Int' -- ^ The created symbol.
+    #}
+
+-- | Create a Variable Symbol.
+{#fun MXSymbolCreateVariable as mxSymbolCreateVariable
+    { `String'                      -- ^ Name of the variable.
+    , alloca- `SymbolHandle' peek*
+    } -> `Int' -- ^ The created variable symbol.
+    #}
+
+-- | Create a Symbol by grouping list of symbols together.
+{#fun MXSymbolCreateGroup as mxSymbolCreateGroup
+    { id `MXUInt'                   -- ^ Number of symbols to be grouped.
+    , withArray* `[SymbolHandle]'
+    , alloca- `SymbolHandle' peek*  -- ^ Symbols to be added into the new group.
+    } -> `Int' -- ^ The created symbol group.
+    #}
+
+-- | Load a symbol from a json file.
+{#fun MXSymbolCreateFromFile as mxSymbolCreateFromFile
+    { `String'                      -- ^ The file name
+    , alloca- `SymbolHandle' peek*
+    } -> `Int' #}
+
+-- | Load a symbol from a json string.
+{#fun MXSymbolCreateFromJSON as mxSymbolCreateFromJSON
+    { `String'                      -- ^ The json string.
+    , alloca- `SymbolHandle' peek*
+    } -> `Int' #}
+
+-- | Save a symbol into a json file.
+{#fun MXSymbolSaveToFile as mxSymbolSaveToFile
+    { id `SymbolHandle' -- ^ The symbol to save.
+    , `String'          -- ^ The target file name.
+    } -> `Int' #}
+
+-- | Save a symbol into a json string.
+{#fun MXSymbolSaveToJSON as mxSymbolSaveToJSON
+    { id `SymbolHandle'             -- ^ The symbol to save.
+    , alloca- `String' peekString*
+    } -> `Int' -- ^ The result json string.
+    #}
+
+-- | Free the symbol handle.
+{#fun MXSymbolFree as mxSymbolFree
+    { id `SymbolHandle'
+    } -> `Int' #}
+
+-- | Copy the symbol to another handle.
+{#fun MXSymbolCopy as mxSymbolCopy
+    { id `SymbolHandle'
+    , alloca- `SymbolHandle' peek*
+    } -> `Int' #}
+
+-- | Print the content of symbol, used for debug.
+{#fun MXSymbolPrint as mxSymbolPrint
+    { id `SymbolHandle'             -- ^ The symbol handle to print.
+    , alloca- `String' peekString*  -- ^ The output string.
+    } -> `Int' #}
+
+-- | Get string name from symbol
+{#fun MXSymbolGetName as mxSymbolGetName
+    { id `SymbolHandle'
+    , alloca- `String' peekString*
+    , alloca- `Int' peekIntegral*
+    } -> `Int' -- ^ The name of the symbol and whether the call is successful.
+    #}
+
+-- | Get string attribute from symbol.
+{#fun MXSymbolGetAttr as mxSymbolGetAttr
+    { id `SymbolHandle'             -- ^ The source symbol.
+    , `String'                      -- ^ The key of this attribute.
+    , alloca- `String' peekString*
+    , alloca- `Int' peekIntegral*
+    } -> `Int' -- ^ The value of this attribute and whether the call is successful.
+    #}
+
+-- | Set string attribute from symbol. Setting attribute to a symbol can affect the semantics
+-- (mutable/immutable) of symbolic graph.
+{#fun MXSymbolSetAttr as mxSymbolSetAttr
+    { id `SymbolHandle' -- ^ The source symbol.
+    , `String'          -- ^ The name of the attribute.
+    , `String'          -- ^ The value of the attribute.
+    } -> `Int' #}
+
+{#fun MXSymbolListAttr as mxSymbolListAttrImpl
+    { id `SymbolHandle'
+    , alloca- `MXUInt' peekIntegral*
+    , alloca- `Ptr (Ptr CChar)' peek*
+    } -> `Int' #}
+
+-- | Get all attributes from symbol, including all descendents.
+mxSymbolListAttr :: SymbolHandle
+                 -> IO (Int, MXUInt, [String])  -- ^ The number of attributes and
+                                                -- attributes list.
+mxSymbolListAttr symbol = do
+    (res, n, p) <- mxSymbolListAttrImpl symbol
+    ss <- peekStringArray n p
+    return (res, n, ss)
+
+{#fun MXSymbolListAttrShallow as mxSymbolListAttrShallowImpl
+    { id `SymbolHandle'
+    , alloca- `MXUInt' peek*
+    , alloca- `Ptr (Ptr CChar)' peek*
+    } -> `Int' #}
+
+-- | Get all attributes from symbol, excluding descendents.
+mxSymbolListAttrShallow :: SymbolHandle
+                        -> IO (Int, MXUInt, [String])   -- ^ The number of attributes and
+                                                        -- attributes list.
+mxSymbolListAttrShallow symbol = do
+    (res, n, p) <- mxSymbolListAttrShallowImpl symbol
+    ss <- peekStringArray n p
+    return (res, n, ss)
+
+{#fun MXSymbolListArguments as mxSymbolListArgumentsImpl
+    { id `SymbolHandle'
+    , alloca- `MXUInt' peek*
+    , alloca- `Ptr (Ptr CChar)' peek*
+    } -> `Int' #}
+
+-- | List arguments in the symbol.
+mxSymbolListArguments :: SymbolHandle
+                      -> IO (Int, MXUInt, [String]) -- ^ The number of arguments and list of
+                                                    -- arguments' names.
+mxSymbolListArguments symbol = do
+    (res, n, p) <- mxSymbolListArgumentsImpl symbol
+    ss <- peekStringArray n p
+    return (res, n, ss)
+
+{#fun MXSymbolListOutputs as mxSymbolListOutputsImpl
+    { id `SymbolHandle'
+    , alloca- `MXUInt' peek*
+    , alloca- `Ptr (Ptr CChar)' peek*
+    } -> `Int' #}
+
+-- | List returns in the symbol.
+mxSymbolListOutputs :: SymbolHandle
+                    -> IO (Int, MXUInt, [String])   -- ^ The number of outputs and list of
+                                                    -- outputs' names.
+mxSymbolListOutputs symbol = do
+    (res, n, p) <- mxSymbolListOutputsImpl symbol
+    ss <- peekStringArray n p
+    return (res, n, ss)
+
+-- | Get a symbol that contains all the internals.
+{#fun MXSymbolGetInternals as mxSymbolGetInternals
+    { id `SymbolHandle'
+    , alloca- `SymbolHandle' peek*
+    } -> `Int' -- ^ The output symbol whose outputs are all the internals.
+    #}
+
+-- | Get index-th outputs of the symbol.
+{#fun MXSymbolGetOutput as mxSymbolGetOutput
+    { id `SymbolHandle'             -- ^ The symbol.
+    , id `MXUInt'                   -- ^ Index of the output.
+    , alloca- `SymbolHandle' peek*
+    } -> `Int' -- ^ The output symbol whose outputs are the index-th symbol.
+    #}
+
+{#fun MXSymbolListAuxiliaryStates as mxSymbolListAuxiliaryStatesImpl
+    { id `SymbolHandle'
+    , alloca- `MXUInt' peek*
+    , alloca- `Ptr (Ptr CChar)' peek*
+    } -> `Int' #}
+
+-- | List auxiliary states in the symbol.
+mxSymbolListAuxiliaryStates
+    :: SymbolHandle
+    -> IO (Int, MXUInt, [String])   -- ^ The output size and the output string array.
+mxSymbolListAuxiliaryStates symbol = do
+    (res, n, p) <- mxSymbolListAuxiliaryStatesImpl symbol
+    ss <- peekStringArray n p
+    return (res, n, ss)
+
+-- | Compose the symbol on other symbols.
+{#fun MXSymbolCompose as mxSymbolCompose
+    { id `SymbolHandle'             -- ^ The symbol to apply.
+    , `String'                      -- ^ Name of the symbol.
+    , id `MXUInt'                   -- ^ Number of arguments.
+    , withStringArray* `[String]'   -- ^ Key of keyword arguments, optional.
+    , withArray* `[SymbolHandle]'   -- ^ Arguments.
+    } -> `Int' #}
+
+-- | Get the gradient graph of the symbol.
+{#fun MXSymbolGrad as mxSymbolGrad
+    { id `SymbolHandle'             -- ^ The symbol to get gradient.
+    , id `MXUInt'                   -- ^ Number of arguments to get gradient.
+    , withStringArray* `[String]'   -- ^ Names of the arguments to get gradient.
+    , alloca- `SymbolHandle' peek*
+    } -> `Int' -- ^ Return the symbol that has gradient.
+    #}
+
+{#fun MXSymbolInferShape as mxSymbolInferShapeImpl
+    { id `SymbolHandle'
+    , id `MXUInt'
+    , withStringArray* `[String]'
+    , id `Ptr MXUInt'
+    , id `Ptr MXUInt'
+    , alloca- `MXUInt' peek*
+    , alloca- `Ptr MXUInt' peek*
+    , alloca- `Ptr (Ptr MXUInt)' peek*
+    , alloca- `MXUInt' peek*
+    , alloca- `Ptr MXUInt' peek*
+    , alloca- `Ptr (Ptr MXUInt)' peek*
+    , alloca- `MXUInt' peek*
+    , alloca- `Ptr MXUInt' peek*
+    , alloca- `Ptr (Ptr MXUInt)' peek*
+    , alloca- `Int' peekIntegral*
+    } -> `Int' #}
+
+-- | Infer shape of unknown input shapes given the known one.
+mxSymbolInferShape :: SymbolHandle                          -- ^ Symbol handle.
+                   -> MXUInt                                -- ^ Number of input arguments.
+                   -> [String]                              -- ^ Number of input arguments.
+                   -> Ptr MXUInt                            -- ^ Keys of keyword arguments, optional.
+                   -> Ptr MXUInt                            -- ^ The head pointer of the rows in CSR
+                   -> IO (Int,
+                          (MXUInt, [MXUInt], [Ptr MXUInt]),
+                          (MXUInt, [MXUInt], [Ptr MXUInt]),
+                          (MXUInt, [MXUInt], [Ptr MXUInt]),
+                          Int)                              -- ^ Return the in, out and auxiliary
+                                                            -- shape size, ndim and data (array
+                                                            -- of pointers to head of the input
+                                                            -- shape), and whether infer shape
+                                                            -- completes or more information is
+                                                            -- needed.
+mxSymbolInferShape sym argc keys indptr shapedata = do
+    (res, in_size, in_ndim, in_data, out_size, out_ndim, out_data, aux_size, aux_ndim, aux_data, success) <- mxSymbolInferShapeImpl sym argc keys indptr shapedata
+    in_ndim' <- peekArray (fromIntegral in_size) in_ndim
+    in_data' <- peekArray (fromIntegral in_size) in_data
+    out_ndim' <- peekArray (fromIntegral out_size) out_ndim
+    out_data' <- peekArray (fromIntegral out_size) out_data
+    aux_ndim' <- peekArray (fromIntegral aux_size) aux_ndim
+    aux_data' <- peekArray (fromIntegral aux_size) aux_data
+    return (res, (in_size, in_ndim', in_data'), (out_size, out_ndim', out_data'), (aux_size, aux_ndim', aux_data'), success)
+
+{#fun MXSymbolInferShapePartial as mxSymbolInferShapePartialImpl
+    { id `SymbolHandle'
+    , id `MXUInt'
+    , withStringArray* `[String]'
+    , id `Ptr MXUInt'
+    , id `Ptr MXUInt'
+    , alloca- `MXUInt' peek*
+    , alloca- `Ptr MXUInt' peek*
+    , alloca- `Ptr (Ptr MXUInt)' peek*
+    , alloca- `MXUInt' peek*
+    , alloca- `Ptr MXUInt' peek*
+    , alloca- `Ptr (Ptr MXUInt)' peek*
+    , alloca- `MXUInt' peek*
+    , alloca- `Ptr MXUInt' peek*
+    , alloca- `Ptr (Ptr MXUInt)' peek*
+    , alloca- `Int' peekIntegral*
+    } -> `Int' #}
+
+-- | Partially infer shape of unknown input shapes given the known one.
+mxSymbolInferShapePartial
+    :: SymbolHandle                             -- ^ Symbol handle.
+    -> MXUInt                                   -- ^ Number of input arguments.
+    -> [String]                                 -- ^ Number of input arguments.
+    -> Ptr MXUInt                               -- ^ Keys of keyword arguments, optional.
+    -> Ptr MXUInt                               -- ^ The head pointer of the rows in CSR
+    -> IO (Int,
+           (MXUInt, [MXUInt], [Ptr MXUInt]),
+           (MXUInt, [MXUInt], [Ptr MXUInt]),
+           (MXUInt, [MXUInt], [Ptr MXUInt]),
+           Int)                                 -- ^ Return the in, out and auxiliary array's
+                                                -- shape size, ndim and data (array of pointers
+                                                -- to head of the input shape), and whether
+                                                -- infer shape completes or more information is
+                                                -- needed.
+mxSymbolInferShapePartial sym argc keys indptr shapedata = do
+    (res, in_size, in_ndim, in_data, out_size, out_ndim, out_data, aux_size, aux_ndim, aux_data, success) <- mxSymbolInferShapePartialImpl sym argc keys indptr shapedata
+    in_ndim' <- peekArray (fromIntegral in_size) in_ndim
+    in_data' <- peekArray (fromIntegral in_size) in_data
+    out_ndim' <- peekArray (fromIntegral out_size) out_ndim
+    out_data' <- peekArray (fromIntegral out_size) out_data
+    aux_ndim' <- peekArray (fromIntegral aux_size) aux_ndim
+    aux_data' <- peekArray (fromIntegral aux_size) aux_data
+    return (res, (in_size, in_ndim', in_data'), (out_size, out_ndim', out_data'), (aux_size, aux_ndim', aux_data'), success)
+
+-- | Infer type of unknown input types given the known one.
+{#fun MXSymbolInferType as mxSymbolInferType
+    { id `SymbolHandle'             -- ^ Symbol handle.
+    , id `MXUInt'                   -- ^ Number of input arguments.
+    , withStringArray* `[String]'   -- ^ Key of keyword arguments, optional.
+    , id `Ptr CInt'                 -- ^ The content of the CSR.
+    , alloca- `MXUInt' peek*
+    , alloca- `Ptr CInt'
+    , alloca- `MXUInt' peek*
+    , alloca- `Ptr CInt'
+    , alloca- `MXUInt' peek*
+    , alloca- `Ptr CInt'
+    , alloca- `Int' peekIntegral*
+    } -> `Int' -- ^ Return the size and an array of pointers to head the input, output and
+               -- auxiliary type, as well as whether infer type completes or more information
+               -- is needed.
+    #}
+
+-------------------------------------------------------------------------------
+
+-- | Delete the executor.
+{#fun MXExecutorFree as mxExecutorFree
+    { id `ExecutorHandle' -- ^ The executor handle.
+    } -> `Int' #}
+
+-- | Print the content of execution plan, used for debug.
+{#fun MXExecutorPrint as mxExecutorPrint
+    { id `ExecutorHandle'           -- ^ The executor handle.
+    , alloca- `String' peekString*  -- ^ Pointer to hold the output string of the printing.
+    } -> `Int' #}
+
+-- | Executor forward method.
+{#fun MXExecutorForward as mxExecutorForward
+    { id `ExecutorHandle'   -- ^ The executor handle.
+    , `Int'                 -- ^ int value to indicate whether the forward pass is for
+                            -- evaluation.
+    } -> `Int' #}
+
+-- | Excecutor run backward.
+{#fun MXExecutorBackward as mxExecutorBackward
+    { id `ExecutorHandle'           -- ^ The executor handle.
+    , id `MXUInt'                   -- ^ Length.
+    , withArray* `[NDArrayHandle]'  -- ^ NDArray handle for heads' gradient.
+    } -> `Int' #}
+
+{#fun MXExecutorOutputs as mxExecutorOutputsImpl
+    { id `ExecutorHandle'               -- ^ The executor handle.
+    , alloca- `MXUInt' peek*            -- ^ NDArray vector size.
+    , alloca- `Ptr NDArrayHandle' peek*
+    } -> `Int' #}
+
+-- | Get executor's head NDArray.
+mxExecutorOutputs :: ExecutorHandle             -- ^ The executor handle.
+                  -> IO (Int, [NDArrayHandle])  -- ^ The handles for outputs.
+mxExecutorOutputs handle = do
+    (r, c, p) <- mxExecutorOutputsImpl handle
+    handles <- peekArray (fromIntegral c) p
+    return (r, handles)
+
+-- | Generate Executor from symbol.
+{#fun MXExecutorBind as mxExecutorBind
+    { id `SymbolHandle'                 -- ^ The symbol handle.
+    , `Int'                             -- ^ Device type.
+    , `Int'                             -- ^ Device id.
+    , id `MXUInt'                       -- ^ Length of arrays in arguments.
+    , withArray* `[NDArrayHandle]'      -- ^ In array.
+    , withArray* `[NDArrayHandle]'      -- ^ Grads handle array.
+    , withArray* `[MXUInt]'             -- ^ Grad req array.
+    , id `MXUInt'                       -- ^ Length of auxiliary states.
+    , withArray* `[NDArrayHandle]'      -- ^ Auxiliary states array.
+    , alloca- `ExecutorHandle' peek*    -- ^ Output executor handle.
+    } -> `Int' #}
+
+-- | Generate Executor from symbol. This is advanced function, allow specify group2ctx map.
+-- The user can annotate "ctx_group" attribute to name each group.
+{#fun MXExecutorBindX as mxExecutorBindX
+    { id `SymbolHandle'                 -- ^ The symbol handle.
+    , `Int'                             -- ^ Device type of default context.
+    , `Int'                             -- ^ Device id of default context.
+    , id `MXUInt'                       -- ^ Size of group2ctx map.
+    , withStringArray* `[String]'       -- ^ Keys of group2ctx map.
+    , withIntegralArray* `[Int]'        -- ^ Device type of group2ctx map.
+    , withIntegralArray* `[Int]'        -- ^ Device id of group2ctx map.
+    , id `MXUInt'                       -- ^ Length of arrays in arguments.
+    , withArray* `[NDArrayHandle]'      -- ^ In array.
+    , withArray* `[NDArrayHandle]'      -- ^ Grads handle array.
+    , withArray* `[MXUInt]'             -- ^ Grad req array.
+    , id `MXUInt'                       -- ^ Length of auxiliary states.
+    , withArray* `[NDArrayHandle]'      -- ^ Auxiliary states array.
+    , alloca- `ExecutorHandle' peek*    -- ^ Output executor handle.
+    } -> `Int' #}
+
+-- | Generate Executor from symbol. This is advanced function, allow specify group2ctx map.
+-- The user can annotate "ctx_group" attribute to name each group.
+{#fun MXExecutorBindEX as mxExecutorBindEX
+    { id `SymbolHandle'                 -- ^ The symbol handle.
+    , `Int'                             -- ^ Device type of default context.
+    , `Int'                             -- ^ Device id of default context.
+    , id `MXUInt'                       -- ^ Size of group2ctx map.
+    , withStringArray* `[String]'       -- ^ Keys of group2ctx map.
+    , withIntegralArray* `[Int]'        -- ^ Device type of group2ctx map.
+    , withIntegralArray* `[Int]'        -- ^ Device id of group2ctx map.
+    , id `MXUInt'                       -- ^ Length of arrays in arguments.
+    , withArray* `[NDArrayHandle]'      -- ^ In array.
+    , withArray* `[NDArrayHandle]'      -- ^ Grads handle array.
+    , withArray* `[MXUInt]'             -- ^ Grad req array.
+    , id `MXUInt'                       -- ^ Length of auxiliary states.
+    , withArray* `[NDArrayHandle]'      -- ^ Auxiliary states array.
+    , id `ExecutorHandle'               -- ^ Input executor handle for memory sharing.
+    , alloca- `ExecutorHandle' peek*    -- ^ Output executor handle.
+    } -> `Int' #}
+
+-- | Set a call back to notify the completion of operation.
+{#fun MXExecutorSetMonitorCallback as mxExecutorSetMonitorCallback
+    { id `ExecutorHandle'           -- ^ The executor handle.
+    , id `ExecutorMonitorCallback'
+    , id `Ptr ()'
+    } -> `Int' #}
+
+-------------------------------------------------------------------------------
+
+{#fun MXListDataIters as mxListDataItersImpl
+    { alloca- `MXUInt' peek*
+    , alloca- `Ptr DataIterCreator' peek*
+    } -> `Int' #}
+
+-- | List all the available iterator entries.
+mxListDataIters :: IO (Int, [DataIterCreator]) -- ^ The output iterator entries.
+mxListDataIters = do
+    (res, c, p) <- mxListDataItersImpl
+    creators <- peekArray (fromIntegral c) p
+    return (res, creators)
+
+-- | Init an iterator, init with parameters the array size of passed in arguments.
+{#fun MXDataIterCreateIter as mxDataIterCreateIter
+    { id `DataIterCreator'              -- ^ The handle pointer to the data iterator.
+    , id `MXUInt'                       -- ^ Size of arrays in arguments.
+    , withStringArray* `[String]'       -- ^ Parameter keys.
+    , withStringArray* `[String]'       -- ^ Parameter values.
+    , alloca- `DataIterHandle' peek*    -- ^ Resulting iterator.
+    } -> `Int' #}
+
+{#fun MXDataIterGetIterInfo as mxDataIterGetIterInfoImpl
+    { id `DataIterCreator'              -- ^ The handle pointer to the data iterator.
+    , alloca- `String' peekString*
+    , alloca- `String' peekString*
+    , alloca- `MXUInt' peek*
+    , alloca- `Ptr (Ptr CChar)' peek*
+    , alloca- `Ptr (Ptr CChar)' peek*
+    , alloca- `Ptr (Ptr CChar)' peek*
+    } -> `Int' #}
+
+-- | Get the detailed information about data iterator.
+mxDataIterGetIterInfo :: DataIterCreator                    -- ^ The handle pointer to the
+                                                            -- data iterator.
+                      -> IO (Int, String, String,
+                             MXUInt,
+                             [String], [String], [String])  -- ^ Return the name and description
+                                                            -- of the data iter creator,
+                                                            -- the name, type and description of
+                                                            -- it's arguments, as well as the
+                                                            -- return type of this symbol.
+mxDataIterGetIterInfo creator = do
+    (res, name, desc, argc, argv, argtype, argdesc) <- mxDataIterGetIterInfoImpl creator
+    argv' <- peekStringArray argc argv
+    argtype' <- peekStringArray argc argtype
+    argdesc' <- peekStringArray argc argdesc
+    return (res, name, desc, argc, argv', argtype', argdesc')
+
+-- | Get the detailed information about data iterator.
+
+-- | Free the handle to the IO module.
+{#fun MXDataIterFree as mxDataIterFree
+    { id `DataIterHandle'   -- ^ The handle pointer to the data iterator.
+    } -> `Int' #}
+
+-- | Move iterator to next position.
+{#fun MXDataIterNext as mxDataIterNext
+    { id `DataIterHandle'           -- ^ The handle pointer to the data iterator.
+    , alloca- `Int' peekIntegral*   -- ^ Return value of next.
+    } -> `Int' #}
+
+-- | Call iterator.Reset.
+{#fun MXDataIterBeforeFirst as mxDataIterBeforeFirst
+    { id `DataIterHandle'   -- ^ The handle pointer to the data iterator.
+    } -> `Int' #}
+
+-- | Get the handle to the NDArray of underlying data.
+{#fun MXDataIterGetData as mxDataIterGetData
+    { id `DataIterHandle'           -- ^ The handle pointer to the data iterator.
+    , alloca- `NDArrayHandle' peek* -- ^ Handle to the underlying data NDArray.
+    } -> `Int' #}
+
+{#fun MXDataIterGetIndex as mxDataIterGetIndexImpl
+    { id `DataIterHandle'               -- ^ The handle pointer to the data iterator.
+    , alloca- `Ptr CULLong' peek*       -- ^ The output indices.
+    , alloca- `CULLong' peekIntegral*   -- ^ Size of output array.
+    } -> `Int' #}
+
+-- | Get the image index by array.
+mxDataIterGetIndex :: DataIterHandle        -- ^ The handle pointer to the data iterator.
+                   -> IO (Int, [CULLong])   -- ^ Output indices of the array.
+mxDataIterGetIndex creator = do
+    (res, p, c) <- mxDataIterGetIndexImpl creator
+    indices <- peekArray (fromIntegral c) p
+    return (res, indices)
+
+-- | Get the padding number in current data batch.
+{#fun MXDataIterGetPadNum as mxDataIterGetPadNum
+    { id `DataIterHandle'           -- ^ The handle pointer to the data iterator.
+    , alloca- `Int' peekIntegral*   -- ^ Pad number.
+    } -> `Int' #}
+
+-- | Get the handle to the NDArray of underlying label.
+{#fun MXDataIterGetLabel as mxDataIterGetLabel
+    { id `DataIterHandle'           -- ^ The handle pointer to the data iterator.
+    , alloca- `NDArrayHandle' peek* -- ^ The handle to underlying label NDArray.
+    } -> `Int' #}
+
+-------------------------------------------------------------------------------
+
+-- | Initialized ps-lite environment variables.
+{#fun MXInitPSEnv as mxInitPSEnv
+    { id `MXUInt'                   -- ^ Number of variables to initialize.
+    , withStringArray* `[String]'   -- ^ Environment keys.
+    , withStringArray* `[String]'   -- ^ Environment values.
+    } -> `Int' #}
+
+-- | Create a kvstore.
+{#fun MXKVStoreCreate as mxKVStoreCreate
+    { `String'                      -- ^ The type of KVStore.
+    , alloca- `KVStoreHandle' peek* -- ^ The output KVStore.
+    } -> `Int' #}
+
+-- | Delete a KVStore handle.
+{#fun MXKVStoreFree as mxKVStoreFree
+    { id `KVStoreHandle'    -- ^ Handle to the kvstore.
+    } -> `Int' #}
+
+-- | Init a list of (key,value) pairs in kvstore.
+{#fun MXKVStoreInit as mxKVStoreInit
+    { id `KVStoreHandle'            -- ^ Handle to the kvstore.
+    , id `MXUInt'                   -- ^ The number of key-value pairs.
+    , withIntegralArray* `[Int]'    -- ^ The list of keys.
+    , withArray* `[NDArrayHandle]'  -- ^ The list of values.
+    } -> `Int' #}
+
+-- | Push a list of (key,value) pairs to kvstore.
+{#fun MXKVStorePush as mxKVStorePush
+    { id `KVStoreHandle'            -- ^ Handle to the kvstore.
+    , id `MXUInt'                   -- ^ The number of key-value pairs.
+    , withIntegralArray* `[Int]'    -- ^ The list of keys.
+    , withArray* `[NDArrayHandle]'  -- ^ The list of values.
+    , `Int'                         -- ^ The priority of the action.
+    } -> `Int' #}
+
+-- | FIXME Pull a list of (key, value) pairs from the kvstore.
+{#fun MXKVStorePull as mxKVStorePull
+    { id `KVStoreHandle'            -- ^ Handle to the kvstore.
+    , id `MXUInt'                   -- ^ The number of key-value pairs.
+    , withIntegralArray* `[Int]'    -- ^ The list of keys.
+    , withArray* `[NDArrayHandle]'  -- ^ The list of values.
+    , `Int'                         -- ^ The priority of the action.
+    } -> `Int' #}
+
+-- | FIXME Register an push updater.
+mxKVStoreSetUpdater = undefined
+{-
+{#fun  as
+    { id `KVStoreHandle'
+    , id `MXUInt'
+    } -> `Int' #}
+-}
+
+-- | Get the type of the kvstore.
+{#fun MXKVStoreGetType as mxKVStoreGetType
+    { id `KVStoreHandle'                -- ^ Handle to the KVStore.
+    , alloca- `String' peekString*   -- ^ A string type.
+    } -> `Int' #}
+
+-------------------------------------------------------------------------------
+
+-- | The rank of this node in its group, which is in [0, GroupSize).
+{#fun MXKVStoreGetRank as mxKVStoreGetRank
+    { id `KVStoreHandle'            -- ^ Handle to the KVStore.
+    , alloca- `Int' peekIntegral*   -- ^ The node rank.
+    } -> `Int' #}
+
+-- | The number of nodes in this group, which is
+--
+--      * number of workers if if `IsWorkerNode() == true`,
+--      * number of servers if if `IsServerNode() == true`,
+--      * 1 if `IsSchedulerNode() == true`.
+{#fun MXKVStoreGetGroupSize as mxKVStoreGetGroupSize
+    { id `KVStoreHandle'            -- ^ Handle to the KVStore.
+    , alloca- `Int' peekIntegral*   -- ^ The group size.
+    } -> `Int' #}
+
+-- | Return whether or not this process is a worker node.
+{#fun MXKVStoreIsWorkerNode as mxKVStoreIsWorkerNode
+    { alloca- `Int' peekIntegral*   -- ^ Return 1 for yes, 0 for no.
+    } -> `Int' #}
+
+-- | Return whether or not this process is a server node.
+{#fun MXKVStoreIsServerNode as mxKVStoreIsServerNode
+    { alloca- `Int' peekIntegral*   -- ^ Return 1 for yes, 0 for no.
+    } -> `Int' #}
+
+-- | Return whether or not this process is a scheduler node.
+{#fun MXKVStoreIsSchedulerNode as mxKVStoreIsSchedulerNode
+    { alloca- `Int' peekIntegral*   -- ^ Return 1 for yes, 0 for no.
+    } -> `Int' #}
+
+-- | Global barrier among all worker machines.
+{#fun MXKVStoreBarrier as mxKVStoreBarrier
+    { id `KVStoreHandle'    -- ^ Handle to the KVStore.
+    } -> `Int' #}
+
+-- | Whether to do barrier when finalize.
+{#fun MXKVStoreSetBarrierBeforeExit as mxKVStoreSetBarrierBeforeExit
+    { id `KVStoreHandle'    -- ^ Handle to the KVStore.
+    , `Int'                 -- ^ Whether to do barrier when kvstore finalize
+    } -> `Int' #}
+
+-- | FIXME  Run as server (or scheduler).
+mxKVStoreRunServer = undefined
+{-
+{#fun MXKVStoreRunServer as mxKVStoreRunServer
+    { id `KVStoreHandle'
+    , id `MXUInt'
+    } -> `Int' #}
+-}
+
+-- | Send a command to all server nodes.
+{#fun MXKVStoreSendCommmandToServers as mxKVStoreSendCommmandToServers
+    { id `KVStoreHandle'    -- ^ Handle to the KVStore.
+    , `Int'                 -- ^ The head of the command.
+    , `String'              -- ^ The body of the command.
+    } -> `Int' #}
+
+-- | Get the number of ps dead node(s) specified by {node_id}.
+{#fun MXKVStoreGetNumDeadNode as mxKVStoreGetNumDeadNode
+    { id `KVStoreHandle'            -- ^ Handle to the kvstore.
+    , `Int'                         -- ^ node id, can be a node group or a single node.
+                                    -- kScheduler = 1, kServerGroup = 2, kWorkerGroup = 4
+    , alloca- `Int' peekIntegral*   -- ^ Ouptut number of dead nodes.
+    , `Int'                         -- ^ A node fails to send heartbeart in {timeout_sec}
+                                    -- seconds will be presumed as 'dead'
+    } -> `Int' #}
+
+-- | Create a RecordIO writer object.
+{#fun MXRecordIOWriterCreate as mxRecordIOWriterCreate
+    { `String'                          -- ^ Path to file.
+    , alloca- `RecordIOHandle' peek*    -- ^ The created object.
+    } -> `Int' #}
+
+-- | Delete a RecordIO writer object.
+{#fun MXRecordIOWriterFree as mxRecordIOWriterFree
+    { id `RecordIOHandle'   -- ^ Handle to RecordIO object.
+    } -> `Int' #}
+
+-- | Write a record to a RecordIO object.
+{#fun MXRecordIOWriterWriteRecord as mxRecordIOWriterWriteRecord
+    { id `RecordIOHandle'   -- ^ Handle to RecordIO object.
+    , id `Ptr CChar'        -- ^ Buffer to write.
+    , `CSize'               -- ^ Size of buffer.
+    } -> `Int' #}
+
+-- | Get the current writer pointer position.
+{#fun MXRecordIOWriterTell as mxRecordIOWriterTell
+    { id `RecordIOHandle'   -- ^ Handle to RecordIO object.
+    , id `Ptr CSize'        -- ^ Handle to output position.
+    } -> `Int' #}
+
+-- | Create a RecordIO reader object.
+{#fun MXRecordIOReaderCreate as mxRecordIOReaderCreate
+    { `String'                          -- ^ Path to file.
+    , alloca- `RecordIOHandle' peek*    -- ^ Handle pointer to the created object.
+    } -> `Int' #}
+
+-- | Delete a RecordIO reader object.
+{#fun MXRecordIOReaderFree as mxRecordIOReaderFree
+    { id `RecordIOHandle'   -- ^ Handle to RecordIO object.
+    } -> `Int' #}
+
+
+-- | Write a record to a RecordIO object.
+{#fun MXRecordIOReaderReadRecord as mxRecordIOReaderReadRecord
+    { id `RecordIOHandle'   -- ^ Handle to RecordIO object.
+    , id `Ptr (Ptr CChar)'  -- ^ Pointer to return buffer.
+    , alloca- `CSize' peek* -- ^ Size of buffer.
+    } -> `Int' #}
+
+-- | Set the current reader pointer position.
+{#fun MXRecordIOReaderSeek as mxRecordIOReaderSeek
+    { id `RecordIOHandle'   -- ^ Handle to RecordIO object.
+    , id `CSize'            -- ^ Target position.
+    } -> `Int' #}
+
+-- | Create a MXRtc object.
+{#fun MXRtcCreate as mxRtcCreate
+    { `String'          -- ^ Name.
+    , id `MXUInt'                   -- ^ Number of inputs.
+    , id `MXUInt'                   -- ^ Number of outputs.
+    , withStringArray* `[String]'   -- ^ Input names.
+    , withStringArray* `[String]'   -- ^ Output names.
+    , withArray* `[NDArrayHandle]'  -- ^ Inputs.
+    , withArray* `[NDArrayHandle]'  -- ^ Outputs.
+    , id `Ptr CChar'                -- ^ Kernel.
+    , alloca- `RtcHandle' peek*     -- ^ The result RTC handle.
+    } -> `Int' #}
+
+-- | Run cuda kernel.
+{#fun MXRtcPush as mxRtcPush
+    { id `RtcHandle'                -- ^ Handle.
+    , id `MXUInt'                   -- ^ Number of inputs.
+    , id `MXUInt'                   -- ^ Number of outputs.
+    , withArray* `[NDArrayHandle]'  -- ^ Inputs.
+    , withArray* `[NDArrayHandle]'  -- ^ Outputs.
+    , id `MXUInt'                   -- ^ Grid dim x
+    , id `MXUInt'                   -- ^ Grid dim y
+    , id `MXUInt'                   -- ^ Grid dim z
+    , id `MXUInt'                   -- ^ Block dim x
+    , id `MXUInt'                   -- ^ Block dim y
+    , id `MXUInt'                   -- ^ Block dim z
+    } -> `Int' #}
+
+-- | Delete a MXRtc object.
+{#fun MXRtcFree as mxRtcFree
+    { id `RtcHandle'
+    } -> `Int' #}
+
+-- |
+{#fun MXCustomOpRegister as mxCustomOpRegister
+    { `String'                  -- ^ op type.
+    , id `CustomOpPropCreator'
+    } -> `Int' #}
diff --git a/src/MXNet/Core/Internal/Types/Raw.chs b/src/MXNet/Core/Internal/Types/Raw.chs
new file mode 100644
--- /dev/null
+++ b/src/MXNet/Core/Internal/Types/Raw.chs
@@ -0,0 +1,183 @@
+-----------------------------------------------------------
+-- |
+-- module:                      MXNet.Core.Internal.Types.Raw
+-- copyright:                   (c) 2016 Tao He
+-- license:                     MIT
+-- maintainer:                  sighingnow@gmail.com
+--
+-- Collect data type defintions into a single raw binding module to avoid redefinitions.
+--
+#if __GLASGOW_HASKELL__ >= 709
+{-# LANGUAGE Safe #-}
+#elif __GLASGOW_HASKELL__ >= 701
+{-# LANGUAGE Trustworthy #-}
+#endif
+{-# LANGUAGE ForeignFunctionInterface #-}
+
+module MXNet.Core.Internal.Types.Raw where
+
+import Foreign.C.Types
+import Foreign.Ptr
+import Foreign.Storable
+
+#include <mxnet/c_api.h>
+#include <mxnet/c_predict_api.h>
+
+-- | Handle size_t type.
+{#typedef size_t CSize#}
+
+{---------------------------------------------------------------------
+- <mxnet/c_api.h>
+---------------------------------------------------------------------}
+
+-- | MXUint type alias.
+type MXUInt = CUInt
+
+-- | MXFloat type alias.
+type MXFloat = CFloat
+
+-- | Handle to NDArray.
+{#pointer NDArrayHandle newtype #}
+
+instance Storable NDArrayHandle where
+    sizeOf (NDArrayHandle t) = sizeOf t
+    alignment (NDArrayHandle t) = alignment t
+    peek p = fmap NDArrayHandle (peek (castPtr p))
+    poke p (NDArrayHandle t) = poke (castPtr p) t
+
+-- | Handle to a mxnet narray function that changes NDArray.
+{#pointer FunctionHandle newtype #}
+
+instance Storable FunctionHandle where
+    sizeOf (FunctionHandle t) = sizeOf t
+    alignment (FunctionHandle t) = alignment t
+    peek p = fmap FunctionHandle (peek (castPtr p))
+    poke p (FunctionHandle t) = poke (castPtr p) t
+
+-- | Handle to a function that takes param and creates symbol.
+{#pointer AtomicSymbolCreator newtype #}
+
+instance Storable AtomicSymbolCreator where
+    sizeOf (AtomicSymbolCreator t) = sizeOf t
+    alignment (AtomicSymbolCreator t) = alignment t
+    peek p = fmap AtomicSymbolCreator (peek (castPtr p))
+    poke p (AtomicSymbolCreator t) = poke (castPtr p) t
+
+-- | Handle to a symbol that can be bind as operator.
+{#pointer SymbolHandle newtype #}
+
+instance Storable SymbolHandle where
+    sizeOf (SymbolHandle t) = sizeOf t
+    alignment (SymbolHandle t) = alignment t
+    peek p = fmap SymbolHandle (peek (castPtr p))
+    poke p (SymbolHandle t) = poke (castPtr p) t
+
+-- | Handle to a AtomicSymbol.
+{#pointer AtomicSymbolHandle newtype #}
+
+instance Storable AtomicSymbolHandle where
+    sizeOf (AtomicSymbolHandle t) = sizeOf t
+    alignment (AtomicSymbolHandle t) = alignment t
+    peek p = fmap AtomicSymbolHandle (peek (castPtr p))
+    poke p (AtomicSymbolHandle t) = poke (castPtr p) t
+
+{#pointer ExecutorHandle newtype #}
+
+-- | Handle to an Executor.
+instance Storable ExecutorHandle where
+    sizeOf (ExecutorHandle t) = sizeOf t
+    alignment (ExecutorHandle t) = alignment t
+    peek p = fmap ExecutorHandle (peek (castPtr p))
+    poke p (ExecutorHandle t) = poke (castPtr p) t
+
+-- | Handle a dataiter creator.
+{#pointer DataIterCreator newtype #}
+
+instance Storable DataIterCreator where
+    sizeOf (DataIterCreator t) = sizeOf t
+    alignment (DataIterCreator t) = alignment t
+    peek p = fmap DataIterCreator (peek (castPtr p))
+    poke p (DataIterCreator t) = poke (castPtr p) t
+
+-- | Handle to a DataIterator.
+{#pointer DataIterHandle newtype #}
+
+instance Storable DataIterHandle where
+    sizeOf (DataIterHandle t) = sizeOf t
+    alignment (DataIterHandle t) = alignment t
+    peek p = fmap DataIterHandle (peek (castPtr p))
+    poke p (DataIterHandle t) = poke (castPtr p) t
+
+-- | Handle to KVStore.
+{#pointer KVStoreHandle newtype #}
+
+instance Storable KVStoreHandle where
+    sizeOf (KVStoreHandle t) = sizeOf t
+    alignment (KVStoreHandle t) = alignment t
+    peek p = fmap KVStoreHandle (peek (castPtr p))
+    poke p (KVStoreHandle t) = poke (castPtr p) t
+
+-- | Handle to RecordIO.
+{#pointer RecordIOHandle newtype #}
+
+instance Storable RecordIOHandle where
+    sizeOf (RecordIOHandle t) = sizeOf t
+    alignment (RecordIOHandle t) = alignment t
+    peek p = fmap RecordIOHandle (peek (castPtr p))
+    poke p (RecordIOHandle t) = poke (castPtr p) t
+
+-- | Handle to MXRtc.
+{#pointer RtcHandle newtype #}
+
+instance Storable RtcHandle where
+    sizeOf (RtcHandle t) = sizeOf t
+    alignment (RtcHandle t) = alignment t
+    peek p = fmap RtcHandle (peek (castPtr p))
+    poke p (RtcHandle t) = poke (castPtr p) t
+
+-- | Callback: ExecutorMonitorCallback.
+{#pointer ExecutorMonitorCallback newtype #}
+
+-- | Callback: CustomOpPropCreator.
+{#pointer CustomOpPropCreator newtype #}
+
+-- | Callback: MXKVStoreUpdater, user-defined updater for the kvstore.
+type MXKVStoreUpdater = Int             -- ^ The key.
+                      -> NDArrayHandle  -- ^ The pushed value on the key.
+                      -> NDArrayHandle  -- ^ The value stored on local on the key.
+                      -> Ptr ()         -- ^ The additional handle to the updater.
+                      -> IO Int
+
+foreign import ccall "wrapper"
+    makeMXKVStoreUpdater :: MXKVStoreUpdater -> IO (FunPtr MXKVStoreUpdater)
+
+-- | Callback: MXKVStoreServerController, the prototype of a server controller.
+type MXKVStoreServerController = Int        -- ^ The head of the command.
+                               -> Ptr CChar -- ^ The body of the command.
+                               -> Ptr ()    -- ^ Helper handle for implementing controller.
+                               -> IO Int
+
+foreign import ccall "wrapper"
+    makeMXKVStoreServerController :: MXKVStoreServerController -> IO (FunPtr MXKVStoreServerController)
+
+{---------------------------------------------------------------------
+- <mxnet/c_predict_api.h>
+---------------------------------------------------------------------}
+
+-- | Handle to Predictor.
+{#pointer PredictorHandle newtype #}
+
+instance Storable PredictorHandle where
+    sizeOf (PredictorHandle t) = sizeOf t
+    alignment (PredictorHandle t) = alignment t
+    peek p = fmap PredictorHandle (peek (castPtr p))
+    poke p (PredictorHandle t) = poke (castPtr p) t
+
+-- | Handle to NDArrayList.
+{#pointer NDListHandle newtype #}
+
+instance Storable NDListHandle where
+    sizeOf (NDListHandle t) = sizeOf t
+    alignment (NDListHandle t) = alignment t
+    peek p = fmap NDListHandle (peek (castPtr p))
+    poke p (NDListHandle t) = poke (castPtr p) t
diff --git a/src/MXNet/Core/NDArray.hs b/src/MXNet/Core/NDArray.hs
new file mode 100644
--- /dev/null
+++ b/src/MXNet/Core/NDArray.hs
@@ -0,0 +1,67 @@
+-----------------------------------------------------------
+-- |
+-- module:                      MXNet.Core.NDArray
+-- copyright:                   (c) 2016 Tao He
+-- license:                     MIT
+-- maintainer:                  sighingnow@gmail.com
+--
+-- NDArray module.
+--
+module MXNet.Core.NDArray (
+      -- * Data type definitions
+      NDArray
+    , Context
+      -- * Functions about NDArray
+    , makeNDArray
+    , getNDArrayShape
+      -- * Default contexts
+    , defaultContext
+    , contextCPU
+    , contextGPU
+    ) where
+
+import           MXNet.Core.Base
+
+-- | NDArray type alias.
+type NDArray = NDArrayHandle
+
+-- | Context definition.
+--
+--      * DeviceType
+--
+--          1. cpu
+--          2. gpu
+--          3. cpu_pinned
+data Context = Context { deviceType :: Int
+                       , deviceId   :: Int
+                       } deriving (Eq, Show)
+
+-- | Default context, use the CPU 0 as device.
+defaultContext :: Context
+defaultContext = Context { deviceType = 1   -- cpu
+                         , deviceId = 1     -- default value.
+                         }
+
+-- | Context for CPU 0.
+contextCPU :: Context
+contextCPU = Context 1 0
+
+-- | Context for GPU 0.
+contextGPU :: Context
+contextGPU = Context 2 0
+
+-- | Make a new NDArray with given shape.
+makeNDArray :: [Int]        -- ^ size of every dimensions.
+            -> IO NDArray
+makeNDArray shape = do
+    let shape' = fromIntegral <$> shape
+        nlen = fromIntegral . length $ shape
+    (_, handle) <- mxNDArrayCreate shape' nlen (deviceType contextCPU) (deviceId contextCPU) 0
+    return handle
+
+-- | Get the shape of given NDArray.
+getNDArrayShape :: NDArray
+                -> IO (Int, [Int])  -- ^ Dimensions and size of every dimensions.
+getNDArrayShape array = do
+    (_, nlen, shape) <- mxNDArrayGetShape array
+    return (fromIntegral nlen, fromIntegral <$> shape)
diff --git a/src/MXNet/Core/Predict/Base.hs b/src/MXNet/Core/Predict/Base.hs
new file mode 100644
--- /dev/null
+++ b/src/MXNet/Core/Predict/Base.hs
@@ -0,0 +1,31 @@
+-----------------------------------------------------------
+-- |
+-- module:                      MXNet.Core.Predict.Base
+-- copyright:                   (c) 2016 Tao He
+-- license:                     MIT
+-- maintainer:                  sighingnow@gmail.com
+--
+-- Predict interfaces in core module of MXNet.
+--
+module MXNet.Core.Predict.Base (
+      -- * Data types
+      PredictorHandle
+    , NDListHandle
+      -- * Re-exports functions.
+    , mxGetLastError
+    , mxPredCreate
+    , mxPredCreatePartialOut
+    , mxPredGetOutputShape
+    , mxPredSetInput
+    , mxPredForward
+    , mxPredPartialForward
+    , mxPredGetOutput
+    , mxPredFree
+    , mxNDListCreate
+    , mxNDListGet
+    , mxNDListFree
+    ) where
+
+import MXNet.Core.Internal.Types.Raw ( PredictorHandle, NDListHandle )
+import MXNet.Core.Base.Internal.Raw ( mxGetLastError )
+import MXNet.Core.Predict.Internal.Raw
diff --git a/src/MXNet/Core/Predict/Internal/Raw.chs b/src/MXNet/Core/Predict/Internal/Raw.chs
new file mode 100644
--- /dev/null
+++ b/src/MXNet/Core/Predict/Internal/Raw.chs
@@ -0,0 +1,147 @@
+-----------------------------------------------------------
+-- |
+-- module:                      MXNet.Core.Predict.Internal.Raw
+-- copyright:                   (c) 2016 Tao He
+-- license:                     MIT
+-- maintainer:                  sighingnow@gmail.com
+--
+-- Direct C FFI bindings for <mxnet/c_predict_api.h>.
+--
+#if __GLASGOW_HASKELL__ >= 709
+{-# LANGUAGE Safe #-}
+#elif __GLASGOW_HASKELL__ >= 701
+{-# LANGUAGE Trustworthy #-}
+#endif
+{-# LANGUAGE ForeignFunctionInterface #-}
+
+module MXNet.Core.Predict.Internal.Raw where
+
+import Foreign.C.Types
+import Foreign.Marshal.Alloc
+import Foreign.Marshal.Array
+import Foreign.Ptr
+import Foreign.Storable
+
+import C2HS.C.Extra.Marshal
+
+{#import MXNet.Core.Internal.Types.Raw #}
+
+#include <mxnet/c_predict_api.h>
+
+-- | Create a predictor.
+{#fun MXPredCreate as mxPredCreate
+    { `String'                      -- ^ The JSON string of the symbol.
+    , id `Ptr ()'                   -- ^ The in-memory raw bytes of parameter ndarray file.
+    , `Int'                         -- ^ The size of parameter ndarray file.
+    , `Int'                         -- ^ The device type, 1: cpu, 2:gpu.
+    , `Int'                         -- ^ The device id of the predictor.
+    , id `MXUInt'                   -- ^ Number of input nodes to the net.
+    , withStringArray* `[String]'   -- ^ The name of input argument.
+    , withArray* `[MXUInt]'
+    , withArray* `[MXUInt]'
+    , alloca- `PredictorHandle' peek*
+    } -> `Int' -- ^ The created predictor handle.
+    #}
+
+-- | Create a predictor wich customized outputs.
+{#fun MXPredCreatePartialOut as mxPredCreatePartialOut
+    { `String'
+    , id `Ptr ()'
+    , `Int'
+    , `Int'
+    , `Int'
+    , id `MXUInt'
+    , withStringArray* `[String]'  -- ^ The names of input arguments.
+    , withArray* `[MXUInt]'
+    , withArray* `[MXUInt]'
+    , id `MXUInt'                  -- ^ Number of output nodes to the net.
+    , alloca- `String' peekString* -- ^ The name of output argument.
+    , alloca- `PredictorHandle' peek*
+    } -> `Int' -- ^ The name of output argument and created predictor handle.
+    #}
+
+{#fun MXPredGetOutputShape as mxPredGetOutputShapeImpl
+    { id `PredictorHandle'
+    , id `MXUInt'
+    , alloca- `Ptr MXUInt' peek*
+    , alloca- `MXUInt' peek*
+    } -> `Int' #}
+
+-- | Get the shape of output node.
+mxPredGetOutputShape :: PredictorHandle             -- ^ The predictor handle.
+                     -> MXUInt                      -- ^ The index of output node, set to 0
+                                                    -- if there is only one output.
+                     -> IO (Int, [MXUInt], MXUInt)  -- ^ Output dimension and the shape data.
+mxPredGetOutputShape handle index = do
+    (res, p, d) <- mxPredGetOutputShapeImpl handle index
+    shapes <- peekArray (fromIntegral d) p
+    return (res, shapes, d)
+
+-- | Set the input data of predictor.
+{#fun MXPredSetInput as mxPredSetInput
+    { id `PredictorHandle'
+    , `String'                  -- ^ The name of input node to set.
+    , withArray* `[MXFloat]'    -- ^ The pointer to the data to be set.
+    , id `MXUInt'               -- ^ The size of data array, used for safety check.
+    } -> `Int' #}
+
+-- | Run a forward pass to get the output.
+{#fun MXPredForward as mxPredForward
+    { id `PredictorHandle'
+    } -> `Int' #}
+
+-- | Run a interactive forward pass to get the output.
+{#fun MXPredPartialForward as mxPredPartialForward
+    { id `PredictorHandle'
+    , `Int'                         -- ^ The current step to run forward on.
+    , alloca- `Int' peekIntegral*
+    } -> `Int' -- ^ The number of steps left.
+    #}
+
+-- | Get the output value of prediction.
+{#fun MXPredGetOutput as mxPredGetOutput
+    { id `PredictorHandle'
+    , id `MXUInt'       -- ^ The index of output node, set to 0 if there is only one output.
+    , id `Ptr MXFloat'  -- ^ __/User allocated/__ data to hold the output.
+    , id `MXUInt'       -- ^ The size of data array, used for safe checking.
+    } -> `Int' #}
+
+-- | Free a predictor handle.
+{#fun MXPredFree as mxPredFree
+    { id `PredictorHandle'
+    } -> `Int' #}
+
+-- | Create a NDArray List by loading from ndarray file.
+{#fun MXNDListCreate as mxNDListCreate
+    { id `Ptr CChar'                -- ^ The byte contents of nd file to be loaded.
+    , `Int'                         -- ^ The size of the nd file to be loaded.
+    , alloca- `NDListHandle' peek*
+    , alloca- `MXUInt' peek*
+    } -> `Int' -- ^ The out put NDListHandle and length of the list.
+    #}
+
+{#fun MXNDListGet as mxNDListGetImpl
+    { id `NDListHandle'
+    , id `MXUInt'
+    , alloca- `String' peekString*
+    , alloca- `Ptr MXFloat' peek*
+    , alloca- `Ptr MXUInt' peek*
+    , alloca- `MXUInt' peek*
+    } -> `Int' #}
+
+-- | Get an element from list.
+mxNDListGet :: NDListHandle
+            -> MXUInt                                       -- ^ The index in the list.
+            -> IO (Int,
+                   String, Ptr MXFloat, [MXUInt], MXUInt)   -- ^ The name of output, the data
+                                                            -- region of the item, the shape of
+                                                            -- the item and shape's dimension.
+mxNDListGet handle index = do
+    (res, name, output, p, d) <- mxNDListGetImpl handle index
+    shapes <- peekArray (fromIntegral d) p
+    return (res, name, output, shapes, d)
+
+-- | Free a predictor handle.
+{#fun MXNDListFree as mxNDListFree
+    { id `NDListHandle'
+    } -> `Int' #}
