diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,6 @@
+# 0.5.0.0, 2018-11-25
+- ported to multilinear-0.5.0.0
+
 # 0.4.0.0, 2018-11-24
 - ported to multilinear-0.4.0.0
 - added more robust tests
diff --git a/multilinear-io.cabal b/multilinear-io.cabal
--- a/multilinear-io.cabal
+++ b/multilinear-io.cabal
@@ -2,11 +2,11 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: e8f399289e551ae39e7efffa83e1b8f92a5cb52d1d5f332879287e1a14387be1
+-- hash: a89d39464086b0628b927b55e010617142476609ffbe530733fcd3edbcf08938
 
 name:           multilinear-io
-version:        0.4.0.0
-synopsis:       Conduit-vased input/output capability for multilinear package.
+version:        0.5.0.0
+synopsis:       Conduit-based input/output capability for multilinear package.
 description:    Conduit-based input & output capability for multilinear package <https://hackage.haskell.org/package/multilinear>. Supports various file formats: binary, CSV, JSON. More information available on GitHub: <https://github.com/ArturB/multilinear-io#readme>
 category:       Machine learning
 homepage:       https://github.com/ArturB/multilinear-io#readme
@@ -28,6 +28,8 @@
 
 library
   exposed-modules:
+      Multilinear.Generic.MultiCore.Serialize
+      Multilinear.Generic.Sequential.Serialize
       Multilinear.Generic.Serialize
       Multilinear.Index.Finite.Serialize
   other-modules:
@@ -55,6 +57,8 @@
   type: exitcode-stdio-1.0
   main-is: Spec.hs
   other-modules:
+      Test.MultiCore
+      Test.Sequential
       Paths_multilinear_io
   hs-source-dirs:
       test/binary
@@ -73,6 +77,8 @@
   type: exitcode-stdio-1.0
   main-is: Spec.hs
   other-modules:
+      Test.MultiCore
+      Test.Sequential
       Paths_multilinear_io
   hs-source-dirs:
       test/csv
@@ -91,6 +97,8 @@
   type: exitcode-stdio-1.0
   main-is: Spec.hs
   other-modules:
+      Test.MultiCore
+      Test.Sequential
       Paths_multilinear_io
   hs-source-dirs:
       test/json
diff --git a/src/Multilinear/Generic/MultiCore/Serialize.hs b/src/Multilinear/Generic/MultiCore/Serialize.hs
new file mode 100644
--- /dev/null
+++ b/src/Multilinear/Generic/MultiCore/Serialize.hs
@@ -0,0 +1,178 @@
+{-|
+Module      : Multilinear.Generic.Serialize
+Description : Generic array tensor serialization: binary, JSON, CSV. 
+Copyright   : (c) Artur M. Brodzki, 2018
+License     : BSD3
+Maintainer  : artur@brodzki.org
+Stability   : experimental
+Portability : Windows/POSIX
+
+-}
+
+module Multilinear.Generic.MultiCore.Serialize (
+    toBinary, toBinaryFile,
+    fromBinary, fromBinaryFile,
+    Multilinear.Generic.MultiCore.Serialize.toJSON, 
+    Multilinear.Generic.MultiCore.Serialize.toJSONFile,
+    Multilinear.Generic.MultiCore.Serialize.fromJSON, 
+    Multilinear.Generic.MultiCore.Serialize.fromJSONFile,
+    fromCSVFile, toCSVFile
+) where
+
+import           Codec.Compression.GZip
+import           Control.Monad.Trans.Class
+import           Control.Monad.Trans.Except
+import           Control.Monad.Trans.Maybe
+import           Data.Aeson
+import qualified Data.ByteString.Internal   as BS
+import qualified Data.ByteString.Lazy       as ByteString
+import           Data.Conduit
+import           Data.Conduit.Combinators
+import           Data.Csv
+import           Data.Either
+import           Data.Serialize
+import qualified Data.Vector                as Boxed
+import           Data.Vector.Serialize      ()
+import qualified Data.Vector.Unboxed        as Unboxed
+import           Multilinear.Generic.MultiCore
+import qualified Multilinear.Index.Finite   as Finite
+import           Multilinear.Index.Finite.Serialize ()
+
+-- Binary serialization instance
+instance (Serialize a, Unboxed.Unbox a) => Serialize (Tensor a)
+-- JSON serialization instance
+instance (ToJSON a, Unboxed.Unbox a) => ToJSON (Tensor a)
+-- JSON deserialization instance
+instance (FromJSON a, Unboxed.Unbox a) => FromJSON (Tensor a)
+-- CSV serialization instance
+instance (ToField a, Unboxed.Unbox a) => ToRecord (Tensor a) where
+  toRecord (Scalar x) = record [toField x]
+  toRecord (SimpleFinite _ scalars) = toRecord scalars
+  toRecord _ = error "Only 1-order tensor may be converted to record!"
+instance (FromField a, Unboxed.Unbox a) => FromRecord (Tensor a) where
+  parseRecord v = 
+    if Boxed.length v == 1 then
+      Scalar <$> v .! 0
+    else
+      error "non-scalar"
+
+
+{-| Serialize tensor to zlib compressed binary string -}
+toBinary :: (
+    Serialize a, Unboxed.Unbox a
+  ) => Tensor a              -- ^ Tensor to serialize
+    -> ByteString.ByteString -- ^ Tensor serialized to lazy ByteString
+toBinary = compress . Data.Serialize.encodeLazy
+
+{-| Write tensor to binary file. Uses compression with gzip -}
+toBinaryFile :: (
+    Serialize a, Unboxed.Unbox a
+  ) => Tensor a  -- ^ Tensor to serialize
+    -> String    -- ^ File name
+    -> IO ()
+toBinaryFile t fileName = do
+  let bs = toBinary t
+  runConduitRes $ 
+    sourceLazy bs .| sinkFile fileName
+
+{-| Deserialize tensor from zlib compressed binary string -}
+fromBinary :: (
+    Serialize a, Unboxed.Unbox a
+  ) => ByteString.ByteString    -- ^ ByteString to deserialize
+    -> Either String (Tensor a) -- ^ Deserialized tensor or an error message. 
+fromBinary = Data.Serialize.decodeLazy . decompress
+
+{-| Read tensor from binary file -}
+fromBinaryFile :: (
+    Serialize a, Unboxed.Unbox a
+  ) => String                       -- ^ File path. 
+    -> ExceptT String IO (Tensor a) -- ^ Deserialized tensor or an error message
+fromBinaryFile fileName = do
+  contents <- lift $ runConduitRes $ 
+    sourceFile fileName .| sinkLazy
+  ExceptT $ return $ fromBinary contents
+
+{-| Serialize tensor to JSON string -}
+toJSON :: (
+    ToJSON a, Unboxed.Unbox a
+  ) => Tensor a              -- ^ Tensor to serialize. 
+    -> ByteString.ByteString -- ^ Tensor serialized to lazy ByteString. 
+toJSON = Data.Aeson.encode
+
+{-| Write tensor to JSON file -}
+toJSONFile :: (
+    ToJSON a, Unboxed.Unbox a
+  ) => Tensor a -- ^ Tensor to serialize
+    -> String   -- ^ File path. 
+    -> IO ()
+toJSONFile t fileName = do
+  let bs = Multilinear.Generic.MultiCore.Serialize.toJSON t
+  runConduitRes $ 
+    sourceLazy bs .| sinkFile fileName
+
+{-| Deserialize tensor from JSON string -}
+fromJSON :: (
+    FromJSON a, Unboxed.Unbox a
+  ) => ByteString.ByteString -- ^ ByteString to deserialize
+    -> Maybe (Tensor a)      -- ^ Deserialized tensor or Nothing, if deserialization error occured. 
+fromJSON = Data.Aeson.decode
+
+{-| Read tensor from JSON file -}
+fromJSONFile :: (
+    FromJSON a, Unboxed.Unbox a
+  ) => String               -- ^ File path. 
+    -> MaybeT IO (Tensor a) -- ^ Deserialized tensor or Nothing, if error occured. 
+fromJSONFile fileName = do
+  contents <- lift $ runConduitRes $ 
+    sourceFile fileName .| sinkLazy
+  MaybeT $ return $ Multilinear.Generic.MultiCore.Serialize.fromJSON contents
+
+{-| Write tensor to CSV file -}
+toCSVFile :: (
+  ToField a, Unboxed.Unbox a
+  ) => Tensor a -- ^ Tensor to serialize
+    -> String   -- ^ File path
+    -> IO ()
+
+-- Encoding Scalar value
+toCSVFile s@(Scalar _) fileName = do
+  let bs = Data.Csv.encode [s]
+  runConduitRes $ 
+    sourceLazy bs .| sinkFile fileName
+
+-- Encoding SimpleFinite (1D) tensor
+toCSVFile (SimpleFinite _ vs) fileName = do
+  let rows = [vs]
+  let bs = Data.Csv.encode rows
+  runConduitRes $ 
+    sourceLazy bs .| sinkFile fileName
+
+-- Encoding FiniteTensor (many dimensions)
+toCSVFile (FiniteTensor _ vrows) fileName = do
+  let rows = Boxed.toList vrows
+  let bs = Data.Csv.encode rows
+  runConduitRes $ 
+    sourceLazy bs .| sinkFile fileName
+
+
+{-| Read tensor from CSV -}
+fromCSVFile :: (
+  FromField a, Unboxed.Unbox a
+  ) => String -- ^ File path. 
+    -> Char   -- ^ CSV separator
+    -> String -- ^ Matrix indices names
+    -> ExceptT String IO (Tensor a)  -- ^ Deserialized tensor or an error message
+fromCSVFile fileName separator [conI,covI] = do
+  --let csvSettings = CSVSettings separator Nothing
+  contents <- lift $ runConduitRes $ 
+    sourceFile fileName .| sinkLazy
+  let decodedData = Data.Csv.decodeWith (DecodeOptions (BS.c2w separator)) NoHeader contents :: (FromField a, Unboxed.Unbox a) => Either String (Boxed.Vector (Unboxed.Vector a))
+  if isLeft decodedData 
+  then do
+    let msg = fromLeft "" decodedData
+    ExceptT $ return $ Left msg
+  else do
+    let components = fromRight Boxed.empty decodedData
+    let rows = (\r -> SimpleFinite (Finite.Covariant (Unboxed.length r) [covI]) r) <$> components
+    ExceptT $ return $ Right $ FiniteTensor (Finite.Contravariant (Boxed.length rows) [conI]) rows 
+fromCSVFile _ _ _ = error "You must provide exactly two indices names!"
diff --git a/src/Multilinear/Generic/Sequential/Serialize.hs b/src/Multilinear/Generic/Sequential/Serialize.hs
new file mode 100644
--- /dev/null
+++ b/src/Multilinear/Generic/Sequential/Serialize.hs
@@ -0,0 +1,178 @@
+{-|
+Module      : Multilinear.Generic.Serialize
+Description : Generic array tensor serialization: binary, JSON, CSV. 
+Copyright   : (c) Artur M. Brodzki, 2018
+License     : BSD3
+Maintainer  : artur@brodzki.org
+Stability   : experimental
+Portability : Windows/POSIX
+
+-}
+
+module Multilinear.Generic.Sequential.Serialize (
+    toBinary, toBinaryFile,
+    fromBinary, fromBinaryFile,
+    Multilinear.Generic.Sequential.Serialize.toJSON, 
+    Multilinear.Generic.Sequential.Serialize.toJSONFile,
+    Multilinear.Generic.Sequential.Serialize.fromJSON, 
+    Multilinear.Generic.Sequential.Serialize.fromJSONFile,
+    fromCSVFile, toCSVFile
+) where
+
+import           Codec.Compression.GZip
+import           Control.Monad.Trans.Class
+import           Control.Monad.Trans.Except
+import           Control.Monad.Trans.Maybe
+import           Data.Aeson
+import qualified Data.ByteString.Internal   as BS
+import qualified Data.ByteString.Lazy       as ByteString
+import           Data.Conduit
+import           Data.Conduit.Combinators
+import           Data.Csv
+import           Data.Either
+import           Data.Serialize
+import qualified Data.Vector                as Boxed
+import           Data.Vector.Serialize      ()
+import qualified Data.Vector.Unboxed        as Unboxed
+import           Multilinear.Generic.Sequential
+import qualified Multilinear.Index.Finite   as Finite
+import           Multilinear.Index.Finite.Serialize ()
+
+-- Binary serialization instance
+instance (Serialize a, Unboxed.Unbox a) => Serialize (Tensor a)
+-- JSON serialization instance
+instance (ToJSON a, Unboxed.Unbox a) => ToJSON (Tensor a)
+-- JSON deserialization instance
+instance (FromJSON a, Unboxed.Unbox a) => FromJSON (Tensor a)
+-- CSV serialization instance
+instance (ToField a, Unboxed.Unbox a) => ToRecord (Tensor a) where
+  toRecord (Scalar x) = record [toField x]
+  toRecord (SimpleFinite _ scalars) = toRecord scalars
+  toRecord _ = error "Only 1-order tensor may be converted to record!"
+instance (FromField a, Unboxed.Unbox a) => FromRecord (Tensor a) where
+  parseRecord v = 
+    if Boxed.length v == 1 then
+      Scalar <$> v .! 0
+    else
+      error "non-scalar"
+
+
+{-| Serialize tensor to zlib compressed binary string -}
+toBinary :: (
+    Serialize a, Unboxed.Unbox a
+  ) => Tensor a              -- ^ Tensor to serialize
+    -> ByteString.ByteString -- ^ Tensor serialized to lazy ByteString
+toBinary = compress . Data.Serialize.encodeLazy
+
+{-| Write tensor to binary file. Uses compression with gzip -}
+toBinaryFile :: (
+    Serialize a, Unboxed.Unbox a
+  ) => Tensor a  -- ^ Tensor to serialize
+    -> String    -- ^ File name
+    -> IO ()
+toBinaryFile t fileName = do
+  let bs = toBinary t
+  runConduitRes $ 
+    sourceLazy bs .| sinkFile fileName
+
+{-| Deserialize tensor from zlib compressed binary string -}
+fromBinary :: (
+    Serialize a, Unboxed.Unbox a
+  ) => ByteString.ByteString    -- ^ ByteString to deserialize
+    -> Either String (Tensor a) -- ^ Deserialized tensor or an error message. 
+fromBinary = Data.Serialize.decodeLazy . decompress
+
+{-| Read tensor from binary file -}
+fromBinaryFile :: (
+    Serialize a, Unboxed.Unbox a
+  ) => String                       -- ^ File path. 
+    -> ExceptT String IO (Tensor a) -- ^ Deserialized tensor or an error message
+fromBinaryFile fileName = do
+  contents <- lift $ runConduitRes $ 
+    sourceFile fileName .| sinkLazy
+  ExceptT $ return $ fromBinary contents
+
+{-| Serialize tensor to JSON string -}
+toJSON :: (
+    ToJSON a, Unboxed.Unbox a
+  ) => Tensor a              -- ^ Tensor to serialize. 
+    -> ByteString.ByteString -- ^ Tensor serialized to lazy ByteString. 
+toJSON = Data.Aeson.encode
+
+{-| Write tensor to JSON file -}
+toJSONFile :: (
+    ToJSON a, Unboxed.Unbox a
+  ) => Tensor a -- ^ Tensor to serialize
+    -> String   -- ^ File path. 
+    -> IO ()
+toJSONFile t fileName = do
+  let bs = Multilinear.Generic.Sequential.Serialize.toJSON t
+  runConduitRes $ 
+    sourceLazy bs .| sinkFile fileName
+
+{-| Deserialize tensor from JSON string -}
+fromJSON :: (
+    FromJSON a, Unboxed.Unbox a
+  ) => ByteString.ByteString -- ^ ByteString to deserialize
+    -> Maybe (Tensor a)      -- ^ Deserialized tensor or Nothing, if deserialization error occured. 
+fromJSON = Data.Aeson.decode
+
+{-| Read tensor from JSON file -}
+fromJSONFile :: (
+    FromJSON a, Unboxed.Unbox a
+  ) => String               -- ^ File path. 
+    -> MaybeT IO (Tensor a) -- ^ Deserialized tensor or Nothing, if error occured. 
+fromJSONFile fileName = do
+  contents <- lift $ runConduitRes $ 
+    sourceFile fileName .| sinkLazy
+  MaybeT $ return $ Multilinear.Generic.Sequential.Serialize.fromJSON contents
+
+{-| Write tensor to CSV file -}
+toCSVFile :: (
+  ToField a, Unboxed.Unbox a
+  ) => Tensor a -- ^ Tensor to serialize
+    -> String   -- ^ File path
+    -> IO ()
+
+-- Encoding Scalar value
+toCSVFile s@(Scalar _) fileName = do
+  let bs = Data.Csv.encode [s]
+  runConduitRes $ 
+    sourceLazy bs .| sinkFile fileName
+
+-- Encoding SimpleFinite (1D) tensor
+toCSVFile (SimpleFinite _ vs) fileName = do
+  let rows = [vs]
+  let bs = Data.Csv.encode rows
+  runConduitRes $ 
+    sourceLazy bs .| sinkFile fileName
+
+-- Encoding FiniteTensor (many dimensions)
+toCSVFile (FiniteTensor _ vrows) fileName = do
+  let rows = Boxed.toList vrows
+  let bs = Data.Csv.encode rows
+  runConduitRes $ 
+    sourceLazy bs .| sinkFile fileName
+
+
+{-| Read tensor from CSV -}
+fromCSVFile :: (
+  FromField a, Unboxed.Unbox a
+  ) => String -- ^ File path. 
+    -> Char   -- ^ CSV separator
+    -> String -- ^ Matrix indices names
+    -> ExceptT String IO (Tensor a)  -- ^ Deserialized tensor or an error message
+fromCSVFile fileName separator [conI,covI] = do
+  --let csvSettings = CSVSettings separator Nothing
+  contents <- lift $ runConduitRes $ 
+    sourceFile fileName .| sinkLazy
+  let decodedData = Data.Csv.decodeWith (DecodeOptions (BS.c2w separator)) NoHeader contents :: (FromField a, Unboxed.Unbox a) => Either String (Boxed.Vector (Unboxed.Vector a))
+  if isLeft decodedData 
+  then do
+    let msg = fromLeft "" decodedData
+    ExceptT $ return $ Left msg
+  else do
+    let components = fromRight Boxed.empty decodedData
+    let rows = (\r -> SimpleFinite (Finite.Covariant (Unboxed.length r) [covI]) r) <$> components
+    ExceptT $ return $ Right $ FiniteTensor (Finite.Contravariant (Boxed.length rows) [conI]) rows 
+fromCSVFile _ _ _ = error "You must provide exactly two indices names!"
diff --git a/src/Multilinear/Generic/Serialize.hs b/src/Multilinear/Generic/Serialize.hs
--- a/src/Multilinear/Generic/Serialize.hs
+++ b/src/Multilinear/Generic/Serialize.hs
@@ -10,169 +10,7 @@
 -}
 
 module Multilinear.Generic.Serialize (
-    toBinary, toBinaryFile,
-    fromBinary, fromBinaryFile,
-    Multilinear.Generic.Serialize.toJSON, 
-    Multilinear.Generic.Serialize.toJSONFile,
-    Multilinear.Generic.Serialize.fromJSON, 
-    Multilinear.Generic.Serialize.fromJSONFile,
-    fromCSVFile, toCSVFile
+    module DefaultTensorImplementation
 ) where
 
-import           Codec.Compression.GZip
-import           Control.Monad.Trans.Class
-import           Control.Monad.Trans.Except
-import           Control.Monad.Trans.Maybe
-import           Data.Aeson
-import qualified Data.ByteString.Internal   as BS
-import qualified Data.ByteString.Lazy       as ByteString
-import           Data.Conduit
-import           Data.Conduit.Combinators
-import           Data.Csv
-import           Data.Either
-import           Data.Serialize
-import qualified Data.Vector                as Boxed
-import           Data.Vector.Serialize      ()
-import qualified Data.Vector.Unboxed        as Unboxed
-import           Multilinear.Generic
-import qualified Multilinear.Index.Finite   as Finite
-import           Multilinear.Index.Finite.Serialize ()
-
--- Binary serialization instance
-instance (Serialize a, Unboxed.Unbox a) => Serialize (Tensor a)
--- JSON serialization instance
-instance (ToJSON a, Unboxed.Unbox a) => ToJSON (Tensor a)
--- JSON deserialization instance
-instance (FromJSON a, Unboxed.Unbox a) => FromJSON (Tensor a)
--- CSV serialization instance
-instance (ToField a, Unboxed.Unbox a) => ToRecord (Tensor a) where
-  toRecord (Scalar x) = record [toField x]
-  toRecord (SimpleFinite _ scalars) = toRecord scalars
-  toRecord _ = error "Only 1-order tensor may be converted to record!"
-instance (FromField a, Unboxed.Unbox a) => FromRecord (Tensor a) where
-  parseRecord v = 
-    if Boxed.length v == 1 then
-      Scalar <$> v .! 0
-    else
-      error "non-scalar"
-
-
-{-| Serialize tensor to zlib compressed binary string -}
-toBinary :: (
-    Serialize a, Unboxed.Unbox a
-  ) => Tensor a              -- ^ Tensor to serialize
-    -> ByteString.ByteString -- ^ Tensor serialized to lazy ByteString
-toBinary = compress . Data.Serialize.encodeLazy
-
-{-| Write tensor to binary file. Uses compression with gzip -}
-toBinaryFile :: (
-    Serialize a, Unboxed.Unbox a
-  ) => Tensor a  -- ^ Tensor to serialize
-    -> String    -- ^ File name
-    -> IO ()
-toBinaryFile t fileName = do
-  let bs = toBinary t
-  runConduitRes $ 
-    sourceLazy bs .| sinkFile fileName
-
-{-| Deserialize tensor from zlib compressed binary string -}
-fromBinary :: (
-    Serialize a, Unboxed.Unbox a
-  ) => ByteString.ByteString    -- ^ ByteString to deserialize
-    -> Either String (Tensor a) -- ^ Deserialized tensor or an error message. 
-fromBinary = Data.Serialize.decodeLazy . decompress
-
-{-| Read tensor from binary file -}
-fromBinaryFile :: (
-    Serialize a, Unboxed.Unbox a
-  ) => String                       -- ^ File path. 
-    -> ExceptT String IO (Tensor a) -- ^ Deserialized tensor or an error message
-fromBinaryFile fileName = do
-  contents <- lift $ runConduitRes $ 
-    sourceFile fileName .| sinkLazy
-  ExceptT $ return $ fromBinary contents
-
-{-| Serialize tensor to JSON string -}
-toJSON :: (
-    ToJSON a, Unboxed.Unbox a
-  ) => Tensor a              -- ^ Tensor to serialize. 
-    -> ByteString.ByteString -- ^ Tensor serialized to lazy ByteString. 
-toJSON = Data.Aeson.encode
-
-{-| Write tensor to JSON file -}
-toJSONFile :: (
-    ToJSON a, Unboxed.Unbox a
-  ) => Tensor a -- ^ Tensor to serialize
-    -> String   -- ^ File path. 
-    -> IO ()
-toJSONFile t fileName = do
-  let bs = Multilinear.Generic.Serialize.toJSON t
-  runConduitRes $ 
-    sourceLazy bs .| sinkFile fileName
-
-{-| Deserialize tensor from JSON string -}
-fromJSON :: (
-    FromJSON a, Unboxed.Unbox a
-  ) => ByteString.ByteString -- ^ ByteString to deserialize
-    -> Maybe (Tensor a)      -- ^ Deserialized tensor or Nothing, if deserialization error occured. 
-fromJSON = Data.Aeson.decode
-
-{-| Read tensor from JSON file -}
-fromJSONFile :: (
-    FromJSON a, Unboxed.Unbox a
-  ) => String               -- ^ File path. 
-    -> MaybeT IO (Tensor a) -- ^ Deserialized tensor or Nothing, if error occured. 
-fromJSONFile fileName = do
-  contents <- lift $ runConduitRes $ 
-    sourceFile fileName .| sinkLazy
-  MaybeT $ return $ Multilinear.Generic.Serialize.fromJSON contents
-
-{-| Write tensor to CSV file -}
-toCSVFile :: (
-  ToField a, Unboxed.Unbox a
-  ) => Tensor a -- ^ Tensor to serialize
-    -> String   -- ^ File path
-    -> IO ()
-
--- Encoding Scalar value
-toCSVFile s@(Scalar _) fileName = do
-  let bs = Data.Csv.encode [s]
-  runConduitRes $ 
-    sourceLazy bs .| sinkFile fileName
-
--- Encoding SimpleFinite (1D) tensor
-toCSVFile (SimpleFinite _ vs) fileName = do
-  let rows = [vs]
-  let bs = Data.Csv.encode rows
-  runConduitRes $ 
-    sourceLazy bs .| sinkFile fileName
-
--- Encoding FiniteTensor (many dimensions)
-toCSVFile (FiniteTensor _ vrows) fileName = do
-  let rows = Boxed.toList vrows
-  let bs = Data.Csv.encode rows
-  runConduitRes $ 
-    sourceLazy bs .| sinkFile fileName
-
-
-{-| Read tensor from CSV -}
-fromCSVFile :: (
-  FromField a, Unboxed.Unbox a
-  ) => String -- ^ File path. 
-    -> Char   -- ^ CSV separator
-    -> String -- ^ Matrix indices names
-    -> ExceptT String IO (Tensor a)  -- ^ Deserialized tensor or an error message
-fromCSVFile fileName separator [conI,covI] = do
-  --let csvSettings = CSVSettings separator Nothing
-  contents <- lift $ runConduitRes $ 
-    sourceFile fileName .| sinkLazy
-  let decodedData = Data.Csv.decodeWith (DecodeOptions (BS.c2w separator)) NoHeader contents :: (FromField a, Unboxed.Unbox a) => Either String (Boxed.Vector (Unboxed.Vector a))
-  if isLeft decodedData 
-  then do
-    let msg = fromLeft "" decodedData
-    ExceptT $ return $ Left msg
-  else do
-    let components = fromRight Boxed.empty decodedData
-    let rows = (\r -> SimpleFinite (Finite.Covariant (Unboxed.length r) [covI]) r) <$> components
-    ExceptT $ return $ Right $ FiniteTensor (Finite.Contravariant (Boxed.length rows) [conI]) rows 
-fromCSVFile _ _ _ = error "You must provide exactly two indices names!"
+import Multilinear.Generic.Sequential.Serialize as DefaultTensorImplementation
diff --git a/test/binary/Spec.hs b/test/binary/Spec.hs
--- a/test/binary/Spec.hs
+++ b/test/binary/Spec.hs
@@ -2,42 +2,32 @@
   main
 ) where
 
-import           Control.Monad.Trans.Class
 import           Control.Monad.Trans.Except
-import           Data.Maybe
-import           Multilinear.Class
-import           Multilinear.Generic
-import           Multilinear.Generic.Serialize
-import           Multilinear.Index
-import qualified Multilinear.Matrix         as Matrix
+import qualified Multilinear.Generic.MultiCore  as MultiCore
+import qualified Multilinear.Generic.Sequential as Sequential
+import qualified Multilinear.Matrix             as Matrix
 import           System.Directory
+import           Test.MultiCore
+import           Test.Sequential
 
 fileName1 :: String
 fileName1  = "test/m1"
 
-m1 :: Tensor Double
-m1 = Matrix.fromIndices "ij" 50 50 $ \i j -> cos (fromIntegral i) + sin (fromIntegral j)
-
-writeMatrixBinary :: Tensor Double -> String -> IO ()
-writeMatrixBinary m fileName = do
-  let [xsize,ysize] = indexSize <$> indices m1
-  putStrLn $ "Writing " ++ show (fromJust xsize) ++ "x" ++ show (fromJust ysize) ++ " matrix to " ++ fileName ++ ".zlib..."
-  m `toBinaryFile` (fileName ++ ".zlib")
-  putStrLn $ "Matrix successfully written!"
+m1Seq :: Sequential.Tensor Double
+m1Seq = Matrix.fromIndices "ij" 50 50 $ \i j -> cos (fromIntegral i) + sin (fromIntegral j)
 
-readMatrixBinary :: String -> ExceptT String IO ()
-readMatrixBinary fileName = do
-  lift $ putStrLn $ "Reading matrix m1 from " ++ fileName ++ ".zlib..."
-  m1' <- fromBinaryFile (fileName ++ ".zlib")
-  if m1' == m1 then
-    lift $ putStrLn "Matrix successfully read!"
-  else
-    ExceptT $ return $ Left "Matrix deserialization error"
+m1MC :: MultiCore.Tensor Double
+m1MC = Matrix.fromIndices "ij" 50 50 $ \i j -> cos (fromIntegral i) + sin (fromIntegral j)
 
 -- ENTRY POINT
 main :: IO ()
 main = do
-  writeMatrixBinary m1 fileName1
-  runExceptT $ readMatrixBinary fileName1
+  putStrLn "Testing MultiCore..."
+  Test.MultiCore.writeMatrixBinary m1MC fileName1
+  runExceptT $ Test.MultiCore.readMatrixBinary m1MC fileName1
+  removeFile $ fileName1 ++ ".zlib"
+  putStrLn "Testing Sequential..."
+  Test.Sequential.writeMatrixBinary m1Seq fileName1
+  runExceptT $ Test.Sequential.readMatrixBinary m1Seq fileName1
   removeFile $ fileName1 ++ ".zlib"
   return ()
diff --git a/test/binary/Test/MultiCore.hs b/test/binary/Test/MultiCore.hs
new file mode 100644
--- /dev/null
+++ b/test/binary/Test/MultiCore.hs
@@ -0,0 +1,27 @@
+module Test.MultiCore (
+  writeMatrixBinary, readMatrixBinary
+) where
+
+import           Control.Monad.Trans.Class
+import           Control.Monad.Trans.Except
+import           Data.Maybe
+import           Multilinear.Class
+import           Multilinear.Generic.MultiCore
+import           Multilinear.Generic.MultiCore.Serialize
+import           Multilinear.Index
+
+writeMatrixBinary :: Tensor Double -> String -> IO ()
+writeMatrixBinary m fileName = do
+  let [xsize,ysize] = indexSize <$> indices m
+  putStrLn $ "Writing " ++ show (fromJust xsize) ++ "x" ++ show (fromJust ysize) ++ " matrix to " ++ fileName ++ ".zlib..."
+  m `toBinaryFile` (fileName ++ ".zlib")
+  putStrLn $ "Matrix successfully written!"
+
+readMatrixBinary :: Tensor Double -> String -> ExceptT String IO ()
+readMatrixBinary m fileName = do
+  lift $ putStrLn $ "Reading matrix m1 from " ++ fileName ++ ".zlib..."
+  m1' <- fromBinaryFile (fileName ++ ".zlib")
+  if m1' == m then
+    lift $ putStrLn "Matrix successfully read!"
+  else
+    ExceptT $ return $ Left "Matrix deserialization error"
diff --git a/test/binary/Test/Sequential.hs b/test/binary/Test/Sequential.hs
new file mode 100644
--- /dev/null
+++ b/test/binary/Test/Sequential.hs
@@ -0,0 +1,27 @@
+module Test.Sequential (
+  writeMatrixBinary, readMatrixBinary
+) where
+
+import           Control.Monad.Trans.Class
+import           Control.Monad.Trans.Except
+import           Data.Maybe
+import           Multilinear.Class
+import           Multilinear.Generic.Sequential
+import           Multilinear.Generic.Sequential.Serialize
+import           Multilinear.Index
+
+writeMatrixBinary :: Tensor Double -> String -> IO ()
+writeMatrixBinary m fileName = do
+  let [xsize,ysize] = indexSize <$> indices m
+  putStrLn $ "Writing " ++ show (fromJust xsize) ++ "x" ++ show (fromJust ysize) ++ " matrix to " ++ fileName ++ ".zlib..."
+  m `toBinaryFile` (fileName ++ ".zlib")
+  putStrLn $ "Matrix successfully written!"
+
+readMatrixBinary :: Tensor Double -> String -> ExceptT String IO ()
+readMatrixBinary m fileName = do
+  lift $ putStrLn $ "Reading matrix m1 from " ++ fileName ++ ".zlib..."
+  m1' <- fromBinaryFile (fileName ++ ".zlib")
+  if m1' == m then
+    lift $ putStrLn "Matrix successfully read!"
+  else
+    ExceptT $ return $ Left "Matrix deserialization error"
diff --git a/test/csv/Spec.hs b/test/csv/Spec.hs
--- a/test/csv/Spec.hs
+++ b/test/csv/Spec.hs
@@ -2,108 +2,76 @@
   main
 ) where
 
-import           Control.Monad.Trans.Class
 import           Control.Monad.Trans.Except
-import           Data.Maybe
-import           Multilinear.Class
-import           Multilinear.Generic
-import           Multilinear.Generic.Serialize
-import           Multilinear.Index
-import qualified Multilinear.Matrix         as Matrix
-import qualified Multilinear.Vector         as Vector
+import qualified Multilinear.Generic.MultiCore  as MultiCore
+import qualified Multilinear.Generic.Sequential as Sequential
+import qualified Multilinear.Matrix             as Matrix
+import qualified Multilinear.Vector             as Vector
 import           System.Directory
-
-matrix :: Tensor Double
-matrix = Matrix.fromIndices "ij" 50 50 $ \i j -> cos (fromIntegral i) + sin (fromIntegral j)
-
-vector :: Tensor Double
-vector = Vector.fromIndices "i" 50 $ \i -> cos (fromIntegral i)
-
-form :: Tensor Double
-form = Vector.fromIndices "i" 50 $ \i -> cos (fromIntegral i)
-
-scalar :: Tensor Double
-scalar = Scalar 5.0
+import           Test.MultiCore
+import           Test.Sequential
 
-writeScalarCSV :: Tensor Double -> String -> IO ()
-writeScalarCSV m fileName = do
-  putStrLn $ "Writing scalar to " ++ fileName ++ ".csv..."
-  m `toCSVFile` (fileName ++ ".csv")
-  putStrLn "Scalar successfully written!"
+matrixSeq :: Sequential.Tensor Double
+matrixSeq = Matrix.fromIndices "ij" 50 50 $ \i j -> cos (fromIntegral i) + sin (fromIntegral j)
 
-readScalarCSV :: Tensor Double -> String -> ExceptT String IO ()
-readScalarCSV m fileName = do
-  lift $ putStrLn $ "Reading scalar s1 from " ++ fileName ++ ".csv..."
-  (m1' :: Tensor Double) <- fromCSVFile (fileName ++ ".csv") ',' "ij"
-  if m1' == m then
-    lift $ putStrLn "Scalar successfully read!"
-  else
-    ExceptT $ return $ Left "Scalar deserialization error"
+vectorSeq :: Sequential.Tensor Double
+vectorSeq = Vector.fromIndices "i" 50 $ \i -> cos (fromIntegral i)
 
-writeVectorCSV :: Tensor Double -> String -> IO ()
-writeVectorCSV m fileName = do
-  let size = fromJust . indexSize <$> head $ indices m
-  putStrLn $ "Writing " ++ show size ++ " elements vector to " ++ fileName ++ ".csv..."
-  m `toCSVFile` (fileName ++ ".csv")
-  putStrLn "Vector successfully written!"
+formSeq :: Sequential.Tensor Double
+formSeq = Vector.fromIndices "i" 50 $ \i -> cos (fromIntegral i)
 
-readVectorCSV :: Tensor Double -> String -> ExceptT String IO ()
-readVectorCSV m fileName = do
-  lift $ putStrLn $ "Reading vector v1 from " ++ fileName ++ ".csv..."
-  (m1' :: Tensor Double) <- fromCSVFile (fileName ++ ".csv") ',' "ij"
-  if m1' == m then
-    lift $ putStrLn "Vector successfully read!"
-  else
-    ExceptT $ return $ Left "Vector deserialization error"
+scalarSeq :: Sequential.Tensor Double
+scalarSeq = Sequential.Scalar 5.0
 
-writeFormCSV :: Tensor Double -> String -> IO ()
-writeFormCSV m fileName = do
-  let size = fromJust . indexSize <$> head $ indices m
-  putStrLn $ "Writing " ++ show size ++ " elements form to " ++ fileName ++ ".csv..."
-  m `toCSVFile` (fileName ++ ".csv")
-  putStrLn "Form successfully written!"
+matrixMC :: MultiCore.Tensor Double
+matrixMC = Matrix.fromIndices "ij" 50 50 $ \i j -> cos (fromIntegral i) + sin (fromIntegral j)
 
-readFormCSV :: Tensor Double -> String -> ExceptT String IO ()
-readFormCSV m fileName = do
-  lift $ putStrLn $ "Reading form f1 from " ++ fileName ++ ".csv..."
-  (m1' :: Tensor Double) <- fromCSVFile (fileName ++ ".csv") ',' "ij"
-  if m1' == m then
-    lift $ putStrLn "Form successfully read!"
-  else
-    ExceptT $ return $ Left "Form deserialization error"
+vectorMC :: MultiCore.Tensor Double
+vectorMC = Vector.fromIndices "i" 50 $ \i -> cos (fromIntegral i)
 
-writeMatrixCSV :: Tensor Double -> String -> IO ()
-writeMatrixCSV m fileName = do
-  let [xsize,ysize] = indexSize <$> indices m
-  putStrLn $ "Writing " ++ show (fromJust xsize) ++ "x" ++ show (fromJust ysize) ++ " matrix to " ++ fileName ++ ".csv..."
-  m `toCSVFile` (fileName ++ ".csv")
-  putStrLn "Matrix successfully written!"
+formMC :: MultiCore.Tensor Double
+formMC = Vector.fromIndices "i" 50 $ \i -> cos (fromIntegral i)
 
-readMatrixCSV :: Tensor Double -> String -> ExceptT String IO ()
-readMatrixCSV m fileName = do
-  lift $ putStrLn $ "Reading matrix m1 from " ++ fileName ++ ".csv..."
-  (m1' :: Tensor Double) <- fromCSVFile (fileName ++ ".csv") ',' "ij"
-  if m1' == m then
-    lift $ putStrLn "Matrix successfully read!"
-  else
-    ExceptT $ return $ Left "Matrix deserialization error"
+scalarMC :: MultiCore.Tensor Double
+scalarMC = MultiCore.Scalar 5.0
 
-  
 -- ENTRY POINT
 main :: IO ()
 main = do
+  -- TEST MULTICORE
+  putStrLn "Testing MultiCore..."
   -- Scalar CSV read/write
-  writeScalarCSV scalar "test/s1"
-  runExceptT $ readScalarCSV scalar "test/s1"
+  Test.MultiCore.writeScalarCSV scalarMC "test/s1"
+  runExceptT $ Test.MultiCore.readScalarCSV scalarMC "test/s1"
   -- Vector CSV read/write
-  writeVectorCSV vector "test/v1"
-  runExceptT $ readVectorCSV vector "test/v1"
+  Test.MultiCore.writeVectorCSV vectorMC "test/v1"
+  runExceptT $ Test.MultiCore.readVectorCSV vectorMC "test/v1"
   -- Form CSV read/write
-  writeFormCSV form "test/f1"
-  runExceptT $ readFormCSV form "test/f1"
+  Test.MultiCore.writeFormCSV formMC "test/f1"
+  runExceptT $ Test.MultiCore.readFormCSV formMC "test/f1"
   -- Matrix CSV read/write
-  writeMatrixCSV matrix "test/m1"
-  runExceptT $ readMatrixCSV matrix "test/m1"
+  Test.MultiCore.writeMatrixCSV matrixMC "test/m1"
+  runExceptT $ Test.MultiCore.readMatrixCSV matrixMC "test/m1"
+  -- Remove test file
+  removeFile "test/s1.csv"
+  removeFile "test/v1.csv"
+  removeFile "test/f1.csv"
+  removeFile "test/m1.csv"
+
+  -- TEST SEQUENTIAL
+  putStrLn "Testing Sequential..."
+  -- Scalar CSV read/write
+  Test.Sequential.writeScalarCSV scalarSeq "test/s1"
+  runExceptT $ Test.Sequential.readScalarCSV scalarSeq "test/s1"
+  -- Vector CSV read/write
+  Test.Sequential.writeVectorCSV vectorSeq "test/v1"
+  runExceptT $ Test.Sequential.readVectorCSV vectorSeq "test/v1"
+  -- Form CSV read/write
+  Test.Sequential.writeFormCSV formSeq "test/f1"
+  runExceptT $ Test.Sequential.readFormCSV formSeq "test/f1"
+  -- Matrix CSV read/write
+  Test.Sequential.writeMatrixCSV matrixSeq "test/m1"
+  runExceptT $ Test.Sequential.readMatrixCSV matrixSeq "test/m1"
   -- Remove test file
   removeFile "test/s1.csv"
   removeFile "test/v1.csv"
diff --git a/test/csv/Test/MultiCore.hs b/test/csv/Test/MultiCore.hs
new file mode 100644
--- /dev/null
+++ b/test/csv/Test/MultiCore.hs
@@ -0,0 +1,77 @@
+module Test.MultiCore (
+  writeScalarCSV, readScalarCSV,
+  writeVectorCSV, readVectorCSV,
+  writeFormCSV, readFormCSV,
+  writeMatrixCSV, readMatrixCSV
+) where
+
+import           Control.Monad.Trans.Class
+import           Control.Monad.Trans.Except
+import           Data.Maybe
+import           Multilinear.Class
+import           Multilinear.Generic.MultiCore
+import           Multilinear.Generic.MultiCore.Serialize
+import           Multilinear.Index
+
+writeScalarCSV :: Tensor Double -> String -> IO ()
+writeScalarCSV m fileName = do
+  putStrLn $ "Writing scalar to " ++ fileName ++ ".csv..."
+  m `toCSVFile` (fileName ++ ".csv")
+  putStrLn "Scalar successfully written!"
+
+readScalarCSV :: Tensor Double -> String -> ExceptT String IO ()
+readScalarCSV m fileName = do
+  lift $ putStrLn $ "Reading scalar s1 from " ++ fileName ++ ".csv..."
+  (m1' :: Tensor Double) <- fromCSVFile (fileName ++ ".csv") ',' "ij"
+  if m1' == m then
+    lift $ putStrLn "Scalar successfully read!"
+  else
+    ExceptT $ return $ Left "Scalar deserialization error"
+
+writeVectorCSV :: Tensor Double -> String -> IO ()
+writeVectorCSV m fileName = do
+  let size = fromJust . indexSize <$> head $ indices m
+  putStrLn $ "Writing " ++ show size ++ " elements vector to " ++ fileName ++ ".csv..."
+  m `toCSVFile` (fileName ++ ".csv")
+  putStrLn "Vector successfully written!"
+
+readVectorCSV :: Tensor Double -> String -> ExceptT String IO ()
+readVectorCSV m fileName = do
+  lift $ putStrLn $ "Reading vector v1 from " ++ fileName ++ ".csv..."
+  (m1' :: Tensor Double) <- fromCSVFile (fileName ++ ".csv") ',' "ij"
+  if m1' == m then
+    lift $ putStrLn "Vector successfully read!"
+  else
+    ExceptT $ return $ Left "Vector deserialization error"
+
+writeFormCSV :: Tensor Double -> String -> IO ()
+writeFormCSV m fileName = do
+  let size = fromJust . indexSize <$> head $ indices m
+  putStrLn $ "Writing " ++ show size ++ " elements form to " ++ fileName ++ ".csv..."
+  m `toCSVFile` (fileName ++ ".csv")
+  putStrLn "Form successfully written!"
+
+readFormCSV :: Tensor Double -> String -> ExceptT String IO ()
+readFormCSV m fileName = do
+  lift $ putStrLn $ "Reading form f1 from " ++ fileName ++ ".csv..."
+  (m1' :: Tensor Double) <- fromCSVFile (fileName ++ ".csv") ',' "ij"
+  if m1' == m then
+    lift $ putStrLn "Form successfully read!"
+  else
+    ExceptT $ return $ Left "Form deserialization error"
+
+writeMatrixCSV :: Tensor Double -> String -> IO ()
+writeMatrixCSV m fileName = do
+  let [xsize,ysize] = indexSize <$> indices m
+  putStrLn $ "Writing " ++ show (fromJust xsize) ++ "x" ++ show (fromJust ysize) ++ " matrix to " ++ fileName ++ ".csv..."
+  m `toCSVFile` (fileName ++ ".csv")
+  putStrLn "Matrix successfully written!"
+
+readMatrixCSV :: Tensor Double -> String -> ExceptT String IO ()
+readMatrixCSV m fileName = do
+  lift $ putStrLn $ "Reading matrix m1 from " ++ fileName ++ ".csv..."
+  (m1' :: Tensor Double) <- fromCSVFile (fileName ++ ".csv") ',' "ij"
+  if m1' == m then
+    lift $ putStrLn "Matrix successfully read!"
+  else
+    ExceptT $ return $ Left "Matrix deserialization error"
diff --git a/test/csv/Test/Sequential.hs b/test/csv/Test/Sequential.hs
new file mode 100644
--- /dev/null
+++ b/test/csv/Test/Sequential.hs
@@ -0,0 +1,77 @@
+module Test.Sequential (
+  writeScalarCSV, readScalarCSV,
+  writeVectorCSV, readVectorCSV,
+  writeFormCSV, readFormCSV,
+  writeMatrixCSV, readMatrixCSV
+) where
+
+import           Control.Monad.Trans.Class
+import           Control.Monad.Trans.Except
+import           Data.Maybe
+import           Multilinear.Class
+import           Multilinear.Generic.Sequential
+import           Multilinear.Generic.Sequential.Serialize
+import           Multilinear.Index
+
+writeScalarCSV :: Tensor Double -> String -> IO ()
+writeScalarCSV m fileName = do
+  putStrLn $ "Writing scalar to " ++ fileName ++ ".csv..."
+  m `toCSVFile` (fileName ++ ".csv")
+  putStrLn "Scalar successfully written!"
+
+readScalarCSV :: Tensor Double -> String -> ExceptT String IO ()
+readScalarCSV m fileName = do
+  lift $ putStrLn $ "Reading scalar s1 from " ++ fileName ++ ".csv..."
+  (m1' :: Tensor Double) <- fromCSVFile (fileName ++ ".csv") ',' "ij"
+  if m1' == m then
+    lift $ putStrLn "Scalar successfully read!"
+  else
+    ExceptT $ return $ Left "Scalar deserialization error"
+
+writeVectorCSV :: Tensor Double -> String -> IO ()
+writeVectorCSV m fileName = do
+  let size = fromJust . indexSize <$> head $ indices m
+  putStrLn $ "Writing " ++ show size ++ " elements vector to " ++ fileName ++ ".csv..."
+  m `toCSVFile` (fileName ++ ".csv")
+  putStrLn "Vector successfully written!"
+
+readVectorCSV :: Tensor Double -> String -> ExceptT String IO ()
+readVectorCSV m fileName = do
+  lift $ putStrLn $ "Reading vector v1 from " ++ fileName ++ ".csv..."
+  (m1' :: Tensor Double) <- fromCSVFile (fileName ++ ".csv") ',' "ij"
+  if m1' == m then
+    lift $ putStrLn "Vector successfully read!"
+  else
+    ExceptT $ return $ Left "Vector deserialization error"
+
+writeFormCSV :: Tensor Double -> String -> IO ()
+writeFormCSV m fileName = do
+  let size = fromJust . indexSize <$> head $ indices m
+  putStrLn $ "Writing " ++ show size ++ " elements form to " ++ fileName ++ ".csv..."
+  m `toCSVFile` (fileName ++ ".csv")
+  putStrLn "Form successfully written!"
+
+readFormCSV :: Tensor Double -> String -> ExceptT String IO ()
+readFormCSV m fileName = do
+  lift $ putStrLn $ "Reading form f1 from " ++ fileName ++ ".csv..."
+  (m1' :: Tensor Double) <- fromCSVFile (fileName ++ ".csv") ',' "ij"
+  if m1' == m then
+    lift $ putStrLn "Form successfully read!"
+  else
+    ExceptT $ return $ Left "Form deserialization error"
+
+writeMatrixCSV :: Tensor Double -> String -> IO ()
+writeMatrixCSV m fileName = do
+  let [xsize,ysize] = indexSize <$> indices m
+  putStrLn $ "Writing " ++ show (fromJust xsize) ++ "x" ++ show (fromJust ysize) ++ " matrix to " ++ fileName ++ ".csv..."
+  m `toCSVFile` (fileName ++ ".csv")
+  putStrLn "Matrix successfully written!"
+
+readMatrixCSV :: Tensor Double -> String -> ExceptT String IO ()
+readMatrixCSV m fileName = do
+  lift $ putStrLn $ "Reading matrix m1 from " ++ fileName ++ ".csv..."
+  (m1' :: Tensor Double) <- fromCSVFile (fileName ++ ".csv") ',' "ij"
+  if m1' == m then
+    lift $ putStrLn "Matrix successfully read!"
+  else
+    ExceptT $ return $ Left "Matrix deserialization error"
diff --git a/test/json/Spec.hs b/test/json/Spec.hs
--- a/test/json/Spec.hs
+++ b/test/json/Spec.hs
@@ -2,42 +2,32 @@
   main
 ) where
 
-import           Control.Monad.Trans.Class
 import           Control.Monad.Trans.Maybe
-import           Data.Maybe
-import           Multilinear.Class
-import           Multilinear.Generic
-import           Multilinear.Generic.Serialize
-import           Multilinear.Index
+import qualified Multilinear.Generic.MultiCore  as MultiCore
+import qualified Multilinear.Generic.Sequential as Sequential
 import qualified Multilinear.Matrix         as Matrix
 import           System.Directory
+import           Test.MultiCore
+import           Test.Sequential
 
 fileName1 :: String
 fileName1  = "test/m1"
 
-m1 :: Tensor Double
-m1 = Matrix.fromIndices "ij" 50 50 $ \i j -> cos (fromIntegral i) + sin (fromIntegral j)
-
-writeMatrixJSON :: Tensor Double -> String -> IO ()
-writeMatrixJSON m fileName = do
-  let [xsize,ysize] = indexSize <$> indices m1
-  putStrLn $ "Writing " ++ show (fromJust xsize) ++ "x" ++ show (fromJust ysize) ++ " matrix to " ++ fileName ++ ".json..."
-  m `toJSONFile` (fileName ++ ".json")
-  putStrLn $ "Matrix successfully written!"
+m1MC :: MultiCore.Tensor Double
+m1MC = Matrix.fromIndices "ij" 50 50 $ \i j -> cos (fromIntegral i) + sin (fromIntegral j)
 
-readMatrixJSON :: String -> MaybeT IO ()
-readMatrixJSON fileName = do
-  lift $ putStrLn $ "Reading matrix m1 from " ++ fileName ++ ".json..."
-  m1' <- fromJSONFile (fileName ++ ".json")
-  if m1' == m1 then
-    lift $ putStrLn "Matrix successfully read!"
-  else
-    MaybeT $ return Nothing
+m1Seq :: Sequential.Tensor Double
+m1Seq = Matrix.fromIndices "ij" 50 50 $ \i j -> cos (fromIntegral i) + sin (fromIntegral j)
 
 -- ENTRY POINT
 main :: IO ()
 main = do
-  writeMatrixJSON m1 fileName1
-  runMaybeT $ readMatrixJSON fileName1
+  putStrLn "Testing MultiCore..."
+  Test.MultiCore.writeMatrixJSON m1MC fileName1
+  runMaybeT $ Test.MultiCore.readMatrixJSON m1MC fileName1
+  removeFile $ fileName1 ++ ".json"
+  putStrLn "Testing Sequential..."
+  Test.Sequential.writeMatrixJSON m1Seq fileName1
+  runMaybeT $ Test.Sequential.readMatrixJSON m1Seq fileName1
   removeFile $ fileName1 ++ ".json"
   return ()
diff --git a/test/json/Test/MultiCore.hs b/test/json/Test/MultiCore.hs
new file mode 100644
--- /dev/null
+++ b/test/json/Test/MultiCore.hs
@@ -0,0 +1,27 @@
+module Test.MultiCore (
+  writeMatrixJSON, readMatrixJSON
+) where
+
+import           Control.Monad.Trans.Class
+import           Control.Monad.Trans.Maybe
+import           Data.Maybe
+import           Multilinear.Class
+import           Multilinear.Generic.MultiCore
+import           Multilinear.Generic.MultiCore.Serialize
+import           Multilinear.Index
+
+writeMatrixJSON :: Tensor Double -> String -> IO ()
+writeMatrixJSON m fileName = do
+  let [xsize,ysize] = indexSize <$> indices m
+  putStrLn $ "Writing " ++ show (fromJust xsize) ++ "x" ++ show (fromJust ysize) ++ " matrix to " ++ fileName ++ ".json..."
+  m `toJSONFile` (fileName ++ ".json")
+  putStrLn $ "Matrix successfully written!"
+
+readMatrixJSON :: Tensor Double -> String -> MaybeT IO ()
+readMatrixJSON m fileName = do
+  lift $ putStrLn $ "Reading matrix m1 from " ++ fileName ++ ".json..."
+  m1' <- fromJSONFile (fileName ++ ".json")
+  if m1' == m then
+    lift $ putStrLn "Matrix successfully read!"
+  else
+    MaybeT $ return Nothing
diff --git a/test/json/Test/Sequential.hs b/test/json/Test/Sequential.hs
new file mode 100644
--- /dev/null
+++ b/test/json/Test/Sequential.hs
@@ -0,0 +1,27 @@
+module Test.Sequential (
+  writeMatrixJSON, readMatrixJSON
+) where
+
+import           Control.Monad.Trans.Class
+import           Control.Monad.Trans.Maybe
+import           Data.Maybe
+import           Multilinear.Class
+import           Multilinear.Generic.Sequential
+import           Multilinear.Generic.Sequential.Serialize
+import           Multilinear.Index
+
+writeMatrixJSON :: Tensor Double -> String -> IO ()
+writeMatrixJSON m fileName = do
+  let [xsize,ysize] = indexSize <$> indices m
+  putStrLn $ "Writing " ++ show (fromJust xsize) ++ "x" ++ show (fromJust ysize) ++ " matrix to " ++ fileName ++ ".json..."
+  m `toJSONFile` (fileName ++ ".json")
+  putStrLn $ "Matrix successfully written!"
+
+readMatrixJSON :: Tensor Double -> String -> MaybeT IO ()
+readMatrixJSON m fileName = do
+  lift $ putStrLn $ "Reading matrix m1 from " ++ fileName ++ ".json..."
+  m1' <- fromJSONFile (fileName ++ ".json")
+  if m1' == m then
+    lift $ putStrLn "Matrix successfully read!"
+  else
+    MaybeT $ return Nothing
