packages feed

hasktorch 0.0.1.0 → 0.2.2.0

raw patch · 173 files changed

Files

+ CHANGELOG.md view
@@ -0,0 +1,10 @@+# Changelog for hasktorch++## 0.2.2.0++- Add support for Stackage lts-23.24 (GHC 9.8); the previous release used GHC 9.6.+- Add `BFloat16` to `DTypeIsFloatingPoint` and `KnownDType`.+- Implement the AdamW optimizer.+- Expose the parameter group interface for `CppOptim` (per-group Adam/AdamW options).+- Implement non-blocking host-to-device transfer.+- Remove partial signatures from `Torch.Typed.NN.Convolution`.
+ LICENSE view
@@ -0,0 +1,41 @@+BSD 3-Clause License++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++* Redistributions of source code must retain the above copyright notice, this+  list of conditions and the following disclaimer.++* Redistributions in binary form must reproduce the above copyright notice,+  this list of conditions and the following disclaimer in the documentation+  and/or other materials provided with the distribution.++* Neither the name of the copyright holder nor the names of its+  contributors may be used to endorse or promote products derived from+  this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++Copyright Austin Huang (c) 2017++Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:++1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.++2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.++3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+
+ Setup.hs view
@@ -0,0 +1,6 @@+module Main where++import Distribution.Extra.Doctest (defaultMainWithDoctests)++main :: IO ()+main = defaultMainWithDoctests "doctests"
+ bench/Alloc.hs view
@@ -0,0 +1,116 @@+-----------------------------------------------------------------------------+-- |+-- Source      : https://github.com/Magalame/fastest-matrices+-- Copyright   : (c) 2019 Magalame+--+-- License     : BSD3+-- Maintainer  : Junji Hashimoto<junji.hashimoto@gmail.com>+-- Stability   : experimental+-- Portability : GHC+--+-----------------------------------------------------------------------------++{-# LANGUAGE DataKinds #-}+{-# LANGUAGE OverloadedLists #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE ExtendedDefaultRules #-}+++module Main where++import qualified Data.Vector.Unboxed         as U+import           Data.Vector.Unboxed         (Vector)+import qualified Data.Vector as V+import           Control.Monad.Primitive+import qualified Data.Vector.Generic         as G+import           Control.DeepSeq+import           System.IO.Unsafe+import           Foreign++-- hmatrix+import qualified Numeric.LinearAlgebra as H++-- hasktorch+import qualified Torch as T+import qualified Torch.Functional.Internal as TI+import qualified Torch.Internal.Unmanaged.Type.Tensor as TIU+import qualified Torch.Internal.Managed.Type.Tensor as TIM++import qualified System.Random.MWC as Mwc++import qualified Weigh as W+++n :: Int+n = 100++instance NFData (ForeignPtr a)+  where+    rnf v = v `seq` ()++uniformVector :: (PrimMonad m, Mwc.Variate a, G.Vector v a)+              => Mwc.Gen (PrimState m) -> Int -> m (v a)+uniformVector gen n = G.replicateM n (Mwc.uniform gen)++vectorGen :: IO (Vector Double)+vectorGen =  do +    gen <- Mwc.create+    uniformVector gen (n*n)++matrixH :: IO (H.Matrix H.R)+matrixH = do+    vec <- vectorGen+    return $ (n H.>< n) $ U.toList $ vec ++identH :: Int -> H.Matrix Double+identH = H.ident++elemZero :: Double -> Double+elemZero = const 0++elemSqr :: Double -> Double+elemSqr x = x*x++mapH :: (Double -> Double) -> H.Matrix Double -> H.Matrix Double+mapH = H.cmap++main :: IO ()+main = do +    vDLA <- vectorGen+    uDLA <- vectorGen++    let +    --+      vList = U.toList vDLA+      uList = U.toList uDLA+    +    --+      aH = (n H.>< n) vList+      bH = (n H.>< n) uList+      vH = H.fromList vList++    --+      to2d [] = []+      to2d xs = take n xs : to2d (drop n xs)+      aT = T.asTensor $ to2d vList+      bT = T.asTensor $ to2d uList+      vT = T.asTensor vList+    +    W.mainWith (do +               W.func "Hmatrix - multiplication" ((<>) aH) bH+               W.func "Hmatrix - qr factorization" H.qr aH+               W.func "Hmatrix - transpose" H.tr aH+               W.func "Hmatrix - norm" H.norm_2 vH+               W.func "Hmatrix - row" ((H.?) aH) [0]+               W.func "Hmatrix - column" ((H.¿) aH) [0]+               W.func "Hmatrix - identity" identH n+               +               W.func "Hasktorch - multiplication" (T.matmul aT) bT+               W.func "Hasktorch - qr factorization" (\v -> TI.qr v True) aT+               W.func "Hasktorch - transpose" TI.t aT+               W.func "Hasktorch - norm" (\v -> TI.normAll v 2) vT+               W.func "Hasktorch - row" ((T.!) aT) (0::Int)+               W.func "Hasktorch - column" ((T.!) aT) [T.slice|...,0|]+               W.func "Hasktorch - identity" (\i -> T.eye' i i) n+               )
+ bench/Runtime.hs view
@@ -0,0 +1,164 @@+-----------------------------------------------------------------------------+-- |+-- Source      : https://github.com/Magalame/fastest-matrices+-- Copyright   : (c) 2019 Magalame+--+-- License     : BSD3+-- Maintainer  : Junji Hashimoto<junji.hashimoto@gmail.com>+-- Stability   : experimental+-- Portability : GHC+--+-----------------------------------------------------------------------------++{-# LANGUAGE DataKinds #-}+{-# LANGUAGE OverloadedLists #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE ExtendedDefaultRules #-}+++module Main where++import qualified Data.Vector.Unboxed         as U+import           Data.Vector.Unboxed         (Vector)+import qualified Data.Vector as V+import           Control.Monad.Primitive+import qualified Data.Vector.Generic         as G+import           Control.DeepSeq+import           System.IO.Unsafe+import           Foreign++-- hmatrix+import qualified Numeric.LinearAlgebra as H++-- hasktorch+import qualified Torch as T+import qualified Torch.Functional.Internal as TI+import qualified Torch.Internal.Unmanaged.Type.Tensor as TIU+import qualified Torch.Internal.Unmanaged.Type.Extra as TIU+import qualified Torch.Internal.Managed.Type.Tensor as TIM+import qualified Torch.Internal.Managed.Type.Extra as TIM+import qualified Torch.Jit as T++import qualified System.Random.MWC as Mwc++import qualified Criterion.Main as C++#define N 10+#define N2 100+#define N3 1000+++instance NFData (ForeignPtr a)+  where+    rnf v = v `seq` ()+++n :: Int+n = N++uniformVector :: (PrimMonad m, Mwc.Variate a, G.Vector v a)+              => Mwc.Gen (PrimState m) -> Int -> m (v a)+uniformVector gen n = G.replicateM n (Mwc.uniform gen)++vectorGen :: IO (Vector Double)+vectorGen =  do +    gen <- Mwc.create+    uniformVector gen (n*n)++matrixH :: IO (H.Matrix H.R)+matrixH = do+    vec <- vectorGen+    return $ (n H.>< n) $ U.toList $ vec ++identH :: Int -> H.Matrix Double+identH = H.ident++elemZero :: Double -> Double+elemZero = const 0++elemSqr :: Double -> Double+elemSqr x = x*x++mapH :: (Double -> Double) -> H.Matrix Double -> H.Matrix Double+mapH = H.cmap++main :: IO ()+main = do +    vDLA' <- vectorGen+    uDLA' <- vectorGen++    let +    --+      vList = U.toList vDLA'+      uList = U.toList uDLA'+    +    --+      aH' = (n H.>< n) vList+      bH' = (n H.>< n) uList++      subH' = H.fromList . take n $ vList+      vH' = H.fromList vList++    --+      to2d [] = []+      to2d xs = take n xs : to2d (drop n xs)+      aT' = T.asTensor $ to2d vList+      bT' = T.asTensor $ to2d uList++      subT' = T.asTensor . take n $ vList+      vT' = T.asTensor vList++    cache <- T.newScriptCache++    let jit :: (T.Tensor -> T.Tensor) -> T.Tensor -> T.Tensor+        jit func input = let [r] = T.jit cache (\[v] -> [func v]) [input] in r++    C.defaultMain [+        C.env (pure (aH', bH', subH', vH')) $ \ ~(aH, bH, subH, vH) ->+            C.bgroup "Hmatrix" [ +                             C.bench "multiplication" $ C.nf ((<>) aH) bH,+                             C.bench "repeated multiplication" $ C.nf ( H.sumElements . flip (H.?) [1] . (<>) bH . (<>) aH . (<>) aH) bH,+                             C.bench "multiplicationV" $ C.nf ((H.#>) aH) subH,+                             -- C.bench "qr factorization" $ C.nf H.qr aH,+                             C.bench "transpose" $ C.nf H.tr aH,+                             C.bench "norm" $ C.nf H.norm_2 vH,+                             C.bench "row" $ C.nf ((H.?) aH) [0],+                             C.bench "column" $ C.nf ((H.¿) aH) [0], +                             C.bench "identity" $ C.nf identH n,+                             C.bench "diag" $ C.nf H.diag subH,+                             C.bench "map const 0" $ C.nf (mapH elemZero) aH,+                             C.bench "map sqr" $ C.nf (mapH elemSqr) aH,+                             C.bench "size" $ C.nf H.size aH+                           ],++        C.env (pure (aT', bT', subT', vT')) $ \ ~(aT, bT, subT, vT) ->+            C.bgroup "Hasktorch" [ +                             C.bench "multiplication" $ C.nf (T.matmul aT) bT,+                             C.bench "repeated multiplication" $ C.nf (T.sumAll . T.matmul bT . T.matmul aT . T.matmul aT) bT,+                             C.bench "repeated multiplication with JIT" $ C.nf (jit $ T.sumAll . T.matmul bT . T.matmul aT . T.matmul aT) bT,+                             C.bench "multiplicationV" $ C.nf (T.matmul aT) subT,+                             -- C.bench "qr factorization" $ C.nf (\v -> TI.qr v True) aT,+                             C.bench "transpose" $ C.nf TI.t aT,+                             C.bench "norm" $ C.nf (\v -> TI.normAll v 2) vT,+                             C.bench "row" $ C.nf ((T.!) aT) (0::Int),+                             C.bench "column" $ C.nf ((T.!) aT) [T.slice|...,0|],+                             C.bench "identity" $ C.nf (\i -> T.eye' i i) n,+                             C.bench "diag" $ C.nf (T.diag (T.Diag 0)) subT,+                             C.bench "map const 0" $ C.nf (\v -> T.maskedFill v  [T.slice|...|] 0) aT,+                             C.bench "map sqr" $ C.nf (\v -> v * v) aT,+                             C.bench "shape" $ C.nf T.shape aT,+                             C.bench "shape(managed)" $ C.nf (\(T.Unsafe v) -> unsafePerformIO $ TIM.tensor_sizes v) aT,+                             C.bench "shape(unmanaged)" $ C.nf (\(T.Unsafe v) -> unsafePerformIO $ withForeignPtr v $ \ptr -> TIU.tensor_sizes ptr) aT,+                             C.bench "dim" $ C.nf T.dim aT,+                             C.bench "dim(managed)" $ C.nf (\(T.Unsafe v) -> unsafePerformIO $ TIM.tensor_dim v) aT,+                             C.bench "dim(unmanaged)" $ C.nf (\(T.Unsafe v) -> unsafePerformIO $ withForeignPtr v $ \ptr -> TIU.tensor_dim ptr) aT,+                             C.bench "dim(unsafe)" $ C.nf T.dimUnsafe aT,+                             C.bench "dim(unsafe/managed)" $ C.nf (\(T.Unsafe v) -> unsafePerformIO $ TIM.tensor_dim_unsafe v) aT,+                             C.bench "dim(unsafe/unmanaged)" $ C.nf (\(T.Unsafe v) -> unsafePerformIO $ withForeignPtr v $ \ptr -> TIU.tensor_dim_unsafe ptr) aT,+                             C.bench "dim(unsafe-c)" $ C.nf T.dimCUnsafe aT,+                             C.bench "dim(unsafe-c/managed)" $ C.nf (\(T.Unsafe v) -> unsafePerformIO $ TIM.tensor_dim_c_unsafe v) aT,+                             C.bench "dim(unsafe-c/unmanaged)" $ C.nf (\(T.Unsafe v) -> unsafePerformIO $ withForeignPtr v $ \ptr -> TIU.tensor_dim_c_unsafe ptr) aT+                           ]+               ]+
− exe/Memcheck.hs
@@ -1,68 +0,0 @@--- Output of:--- # valgrind --tool=memcheck ./dist-newstyle/build/x86_64-linux/ghc-8.4.3/hasktorch-core-0.0.1.0/x/memcheck/noopt/build/memcheck/memcheck--{---==19639== Memcheck, a memory error detector-==19639== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.-==19639== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info-==19639== Command: ./dist-newstyle/build/x86_64-linux/ghc-8.4.3/hasktorch-core-0.0.1.0/x/memcheck/noopt/build/memcheck/memcheck-==19639==-==19639== Warning: set address range perms: large range [0x51da000, 0x17bd0000) (defined)-==19639== Warning: set address range perms: large range [0x26eee000, 0x3b56e000) (defined)-==19639== Warning: set address range perms: large range [0x4200000000, 0x14200100000) (noaccess)-(0x0000000000000000,0x000000004a488ac0)-[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0,20.0,21.0,22.0,23.0,24.0,25.0,26.0,27.0,28.0,29.0,30.0,31.0,32.0,33.0,34.0,35.0,36.0,37.0,38.0,39.0,40.0,41.0,42.0,43.0,44.0,45.0,46.0,47.0,48.0,49.0,50.0,51.0,52.0,53.0,54.0,55.0,56.0,57.0,58.0,59.0,60.0,61.0,62.0,63.0,64.0,65.0,66.0,67.0,68.0,69.0,70.0,71.0,72.0,73.0,74.0,75.0,76.0,77.0,78.0,79.0,80.0,81.0,82.0,83.0,84.0,85.0,86.0,87.0,88.0,89.0,90.0,91.0,92.0,93.0,94.0,95.0,96.0,97.0,98.0,99.0,100.0]-==19639== Invalid free() / delete / delete[] / realloc()-==19639==    at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)-==19639==    by 0x6167A94: THFree (in /home/stites/git/hasktorch/vendor/aten/build/lib/libATen.so.1)-==19639==    by 0x616800B: THDefaultAllocator_free (in /home/stites/git/hasktorch/vendor/aten/build/lib/libATen.so.1)-==19639==    by 0x6169855: THDoubleStorage_free (in /home/stites/git/hasktorch/vendor/aten/build/lib/libATen.so.1)-==19639==    by 0x43C4B9: free_DoubleStorage (finalizers.c:77)-==19639==    by 0x560735: runCFinalizers (in /home/stites/git/hasktorch/dist-newstyle/build/x86_64-linux/ghc-8.4.3/hasktorch-core-0.0.1.0/x/memcheck/noopt/build/memcheck/memcheck)-==19639==    by 0x560833: scheduleFinalizers (in /home/stites/git/hasktorch/dist-newstyle/build/x86_64-linux/ghc-8.4.3/hasktorch-core-0.0.1.0/x/memcheck/noopt/build/memcheck/memcheck)-==19639==    by 0x567BA8: GarbageCollect (in /home/stites/git/hasktorch/dist-newstyle/build/x86_64-linux/ghc-8.4.3/hasktorch-core-0.0.1.0/x/memcheck/noopt/build/memcheck/memcheck)-==19639==    by 0x5612DB: scheduleDoGC.constprop.23 (in /home/stites/git/hasktorch/dist-newstyle/build/x86_64-linux/ghc-8.4.3/hasktorch-core-0.0.1.0/x/memcheck/noopt/build/memcheck/memcheck)-==19639==    by 0x561475: performGC_ (in /home/stites/git/hasktorch/dist-newstyle/build/x86_64-linux/ghc-8.4.3/hasktorch-core-0.0.1.0/x/memcheck/noopt/build/memcheck/memcheck)-==19639==    by 0x4F800C: ??? (in /home/stites/git/hasktorch/dist-newstyle/build/x86_64-linux/ghc-8.4.3/hasktorch-core-0.0.1.0/x/memcheck/noopt/build/memcheck/memcheck)-==19639==  Address 0x420000c010 is in a rw- anonymous segment-==19639==-==19639==-==19639== HEAP SUMMARY:-==19639==     in use at exit: 2,295 bytes in 15 blocks-==19639==   total heap usage: 73,694 allocs, 73,680 frees, 6,638,289 bytes allocated-==19639==-==19639== LEAK SUMMARY:-==19639==    definitely lost: 0 bytes in 0 blocks-==19639==    indirectly lost: 0 bytes in 0 blocks-==19639==      possibly lost: 0 bytes in 0 blocks-==19639==    still reachable: 2,295 bytes in 15 blocks-==19639==         suppressed: 0 bytes in 0 blocks-==19639== Rerun with --leak-check=full to see details of leaked memory-==19639==-==19639== For counts of detected and suppressed errors, rerun with: -v-==19639== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)---}--{-# LANGUAGE DataKinds #-}-module Main where--import Torch.Double.Storage-import System.Mem---- TODO: test GC with different formats:-main = do-  -- let Just s = vector [0..100] :: Maybe (Tensor '[101])-  -- let s = vector [0..100] :: Dynamic-  -- print s--  let s = fromList [0..100]-  print $ storageState s-  print $ storagedata s-  performGC--  -- fromList [10..1990] >>= tensordata >>= print-  -- performMajorGC--
− exe/Noop.hs
@@ -1,2 +0,0 @@-main :: IO ()-main = putStrLn "package can be compiled!"
hasktorch.cabal view
@@ -1,558 +1,288 @@-cabal-version: 2.2--- ================================================================ ----- ======== This cabal file has been modified from dhall ========== ----- ======== This constitutes the 0.0.1.0 release.        ========== ----- ======== Dhall can generate this file, but will never ========== ----- ======== be able to upload to hackage. For more, see: ========== ----- ==== https://github.com/haskell/hackage-server/issues/795 ====== ----- ================================================================ ---name: hasktorch-version: 0.0.1.0-license: BSD-3-Clause-maintainer: Sam Stites <fnz@fgvgrf.vb>, Austin Huang <nhfgvau@nyhz.zvg.rqh> - cipher:ROT13-author: Hasktorch dev team-homepage: https://github.com/hasktorch/hasktorch#readme-bug-reports: https://github.com/hasktorch/hasktorch/issues-synopsis: Torch for tensors and neural networks in Haskell-description:-    Hasktorch is a library for tensors and neural networks in Haskell. It is an independent open source community project which leverages the core C libraries shared by Torch and PyTorch. This library leverages @cabal v2-build@ and @backpack@. *Note that this project is in early development and should only be used by contributing developers. Expect substantial changes to the library API as it evolves. Contributions and PRs are welcome (see details on github).*-category: Tensors, Machine Learning, AI-build-type: Simple--source-repository head-    type: git-    location: https://github.com/hasktorch/hasktorch+cabal-version:       3.0+name:                hasktorch+version:             0.2.2.0+synopsis:            Haskell bindings to libtorch, supporting both typed and untyped tensors.+description:         Hasktorch is a library for tensors and neural networks in Haskell. It is an independent open source community project which leverages the core C++ libraries shared by PyTorch.+homepage:            https://github.com/hasktorch/hasktorch#readme+license:             BSD-3-Clause+license-file:        LICENSE+author:              Hasktorch Contributor Team+maintainer:          hasktorch@gmail.com+copyright:           2019 Austin Huang+category:            Codegen+build-type:          Custom+extra-source-files:+  CHANGELOG.md+  ./test/data/numpy_rawfile+  ./test/data/mnist-sample-labels-idx1-ubyte.gz+  ./test/data/mnist-sample-images-idx3-ubyte.gz -flag cuda-    description:-        build with THC support-    default: False+custom-setup+  setup-depends:+      base >= 4.9 && < 5+    , Cabal >= 3.10.1.0 && < 3.16+    , cabal-doctest >=1.0.9 && <1.1 -flag lite-    description:-        only build with Double and Long support-    default: False+Flag disable-doctest+ Description: Disable doctest. ToDo: This flag is to avoid relocation-error of ghci for macos.+ Default:     False+ Manual:      True  library-    exposed-modules:-        Torch.Core.Exceptions-        Torch.Core.Random-        Torch.Core.LogAdd-    reexported-modules: Torch.Types.Numeric,-                        Torch.Long,-                        Torch.Long.Dynamic,-                        Torch.Long.Storage,-                        Torch.Double,-                        Torch.Double.Dynamic,-                        Torch.Double.Storage,-                        Torch.Double.NN,-                        Torch.Double.NN.Activation,-                        Torch.Double.NN.Backprop,-                        Torch.Double.NN.Conv1d,-                        Torch.Double.NN.Conv2d,-                        Torch.Double.NN.Criterion,-                        Torch.Double.NN.Layers,-                        Torch.Double.NN.Linear,-                        Torch.Double.NN.Math,-                        Torch.Double.NN.Padding,-                        Torch.Double.NN.Pooling,-                        Torch.Double.NN.Sampling,-                        Torch.Double.Dynamic.NN,-                        Torch.Double.Dynamic.NN.Activation,-                        Torch.Double.Dynamic.NN.Pooling,-                        Torch.Double.Dynamic.NN.Criterion-    hs-source-dirs: utils-    default-language: Haskell2010-    default-extensions: LambdaCase DataKinds TypeFamilies-                        TypeSynonymInstances ScopedTypeVariables FlexibleContexts CPP-    build-depends:-        base (==4.7 || >4.7) && <5,-        -- containers ==0.5.10 || >0.5.10,-        -- deepseq ==1.3.0 || >1.3.0,-        dimensions ==1.0 || >1.0,-        -- managed (==1.0.0 || >1.0.0) && <1.1,-        -- microlens ==0.4.8 || >0.4.8,-        -- numeric-limits ==0.1.0 || >0.1.0,-        safe-exceptions ==0.1.0 || >0.1.0,-        singletons ==2.2 || >2.2,-        text ==1.2.2 || >1.2.2,-        -- typelits-witnesses ==0.2.3 || >0.2.3,-        hasktorch-cpu -any,-        hasktorch-ffi-th (==0.0.1 || >0.0.1) && <0.0.2,-        hasktorch-types-th (==0.0.1 || >0.0.1) && <0.0.2+ exposed-modules:     Torch+                    , Torch.Tensor+                    , Torch.TensorOptions+                    , Torch.DType+                    , Torch.Device+                    , Torch.TensorFactories+                    , Torch.Functional+                    , Torch.Functional.Internal+                    , Torch.Initializers+                    , Torch.Autograd+                    , Torch.Optim+                    , Torch.Optim.CppOptim+                    , Torch.Vision+                    , Torch.NN+                    , Torch.NN.Recurrent.Cell.Elman+                    , Torch.NN.Recurrent.Cell.GRU+                    , Torch.NN.Recurrent.Cell.LSTM+                    , Torch.Scalar+                    , Torch.Backend+                    , Torch.Layout+                    , Torch.Cast+                    , Torch.Dimname+                    , Torch.Serialize+                    , Torch.Random+                    , Torch.Script+                    , Torch.HList+                    , Torch.Lens+                    , Torch.Typed+                    , Torch.Typed.Auxiliary+                    , Torch.Typed.Factories+                    , Torch.Typed.Functional+                    , Torch.Typed.NN+                    , Torch.Typed.NN.Convolution+                    , Torch.Typed.NN.Normalization+                    , Torch.Typed.NN.Recurrent+                    , Torch.Typed.NN.Recurrent.Auxiliary+                    , Torch.Typed.NN.Recurrent.Cell.LSTM+                    , Torch.Typed.NN.Recurrent.Cell.GRU+                    , Torch.Typed.NN.Recurrent.LSTM+                    , Torch.Typed.NN.Recurrent.GRU+                    , Torch.Typed.NN.Transformer+                    , Torch.Typed.NN.Linear+                    , Torch.Typed.NN.Dropout+                    , Torch.Typed.NN.Sparse+                    , Torch.Typed.NN.DataParallel+                    , Torch.Typed.Tensor+                    , Torch.Typed.Parameter+                    , Torch.Typed.Device+                    , Torch.Typed.DType+                    , Torch.Typed.Autograd+                    , Torch.Typed.Optim+                    , Torch.Typed.Optim.CppOptim+                    , Torch.Typed.Serialize+                    , Torch.Typed.Vision+                    , Torch.Typed.Lens+                    , Torch.Typed.NamedTensor+                    , Torch.Typed.VLTensor+                    , Torch.Distributions.Constraints+                    , Torch.Distributions.Distribution+                    , Torch.Distributions.Bernoulli+                    , Torch.Distributions.Categorical+                    , Torch.Data+                    , Torch.Data.Pipeline+                    , Torch.Data.StreamedPipeline+                    , Torch.Data.Utils+                    , Torch.Data.Internal+                    , Torch.Data.Dataset+                    , Torch.Data.CsvDatastream+                    , Torch.Tutorial+                    , Torch.Index+                    , Torch.Jit -    -- <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> ---    -- BEGIN EDITS-    -- <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> ---    if !flag(lite)-      reexported-modules:-        Torch.Byte,-        Torch.Byte.Dynamic,-        Torch.Byte.Storage,-        Torch.Char,-        Torch.Char.Dynamic,-        Torch.Char.Storage,-        Torch.Short,-        Torch.Short.Dynamic,-        Torch.Short.Storage,-        Torch.Int,-        Torch.Int.Dynamic,-        Torch.Int.Storage,-        Torch.Float,-        Torch.Float.Dynamic,-        Torch.Float.Storage+ hs-source-dirs:      src+ default-language:    Haskell2010+ ghc-options:         -fplugin GHC.TypeLits.Normalise -fplugin GHC.TypeLits.KnownNat.Solver -fplugin GHC.TypeLits.Extra.Solver -fconstraint-solver-iterations=0 -fplugin GHC.NotExport.Plugin+ if os(darwin)+  cpp-options:        -D__APPLE__+ build-depends:       async >= 2.2.5 && < 2.3+                    , base >= 4.7 && < 5+                    , libtorch-ffi >= 2.0.2.0 && < 2.0.3+                    , libtorch-ffi-helper == 2.0.0.*+                    , finite-typelits >= 0.1 && < 0.3+                    , ghc-typelits-extra >= 0.4.6 && < 0.6+                    , ghc-typelits-knownnat >= 0.7.9 && < 0.9+                    , ghc-typelits-natnormalise >= 0.7.9 && < 0.10+                    , mtl >= 2.3.1 && < 2.4+                    , safe-exceptions >= 0.1.7 && < 0.2+                    , random >= 1.2.1 && < 1.4+                    , reflection >= 2.1 && < 2.2+                    , stm >= 2.5.1 && < 2.6+                    , JuicyPixels >= 3.3 && < 3.4+                    , vector >= 0.13 && < 0.14+                    , bytestring >= 0.11.5 && < 0.13+                    , safe-exceptions+                    , zlib >= 0.6 && < 0.8+                    , pipes >= 4.3.16 && < 4.4+                    , pipes-group >= 1.0.12 && < 1.1+                    , pipes-concurrency >= 2.0.14 && < 2.1+                    , pipes-safe >= 2.3.5 && < 2.4+                    , pipes-bytestring >= 2.1.7 && < 2.2+                    , pipes-csv >= 1.4.3 && < 1.5+                    , lens-family-core >= 2.1.3 && < 2.2+                    , cassava >= 0.5.3 && < 0.6+                    , lifted-async >= 0.10.2 && < 0.12+                    , monad-control >= 1.0.3 && < 1.1+                    , foldl >= 1.4 && < 1.5+                    , transformers-base >= 0.4.6 && < 0.5+                    , array >= 0.5.5 && < 0.6+                    , data-default-class >= 0.1 && < 0.3+                    , containers >= 0.6.7 && < 0.8+                    , inline-c >= 0.9.1 && < 0.10+                    , vector-sized >= 1.5 && < 1.7+                    , template-haskell >= 2.20.0 && < 2.24+                    , megaparsec >= 9.5 && < 9.8+                    , half >= 0.3 && < 0.4+                    , constraints >= 0.14 && < 0.15+                    , deepseq >= 1.4.8 && < 1.6 -    if flag(cuda)-      build-depends:-        hasktorch-gpu -any-      reexported-modules:-        Torch.Cuda.Long,-        Torch.Cuda.Long.Dynamic,-        Torch.Cuda.Long.Storage,-        Torch.Cuda.Double,-        Torch.Cuda.Double.Dynamic,-        Torch.Cuda.Double.Storage,-        Torch.Cuda.Double.NN,-        Torch.Cuda.Double.NN.Activation,-        Torch.Cuda.Double.NN.Backprop,-        Torch.Cuda.Double.NN.Conv1d,-        Torch.Cuda.Double.NN.Conv2d,-        Torch.Cuda.Double.NN.Criterion,-        Torch.Cuda.Double.NN.Layers,-        Torch.Cuda.Double.NN.Linear,-        Torch.Cuda.Double.NN.Math,-        Torch.Cuda.Double.NN.Padding,-        Torch.Cuda.Double.NN.Pooling,-        Torch.Cuda.Double.NN.Sampling,-        Torch.Cuda.Double.Dynamic.NN,-        Torch.Cuda.Double.Dynamic.NN.Activation,-        Torch.Cuda.Double.Dynamic.NN.Pooling,-        Torch.Cuda.Double.Dynamic.NN.Criterion-      if !flag(lite)-        reexported-modules:-          Torch.Cuda.Byte,-          Torch.Cuda.Byte.Dynamic,-          Torch.Cuda.Byte.Storage,-          Torch.Cuda.Char,-          Torch.Cuda.Char.Dynamic,-          Torch.Cuda.Char.Storage,-          Torch.Cuda.Short,-          Torch.Cuda.Short.Dynamic,-          Torch.Cuda.Short.Storage,-          Torch.Cuda.Int,-          Torch.Cuda.Int.Dynamic,-          Torch.Cuda.Int.Storage,-          Torch.Cuda.Float,-          Torch.Cuda.Float.Dynamic,-          Torch.Cuda.Float.Storage-    -- <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> ---    -- END EDITS-    -- <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> --+ default-extensions:  Strict+                    , StrictData -library hasktorch-cpu-    exposed-modules:-        Torch.Long-        Torch.Long.Dynamic-        Torch.Long.Storage-        Torch.Double-        Torch.Double.Dynamic-        Torch.Double.Storage-    reexported-modules: Torch.Double.NN,-                        Torch.Double.NN.Activation,-                        Torch.Double.NN.Backprop,-                        Torch.Double.NN.Conv1d,-                        Torch.Double.NN.Conv2d,-                        Torch.Double.NN.Criterion,-                        Torch.Double.NN.Layers,-                        Torch.Double.NN.Linear,-                        Torch.Double.NN.Math,-                        Torch.Double.NN.Padding,-                        Torch.Double.NN.Pooling,-                        Torch.Double.NN.Sampling,-                        Torch.Double.Dynamic.NN,-                        Torch.Double.Dynamic.NN.Activation,-                        Torch.Double.Dynamic.NN.Pooling,-                        Torch.Double.Dynamic.NN.Criterion,-                        Torch.Float.NN,-                        Torch.Float.NN.Activation,-                        Torch.Float.NN.Backprop,-                        Torch.Float.NN.Conv1d,-                        Torch.Float.NN.Conv2d,-                        Torch.Float.NN.Criterion,-                        Torch.Float.NN.Layers,-                        Torch.Float.NN.Linear,-                        Torch.Float.NN.Math,-                        Torch.Float.NN.Padding,-                        Torch.Float.NN.Pooling,-                        Torch.Float.NN.Sampling,-                        Torch.Float.Dynamic.NN,-                        Torch.Float.Dynamic.NN.Activation,-                        Torch.Float.Dynamic.NN.Pooling,-                        Torch.Float.Dynamic.NN.Criterion-    hs-source-dirs: utils src-    other-modules:-        Torch.Core.Exceptions-        Torch.Core.Random-        Torch.Core.LogAdd-    default-language: Haskell2010-    default-extensions: LambdaCase DataKinds TypeFamilies-                        TypeSynonymInstances ScopedTypeVariables FlexibleContexts CPP-    build-depends:-        base (==4.7 || >4.7) && <5,-        hasktorch-types-th (==0.0.1 || >0.0.1) && <0.0.2,-        -- containers ==0.5.10 || >0.5.10,-        -- deepseq ==1.3.0 || >1.3.0,-        dimensions ==1.0 || >1.0,-        hasktorch-ffi-th (==0.0.1 || >0.0.1) && <0.0.2,-        hasktorch-types-th (==0.0.1 || >0.0.1) && <0.0.2,-        -- managed (==1.0.0 || >1.0.0) && <1.1,-        -- microlens ==0.4.8 || >0.4.8,-        -- numeric-limits ==0.1.0 || >0.1.0,-        safe-exceptions ==0.1.0 || >0.1.0,-        singletons ==2.2 || >2.2,-        text ==1.2.2 || >1.2.2,-        -- typelits-witnesses ==0.2.3 || >0.2.3,-        hasktorch-indef-floating -any,-        hasktorch-indef-signed -any-    mixins: hasktorch-indef-signed (Torch.Indef.Storage as Torch.Indef.Long.Storage, Torch.Indef.Storage.Copy as Torch.Indef.Long.Storage.Copy, Torch.Indef.Static.Tensor as Torch.Indef.Long.Tensor, Torch.Indef.Static.Tensor.Copy as Torch.Indef.Long.Tensor.Copy, Torch.Indef.Static.Tensor.Index as Torch.Indef.Long.Tensor.Index, Torch.Indef.Static.Tensor.Masked as Torch.Indef.Long.Tensor.Masked, Torch.Indef.Static.Tensor.Math as Torch.Indef.Long.Tensor.Math, Torch.Indef.Static.Tensor.Math.Compare as Torch.Indef.Long.Tensor.Math.Compare, Torch.Indef.Static.Tensor.Math.CompareT as Torch.Indef.Long.Tensor.Math.CompareT, Torch.Indef.Static.Tensor.Math.Pairwise as Torch.Indef.Long.Tensor.Math.Pairwise, Torch.Indef.Static.Tensor.Math.Pointwise as Torch.Indef.Long.Tensor.Math.Pointwise, Torch.Indef.Static.Tensor.Math.Reduce as Torch.Indef.Long.Tensor.Math.Reduce, Torch.Indef.Static.Tensor.Math.Scan as Torch.Indef.Long.Tensor.Math.Scan, Torch.Indef.Static.Tensor.Mode as Torch.Indef.Long.Tensor.Mode, Torch.Indef.Static.Tensor.ScatterGather as Torch.Indef.Long.Tensor.ScatterGather, Torch.Indef.Static.Tensor.Sort as Torch.Indef.Long.Tensor.Sort, Torch.Indef.Static.Tensor.TopK as Torch.Indef.Long.Tensor.TopK, Torch.Indef.Dynamic.Tensor as Torch.Indef.Long.Dynamic.Tensor, Torch.Indef.Dynamic.Tensor.Copy as Torch.Indef.Long.Dynamic.Tensor.Copy, Torch.Indef.Dynamic.Tensor.Index as Torch.Indef.Long.Dynamic.Tensor.Index, Torch.Indef.Dynamic.Tensor.Masked as Torch.Indef.Long.Dynamic.Tensor.Masked, Torch.Indef.Dynamic.Tensor.Math as Torch.Indef.Long.Dynamic.Tensor.Math, Torch.Indef.Dynamic.Tensor.Math.Compare as Torch.Indef.Long.Dynamic.Tensor.Math.Compare, Torch.Indef.Dynamic.Tensor.Math.CompareT as Torch.Indef.Long.Dynamic.Tensor.Math.CompareT, Torch.Indef.Dynamic.Tensor.Math.Pairwise as Torch.Indef.Long.Dynamic.Tensor.Math.Pairwise, Torch.Indef.Dynamic.Tensor.Math.Pointwise as Torch.Indef.Long.Dynamic.Tensor.Math.Pointwise, Torch.Indef.Dynamic.Tensor.Math.Reduce as Torch.Indef.Long.Dynamic.Tensor.Math.Reduce, Torch.Indef.Dynamic.Tensor.Math.Scan as Torch.Indef.Long.Dynamic.Tensor.Math.Scan, Torch.Indef.Dynamic.Tensor.Mode as Torch.Indef.Long.Dynamic.Tensor.Mode, Torch.Indef.Dynamic.Tensor.ScatterGather as Torch.Indef.Long.Dynamic.Tensor.ScatterGather, Torch.Indef.Dynamic.Tensor.Sort as Torch.Indef.Long.Dynamic.Tensor.Sort, Torch.Indef.Dynamic.Tensor.TopK as Torch.Indef.Long.Dynamic.Tensor.TopK, Torch.Indef.Types as Torch.Long.Types, Torch.Indef.Index as Torch.Long.Index, Torch.Indef.Mask as Torch.Long.Mask, Torch.Indef.Static.Tensor.Math.Pointwise.Signed as Torch.Indef.Long.Tensor.Math.Pointwise.Signed, Torch.Indef.Dynamic.Tensor.Math.Pointwise.Signed as Torch.Indef.Long.Dynamic.Tensor.Math.Pointwise.Signed) requires (Torch.Sig.Index.Tensor as Torch.FFI.TH.Long.Tensor, Torch.Sig.Index.TensorFree as Torch.FFI.TH.Long.FreeTensor, Torch.Sig.Mask.Tensor as Torch.FFI.TH.Byte.Tensor, Torch.Sig.Mask.TensorFree as Torch.FFI.TH.Byte.FreeTensor, Torch.Sig.Mask.MathReduce as Torch.FFI.TH.Byte.TensorMath, Torch.Sig.State as Torch.Types.TH, Torch.Sig.Types.Global as Torch.Types.TH, Torch.Sig.Types as Torch.Types.TH.Long, Torch.Sig.Storage as Torch.FFI.TH.Long.Storage, Torch.Sig.Storage.Copy as Torch.FFI.TH.Long.StorageCopy, Torch.Sig.Storage.Memory as Torch.FFI.TH.Long.FreeStorage, Torch.Sig.Tensor as Torch.FFI.TH.Long.Tensor, Torch.Sig.Tensor.Copy as Torch.FFI.TH.Long.TensorCopy, Torch.Sig.Tensor.Memory as Torch.FFI.TH.Long.FreeTensor, Torch.Sig.Tensor.Index as Torch.FFI.TH.Long.TensorMath, Torch.Sig.Tensor.Masked as Torch.FFI.TH.Long.TensorMath, Torch.Sig.Tensor.Math as Torch.FFI.TH.Long.TensorMath, Torch.Sig.Tensor.Math.Compare as Torch.FFI.TH.Long.TensorMath, Torch.Sig.Tensor.Math.CompareT as Torch.FFI.TH.Long.TensorMath, Torch.Sig.Tensor.Math.Pairwise as Torch.FFI.TH.Long.TensorMath, Torch.Sig.Tensor.Math.Pointwise as Torch.FFI.TH.Long.TensorMath, Torch.Sig.Tensor.Math.Reduce as Torch.FFI.TH.Long.TensorMath, Torch.Sig.Tensor.Math.Scan as Torch.FFI.TH.Long.TensorMath, Torch.Sig.Tensor.Mode as Torch.FFI.TH.Long.TensorMath, Torch.Sig.Tensor.ScatterGather as Torch.FFI.TH.Long.TensorMath, Torch.Sig.Tensor.Sort as Torch.FFI.TH.Long.TensorMath, Torch.Sig.Tensor.TopK as Torch.FFI.TH.Long.TensorMath, Torch.Sig.Tensor.Math.Pointwise.Signed as Torch.FFI.TH.Long.TensorMath),-            hasktorch-indef-floating (Torch.Indef.Storage as Torch.Indef.Double.Storage, Torch.Indef.Storage.Copy as Torch.Indef.Double.Storage.Copy, Torch.Indef.Static.Tensor as Torch.Indef.Double.Tensor, Torch.Indef.Static.Tensor.Copy as Torch.Indef.Double.Tensor.Copy, Torch.Indef.Static.Tensor.Index as Torch.Indef.Double.Tensor.Index, Torch.Indef.Static.Tensor.Masked as Torch.Indef.Double.Tensor.Masked, Torch.Indef.Static.Tensor.Math as Torch.Indef.Double.Tensor.Math, Torch.Indef.Static.Tensor.Math.Compare as Torch.Indef.Double.Tensor.Math.Compare, Torch.Indef.Static.Tensor.Math.CompareT as Torch.Indef.Double.Tensor.Math.CompareT, Torch.Indef.Static.Tensor.Math.Pairwise as Torch.Indef.Double.Tensor.Math.Pairwise, Torch.Indef.Static.Tensor.Math.Pointwise as Torch.Indef.Double.Tensor.Math.Pointwise, Torch.Indef.Static.Tensor.Math.Reduce as Torch.Indef.Double.Tensor.Math.Reduce, Torch.Indef.Static.Tensor.Math.Scan as Torch.Indef.Double.Tensor.Math.Scan, Torch.Indef.Static.Tensor.Mode as Torch.Indef.Double.Tensor.Mode, Torch.Indef.Static.Tensor.ScatterGather as Torch.Indef.Double.Tensor.ScatterGather, Torch.Indef.Static.Tensor.Sort as Torch.Indef.Double.Tensor.Sort, Torch.Indef.Static.Tensor.TopK as Torch.Indef.Double.Tensor.TopK, Torch.Indef.Dynamic.Tensor as Torch.Indef.Double.Dynamic.Tensor, Torch.Indef.Dynamic.Tensor.Copy as Torch.Indef.Double.Dynamic.Tensor.Copy, Torch.Indef.Dynamic.Tensor.Index as Torch.Indef.Double.Dynamic.Tensor.Index, Torch.Indef.Dynamic.Tensor.Masked as Torch.Indef.Double.Dynamic.Tensor.Masked, Torch.Indef.Dynamic.Tensor.Math as Torch.Indef.Double.Dynamic.Tensor.Math, Torch.Indef.Dynamic.Tensor.Math.Compare as Torch.Indef.Double.Dynamic.Tensor.Math.Compare, Torch.Indef.Dynamic.Tensor.Math.CompareT as Torch.Indef.Double.Dynamic.Tensor.Math.CompareT, Torch.Indef.Dynamic.Tensor.Math.Pairwise as Torch.Indef.Double.Dynamic.Tensor.Math.Pairwise, Torch.Indef.Dynamic.Tensor.Math.Pointwise as Torch.Indef.Double.Dynamic.Tensor.Math.Pointwise, Torch.Indef.Dynamic.Tensor.Math.Reduce as Torch.Indef.Double.Dynamic.Tensor.Math.Reduce, Torch.Indef.Dynamic.Tensor.Math.Scan as Torch.Indef.Double.Dynamic.Tensor.Math.Scan, Torch.Indef.Dynamic.Tensor.Mode as Torch.Indef.Double.Dynamic.Tensor.Mode, Torch.Indef.Dynamic.Tensor.ScatterGather as Torch.Indef.Double.Dynamic.Tensor.ScatterGather, Torch.Indef.Dynamic.Tensor.Sort as Torch.Indef.Double.Dynamic.Tensor.Sort, Torch.Indef.Dynamic.Tensor.TopK as Torch.Indef.Double.Dynamic.Tensor.TopK, Torch.Indef.Types as Torch.Double.Types, Torch.Indef.Index as Torch.Double.Index, Torch.Indef.Mask as Torch.Double.Mask, Torch.Indef.Static.Tensor.Math.Pointwise.Signed as Torch.Indef.Double.Tensor.Math.Pointwise.Signed, Torch.Indef.Dynamic.Tensor.Math.Pointwise.Signed as Torch.Indef.Double.Dynamic.Tensor.Math.Pointwise.Signed, Torch.Indef.Dynamic.Tensor.Math.Blas as Torch.Indef.Double.Dynamic.Tensor.Math.Blas, Torch.Indef.Dynamic.Tensor.Math.Lapack as Torch.Indef.Double.Dynamic.Tensor.Math.Lapack, Torch.Indef.Dynamic.Tensor.Math.Pointwise.Floating as Torch.Indef.Double.Dynamic.Tensor.Math.Pointwise.Floating, Torch.Indef.Dynamic.Tensor.Math.Reduce.Floating as Torch.Indef.Double.Dynamic.Tensor.Math.Reduce.Floating, Torch.Indef.Dynamic.Tensor.Math.Floating as Torch.Indef.Double.Dynamic.Tensor.Math.Floating, Torch.Indef.Static.Tensor.Math.Blas as Torch.Indef.Double.Tensor.Math.Blas, Torch.Indef.Static.Tensor.Math.Lapack as Torch.Indef.Double.Tensor.Math.Lapack, Torch.Indef.Static.Tensor.Math.Pointwise.Floating as Torch.Indef.Double.Tensor.Math.Pointwise.Floating, Torch.Indef.Static.Tensor.Math.Reduce.Floating as Torch.Indef.Double.Tensor.Math.Reduce.Floating, Torch.Indef.Static.Tensor.Math.Floating as Torch.Indef.Double.Tensor.Math.Floating, Torch.Indef.Static.Tensor.Random.TH as Torch.Indef.Double.Tensor.Random.TH, Torch.Indef.Static.Tensor.Math.Random.TH as Torch.Indef.Double.Tensor.Math.Random.TH, Torch.Indef.Dynamic.Tensor.Random.TH as Torch.Indef.Double.Dynamic.Tensor.Random.TH, Torch.Indef.Dynamic.Tensor.Math.Random.TH as Torch.Indef.Double.Dynamic.Tensor.Math.Random.TH, Torch.Undefined.Tensor.Random.THC as Torch.Undefined.Double.Tensor.Random.THC, Torch.Indef.Storage as Torch.Indef.Double.Storage, Torch.Indef.Storage.Copy as Torch.Indef.Double.Storage.Copy, Torch.Indef.Static.Tensor as Torch.Indef.Double.Tensor, Torch.Indef.Static.Tensor.Copy as Torch.Indef.Double.Tensor.Copy, Torch.Indef.Static.Tensor.Index as Torch.Indef.Double.Tensor.Index, Torch.Indef.Static.Tensor.Masked as Torch.Indef.Double.Tensor.Masked, Torch.Indef.Static.Tensor.Math as Torch.Indef.Double.Tensor.Math, Torch.Indef.Static.Tensor.Math.Compare as Torch.Indef.Double.Tensor.Math.Compare, Torch.Indef.Static.Tensor.Math.CompareT as Torch.Indef.Double.Tensor.Math.CompareT, Torch.Indef.Static.Tensor.Math.Pairwise as Torch.Indef.Double.Tensor.Math.Pairwise, Torch.Indef.Static.Tensor.Math.Pointwise as Torch.Indef.Double.Tensor.Math.Pointwise, Torch.Indef.Static.Tensor.Math.Reduce as Torch.Indef.Double.Tensor.Math.Reduce, Torch.Indef.Static.Tensor.Math.Scan as Torch.Indef.Double.Tensor.Math.Scan, Torch.Indef.Static.Tensor.Mode as Torch.Indef.Double.Tensor.Mode, Torch.Indef.Static.Tensor.ScatterGather as Torch.Indef.Double.Tensor.ScatterGather, Torch.Indef.Static.Tensor.Sort as Torch.Indef.Double.Tensor.Sort, Torch.Indef.Static.Tensor.TopK as Torch.Indef.Double.Tensor.TopK, Torch.Indef.Dynamic.Tensor as Torch.Indef.Double.Dynamic.Tensor, Torch.Indef.Dynamic.Tensor.Copy as Torch.Indef.Double.Dynamic.Tensor.Copy, Torch.Indef.Dynamic.Tensor.Index as Torch.Indef.Double.Dynamic.Tensor.Index, Torch.Indef.Dynamic.Tensor.Masked as Torch.Indef.Double.Dynamic.Tensor.Masked, Torch.Indef.Dynamic.Tensor.Math as Torch.Indef.Double.Dynamic.Tensor.Math, Torch.Indef.Dynamic.Tensor.Math.Compare as Torch.Indef.Double.Dynamic.Tensor.Math.Compare, Torch.Indef.Dynamic.Tensor.Math.CompareT as Torch.Indef.Double.Dynamic.Tensor.Math.CompareT, Torch.Indef.Dynamic.Tensor.Math.Pairwise as Torch.Indef.Double.Dynamic.Tensor.Math.Pairwise, Torch.Indef.Dynamic.Tensor.Math.Pointwise as Torch.Indef.Double.Dynamic.Tensor.Math.Pointwise, Torch.Indef.Dynamic.Tensor.Math.Reduce as Torch.Indef.Double.Dynamic.Tensor.Math.Reduce, Torch.Indef.Dynamic.Tensor.Math.Scan as Torch.Indef.Double.Dynamic.Tensor.Math.Scan, Torch.Indef.Dynamic.Tensor.Mode as Torch.Indef.Double.Dynamic.Tensor.Mode, Torch.Indef.Dynamic.Tensor.ScatterGather as Torch.Indef.Double.Dynamic.Tensor.ScatterGather, Torch.Indef.Dynamic.Tensor.Sort as Torch.Indef.Double.Dynamic.Tensor.Sort, Torch.Indef.Dynamic.Tensor.TopK as Torch.Indef.Double.Dynamic.Tensor.TopK, Torch.Indef.Types as Torch.Double.Types, Torch.Indef.Index as Torch.Double.Index, Torch.Indef.Mask as Torch.Double.Mask, Torch.Indef.Static.Tensor.Math.Pointwise.Signed as Torch.Indef.Double.Tensor.Math.Pointwise.Signed, Torch.Indef.Dynamic.Tensor.Math.Pointwise.Signed as Torch.Indef.Double.Dynamic.Tensor.Math.Pointwise.Signed, Torch.Indef.Dynamic.NN as Torch.Double.Dynamic.NN, Torch.Indef.Dynamic.NN.Activation as Torch.Double.Dynamic.NN.Activation, Torch.Indef.Dynamic.NN.Pooling as Torch.Double.Dynamic.NN.Pooling, Torch.Indef.Dynamic.NN.Criterion as Torch.Double.Dynamic.NN.Criterion, Torch.Indef.Static.NN as Torch.Double.NN, Torch.Indef.Static.NN as Torch.Double.NN, Torch.Indef.Static.NN.Activation as Torch.Double.NN.Activation, Torch.Indef.Static.NN.Backprop as Torch.Double.NN.Backprop, Torch.Indef.Static.NN.Conv1d as Torch.Double.NN.Conv1d, Torch.Indef.Static.NN.Conv2d as Torch.Double.NN.Conv2d, Torch.Indef.Static.NN.Criterion as Torch.Double.NN.Criterion, Torch.Indef.Static.NN.Layers as Torch.Double.NN.Layers, Torch.Indef.Static.NN.Linear as Torch.Double.NN.Linear, Torch.Indef.Static.NN.Math as Torch.Double.NN.Math, Torch.Indef.Static.NN.Padding as Torch.Double.NN.Padding, Torch.Indef.Static.NN.Pooling as Torch.Double.NN.Pooling, Torch.Indef.Static.NN.Sampling as Torch.Double.NN.Sampling) requires (Torch.Sig.Index.Tensor as Torch.FFI.TH.Long.Tensor, Torch.Sig.Index.TensorFree as Torch.FFI.TH.Long.FreeTensor, Torch.Sig.Mask.Tensor as Torch.FFI.TH.Byte.Tensor, Torch.Sig.Mask.TensorFree as Torch.FFI.TH.Byte.FreeTensor, Torch.Sig.Mask.MathReduce as Torch.FFI.TH.Byte.TensorMath, Torch.Sig.State as Torch.Types.TH, Torch.Sig.Types.Global as Torch.Types.TH, Torch.Sig.Types as Torch.Types.TH.Double, Torch.Sig.Storage as Torch.FFI.TH.Double.Storage, Torch.Sig.Storage.Copy as Torch.FFI.TH.Double.StorageCopy, Torch.Sig.Storage.Memory as Torch.FFI.TH.Double.FreeStorage, Torch.Sig.Tensor as Torch.FFI.TH.Double.Tensor, Torch.Sig.Tensor.Copy as Torch.FFI.TH.Double.TensorCopy, Torch.Sig.Tensor.Memory as Torch.FFI.TH.Double.FreeTensor, Torch.Sig.Tensor.Index as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Masked as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Math as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Math.Compare as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Math.CompareT as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Math.Pairwise as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Math.Pointwise as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Math.Reduce as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Math.Scan as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Mode as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.ScatterGather as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Sort as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.TopK as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Math.Pointwise.Signed as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Math.Pointwise.Floating as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Math.Reduce.Floating as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Math.Floating as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Math.Blas as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Math.Lapack as Torch.FFI.TH.Double.TensorLapack, Torch.Sig.NN as Torch.FFI.TH.NN.Double, Torch.Sig.Types.NN as Torch.Types.TH, Torch.Sig.Tensor.Math.Random.TH as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Random.TH as Torch.FFI.TH.Double.TensorRandom, Torch.Sig.Tensor.Random.THC as Torch.Undefined.Double.Tensor.Random.THC)-    -    if flag(lite)-    else-        exposed-modules:-            Torch.Byte-            Torch.Byte.Dynamic-            Torch.Byte.Storage-            Torch.Char-            Torch.Char.Dynamic-            Torch.Char.Storage-            Torch.Short-            Torch.Short.Dynamic-            Torch.Short.Storage-            Torch.Int-            Torch.Int.Dynamic-            Torch.Int.Storage-            Torch.Float-            Torch.Float.Dynamic-            Torch.Float.Storage-        build-depends:-            hasktorch-indef-unsigned -any-        mixins: hasktorch-indef-unsigned (Torch.Indef.Storage as Torch.Indef.Byte.Storage, Torch.Indef.Storage.Copy as Torch.Indef.Byte.Storage.Copy, Torch.Indef.Static.Tensor as Torch.Indef.Byte.Tensor, Torch.Indef.Static.Tensor.Copy as Torch.Indef.Byte.Tensor.Copy, Torch.Indef.Static.Tensor.Index as Torch.Indef.Byte.Tensor.Index, Torch.Indef.Static.Tensor.Masked as Torch.Indef.Byte.Tensor.Masked, Torch.Indef.Static.Tensor.Math as Torch.Indef.Byte.Tensor.Math, Torch.Indef.Static.Tensor.Math.Compare as Torch.Indef.Byte.Tensor.Math.Compare, Torch.Indef.Static.Tensor.Math.CompareT as Torch.Indef.Byte.Tensor.Math.CompareT, Torch.Indef.Static.Tensor.Math.Pairwise as Torch.Indef.Byte.Tensor.Math.Pairwise, Torch.Indef.Static.Tensor.Math.Pointwise as Torch.Indef.Byte.Tensor.Math.Pointwise, Torch.Indef.Static.Tensor.Math.Reduce as Torch.Indef.Byte.Tensor.Math.Reduce, Torch.Indef.Static.Tensor.Math.Scan as Torch.Indef.Byte.Tensor.Math.Scan, Torch.Indef.Static.Tensor.Mode as Torch.Indef.Byte.Tensor.Mode, Torch.Indef.Static.Tensor.ScatterGather as Torch.Indef.Byte.Tensor.ScatterGather, Torch.Indef.Static.Tensor.Sort as Torch.Indef.Byte.Tensor.Sort, Torch.Indef.Static.Tensor.TopK as Torch.Indef.Byte.Tensor.TopK, Torch.Indef.Dynamic.Tensor as Torch.Indef.Byte.Dynamic.Tensor, Torch.Indef.Dynamic.Tensor.Copy as Torch.Indef.Byte.Dynamic.Tensor.Copy, Torch.Indef.Dynamic.Tensor.Index as Torch.Indef.Byte.Dynamic.Tensor.Index, Torch.Indef.Dynamic.Tensor.Masked as Torch.Indef.Byte.Dynamic.Tensor.Masked, Torch.Indef.Dynamic.Tensor.Math as Torch.Indef.Byte.Dynamic.Tensor.Math, Torch.Indef.Dynamic.Tensor.Math.Compare as Torch.Indef.Byte.Dynamic.Tensor.Math.Compare, Torch.Indef.Dynamic.Tensor.Math.CompareT as Torch.Indef.Byte.Dynamic.Tensor.Math.CompareT, Torch.Indef.Dynamic.Tensor.Math.Pairwise as Torch.Indef.Byte.Dynamic.Tensor.Math.Pairwise, Torch.Indef.Dynamic.Tensor.Math.Pointwise as Torch.Indef.Byte.Dynamic.Tensor.Math.Pointwise, Torch.Indef.Dynamic.Tensor.Math.Reduce as Torch.Indef.Byte.Dynamic.Tensor.Math.Reduce, Torch.Indef.Dynamic.Tensor.Math.Scan as Torch.Indef.Byte.Dynamic.Tensor.Math.Scan, Torch.Indef.Dynamic.Tensor.Mode as Torch.Indef.Byte.Dynamic.Tensor.Mode, Torch.Indef.Dynamic.Tensor.ScatterGather as Torch.Indef.Byte.Dynamic.Tensor.ScatterGather, Torch.Indef.Dynamic.Tensor.Sort as Torch.Indef.Byte.Dynamic.Tensor.Sort, Torch.Indef.Dynamic.Tensor.TopK as Torch.Indef.Byte.Dynamic.Tensor.TopK, Torch.Indef.Types as Torch.Byte.Types, Torch.Indef.Index as Torch.Byte.Index, Torch.Indef.Mask as Torch.Byte.Mask) requires (Torch.Sig.Index.Tensor as Torch.FFI.TH.Long.Tensor, Torch.Sig.Index.TensorFree as Torch.FFI.TH.Long.FreeTensor, Torch.Sig.Mask.Tensor as Torch.FFI.TH.Byte.Tensor, Torch.Sig.Mask.TensorFree as Torch.FFI.TH.Byte.FreeTensor, Torch.Sig.Mask.MathReduce as Torch.FFI.TH.Byte.TensorMath, Torch.Sig.State as Torch.Types.TH, Torch.Sig.Types.Global as Torch.Types.TH, Torch.Sig.Types as Torch.Types.TH.Byte, Torch.Sig.Storage as Torch.FFI.TH.Byte.Storage, Torch.Sig.Storage.Copy as Torch.FFI.TH.Byte.StorageCopy, Torch.Sig.Storage.Memory as Torch.FFI.TH.Byte.FreeStorage, Torch.Sig.Tensor as Torch.FFI.TH.Byte.Tensor, Torch.Sig.Tensor.Copy as Torch.FFI.TH.Byte.TensorCopy, Torch.Sig.Tensor.Memory as Torch.FFI.TH.Byte.FreeTensor, Torch.Sig.Tensor.Index as Torch.FFI.TH.Byte.TensorMath, Torch.Sig.Tensor.Masked as Torch.FFI.TH.Byte.TensorMath, Torch.Sig.Tensor.Math as Torch.FFI.TH.Byte.TensorMath, Torch.Sig.Tensor.Math.Compare as Torch.FFI.TH.Byte.TensorMath, Torch.Sig.Tensor.Math.CompareT as Torch.FFI.TH.Byte.TensorMath, Torch.Sig.Tensor.Math.Pairwise as Torch.FFI.TH.Byte.TensorMath, Torch.Sig.Tensor.Math.Pointwise as Torch.FFI.TH.Byte.TensorMath, Torch.Sig.Tensor.Math.Reduce as Torch.FFI.TH.Byte.TensorMath, Torch.Sig.Tensor.Math.Scan as Torch.FFI.TH.Byte.TensorMath, Torch.Sig.Tensor.Mode as Torch.FFI.TH.Byte.TensorMath, Torch.Sig.Tensor.ScatterGather as Torch.FFI.TH.Byte.TensorMath, Torch.Sig.Tensor.Sort as Torch.FFI.TH.Byte.TensorMath, Torch.Sig.Tensor.TopK as Torch.FFI.TH.Byte.TensorMath),-                hasktorch-indef-unsigned (Torch.Indef.Storage as Torch.Indef.Char.Storage, Torch.Indef.Storage.Copy as Torch.Indef.Char.Storage.Copy, Torch.Indef.Static.Tensor as Torch.Indef.Char.Tensor, Torch.Indef.Static.Tensor.Copy as Torch.Indef.Char.Tensor.Copy, Torch.Indef.Static.Tensor.Index as Torch.Indef.Char.Tensor.Index, Torch.Indef.Static.Tensor.Masked as Torch.Indef.Char.Tensor.Masked, Torch.Indef.Static.Tensor.Math as Torch.Indef.Char.Tensor.Math, Torch.Indef.Static.Tensor.Math.Compare as Torch.Indef.Char.Tensor.Math.Compare, Torch.Indef.Static.Tensor.Math.CompareT as Torch.Indef.Char.Tensor.Math.CompareT, Torch.Indef.Static.Tensor.Math.Pairwise as Torch.Indef.Char.Tensor.Math.Pairwise, Torch.Indef.Static.Tensor.Math.Pointwise as Torch.Indef.Char.Tensor.Math.Pointwise, Torch.Indef.Static.Tensor.Math.Reduce as Torch.Indef.Char.Tensor.Math.Reduce, Torch.Indef.Static.Tensor.Math.Scan as Torch.Indef.Char.Tensor.Math.Scan, Torch.Indef.Static.Tensor.Mode as Torch.Indef.Char.Tensor.Mode, Torch.Indef.Static.Tensor.ScatterGather as Torch.Indef.Char.Tensor.ScatterGather, Torch.Indef.Static.Tensor.Sort as Torch.Indef.Char.Tensor.Sort, Torch.Indef.Static.Tensor.TopK as Torch.Indef.Char.Tensor.TopK, Torch.Indef.Dynamic.Tensor as Torch.Indef.Char.Dynamic.Tensor, Torch.Indef.Dynamic.Tensor.Copy as Torch.Indef.Char.Dynamic.Tensor.Copy, Torch.Indef.Dynamic.Tensor.Index as Torch.Indef.Char.Dynamic.Tensor.Index, Torch.Indef.Dynamic.Tensor.Masked as Torch.Indef.Char.Dynamic.Tensor.Masked, Torch.Indef.Dynamic.Tensor.Math as Torch.Indef.Char.Dynamic.Tensor.Math, Torch.Indef.Dynamic.Tensor.Math.Compare as Torch.Indef.Char.Dynamic.Tensor.Math.Compare, Torch.Indef.Dynamic.Tensor.Math.CompareT as Torch.Indef.Char.Dynamic.Tensor.Math.CompareT, Torch.Indef.Dynamic.Tensor.Math.Pairwise as Torch.Indef.Char.Dynamic.Tensor.Math.Pairwise, Torch.Indef.Dynamic.Tensor.Math.Pointwise as Torch.Indef.Char.Dynamic.Tensor.Math.Pointwise, Torch.Indef.Dynamic.Tensor.Math.Reduce as Torch.Indef.Char.Dynamic.Tensor.Math.Reduce, Torch.Indef.Dynamic.Tensor.Math.Scan as Torch.Indef.Char.Dynamic.Tensor.Math.Scan, Torch.Indef.Dynamic.Tensor.Mode as Torch.Indef.Char.Dynamic.Tensor.Mode, Torch.Indef.Dynamic.Tensor.ScatterGather as Torch.Indef.Char.Dynamic.Tensor.ScatterGather, Torch.Indef.Dynamic.Tensor.Sort as Torch.Indef.Char.Dynamic.Tensor.Sort, Torch.Indef.Dynamic.Tensor.TopK as Torch.Indef.Char.Dynamic.Tensor.TopK, Torch.Indef.Types as Torch.Char.Types, Torch.Indef.Index as Torch.Char.Index, Torch.Indef.Mask as Torch.Char.Mask) requires (Torch.Sig.Index.Tensor as Torch.FFI.TH.Long.Tensor, Torch.Sig.Index.TensorFree as Torch.FFI.TH.Long.FreeTensor, Torch.Sig.Mask.Tensor as Torch.FFI.TH.Byte.Tensor, Torch.Sig.Mask.TensorFree as Torch.FFI.TH.Byte.FreeTensor, Torch.Sig.Mask.MathReduce as Torch.FFI.TH.Byte.TensorMath, Torch.Sig.State as Torch.Types.TH, Torch.Sig.Types.Global as Torch.Types.TH, Torch.Sig.Types as Torch.Types.TH.Char, Torch.Sig.Storage as Torch.FFI.TH.Char.Storage, Torch.Sig.Storage.Copy as Torch.FFI.TH.Char.StorageCopy, Torch.Sig.Storage.Memory as Torch.FFI.TH.Char.FreeStorage, Torch.Sig.Tensor as Torch.FFI.TH.Char.Tensor, Torch.Sig.Tensor.Copy as Torch.FFI.TH.Char.TensorCopy, Torch.Sig.Tensor.Memory as Torch.FFI.TH.Char.FreeTensor, Torch.Sig.Tensor.Index as Torch.FFI.TH.Char.TensorMath, Torch.Sig.Tensor.Masked as Torch.FFI.TH.Char.TensorMath, Torch.Sig.Tensor.Math as Torch.FFI.TH.Char.TensorMath, Torch.Sig.Tensor.Math.Compare as Torch.FFI.TH.Char.TensorMath, Torch.Sig.Tensor.Math.CompareT as Torch.FFI.TH.Char.TensorMath, Torch.Sig.Tensor.Math.Pairwise as Torch.FFI.TH.Char.TensorMath, Torch.Sig.Tensor.Math.Pointwise as Torch.FFI.TH.Char.TensorMath, Torch.Sig.Tensor.Math.Reduce as Torch.FFI.TH.Char.TensorMath, Torch.Sig.Tensor.Math.Scan as Torch.FFI.TH.Char.TensorMath, Torch.Sig.Tensor.Mode as Torch.FFI.TH.Char.TensorMath, Torch.Sig.Tensor.ScatterGather as Torch.FFI.TH.Char.TensorMath, Torch.Sig.Tensor.Sort as Torch.FFI.TH.Char.TensorMath, Torch.Sig.Tensor.TopK as Torch.FFI.TH.Char.TensorMath),-                hasktorch-indef-signed (Torch.Indef.Storage as Torch.Indef.Short.Storage, Torch.Indef.Storage.Copy as Torch.Indef.Short.Storage.Copy, Torch.Indef.Static.Tensor as Torch.Indef.Short.Tensor, Torch.Indef.Static.Tensor.Copy as Torch.Indef.Short.Tensor.Copy, Torch.Indef.Static.Tensor.Index as Torch.Indef.Short.Tensor.Index, Torch.Indef.Static.Tensor.Masked as Torch.Indef.Short.Tensor.Masked, Torch.Indef.Static.Tensor.Math as Torch.Indef.Short.Tensor.Math, Torch.Indef.Static.Tensor.Math.Compare as Torch.Indef.Short.Tensor.Math.Compare, Torch.Indef.Static.Tensor.Math.CompareT as Torch.Indef.Short.Tensor.Math.CompareT, Torch.Indef.Static.Tensor.Math.Pairwise as Torch.Indef.Short.Tensor.Math.Pairwise, Torch.Indef.Static.Tensor.Math.Pointwise as Torch.Indef.Short.Tensor.Math.Pointwise, Torch.Indef.Static.Tensor.Math.Reduce as Torch.Indef.Short.Tensor.Math.Reduce, Torch.Indef.Static.Tensor.Math.Scan as Torch.Indef.Short.Tensor.Math.Scan, Torch.Indef.Static.Tensor.Mode as Torch.Indef.Short.Tensor.Mode, Torch.Indef.Static.Tensor.ScatterGather as Torch.Indef.Short.Tensor.ScatterGather, Torch.Indef.Static.Tensor.Sort as Torch.Indef.Short.Tensor.Sort, Torch.Indef.Static.Tensor.TopK as Torch.Indef.Short.Tensor.TopK, Torch.Indef.Dynamic.Tensor as Torch.Indef.Short.Dynamic.Tensor, Torch.Indef.Dynamic.Tensor.Copy as Torch.Indef.Short.Dynamic.Tensor.Copy, Torch.Indef.Dynamic.Tensor.Index as Torch.Indef.Short.Dynamic.Tensor.Index, Torch.Indef.Dynamic.Tensor.Masked as Torch.Indef.Short.Dynamic.Tensor.Masked, Torch.Indef.Dynamic.Tensor.Math as Torch.Indef.Short.Dynamic.Tensor.Math, Torch.Indef.Dynamic.Tensor.Math.Compare as Torch.Indef.Short.Dynamic.Tensor.Math.Compare, Torch.Indef.Dynamic.Tensor.Math.CompareT as Torch.Indef.Short.Dynamic.Tensor.Math.CompareT, Torch.Indef.Dynamic.Tensor.Math.Pairwise as Torch.Indef.Short.Dynamic.Tensor.Math.Pairwise, Torch.Indef.Dynamic.Tensor.Math.Pointwise as Torch.Indef.Short.Dynamic.Tensor.Math.Pointwise, Torch.Indef.Dynamic.Tensor.Math.Reduce as Torch.Indef.Short.Dynamic.Tensor.Math.Reduce, Torch.Indef.Dynamic.Tensor.Math.Scan as Torch.Indef.Short.Dynamic.Tensor.Math.Scan, Torch.Indef.Dynamic.Tensor.Mode as Torch.Indef.Short.Dynamic.Tensor.Mode, Torch.Indef.Dynamic.Tensor.ScatterGather as Torch.Indef.Short.Dynamic.Tensor.ScatterGather, Torch.Indef.Dynamic.Tensor.Sort as Torch.Indef.Short.Dynamic.Tensor.Sort, Torch.Indef.Dynamic.Tensor.TopK as Torch.Indef.Short.Dynamic.Tensor.TopK, Torch.Indef.Types as Torch.Short.Types, Torch.Indef.Index as Torch.Short.Index, Torch.Indef.Mask as Torch.Short.Mask, Torch.Indef.Static.Tensor.Math.Pointwise.Signed as Torch.Indef.Short.Tensor.Math.Pointwise.Signed, Torch.Indef.Dynamic.Tensor.Math.Pointwise.Signed as Torch.Indef.Short.Dynamic.Tensor.Math.Pointwise.Signed) requires (Torch.Sig.Index.Tensor as Torch.FFI.TH.Long.Tensor, Torch.Sig.Index.TensorFree as Torch.FFI.TH.Long.FreeTensor, Torch.Sig.Mask.Tensor as Torch.FFI.TH.Byte.Tensor, Torch.Sig.Mask.TensorFree as Torch.FFI.TH.Byte.FreeTensor, Torch.Sig.Mask.MathReduce as Torch.FFI.TH.Byte.TensorMath, Torch.Sig.State as Torch.Types.TH, Torch.Sig.Types.Global as Torch.Types.TH, Torch.Sig.Types as Torch.Types.TH.Short, Torch.Sig.Storage as Torch.FFI.TH.Short.Storage, Torch.Sig.Storage.Copy as Torch.FFI.TH.Short.StorageCopy, Torch.Sig.Storage.Memory as Torch.FFI.TH.Short.FreeStorage, Torch.Sig.Tensor as Torch.FFI.TH.Short.Tensor, Torch.Sig.Tensor.Copy as Torch.FFI.TH.Short.TensorCopy, Torch.Sig.Tensor.Memory as Torch.FFI.TH.Short.FreeTensor, Torch.Sig.Tensor.Index as Torch.FFI.TH.Short.TensorMath, Torch.Sig.Tensor.Masked as Torch.FFI.TH.Short.TensorMath, Torch.Sig.Tensor.Math as Torch.FFI.TH.Short.TensorMath, Torch.Sig.Tensor.Math.Compare as Torch.FFI.TH.Short.TensorMath, Torch.Sig.Tensor.Math.CompareT as Torch.FFI.TH.Short.TensorMath, Torch.Sig.Tensor.Math.Pairwise as Torch.FFI.TH.Short.TensorMath, Torch.Sig.Tensor.Math.Pointwise as Torch.FFI.TH.Short.TensorMath, Torch.Sig.Tensor.Math.Reduce as Torch.FFI.TH.Short.TensorMath, Torch.Sig.Tensor.Math.Scan as Torch.FFI.TH.Short.TensorMath, Torch.Sig.Tensor.Mode as Torch.FFI.TH.Short.TensorMath, Torch.Sig.Tensor.ScatterGather as Torch.FFI.TH.Short.TensorMath, Torch.Sig.Tensor.Sort as Torch.FFI.TH.Short.TensorMath, Torch.Sig.Tensor.TopK as Torch.FFI.TH.Short.TensorMath, Torch.Sig.Tensor.Math.Pointwise.Signed as Torch.FFI.TH.Short.TensorMath),-                hasktorch-indef-signed (Torch.Indef.Storage as Torch.Indef.Int.Storage, Torch.Indef.Storage.Copy as Torch.Indef.Int.Storage.Copy, Torch.Indef.Static.Tensor as Torch.Indef.Int.Tensor, Torch.Indef.Static.Tensor.Copy as Torch.Indef.Int.Tensor.Copy, Torch.Indef.Static.Tensor.Index as Torch.Indef.Int.Tensor.Index, Torch.Indef.Static.Tensor.Masked as Torch.Indef.Int.Tensor.Masked, Torch.Indef.Static.Tensor.Math as Torch.Indef.Int.Tensor.Math, Torch.Indef.Static.Tensor.Math.Compare as Torch.Indef.Int.Tensor.Math.Compare, Torch.Indef.Static.Tensor.Math.CompareT as Torch.Indef.Int.Tensor.Math.CompareT, Torch.Indef.Static.Tensor.Math.Pairwise as Torch.Indef.Int.Tensor.Math.Pairwise, Torch.Indef.Static.Tensor.Math.Pointwise as Torch.Indef.Int.Tensor.Math.Pointwise, Torch.Indef.Static.Tensor.Math.Reduce as Torch.Indef.Int.Tensor.Math.Reduce, Torch.Indef.Static.Tensor.Math.Scan as Torch.Indef.Int.Tensor.Math.Scan, Torch.Indef.Static.Tensor.Mode as Torch.Indef.Int.Tensor.Mode, Torch.Indef.Static.Tensor.ScatterGather as Torch.Indef.Int.Tensor.ScatterGather, Torch.Indef.Static.Tensor.Sort as Torch.Indef.Int.Tensor.Sort, Torch.Indef.Static.Tensor.TopK as Torch.Indef.Int.Tensor.TopK, Torch.Indef.Dynamic.Tensor as Torch.Indef.Int.Dynamic.Tensor, Torch.Indef.Dynamic.Tensor.Copy as Torch.Indef.Int.Dynamic.Tensor.Copy, Torch.Indef.Dynamic.Tensor.Index as Torch.Indef.Int.Dynamic.Tensor.Index, Torch.Indef.Dynamic.Tensor.Masked as Torch.Indef.Int.Dynamic.Tensor.Masked, Torch.Indef.Dynamic.Tensor.Math as Torch.Indef.Int.Dynamic.Tensor.Math, Torch.Indef.Dynamic.Tensor.Math.Compare as Torch.Indef.Int.Dynamic.Tensor.Math.Compare, Torch.Indef.Dynamic.Tensor.Math.CompareT as Torch.Indef.Int.Dynamic.Tensor.Math.CompareT, Torch.Indef.Dynamic.Tensor.Math.Pairwise as Torch.Indef.Int.Dynamic.Tensor.Math.Pairwise, Torch.Indef.Dynamic.Tensor.Math.Pointwise as Torch.Indef.Int.Dynamic.Tensor.Math.Pointwise, Torch.Indef.Dynamic.Tensor.Math.Reduce as Torch.Indef.Int.Dynamic.Tensor.Math.Reduce, Torch.Indef.Dynamic.Tensor.Math.Scan as Torch.Indef.Int.Dynamic.Tensor.Math.Scan, Torch.Indef.Dynamic.Tensor.Mode as Torch.Indef.Int.Dynamic.Tensor.Mode, Torch.Indef.Dynamic.Tensor.ScatterGather as Torch.Indef.Int.Dynamic.Tensor.ScatterGather, Torch.Indef.Dynamic.Tensor.Sort as Torch.Indef.Int.Dynamic.Tensor.Sort, Torch.Indef.Dynamic.Tensor.TopK as Torch.Indef.Int.Dynamic.Tensor.TopK, Torch.Indef.Types as Torch.Int.Types, Torch.Indef.Index as Torch.Int.Index, Torch.Indef.Mask as Torch.Int.Mask, Torch.Indef.Static.Tensor.Math.Pointwise.Signed as Torch.Indef.Int.Tensor.Math.Pointwise.Signed, Torch.Indef.Dynamic.Tensor.Math.Pointwise.Signed as Torch.Indef.Int.Dynamic.Tensor.Math.Pointwise.Signed) requires (Torch.Sig.Index.Tensor as Torch.FFI.TH.Long.Tensor, Torch.Sig.Index.TensorFree as Torch.FFI.TH.Long.FreeTensor, Torch.Sig.Mask.Tensor as Torch.FFI.TH.Byte.Tensor, Torch.Sig.Mask.TensorFree as Torch.FFI.TH.Byte.FreeTensor, Torch.Sig.Mask.MathReduce as Torch.FFI.TH.Byte.TensorMath, Torch.Sig.State as Torch.Types.TH, Torch.Sig.Types.Global as Torch.Types.TH, Torch.Sig.Types as Torch.Types.TH.Int, Torch.Sig.Storage as Torch.FFI.TH.Int.Storage, Torch.Sig.Storage.Copy as Torch.FFI.TH.Int.StorageCopy, Torch.Sig.Storage.Memory as Torch.FFI.TH.Int.FreeStorage, Torch.Sig.Tensor as Torch.FFI.TH.Int.Tensor, Torch.Sig.Tensor.Copy as Torch.FFI.TH.Int.TensorCopy, Torch.Sig.Tensor.Memory as Torch.FFI.TH.Int.FreeTensor, Torch.Sig.Tensor.Index as Torch.FFI.TH.Int.TensorMath, Torch.Sig.Tensor.Masked as Torch.FFI.TH.Int.TensorMath, Torch.Sig.Tensor.Math as Torch.FFI.TH.Int.TensorMath, Torch.Sig.Tensor.Math.Compare as Torch.FFI.TH.Int.TensorMath, Torch.Sig.Tensor.Math.CompareT as Torch.FFI.TH.Int.TensorMath, Torch.Sig.Tensor.Math.Pairwise as Torch.FFI.TH.Int.TensorMath, Torch.Sig.Tensor.Math.Pointwise as Torch.FFI.TH.Int.TensorMath, Torch.Sig.Tensor.Math.Reduce as Torch.FFI.TH.Int.TensorMath, Torch.Sig.Tensor.Math.Scan as Torch.FFI.TH.Int.TensorMath, Torch.Sig.Tensor.Mode as Torch.FFI.TH.Int.TensorMath, Torch.Sig.Tensor.ScatterGather as Torch.FFI.TH.Int.TensorMath, Torch.Sig.Tensor.Sort as Torch.FFI.TH.Int.TensorMath, Torch.Sig.Tensor.TopK as Torch.FFI.TH.Int.TensorMath, Torch.Sig.Tensor.Math.Pointwise.Signed as Torch.FFI.TH.Int.TensorMath),-                hasktorch-indef-floating (Torch.Indef.Storage as Torch.Indef.Float.Storage, Torch.Indef.Storage.Copy as Torch.Indef.Float.Storage.Copy, Torch.Indef.Static.Tensor as Torch.Indef.Float.Tensor, Torch.Indef.Static.Tensor.Copy as Torch.Indef.Float.Tensor.Copy, Torch.Indef.Static.Tensor.Index as Torch.Indef.Float.Tensor.Index, Torch.Indef.Static.Tensor.Masked as Torch.Indef.Float.Tensor.Masked, Torch.Indef.Static.Tensor.Math as Torch.Indef.Float.Tensor.Math, Torch.Indef.Static.Tensor.Math.Compare as Torch.Indef.Float.Tensor.Math.Compare, Torch.Indef.Static.Tensor.Math.CompareT as Torch.Indef.Float.Tensor.Math.CompareT, Torch.Indef.Static.Tensor.Math.Pairwise as Torch.Indef.Float.Tensor.Math.Pairwise, Torch.Indef.Static.Tensor.Math.Pointwise as Torch.Indef.Float.Tensor.Math.Pointwise, Torch.Indef.Static.Tensor.Math.Reduce as Torch.Indef.Float.Tensor.Math.Reduce, Torch.Indef.Static.Tensor.Math.Scan as Torch.Indef.Float.Tensor.Math.Scan, Torch.Indef.Static.Tensor.Mode as Torch.Indef.Float.Tensor.Mode, Torch.Indef.Static.Tensor.ScatterGather as Torch.Indef.Float.Tensor.ScatterGather, Torch.Indef.Static.Tensor.Sort as Torch.Indef.Float.Tensor.Sort, Torch.Indef.Static.Tensor.TopK as Torch.Indef.Float.Tensor.TopK, Torch.Indef.Dynamic.Tensor as Torch.Indef.Float.Dynamic.Tensor, Torch.Indef.Dynamic.Tensor.Copy as Torch.Indef.Float.Dynamic.Tensor.Copy, Torch.Indef.Dynamic.Tensor.Index as Torch.Indef.Float.Dynamic.Tensor.Index, Torch.Indef.Dynamic.Tensor.Masked as Torch.Indef.Float.Dynamic.Tensor.Masked, Torch.Indef.Dynamic.Tensor.Math as Torch.Indef.Float.Dynamic.Tensor.Math, Torch.Indef.Dynamic.Tensor.Math.Compare as Torch.Indef.Float.Dynamic.Tensor.Math.Compare, Torch.Indef.Dynamic.Tensor.Math.CompareT as Torch.Indef.Float.Dynamic.Tensor.Math.CompareT, Torch.Indef.Dynamic.Tensor.Math.Pairwise as Torch.Indef.Float.Dynamic.Tensor.Math.Pairwise, Torch.Indef.Dynamic.Tensor.Math.Pointwise as Torch.Indef.Float.Dynamic.Tensor.Math.Pointwise, Torch.Indef.Dynamic.Tensor.Math.Reduce as Torch.Indef.Float.Dynamic.Tensor.Math.Reduce, Torch.Indef.Dynamic.Tensor.Math.Scan as Torch.Indef.Float.Dynamic.Tensor.Math.Scan, Torch.Indef.Dynamic.Tensor.Mode as Torch.Indef.Float.Dynamic.Tensor.Mode, Torch.Indef.Dynamic.Tensor.ScatterGather as Torch.Indef.Float.Dynamic.Tensor.ScatterGather, Torch.Indef.Dynamic.Tensor.Sort as Torch.Indef.Float.Dynamic.Tensor.Sort, Torch.Indef.Dynamic.Tensor.TopK as Torch.Indef.Float.Dynamic.Tensor.TopK, Torch.Indef.Types as Torch.Float.Types, Torch.Indef.Index as Torch.Float.Index, Torch.Indef.Mask as Torch.Float.Mask, Torch.Indef.Static.Tensor.Math.Pointwise.Signed as Torch.Indef.Float.Tensor.Math.Pointwise.Signed, Torch.Indef.Dynamic.Tensor.Math.Pointwise.Signed as Torch.Indef.Float.Dynamic.Tensor.Math.Pointwise.Signed, Torch.Indef.Dynamic.Tensor.Math.Blas as Torch.Indef.Float.Dynamic.Tensor.Math.Blas, Torch.Indef.Dynamic.Tensor.Math.Lapack as Torch.Indef.Float.Dynamic.Tensor.Math.Lapack, Torch.Indef.Dynamic.Tensor.Math.Pointwise.Floating as Torch.Indef.Float.Dynamic.Tensor.Math.Pointwise.Floating, Torch.Indef.Dynamic.Tensor.Math.Reduce.Floating as Torch.Indef.Float.Dynamic.Tensor.Math.Reduce.Floating, Torch.Indef.Dynamic.Tensor.Math.Floating as Torch.Indef.Float.Dynamic.Tensor.Math.Floating, Torch.Indef.Static.Tensor.Math.Blas as Torch.Indef.Float.Tensor.Math.Blas, Torch.Indef.Static.Tensor.Math.Lapack as Torch.Indef.Float.Tensor.Math.Lapack, Torch.Indef.Static.Tensor.Math.Pointwise.Floating as Torch.Indef.Float.Tensor.Math.Pointwise.Floating, Torch.Indef.Static.Tensor.Math.Reduce.Floating as Torch.Indef.Float.Tensor.Math.Reduce.Floating, Torch.Indef.Static.Tensor.Math.Floating as Torch.Indef.Float.Tensor.Math.Floating, Torch.Indef.Static.Tensor.Random.TH as Torch.Indef.Float.Tensor.Random.TH, Torch.Indef.Static.Tensor.Math.Random.TH as Torch.Indef.Float.Tensor.Math.Random.TH, Torch.Indef.Dynamic.Tensor.Random.TH as Torch.Indef.Float.Dynamic.Tensor.Random.TH, Torch.Indef.Dynamic.Tensor.Math.Random.TH as Torch.Indef.Float.Dynamic.Tensor.Math.Random.TH, Torch.Undefined.Tensor.Random.THC as Torch.Undefined.Float.Tensor.Random.THC, Torch.Indef.Storage as Torch.Indef.Float.Storage, Torch.Indef.Storage.Copy as Torch.Indef.Float.Storage.Copy, Torch.Indef.Static.Tensor as Torch.Indef.Float.Tensor, Torch.Indef.Static.Tensor.Copy as Torch.Indef.Float.Tensor.Copy, Torch.Indef.Static.Tensor.Index as Torch.Indef.Float.Tensor.Index, Torch.Indef.Static.Tensor.Masked as Torch.Indef.Float.Tensor.Masked, Torch.Indef.Static.Tensor.Math as Torch.Indef.Float.Tensor.Math, Torch.Indef.Static.Tensor.Math.Compare as Torch.Indef.Float.Tensor.Math.Compare, Torch.Indef.Static.Tensor.Math.CompareT as Torch.Indef.Float.Tensor.Math.CompareT, Torch.Indef.Static.Tensor.Math.Pairwise as Torch.Indef.Float.Tensor.Math.Pairwise, Torch.Indef.Static.Tensor.Math.Pointwise as Torch.Indef.Float.Tensor.Math.Pointwise, Torch.Indef.Static.Tensor.Math.Reduce as Torch.Indef.Float.Tensor.Math.Reduce, Torch.Indef.Static.Tensor.Math.Scan as Torch.Indef.Float.Tensor.Math.Scan, Torch.Indef.Static.Tensor.Mode as Torch.Indef.Float.Tensor.Mode, Torch.Indef.Static.Tensor.ScatterGather as Torch.Indef.Float.Tensor.ScatterGather, Torch.Indef.Static.Tensor.Sort as Torch.Indef.Float.Tensor.Sort, Torch.Indef.Static.Tensor.TopK as Torch.Indef.Float.Tensor.TopK, Torch.Indef.Dynamic.Tensor as Torch.Indef.Float.Dynamic.Tensor, Torch.Indef.Dynamic.Tensor.Copy as Torch.Indef.Float.Dynamic.Tensor.Copy, Torch.Indef.Dynamic.Tensor.Index as Torch.Indef.Float.Dynamic.Tensor.Index, Torch.Indef.Dynamic.Tensor.Masked as Torch.Indef.Float.Dynamic.Tensor.Masked, Torch.Indef.Dynamic.Tensor.Math as Torch.Indef.Float.Dynamic.Tensor.Math, Torch.Indef.Dynamic.Tensor.Math.Compare as Torch.Indef.Float.Dynamic.Tensor.Math.Compare, Torch.Indef.Dynamic.Tensor.Math.CompareT as Torch.Indef.Float.Dynamic.Tensor.Math.CompareT, Torch.Indef.Dynamic.Tensor.Math.Pairwise as Torch.Indef.Float.Dynamic.Tensor.Math.Pairwise, Torch.Indef.Dynamic.Tensor.Math.Pointwise as Torch.Indef.Float.Dynamic.Tensor.Math.Pointwise, Torch.Indef.Dynamic.Tensor.Math.Reduce as Torch.Indef.Float.Dynamic.Tensor.Math.Reduce, Torch.Indef.Dynamic.Tensor.Math.Scan as Torch.Indef.Float.Dynamic.Tensor.Math.Scan, Torch.Indef.Dynamic.Tensor.Mode as Torch.Indef.Float.Dynamic.Tensor.Mode, Torch.Indef.Dynamic.Tensor.ScatterGather as Torch.Indef.Float.Dynamic.Tensor.ScatterGather, Torch.Indef.Dynamic.Tensor.Sort as Torch.Indef.Float.Dynamic.Tensor.Sort, Torch.Indef.Dynamic.Tensor.TopK as Torch.Indef.Float.Dynamic.Tensor.TopK, Torch.Indef.Types as Torch.Float.Types, Torch.Indef.Index as Torch.Float.Index, Torch.Indef.Mask as Torch.Float.Mask, Torch.Indef.Static.Tensor.Math.Pointwise.Signed as Torch.Indef.Float.Tensor.Math.Pointwise.Signed, Torch.Indef.Dynamic.Tensor.Math.Pointwise.Signed as Torch.Indef.Float.Dynamic.Tensor.Math.Pointwise.Signed, Torch.Indef.Dynamic.NN as Torch.Float.Dynamic.NN, Torch.Indef.Dynamic.NN.Activation as Torch.Float.Dynamic.NN.Activation, Torch.Indef.Dynamic.NN.Pooling as Torch.Float.Dynamic.NN.Pooling, Torch.Indef.Dynamic.NN.Criterion as Torch.Float.Dynamic.NN.Criterion, Torch.Indef.Static.NN as Torch.Float.NN, Torch.Indef.Static.NN as Torch.Float.NN, Torch.Indef.Static.NN.Activation as Torch.Float.NN.Activation, Torch.Indef.Static.NN.Backprop as Torch.Float.NN.Backprop, Torch.Indef.Static.NN.Conv1d as Torch.Float.NN.Conv1d, Torch.Indef.Static.NN.Conv2d as Torch.Float.NN.Conv2d, Torch.Indef.Static.NN.Criterion as Torch.Float.NN.Criterion, Torch.Indef.Static.NN.Layers as Torch.Float.NN.Layers, Torch.Indef.Static.NN.Linear as Torch.Float.NN.Linear, Torch.Indef.Static.NN.Math as Torch.Float.NN.Math, Torch.Indef.Static.NN.Padding as Torch.Float.NN.Padding, Torch.Indef.Static.NN.Pooling as Torch.Float.NN.Pooling, Torch.Indef.Static.NN.Sampling as Torch.Float.NN.Sampling) requires (Torch.Sig.Index.Tensor as Torch.FFI.TH.Long.Tensor, Torch.Sig.Index.TensorFree as Torch.FFI.TH.Long.FreeTensor, Torch.Sig.Mask.Tensor as Torch.FFI.TH.Byte.Tensor, Torch.Sig.Mask.TensorFree as Torch.FFI.TH.Byte.FreeTensor, Torch.Sig.Mask.MathReduce as Torch.FFI.TH.Byte.TensorMath, Torch.Sig.State as Torch.Types.TH, Torch.Sig.Types.Global as Torch.Types.TH, Torch.Sig.Types as Torch.Types.TH.Float, Torch.Sig.Storage as Torch.FFI.TH.Float.Storage, Torch.Sig.Storage.Copy as Torch.FFI.TH.Float.StorageCopy, Torch.Sig.Storage.Memory as Torch.FFI.TH.Float.FreeStorage, Torch.Sig.Tensor as Torch.FFI.TH.Float.Tensor, Torch.Sig.Tensor.Copy as Torch.FFI.TH.Float.TensorCopy, Torch.Sig.Tensor.Memory as Torch.FFI.TH.Float.FreeTensor, Torch.Sig.Tensor.Index as Torch.FFI.TH.Float.TensorMath, Torch.Sig.Tensor.Masked as Torch.FFI.TH.Float.TensorMath, Torch.Sig.Tensor.Math as Torch.FFI.TH.Float.TensorMath, Torch.Sig.Tensor.Math.Compare as Torch.FFI.TH.Float.TensorMath, Torch.Sig.Tensor.Math.CompareT as Torch.FFI.TH.Float.TensorMath, Torch.Sig.Tensor.Math.Pairwise as Torch.FFI.TH.Float.TensorMath, Torch.Sig.Tensor.Math.Pointwise as Torch.FFI.TH.Float.TensorMath, Torch.Sig.Tensor.Math.Reduce as Torch.FFI.TH.Float.TensorMath, Torch.Sig.Tensor.Math.Scan as Torch.FFI.TH.Float.TensorMath, Torch.Sig.Tensor.Mode as Torch.FFI.TH.Float.TensorMath, Torch.Sig.Tensor.ScatterGather as Torch.FFI.TH.Float.TensorMath, Torch.Sig.Tensor.Sort as Torch.FFI.TH.Float.TensorMath, Torch.Sig.Tensor.TopK as Torch.FFI.TH.Float.TensorMath, Torch.Sig.Tensor.Math.Pointwise.Signed as Torch.FFI.TH.Float.TensorMath, Torch.Sig.Tensor.Math.Pointwise.Floating as Torch.FFI.TH.Float.TensorMath, Torch.Sig.Tensor.Math.Reduce.Floating as Torch.FFI.TH.Float.TensorMath, Torch.Sig.Tensor.Math.Floating as Torch.FFI.TH.Float.TensorMath, Torch.Sig.Tensor.Math.Blas as Torch.FFI.TH.Float.TensorMath, Torch.Sig.Tensor.Math.Lapack as Torch.FFI.TH.Float.TensorLapack, Torch.Sig.NN as Torch.FFI.TH.NN.Float, Torch.Sig.Types.NN as Torch.Types.TH, Torch.Sig.Tensor.Math.Random.TH as Torch.FFI.TH.Float.TensorMath, Torch.Sig.Tensor.Random.TH as Torch.FFI.TH.Float.TensorRandom, Torch.Sig.Tensor.Random.THC as Torch.Undefined.Float.Tensor.Random.THC)+test-suite spec+  type:               exitcode-stdio-1.0+  hs-source-dirs:     test+  main-is:            Spec.hs+  other-modules:      FactorySpec+                    , FunctionalSpec+                    , GradSpec+                    , InitializerSpec+                    , LensSpec+                    , OptimSpec+                    , SparseSpec+                    , ScriptSpec+                    , TensorSpec+                    , NNSpec+                    , DimnameSpec+                    , PipelineSpec+                    , Torch.Typed.AuxiliarySpec+                    , Torch.Typed.TensorSpec0+                    , Torch.Typed.TensorSpec1+                    , Torch.Typed.FactoriesSpec+                    , Torch.Typed.FunctionalSpec0+                    , Torch.Typed.FunctionalSpec1+                    , Torch.Typed.FunctionalSpec2+                    , Torch.Typed.AutogradSpec+                    , Torch.Typed.OptimSpec+                    , Torch.Typed.NNSpec+                    , Torch.Typed.NN.Recurrent.LSTMSpec+                    , Torch.Typed.NN.Recurrent.GRUSpec+                    , Torch.Typed.NN.Recurrent.Cell.LSTMSpec+                    , Torch.Typed.NN.Recurrent.Cell.GRUSpec+                    , Torch.Typed.NN.TransformerSpec+                    , Torch.Typed.VisionSpec+                    , Torch.Typed.NamedTensorSpec+                    , Torch.Typed.SerializeSpec+                    , SerializeSpec+                    , RandomSpec+                    , VisionSpec+                    , Torch.Distributions.ConstraintsSpec+                    , Torch.Distributions.BernoulliSpec+                    , Torch.Distributions.CategoricalSpec+                    , IndexSpec+  default-language: Haskell2010+  ghc-options:         -fplugin GHC.TypeLits.Normalise -fplugin GHC.TypeLits.KnownNat.Solver -fplugin GHC.TypeLits.Extra.Solver -fconstraint-solver-iterations=0+  if os(darwin)+   cpp-options:       -D__APPLE__+  build-depends:      base+                    , ghc-typelits-extra+                    , ghc-typelits-knownnat+                    , ghc-typelits-natnormalise+                    , hasktorch+                    , hspec+                    , libtorch-ffi+                    , mtl+                    , reflection+                    , safe-exceptions+                    , QuickCheck+                    , directory+                    , JuicyPixels+                    , inline-c-cpp+                    , async+                    , pipes+                    , random+                    , vector-sized+                    , lens-family-core+                    , data-default-class+                    , half+                    , vector -library hasktorch-gpu-    exposed-modules:-        Torch.Cuda.Long-        Torch.Cuda.Long.Dynamic-        Torch.Cuda.Long.Storage-        Torch.Cuda.Double-        Torch.Cuda.Double.Dynamic-        Torch.Cuda.Double.Storage-    reexported-modules: Torch.Cuda.Double.NN,-                        Torch.Cuda.Double.NN.Activation,-                        Torch.Cuda.Double.NN.Backprop,-                        Torch.Cuda.Double.NN.Conv1d,-                        Torch.Cuda.Double.NN.Conv2d,-                        Torch.Cuda.Double.NN.Criterion,-                        Torch.Cuda.Double.NN.Layers,-                        Torch.Cuda.Double.NN.Linear,-                        Torch.Cuda.Double.NN.Math,-                        Torch.Cuda.Double.NN.Padding,-                        Torch.Cuda.Double.NN.Pooling,-                        Torch.Cuda.Double.NN.Sampling,-                        Torch.Cuda.Double.Dynamic.NN,-                        Torch.Cuda.Double.Dynamic.NN.Activation,-                        Torch.Cuda.Double.Dynamic.NN.Pooling,-                        Torch.Cuda.Double.Dynamic.NN.Criterion-    cpp-options: -DCUDA -DHASKTORCH_INTERNAL_CUDA-    hs-source-dirs: utils src-    other-modules:-        Torch.Core.Exceptions-        Torch.Core.Random-        Torch.Core.LogAdd-    default-language: Haskell2010-    default-extensions: LambdaCase DataKinds TypeFamilies-                        TypeSynonymInstances ScopedTypeVariables FlexibleContexts CPP-    build-depends:-        base (==4.7 || >4.7) && <5,-        hasktorch-types-th (==0.0.1 || >0.0.1) && <0.0.2,-        -- containers ==0.5.10 || >0.5.10,-        -- deepseq ==1.3.0 || >1.3.0,-        dimensions ==1.0 || >1.0,-        hasktorch-ffi-th (==0.0.1 || >0.0.1) && <0.0.2,-        hasktorch-types-th (==0.0.1 || >0.0.1) && <0.0.2,-        -- managed (==1.0.0 || >1.0.0) && <1.1,-        -- microlens ==0.4.8 || >0.4.8,-        -- numeric-limits ==0.1.0 || >0.1.0,-        safe-exceptions ==0.1.0 || >0.1.0,-        singletons ==2.2 || >2.2,-        text ==1.2.2 || >1.2.2,-        -- typelits-witnesses ==0.2.3 || >0.2.3,-        hasktorch-indef-floating -any,-        hasktorch-indef-signed -any,-        hasktorch-ffi-thc (==0.0.1 || >0.0.1) && <0.0.2,-        hasktorch-types-thc (==0.0.1 || >0.0.1) && <0.0.2-    mixins: hasktorch-indef-signed (Torch.Indef.Storage as Torch.Indef.Cuda.Long.Storage, Torch.Indef.Storage.Copy as Torch.Indef.Cuda.Long.Storage.Copy, Torch.Indef.Static.Tensor as Torch.Indef.Cuda.Long.Tensor, Torch.Indef.Static.Tensor.Copy as Torch.Indef.Cuda.Long.Tensor.Copy, Torch.Indef.Static.Tensor.Index as Torch.Indef.Cuda.Long.Tensor.Index, Torch.Indef.Static.Tensor.Masked as Torch.Indef.Cuda.Long.Tensor.Masked, Torch.Indef.Static.Tensor.Math as Torch.Indef.Cuda.Long.Tensor.Math, Torch.Indef.Static.Tensor.Math.Compare as Torch.Indef.Cuda.Long.Tensor.Math.Compare, Torch.Indef.Static.Tensor.Math.CompareT as Torch.Indef.Cuda.Long.Tensor.Math.CompareT, Torch.Indef.Static.Tensor.Math.Pairwise as Torch.Indef.Cuda.Long.Tensor.Math.Pairwise, Torch.Indef.Static.Tensor.Math.Pointwise as Torch.Indef.Cuda.Long.Tensor.Math.Pointwise, Torch.Indef.Static.Tensor.Math.Reduce as Torch.Indef.Cuda.Long.Tensor.Math.Reduce, Torch.Indef.Static.Tensor.Math.Scan as Torch.Indef.Cuda.Long.Tensor.Math.Scan, Torch.Indef.Static.Tensor.Mode as Torch.Indef.Cuda.Long.Tensor.Mode, Torch.Indef.Static.Tensor.ScatterGather as Torch.Indef.Cuda.Long.Tensor.ScatterGather, Torch.Indef.Static.Tensor.Sort as Torch.Indef.Cuda.Long.Tensor.Sort, Torch.Indef.Static.Tensor.TopK as Torch.Indef.Cuda.Long.Tensor.TopK, Torch.Indef.Dynamic.Tensor as Torch.Indef.Cuda.Long.Dynamic.Tensor, Torch.Indef.Dynamic.Tensor.Copy as Torch.Indef.Cuda.Long.Dynamic.Tensor.Copy, Torch.Indef.Dynamic.Tensor.Index as Torch.Indef.Cuda.Long.Dynamic.Tensor.Index, Torch.Indef.Dynamic.Tensor.Masked as Torch.Indef.Cuda.Long.Dynamic.Tensor.Masked, Torch.Indef.Dynamic.Tensor.Math as Torch.Indef.Cuda.Long.Dynamic.Tensor.Math, Torch.Indef.Dynamic.Tensor.Math.Compare as Torch.Indef.Cuda.Long.Dynamic.Tensor.Math.Compare, Torch.Indef.Dynamic.Tensor.Math.CompareT as Torch.Indef.Cuda.Long.Dynamic.Tensor.Math.CompareT, Torch.Indef.Dynamic.Tensor.Math.Pairwise as Torch.Indef.Cuda.Long.Dynamic.Tensor.Math.Pairwise, Torch.Indef.Dynamic.Tensor.Math.Pointwise as Torch.Indef.Cuda.Long.Dynamic.Tensor.Math.Pointwise, Torch.Indef.Dynamic.Tensor.Math.Reduce as Torch.Indef.Cuda.Long.Dynamic.Tensor.Math.Reduce, Torch.Indef.Dynamic.Tensor.Math.Scan as Torch.Indef.Cuda.Long.Dynamic.Tensor.Math.Scan, Torch.Indef.Dynamic.Tensor.Mode as Torch.Indef.Cuda.Long.Dynamic.Tensor.Mode, Torch.Indef.Dynamic.Tensor.ScatterGather as Torch.Indef.Cuda.Long.Dynamic.Tensor.ScatterGather, Torch.Indef.Dynamic.Tensor.Sort as Torch.Indef.Cuda.Long.Dynamic.Tensor.Sort, Torch.Indef.Dynamic.Tensor.TopK as Torch.Indef.Cuda.Long.Dynamic.Tensor.TopK, Torch.Indef.Types as Torch.Cuda.Long.Types, Torch.Indef.Index as Torch.Cuda.Long.Index, Torch.Indef.Mask as Torch.Cuda.Long.Mask, Torch.Indef.Static.Tensor.Math.Pointwise.Signed as Torch.Indef.Cuda.Long.Tensor.Math.Pointwise.Signed, Torch.Indef.Dynamic.Tensor.Math.Pointwise.Signed as Torch.Indef.Cuda.Long.Dynamic.Tensor.Math.Pointwise.Signed) requires (Torch.Sig.Index.Tensor as Torch.FFI.THC.Long.Tensor, Torch.Sig.Index.TensorFree as Torch.FFI.THC.Long.Tensor, Torch.Sig.Mask.Tensor as Torch.FFI.THC.Byte.Tensor, Torch.Sig.Mask.TensorFree as Torch.FFI.THC.Byte.Tensor, Torch.Sig.Mask.MathReduce as Torch.FFI.THC.Byte.TensorMathReduce, Torch.Sig.State as Torch.FFI.THC.State, Torch.Sig.Types.Global as Torch.Types.THC, Torch.Sig.Types as Torch.Types.THC.Long, Torch.Sig.Storage as Torch.FFI.THC.Long.Storage, Torch.Sig.Storage.Copy as Torch.FFI.THC.Long.StorageCopy, Torch.Sig.Storage.Memory as Torch.FFI.THC.Long.Storage, Torch.Sig.Tensor as Torch.FFI.THC.Long.Tensor, Torch.Sig.Tensor.Copy as Torch.FFI.THC.Long.TensorCopy, Torch.Sig.Tensor.Memory as Torch.FFI.THC.Long.Tensor, Torch.Sig.Tensor.Index as Torch.FFI.THC.Long.TensorIndex, Torch.Sig.Tensor.Masked as Torch.FFI.THC.Long.TensorMasked, Torch.Sig.Tensor.Math as Torch.FFI.THC.Long.TensorMath, Torch.Sig.Tensor.Math.Compare as Torch.FFI.THC.Long.TensorMathCompare, Torch.Sig.Tensor.Math.CompareT as Torch.FFI.THC.Long.TensorMathCompareT, Torch.Sig.Tensor.Math.Pairwise as Torch.FFI.THC.Long.TensorMathPairwise, Torch.Sig.Tensor.Math.Pointwise as Torch.FFI.THC.Long.TensorMathPointwise, Torch.Sig.Tensor.Math.Reduce as Torch.FFI.THC.Long.TensorMathReduce, Torch.Sig.Tensor.Math.Scan as Torch.FFI.THC.Long.TensorMathScan, Torch.Sig.Tensor.Mode as Torch.FFI.THC.Long.TensorMode, Torch.Sig.Tensor.ScatterGather as Torch.FFI.THC.Long.TensorScatterGather, Torch.Sig.Tensor.Sort as Torch.FFI.THC.Long.TensorSort, Torch.Sig.Tensor.TopK as Torch.FFI.THC.Long.TensorTopK, Torch.Sig.Tensor.Math.Pointwise.Signed as Torch.FFI.THC.Long.TensorMathPointwise),-            hasktorch-indef-floating (Torch.Indef.Storage as Torch.Indef.Cuda.Double.Storage, Torch.Indef.Storage.Copy as Torch.Indef.Cuda.Double.Storage.Copy, Torch.Indef.Static.Tensor as Torch.Indef.Cuda.Double.Tensor, Torch.Indef.Static.Tensor.Copy as Torch.Indef.Cuda.Double.Tensor.Copy, Torch.Indef.Static.Tensor.Index as Torch.Indef.Cuda.Double.Tensor.Index, Torch.Indef.Static.Tensor.Masked as Torch.Indef.Cuda.Double.Tensor.Masked, Torch.Indef.Static.Tensor.Math as Torch.Indef.Cuda.Double.Tensor.Math, Torch.Indef.Static.Tensor.Math.Compare as Torch.Indef.Cuda.Double.Tensor.Math.Compare, Torch.Indef.Static.Tensor.Math.CompareT as Torch.Indef.Cuda.Double.Tensor.Math.CompareT, Torch.Indef.Static.Tensor.Math.Pairwise as Torch.Indef.Cuda.Double.Tensor.Math.Pairwise, Torch.Indef.Static.Tensor.Math.Pointwise as Torch.Indef.Cuda.Double.Tensor.Math.Pointwise, Torch.Indef.Static.Tensor.Math.Reduce as Torch.Indef.Cuda.Double.Tensor.Math.Reduce, Torch.Indef.Static.Tensor.Math.Scan as Torch.Indef.Cuda.Double.Tensor.Math.Scan, Torch.Indef.Static.Tensor.Mode as Torch.Indef.Cuda.Double.Tensor.Mode, Torch.Indef.Static.Tensor.ScatterGather as Torch.Indef.Cuda.Double.Tensor.ScatterGather, Torch.Indef.Static.Tensor.Sort as Torch.Indef.Cuda.Double.Tensor.Sort, Torch.Indef.Static.Tensor.TopK as Torch.Indef.Cuda.Double.Tensor.TopK, Torch.Indef.Dynamic.Tensor as Torch.Indef.Cuda.Double.Dynamic.Tensor, Torch.Indef.Dynamic.Tensor.Copy as Torch.Indef.Cuda.Double.Dynamic.Tensor.Copy, Torch.Indef.Dynamic.Tensor.Index as Torch.Indef.Cuda.Double.Dynamic.Tensor.Index, Torch.Indef.Dynamic.Tensor.Masked as Torch.Indef.Cuda.Double.Dynamic.Tensor.Masked, Torch.Indef.Dynamic.Tensor.Math as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math, Torch.Indef.Dynamic.Tensor.Math.Compare as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Compare, Torch.Indef.Dynamic.Tensor.Math.CompareT as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.CompareT, Torch.Indef.Dynamic.Tensor.Math.Pairwise as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Pairwise, Torch.Indef.Dynamic.Tensor.Math.Pointwise as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Pointwise, Torch.Indef.Dynamic.Tensor.Math.Reduce as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Reduce, Torch.Indef.Dynamic.Tensor.Math.Scan as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Scan, Torch.Indef.Dynamic.Tensor.Mode as Torch.Indef.Cuda.Double.Dynamic.Tensor.Mode, Torch.Indef.Dynamic.Tensor.ScatterGather as Torch.Indef.Cuda.Double.Dynamic.Tensor.ScatterGather, Torch.Indef.Dynamic.Tensor.Sort as Torch.Indef.Cuda.Double.Dynamic.Tensor.Sort, Torch.Indef.Dynamic.Tensor.TopK as Torch.Indef.Cuda.Double.Dynamic.Tensor.TopK, Torch.Indef.Types as Torch.Cuda.Double.Types, Torch.Indef.Index as Torch.Cuda.Double.Index, Torch.Indef.Mask as Torch.Cuda.Double.Mask, Torch.Indef.Static.Tensor.Math.Pointwise.Signed as Torch.Indef.Cuda.Double.Tensor.Math.Pointwise.Signed, Torch.Indef.Dynamic.Tensor.Math.Pointwise.Signed as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Pointwise.Signed, Torch.Indef.Dynamic.Tensor.Math.Blas as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Blas, Torch.Indef.Dynamic.Tensor.Math.Lapack as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Lapack, Torch.Indef.Dynamic.Tensor.Math.Pointwise.Floating as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Pointwise.Floating, Torch.Indef.Dynamic.Tensor.Math.Reduce.Floating as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Reduce.Floating, Torch.Indef.Dynamic.Tensor.Math.Floating as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Floating, Torch.Indef.Static.Tensor.Math.Blas as Torch.Indef.Cuda.Double.Tensor.Math.Blas, Torch.Indef.Static.Tensor.Math.Lapack as Torch.Indef.Cuda.Double.Tensor.Math.Lapack, Torch.Indef.Static.Tensor.Math.Pointwise.Floating as Torch.Indef.Cuda.Double.Tensor.Math.Pointwise.Floating, Torch.Indef.Static.Tensor.Math.Reduce.Floating as Torch.Indef.Cuda.Double.Tensor.Math.Reduce.Floating, Torch.Indef.Static.Tensor.Math.Floating as Torch.Indef.Cuda.Double.Tensor.Math.Floating, Torch.Undefined.Tensor.Random.TH as Torch.Undefined.Cuda.Double.Tensor.Random.TH, Torch.Undefined.Tensor.Math.Random.TH as Torch.Undefined.Cuda.Double.Tensor.Math.Random.TH, Torch.Indef.Static.Tensor.Random.THC as Torch.Indef.Cuda.Double.Tensor.Random.THC, Torch.Indef.Dynamic.Tensor.Random.THC as Torch.Indef.Cuda.Double.Dynamic.Tensor.Random.THC, Torch.Indef.Storage as Torch.Indef.Cuda.Double.Storage, Torch.Indef.Storage.Copy as Torch.Indef.Cuda.Double.Storage.Copy, Torch.Indef.Static.Tensor as Torch.Indef.Cuda.Double.Tensor, Torch.Indef.Static.Tensor.Copy as Torch.Indef.Cuda.Double.Tensor.Copy, Torch.Indef.Static.Tensor.Index as Torch.Indef.Cuda.Double.Tensor.Index, Torch.Indef.Static.Tensor.Masked as Torch.Indef.Cuda.Double.Tensor.Masked, Torch.Indef.Static.Tensor.Math as Torch.Indef.Cuda.Double.Tensor.Math, Torch.Indef.Static.Tensor.Math.Compare as Torch.Indef.Cuda.Double.Tensor.Math.Compare, Torch.Indef.Static.Tensor.Math.CompareT as Torch.Indef.Cuda.Double.Tensor.Math.CompareT, Torch.Indef.Static.Tensor.Math.Pairwise as Torch.Indef.Cuda.Double.Tensor.Math.Pairwise, Torch.Indef.Static.Tensor.Math.Pointwise as Torch.Indef.Cuda.Double.Tensor.Math.Pointwise, Torch.Indef.Static.Tensor.Math.Reduce as Torch.Indef.Cuda.Double.Tensor.Math.Reduce, Torch.Indef.Static.Tensor.Math.Scan as Torch.Indef.Cuda.Double.Tensor.Math.Scan, Torch.Indef.Static.Tensor.Mode as Torch.Indef.Cuda.Double.Tensor.Mode, Torch.Indef.Static.Tensor.ScatterGather as Torch.Indef.Cuda.Double.Tensor.ScatterGather, Torch.Indef.Static.Tensor.Sort as Torch.Indef.Cuda.Double.Tensor.Sort, Torch.Indef.Static.Tensor.TopK as Torch.Indef.Cuda.Double.Tensor.TopK, Torch.Indef.Dynamic.Tensor as Torch.Indef.Cuda.Double.Dynamic.Tensor, Torch.Indef.Dynamic.Tensor.Copy as Torch.Indef.Cuda.Double.Dynamic.Tensor.Copy, Torch.Indef.Dynamic.Tensor.Index as Torch.Indef.Cuda.Double.Dynamic.Tensor.Index, Torch.Indef.Dynamic.Tensor.Masked as Torch.Indef.Cuda.Double.Dynamic.Tensor.Masked, Torch.Indef.Dynamic.Tensor.Math as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math, Torch.Indef.Dynamic.Tensor.Math.Compare as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Compare, Torch.Indef.Dynamic.Tensor.Math.CompareT as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.CompareT, Torch.Indef.Dynamic.Tensor.Math.Pairwise as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Pairwise, Torch.Indef.Dynamic.Tensor.Math.Pointwise as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Pointwise, Torch.Indef.Dynamic.Tensor.Math.Reduce as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Reduce, Torch.Indef.Dynamic.Tensor.Math.Scan as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Scan, Torch.Indef.Dynamic.Tensor.Mode as Torch.Indef.Cuda.Double.Dynamic.Tensor.Mode, Torch.Indef.Dynamic.Tensor.ScatterGather as Torch.Indef.Cuda.Double.Dynamic.Tensor.ScatterGather, Torch.Indef.Dynamic.Tensor.Sort as Torch.Indef.Cuda.Double.Dynamic.Tensor.Sort, Torch.Indef.Dynamic.Tensor.TopK as Torch.Indef.Cuda.Double.Dynamic.Tensor.TopK, Torch.Indef.Types as Torch.Cuda.Double.Types, Torch.Indef.Index as Torch.Cuda.Double.Index, Torch.Indef.Mask as Torch.Cuda.Double.Mask, Torch.Indef.Static.Tensor.Math.Pointwise.Signed as Torch.Indef.Cuda.Double.Tensor.Math.Pointwise.Signed, Torch.Indef.Dynamic.Tensor.Math.Pointwise.Signed as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Pointwise.Signed, Torch.Indef.Dynamic.NN as Torch.Cuda.Double.Dynamic.NN, Torch.Indef.Dynamic.NN.Activation as Torch.Cuda.Double.Dynamic.NN.Activation, Torch.Indef.Dynamic.NN.Pooling as Torch.Cuda.Double.Dynamic.NN.Pooling, Torch.Indef.Dynamic.NN.Criterion as Torch.Cuda.Double.Dynamic.NN.Criterion, Torch.Indef.Static.NN as Torch.Cuda.Double.NN, Torch.Indef.Static.NN as Torch.Cuda.Double.NN, Torch.Indef.Static.NN.Activation as Torch.Cuda.Double.NN.Activation, Torch.Indef.Static.NN.Backprop as Torch.Cuda.Double.NN.Backprop, Torch.Indef.Static.NN.Conv1d as Torch.Cuda.Double.NN.Conv1d, Torch.Indef.Static.NN.Conv2d as Torch.Cuda.Double.NN.Conv2d, Torch.Indef.Static.NN.Criterion as Torch.Cuda.Double.NN.Criterion, Torch.Indef.Static.NN.Layers as Torch.Cuda.Double.NN.Layers, Torch.Indef.Static.NN.Linear as Torch.Cuda.Double.NN.Linear, Torch.Indef.Static.NN.Math as Torch.Cuda.Double.NN.Math, Torch.Indef.Static.NN.Padding as Torch.Cuda.Double.NN.Padding, Torch.Indef.Static.NN.Pooling as Torch.Cuda.Double.NN.Pooling, Torch.Indef.Static.NN.Sampling as Torch.Cuda.Double.NN.Sampling) requires (Torch.Sig.Index.Tensor as Torch.FFI.THC.Long.Tensor, Torch.Sig.Index.TensorFree as Torch.FFI.THC.Long.Tensor, Torch.Sig.Mask.Tensor as Torch.FFI.THC.Byte.Tensor, Torch.Sig.Mask.TensorFree as Torch.FFI.THC.Byte.Tensor, Torch.Sig.Mask.MathReduce as Torch.FFI.THC.Byte.TensorMathReduce, Torch.Sig.State as Torch.FFI.THC.State, Torch.Sig.Types.Global as Torch.Types.THC, Torch.Sig.Types as Torch.Types.THC.Double, Torch.Sig.Storage as Torch.FFI.THC.Double.Storage, Torch.Sig.Storage.Copy as Torch.FFI.THC.Double.StorageCopy, Torch.Sig.Storage.Memory as Torch.FFI.THC.Double.Storage, Torch.Sig.Tensor as Torch.FFI.THC.Double.Tensor, Torch.Sig.Tensor.Copy as Torch.FFI.THC.Double.TensorCopy, Torch.Sig.Tensor.Memory as Torch.FFI.THC.Double.Tensor, Torch.Sig.Tensor.Index as Torch.FFI.THC.Double.TensorIndex, Torch.Sig.Tensor.Masked as Torch.FFI.THC.Double.TensorMasked, Torch.Sig.Tensor.Math as Torch.FFI.THC.Double.TensorMath, Torch.Sig.Tensor.Math.Compare as Torch.FFI.THC.Double.TensorMathCompare, Torch.Sig.Tensor.Math.CompareT as Torch.FFI.THC.Double.TensorMathCompareT, Torch.Sig.Tensor.Math.Pairwise as Torch.FFI.THC.Double.TensorMathPairwise, Torch.Sig.Tensor.Math.Pointwise as Torch.FFI.THC.Double.TensorMathPointwise, Torch.Sig.Tensor.Math.Reduce as Torch.FFI.THC.Double.TensorMathReduce, Torch.Sig.Tensor.Math.Scan as Torch.FFI.THC.Double.TensorMathScan, Torch.Sig.Tensor.Mode as Torch.FFI.THC.Double.TensorMode, Torch.Sig.Tensor.ScatterGather as Torch.FFI.THC.Double.TensorScatterGather, Torch.Sig.Tensor.Sort as Torch.FFI.THC.Double.TensorSort, Torch.Sig.Tensor.TopK as Torch.FFI.THC.Double.TensorTopK, Torch.Sig.Tensor.Math.Pointwise.Signed as Torch.FFI.THC.Double.TensorMathPointwise, Torch.Sig.Tensor.Math.Pointwise.Floating as Torch.FFI.THC.Double.TensorMathPointwise, Torch.Sig.Tensor.Math.Reduce.Floating as Torch.FFI.THC.Double.TensorMathReduce, Torch.Sig.Tensor.Math.Floating as Torch.FFI.THC.Double.TensorMath, Torch.Sig.Tensor.Math.Blas as Torch.FFI.THC.Double.TensorMathBlas, Torch.Sig.Tensor.Math.Lapack as Torch.FFI.THC.Double.TensorMathMagma, Torch.Sig.NN as Torch.FFI.THC.NN.Double, Torch.Sig.Types.NN as Torch.Types.THC, Torch.Sig.Tensor.Math.Random.TH as Torch.Undefined.Cuda.Double.Tensor.Math.Random.TH, Torch.Sig.Tensor.Random.TH as Torch.Undefined.Cuda.Double.Tensor.Random.TH, Torch.Sig.Tensor.Random.THC as Torch.FFI.THC.Double.TensorRandom)-    -    if flag(lite)-    else-        exposed-modules:-            Torch.Cuda.Byte-            Torch.Cuda.Byte.Dynamic-            Torch.Cuda.Byte.Storage-            Torch.Cuda.Char-            Torch.Cuda.Char.Dynamic-            Torch.Cuda.Char.Storage-            Torch.Cuda.Short-            Torch.Cuda.Short.Dynamic-            Torch.Cuda.Short.Storage-            Torch.Cuda.Int-            Torch.Cuda.Int.Dynamic-            Torch.Cuda.Int.Storage-        build-depends:-            hasktorch-indef-unsigned -any-        mixins: hasktorch-indef-unsigned (Torch.Indef.Storage as Torch.Indef.Cuda.Byte.Storage, Torch.Indef.Storage.Copy as Torch.Indef.Cuda.Byte.Storage.Copy, Torch.Indef.Static.Tensor as Torch.Indef.Cuda.Byte.Tensor, Torch.Indef.Static.Tensor.Copy as Torch.Indef.Cuda.Byte.Tensor.Copy, Torch.Indef.Static.Tensor.Index as Torch.Indef.Cuda.Byte.Tensor.Index, Torch.Indef.Static.Tensor.Masked as Torch.Indef.Cuda.Byte.Tensor.Masked, Torch.Indef.Static.Tensor.Math as Torch.Indef.Cuda.Byte.Tensor.Math, Torch.Indef.Static.Tensor.Math.Compare as Torch.Indef.Cuda.Byte.Tensor.Math.Compare, Torch.Indef.Static.Tensor.Math.CompareT as Torch.Indef.Cuda.Byte.Tensor.Math.CompareT, Torch.Indef.Static.Tensor.Math.Pairwise as Torch.Indef.Cuda.Byte.Tensor.Math.Pairwise, Torch.Indef.Static.Tensor.Math.Pointwise as Torch.Indef.Cuda.Byte.Tensor.Math.Pointwise, Torch.Indef.Static.Tensor.Math.Reduce as Torch.Indef.Cuda.Byte.Tensor.Math.Reduce, Torch.Indef.Static.Tensor.Math.Scan as Torch.Indef.Cuda.Byte.Tensor.Math.Scan, Torch.Indef.Static.Tensor.Mode as Torch.Indef.Cuda.Byte.Tensor.Mode, Torch.Indef.Static.Tensor.ScatterGather as Torch.Indef.Cuda.Byte.Tensor.ScatterGather, Torch.Indef.Static.Tensor.Sort as Torch.Indef.Cuda.Byte.Tensor.Sort, Torch.Indef.Static.Tensor.TopK as Torch.Indef.Cuda.Byte.Tensor.TopK, Torch.Indef.Dynamic.Tensor as Torch.Indef.Cuda.Byte.Dynamic.Tensor, Torch.Indef.Dynamic.Tensor.Copy as Torch.Indef.Cuda.Byte.Dynamic.Tensor.Copy, Torch.Indef.Dynamic.Tensor.Index as Torch.Indef.Cuda.Byte.Dynamic.Tensor.Index, Torch.Indef.Dynamic.Tensor.Masked as Torch.Indef.Cuda.Byte.Dynamic.Tensor.Masked, Torch.Indef.Dynamic.Tensor.Math as Torch.Indef.Cuda.Byte.Dynamic.Tensor.Math, Torch.Indef.Dynamic.Tensor.Math.Compare as Torch.Indef.Cuda.Byte.Dynamic.Tensor.Math.Compare, Torch.Indef.Dynamic.Tensor.Math.CompareT as Torch.Indef.Cuda.Byte.Dynamic.Tensor.Math.CompareT, Torch.Indef.Dynamic.Tensor.Math.Pairwise as Torch.Indef.Cuda.Byte.Dynamic.Tensor.Math.Pairwise, Torch.Indef.Dynamic.Tensor.Math.Pointwise as Torch.Indef.Cuda.Byte.Dynamic.Tensor.Math.Pointwise, Torch.Indef.Dynamic.Tensor.Math.Reduce as Torch.Indef.Cuda.Byte.Dynamic.Tensor.Math.Reduce, Torch.Indef.Dynamic.Tensor.Math.Scan as Torch.Indef.Cuda.Byte.Dynamic.Tensor.Math.Scan, Torch.Indef.Dynamic.Tensor.Mode as Torch.Indef.Cuda.Byte.Dynamic.Tensor.Mode, Torch.Indef.Dynamic.Tensor.ScatterGather as Torch.Indef.Cuda.Byte.Dynamic.Tensor.ScatterGather, Torch.Indef.Dynamic.Tensor.Sort as Torch.Indef.Cuda.Byte.Dynamic.Tensor.Sort, Torch.Indef.Dynamic.Tensor.TopK as Torch.Indef.Cuda.Byte.Dynamic.Tensor.TopK, Torch.Indef.Types as Torch.Cuda.Byte.Types, Torch.Indef.Index as Torch.Cuda.Byte.Index, Torch.Indef.Mask as Torch.Cuda.Byte.Mask) requires (Torch.Sig.Index.Tensor as Torch.FFI.THC.Long.Tensor, Torch.Sig.Index.TensorFree as Torch.FFI.THC.Long.Tensor, Torch.Sig.Mask.Tensor as Torch.FFI.THC.Byte.Tensor, Torch.Sig.Mask.TensorFree as Torch.FFI.THC.Byte.Tensor, Torch.Sig.Mask.MathReduce as Torch.FFI.THC.Byte.TensorMathReduce, Torch.Sig.State as Torch.FFI.THC.State, Torch.Sig.Types.Global as Torch.Types.THC, Torch.Sig.Types as Torch.Types.THC.Byte, Torch.Sig.Storage as Torch.FFI.THC.Byte.Storage, Torch.Sig.Storage.Copy as Torch.FFI.THC.Byte.StorageCopy, Torch.Sig.Storage.Memory as Torch.FFI.THC.Byte.Storage, Torch.Sig.Tensor as Torch.FFI.THC.Byte.Tensor, Torch.Sig.Tensor.Copy as Torch.FFI.THC.Byte.TensorCopy, Torch.Sig.Tensor.Memory as Torch.FFI.THC.Byte.Tensor, Torch.Sig.Tensor.Index as Torch.FFI.THC.Byte.TensorIndex, Torch.Sig.Tensor.Masked as Torch.FFI.THC.Byte.TensorMasked, Torch.Sig.Tensor.Math as Torch.FFI.THC.Byte.TensorMath, Torch.Sig.Tensor.Math.Compare as Torch.FFI.THC.Byte.TensorMathCompare, Torch.Sig.Tensor.Math.CompareT as Torch.FFI.THC.Byte.TensorMathCompareT, Torch.Sig.Tensor.Math.Pairwise as Torch.FFI.THC.Byte.TensorMathPairwise, Torch.Sig.Tensor.Math.Pointwise as Torch.FFI.THC.Byte.TensorMathPointwise, Torch.Sig.Tensor.Math.Reduce as Torch.FFI.THC.Byte.TensorMathReduce, Torch.Sig.Tensor.Math.Scan as Torch.FFI.THC.Byte.TensorMathScan, Torch.Sig.Tensor.Mode as Torch.FFI.THC.Byte.TensorMode, Torch.Sig.Tensor.ScatterGather as Torch.FFI.THC.Byte.TensorScatterGather, Torch.Sig.Tensor.Sort as Torch.FFI.THC.Byte.TensorSort, Torch.Sig.Tensor.TopK as Torch.FFI.THC.Byte.TensorTopK),-                hasktorch-indef-unsigned (Torch.Indef.Storage as Torch.Indef.Cuda.Char.Storage, Torch.Indef.Storage.Copy as Torch.Indef.Cuda.Char.Storage.Copy, Torch.Indef.Static.Tensor as Torch.Indef.Cuda.Char.Tensor, Torch.Indef.Static.Tensor.Copy as Torch.Indef.Cuda.Char.Tensor.Copy, Torch.Indef.Static.Tensor.Index as Torch.Indef.Cuda.Char.Tensor.Index, Torch.Indef.Static.Tensor.Masked as Torch.Indef.Cuda.Char.Tensor.Masked, Torch.Indef.Static.Tensor.Math as Torch.Indef.Cuda.Char.Tensor.Math, Torch.Indef.Static.Tensor.Math.Compare as Torch.Indef.Cuda.Char.Tensor.Math.Compare, Torch.Indef.Static.Tensor.Math.CompareT as Torch.Indef.Cuda.Char.Tensor.Math.CompareT, Torch.Indef.Static.Tensor.Math.Pairwise as Torch.Indef.Cuda.Char.Tensor.Math.Pairwise, Torch.Indef.Static.Tensor.Math.Pointwise as Torch.Indef.Cuda.Char.Tensor.Math.Pointwise, Torch.Indef.Static.Tensor.Math.Reduce as Torch.Indef.Cuda.Char.Tensor.Math.Reduce, Torch.Indef.Static.Tensor.Math.Scan as Torch.Indef.Cuda.Char.Tensor.Math.Scan, Torch.Indef.Static.Tensor.Mode as Torch.Indef.Cuda.Char.Tensor.Mode, Torch.Indef.Static.Tensor.ScatterGather as Torch.Indef.Cuda.Char.Tensor.ScatterGather, Torch.Indef.Static.Tensor.Sort as Torch.Indef.Cuda.Char.Tensor.Sort, Torch.Indef.Static.Tensor.TopK as Torch.Indef.Cuda.Char.Tensor.TopK, Torch.Indef.Dynamic.Tensor as Torch.Indef.Cuda.Char.Dynamic.Tensor, Torch.Indef.Dynamic.Tensor.Copy as Torch.Indef.Cuda.Char.Dynamic.Tensor.Copy, Torch.Indef.Dynamic.Tensor.Index as Torch.Indef.Cuda.Char.Dynamic.Tensor.Index, Torch.Indef.Dynamic.Tensor.Masked as Torch.Indef.Cuda.Char.Dynamic.Tensor.Masked, Torch.Indef.Dynamic.Tensor.Math as Torch.Indef.Cuda.Char.Dynamic.Tensor.Math, Torch.Indef.Dynamic.Tensor.Math.Compare as Torch.Indef.Cuda.Char.Dynamic.Tensor.Math.Compare, Torch.Indef.Dynamic.Tensor.Math.CompareT as Torch.Indef.Cuda.Char.Dynamic.Tensor.Math.CompareT, Torch.Indef.Dynamic.Tensor.Math.Pairwise as Torch.Indef.Cuda.Char.Dynamic.Tensor.Math.Pairwise, Torch.Indef.Dynamic.Tensor.Math.Pointwise as Torch.Indef.Cuda.Char.Dynamic.Tensor.Math.Pointwise, Torch.Indef.Dynamic.Tensor.Math.Reduce as Torch.Indef.Cuda.Char.Dynamic.Tensor.Math.Reduce, Torch.Indef.Dynamic.Tensor.Math.Scan as Torch.Indef.Cuda.Char.Dynamic.Tensor.Math.Scan, Torch.Indef.Dynamic.Tensor.Mode as Torch.Indef.Cuda.Char.Dynamic.Tensor.Mode, Torch.Indef.Dynamic.Tensor.ScatterGather as Torch.Indef.Cuda.Char.Dynamic.Tensor.ScatterGather, Torch.Indef.Dynamic.Tensor.Sort as Torch.Indef.Cuda.Char.Dynamic.Tensor.Sort, Torch.Indef.Dynamic.Tensor.TopK as Torch.Indef.Cuda.Char.Dynamic.Tensor.TopK, Torch.Indef.Types as Torch.Cuda.Char.Types, Torch.Indef.Index as Torch.Cuda.Char.Index, Torch.Indef.Mask as Torch.Cuda.Char.Mask) requires (Torch.Sig.Index.Tensor as Torch.FFI.THC.Long.Tensor, Torch.Sig.Index.TensorFree as Torch.FFI.THC.Long.Tensor, Torch.Sig.Mask.Tensor as Torch.FFI.THC.Byte.Tensor, Torch.Sig.Mask.TensorFree as Torch.FFI.THC.Byte.Tensor, Torch.Sig.Mask.MathReduce as Torch.FFI.THC.Byte.TensorMathReduce, Torch.Sig.State as Torch.FFI.THC.State, Torch.Sig.Types.Global as Torch.Types.THC, Torch.Sig.Types as Torch.Types.THC.Char, Torch.Sig.Storage as Torch.FFI.THC.Char.Storage, Torch.Sig.Storage.Copy as Torch.FFI.THC.Char.StorageCopy, Torch.Sig.Storage.Memory as Torch.FFI.THC.Char.Storage, Torch.Sig.Tensor as Torch.FFI.THC.Char.Tensor, Torch.Sig.Tensor.Copy as Torch.FFI.THC.Char.TensorCopy, Torch.Sig.Tensor.Memory as Torch.FFI.THC.Char.Tensor, Torch.Sig.Tensor.Index as Torch.FFI.THC.Char.TensorIndex, Torch.Sig.Tensor.Masked as Torch.FFI.THC.Char.TensorMasked, Torch.Sig.Tensor.Math as Torch.FFI.THC.Char.TensorMath, Torch.Sig.Tensor.Math.Compare as Torch.FFI.THC.Char.TensorMathCompare, Torch.Sig.Tensor.Math.CompareT as Torch.FFI.THC.Char.TensorMathCompareT, Torch.Sig.Tensor.Math.Pairwise as Torch.FFI.THC.Char.TensorMathPairwise, Torch.Sig.Tensor.Math.Pointwise as Torch.FFI.THC.Char.TensorMathPointwise, Torch.Sig.Tensor.Math.Reduce as Torch.FFI.THC.Char.TensorMathReduce, Torch.Sig.Tensor.Math.Scan as Torch.FFI.THC.Char.TensorMathScan, Torch.Sig.Tensor.Mode as Torch.FFI.THC.Char.TensorMode, Torch.Sig.Tensor.ScatterGather as Torch.FFI.THC.Char.TensorScatterGather, Torch.Sig.Tensor.Sort as Torch.FFI.THC.Char.TensorSort, Torch.Sig.Tensor.TopK as Torch.FFI.THC.Char.TensorTopK),-                hasktorch-indef-signed (Torch.Indef.Storage as Torch.Indef.Cuda.Short.Storage, Torch.Indef.Storage.Copy as Torch.Indef.Cuda.Short.Storage.Copy, Torch.Indef.Static.Tensor as Torch.Indef.Cuda.Short.Tensor, Torch.Indef.Static.Tensor.Copy as Torch.Indef.Cuda.Short.Tensor.Copy, Torch.Indef.Static.Tensor.Index as Torch.Indef.Cuda.Short.Tensor.Index, Torch.Indef.Static.Tensor.Masked as Torch.Indef.Cuda.Short.Tensor.Masked, Torch.Indef.Static.Tensor.Math as Torch.Indef.Cuda.Short.Tensor.Math, Torch.Indef.Static.Tensor.Math.Compare as Torch.Indef.Cuda.Short.Tensor.Math.Compare, Torch.Indef.Static.Tensor.Math.CompareT as Torch.Indef.Cuda.Short.Tensor.Math.CompareT, Torch.Indef.Static.Tensor.Math.Pairwise as Torch.Indef.Cuda.Short.Tensor.Math.Pairwise, Torch.Indef.Static.Tensor.Math.Pointwise as Torch.Indef.Cuda.Short.Tensor.Math.Pointwise, Torch.Indef.Static.Tensor.Math.Reduce as Torch.Indef.Cuda.Short.Tensor.Math.Reduce, Torch.Indef.Static.Tensor.Math.Scan as Torch.Indef.Cuda.Short.Tensor.Math.Scan, Torch.Indef.Static.Tensor.Mode as Torch.Indef.Cuda.Short.Tensor.Mode, Torch.Indef.Static.Tensor.ScatterGather as Torch.Indef.Cuda.Short.Tensor.ScatterGather, Torch.Indef.Static.Tensor.Sort as Torch.Indef.Cuda.Short.Tensor.Sort, Torch.Indef.Static.Tensor.TopK as Torch.Indef.Cuda.Short.Tensor.TopK, Torch.Indef.Dynamic.Tensor as Torch.Indef.Cuda.Short.Dynamic.Tensor, Torch.Indef.Dynamic.Tensor.Copy as Torch.Indef.Cuda.Short.Dynamic.Tensor.Copy, Torch.Indef.Dynamic.Tensor.Index as Torch.Indef.Cuda.Short.Dynamic.Tensor.Index, Torch.Indef.Dynamic.Tensor.Masked as Torch.Indef.Cuda.Short.Dynamic.Tensor.Masked, Torch.Indef.Dynamic.Tensor.Math as Torch.Indef.Cuda.Short.Dynamic.Tensor.Math, Torch.Indef.Dynamic.Tensor.Math.Compare as Torch.Indef.Cuda.Short.Dynamic.Tensor.Math.Compare, Torch.Indef.Dynamic.Tensor.Math.CompareT as Torch.Indef.Cuda.Short.Dynamic.Tensor.Math.CompareT, Torch.Indef.Dynamic.Tensor.Math.Pairwise as Torch.Indef.Cuda.Short.Dynamic.Tensor.Math.Pairwise, Torch.Indef.Dynamic.Tensor.Math.Pointwise as Torch.Indef.Cuda.Short.Dynamic.Tensor.Math.Pointwise, Torch.Indef.Dynamic.Tensor.Math.Reduce as Torch.Indef.Cuda.Short.Dynamic.Tensor.Math.Reduce, Torch.Indef.Dynamic.Tensor.Math.Scan as Torch.Indef.Cuda.Short.Dynamic.Tensor.Math.Scan, Torch.Indef.Dynamic.Tensor.Mode as Torch.Indef.Cuda.Short.Dynamic.Tensor.Mode, Torch.Indef.Dynamic.Tensor.ScatterGather as Torch.Indef.Cuda.Short.Dynamic.Tensor.ScatterGather, Torch.Indef.Dynamic.Tensor.Sort as Torch.Indef.Cuda.Short.Dynamic.Tensor.Sort, Torch.Indef.Dynamic.Tensor.TopK as Torch.Indef.Cuda.Short.Dynamic.Tensor.TopK, Torch.Indef.Types as Torch.Cuda.Short.Types, Torch.Indef.Index as Torch.Cuda.Short.Index, Torch.Indef.Mask as Torch.Cuda.Short.Mask, Torch.Indef.Static.Tensor.Math.Pointwise.Signed as Torch.Indef.Cuda.Short.Tensor.Math.Pointwise.Signed, Torch.Indef.Dynamic.Tensor.Math.Pointwise.Signed as Torch.Indef.Cuda.Short.Dynamic.Tensor.Math.Pointwise.Signed) requires (Torch.Sig.Index.Tensor as Torch.FFI.THC.Long.Tensor, Torch.Sig.Index.TensorFree as Torch.FFI.THC.Long.Tensor, Torch.Sig.Mask.Tensor as Torch.FFI.THC.Byte.Tensor, Torch.Sig.Mask.TensorFree as Torch.FFI.THC.Byte.Tensor, Torch.Sig.Mask.MathReduce as Torch.FFI.THC.Byte.TensorMathReduce, Torch.Sig.State as Torch.FFI.THC.State, Torch.Sig.Types.Global as Torch.Types.THC, Torch.Sig.Types as Torch.Types.THC.Short, Torch.Sig.Storage as Torch.FFI.THC.Short.Storage, Torch.Sig.Storage.Copy as Torch.FFI.THC.Short.StorageCopy, Torch.Sig.Storage.Memory as Torch.FFI.THC.Short.Storage, Torch.Sig.Tensor as Torch.FFI.THC.Short.Tensor, Torch.Sig.Tensor.Copy as Torch.FFI.THC.Short.TensorCopy, Torch.Sig.Tensor.Memory as Torch.FFI.THC.Short.Tensor, Torch.Sig.Tensor.Index as Torch.FFI.THC.Short.TensorIndex, Torch.Sig.Tensor.Masked as Torch.FFI.THC.Short.TensorMasked, Torch.Sig.Tensor.Math as Torch.FFI.THC.Short.TensorMath, Torch.Sig.Tensor.Math.Compare as Torch.FFI.THC.Short.TensorMathCompare, Torch.Sig.Tensor.Math.CompareT as Torch.FFI.THC.Short.TensorMathCompareT, Torch.Sig.Tensor.Math.Pairwise as Torch.FFI.THC.Short.TensorMathPairwise, Torch.Sig.Tensor.Math.Pointwise as Torch.FFI.THC.Short.TensorMathPointwise, Torch.Sig.Tensor.Math.Reduce as Torch.FFI.THC.Short.TensorMathReduce, Torch.Sig.Tensor.Math.Scan as Torch.FFI.THC.Short.TensorMathScan, Torch.Sig.Tensor.Mode as Torch.FFI.THC.Short.TensorMode, Torch.Sig.Tensor.ScatterGather as Torch.FFI.THC.Short.TensorScatterGather, Torch.Sig.Tensor.Sort as Torch.FFI.THC.Short.TensorSort, Torch.Sig.Tensor.TopK as Torch.FFI.THC.Short.TensorTopK, Torch.Sig.Tensor.Math.Pointwise.Signed as Torch.FFI.THC.Short.TensorMathPointwise),-                hasktorch-indef-signed (Torch.Indef.Storage as Torch.Indef.Cuda.Int.Storage, Torch.Indef.Storage.Copy as Torch.Indef.Cuda.Int.Storage.Copy, Torch.Indef.Static.Tensor as Torch.Indef.Cuda.Int.Tensor, Torch.Indef.Static.Tensor.Copy as Torch.Indef.Cuda.Int.Tensor.Copy, Torch.Indef.Static.Tensor.Index as Torch.Indef.Cuda.Int.Tensor.Index, Torch.Indef.Static.Tensor.Masked as Torch.Indef.Cuda.Int.Tensor.Masked, Torch.Indef.Static.Tensor.Math as Torch.Indef.Cuda.Int.Tensor.Math, Torch.Indef.Static.Tensor.Math.Compare as Torch.Indef.Cuda.Int.Tensor.Math.Compare, Torch.Indef.Static.Tensor.Math.CompareT as Torch.Indef.Cuda.Int.Tensor.Math.CompareT, Torch.Indef.Static.Tensor.Math.Pairwise as Torch.Indef.Cuda.Int.Tensor.Math.Pairwise, Torch.Indef.Static.Tensor.Math.Pointwise as Torch.Indef.Cuda.Int.Tensor.Math.Pointwise, Torch.Indef.Static.Tensor.Math.Reduce as Torch.Indef.Cuda.Int.Tensor.Math.Reduce, Torch.Indef.Static.Tensor.Math.Scan as Torch.Indef.Cuda.Int.Tensor.Math.Scan, Torch.Indef.Static.Tensor.Mode as Torch.Indef.Cuda.Int.Tensor.Mode, Torch.Indef.Static.Tensor.ScatterGather as Torch.Indef.Cuda.Int.Tensor.ScatterGather, Torch.Indef.Static.Tensor.Sort as Torch.Indef.Cuda.Int.Tensor.Sort, Torch.Indef.Static.Tensor.TopK as Torch.Indef.Cuda.Int.Tensor.TopK, Torch.Indef.Dynamic.Tensor as Torch.Indef.Cuda.Int.Dynamic.Tensor, Torch.Indef.Dynamic.Tensor.Copy as Torch.Indef.Cuda.Int.Dynamic.Tensor.Copy, Torch.Indef.Dynamic.Tensor.Index as Torch.Indef.Cuda.Int.Dynamic.Tensor.Index, Torch.Indef.Dynamic.Tensor.Masked as Torch.Indef.Cuda.Int.Dynamic.Tensor.Masked, Torch.Indef.Dynamic.Tensor.Math as Torch.Indef.Cuda.Int.Dynamic.Tensor.Math, Torch.Indef.Dynamic.Tensor.Math.Compare as Torch.Indef.Cuda.Int.Dynamic.Tensor.Math.Compare, Torch.Indef.Dynamic.Tensor.Math.CompareT as Torch.Indef.Cuda.Int.Dynamic.Tensor.Math.CompareT, Torch.Indef.Dynamic.Tensor.Math.Pairwise as Torch.Indef.Cuda.Int.Dynamic.Tensor.Math.Pairwise, Torch.Indef.Dynamic.Tensor.Math.Pointwise as Torch.Indef.Cuda.Int.Dynamic.Tensor.Math.Pointwise, Torch.Indef.Dynamic.Tensor.Math.Reduce as Torch.Indef.Cuda.Int.Dynamic.Tensor.Math.Reduce, Torch.Indef.Dynamic.Tensor.Math.Scan as Torch.Indef.Cuda.Int.Dynamic.Tensor.Math.Scan, Torch.Indef.Dynamic.Tensor.Mode as Torch.Indef.Cuda.Int.Dynamic.Tensor.Mode, Torch.Indef.Dynamic.Tensor.ScatterGather as Torch.Indef.Cuda.Int.Dynamic.Tensor.ScatterGather, Torch.Indef.Dynamic.Tensor.Sort as Torch.Indef.Cuda.Int.Dynamic.Tensor.Sort, Torch.Indef.Dynamic.Tensor.TopK as Torch.Indef.Cuda.Int.Dynamic.Tensor.TopK, Torch.Indef.Types as Torch.Cuda.Int.Types, Torch.Indef.Index as Torch.Cuda.Int.Index, Torch.Indef.Mask as Torch.Cuda.Int.Mask, Torch.Indef.Static.Tensor.Math.Pointwise.Signed as Torch.Indef.Cuda.Int.Tensor.Math.Pointwise.Signed, Torch.Indef.Dynamic.Tensor.Math.Pointwise.Signed as Torch.Indef.Cuda.Int.Dynamic.Tensor.Math.Pointwise.Signed) requires (Torch.Sig.Index.Tensor as Torch.FFI.THC.Long.Tensor, Torch.Sig.Index.TensorFree as Torch.FFI.THC.Long.Tensor, Torch.Sig.Mask.Tensor as Torch.FFI.THC.Byte.Tensor, Torch.Sig.Mask.TensorFree as Torch.FFI.THC.Byte.Tensor, Torch.Sig.Mask.MathReduce as Torch.FFI.THC.Byte.TensorMathReduce, Torch.Sig.State as Torch.FFI.THC.State, Torch.Sig.Types.Global as Torch.Types.THC, Torch.Sig.Types as Torch.Types.THC.Int, Torch.Sig.Storage as Torch.FFI.THC.Int.Storage, Torch.Sig.Storage.Copy as Torch.FFI.THC.Int.StorageCopy, Torch.Sig.Storage.Memory as Torch.FFI.THC.Int.Storage, Torch.Sig.Tensor as Torch.FFI.THC.Int.Tensor, Torch.Sig.Tensor.Copy as Torch.FFI.THC.Int.TensorCopy, Torch.Sig.Tensor.Memory as Torch.FFI.THC.Int.Tensor, Torch.Sig.Tensor.Index as Torch.FFI.THC.Int.TensorIndex, Torch.Sig.Tensor.Masked as Torch.FFI.THC.Int.TensorMasked, Torch.Sig.Tensor.Math as Torch.FFI.THC.Int.TensorMath, Torch.Sig.Tensor.Math.Compare as Torch.FFI.THC.Int.TensorMathCompare, Torch.Sig.Tensor.Math.CompareT as Torch.FFI.THC.Int.TensorMathCompareT, Torch.Sig.Tensor.Math.Pairwise as Torch.FFI.THC.Int.TensorMathPairwise, Torch.Sig.Tensor.Math.Pointwise as Torch.FFI.THC.Int.TensorMathPointwise, Torch.Sig.Tensor.Math.Reduce as Torch.FFI.THC.Int.TensorMathReduce, Torch.Sig.Tensor.Math.Scan as Torch.FFI.THC.Int.TensorMathScan, Torch.Sig.Tensor.Mode as Torch.FFI.THC.Int.TensorMode, Torch.Sig.Tensor.ScatterGather as Torch.FFI.THC.Int.TensorScatterGather, Torch.Sig.Tensor.Sort as Torch.FFI.THC.Int.TensorSort, Torch.Sig.Tensor.TopK as Torch.FFI.THC.Int.TensorTopK, Torch.Sig.Tensor.Math.Pointwise.Signed as Torch.FFI.THC.Int.TensorMathPointwise)+test-suite doctests+  if os(darwin) || flag(disable-doctest)+    Buildable: False+  else+    Buildable: True+  type:               exitcode-stdio-1.0+  hs-source-dirs:     test+  main-is:            doctests.hs+  ghc-options:        -Wall -threaded -fplugin GHC.TypeLits.Normalise -fplugin GHC.TypeLits.KnownNat.Solver -fplugin GHC.TypeLits.Extra.Solver -fconstraint-solver-iterations=0+  default-language:   Haskell2010+  build-depends:      doctest >=0.16.0.1 && <0.25+                    , async+                    , base+                    , libtorch-ffi+                    , finite-typelits+                    , ghc-typelits-extra+                    , ghc-typelits-knownnat+                    , ghc-typelits-natnormalise+                    , mtl+                    , safe-exceptions+                    , random+                    , reflection+                    , stm+                    , JuicyPixels+                    , vector+                    , bytestring+                    , safe-exceptions+                    , zlib >= 0.6+                    , inline-c+                    , hasktorch -library hasktorch-indef-unsigned-    reexported-modules: Torch.Indef.Index,-                        Torch.Indef.Mask,-                        Torch.Indef.Types,-                        Torch.Indef.Storage,-                        Torch.Indef.Storage.Copy,-                        Torch.Indef.Dynamic.Print,-                        Torch.Indef.Dynamic.Tensor,-                        Torch.Indef.Dynamic.Tensor.Copy,-                        Torch.Indef.Dynamic.Tensor.Index,-                        Torch.Indef.Dynamic.Tensor.Masked,-                        Torch.Indef.Dynamic.Tensor.Math,-                        Torch.Indef.Dynamic.Tensor.Math.Compare,-                        Torch.Indef.Dynamic.Tensor.Math.CompareT,-                        Torch.Indef.Dynamic.Tensor.Math.Pairwise,-                        Torch.Indef.Dynamic.Tensor.Math.Pointwise,-                        Torch.Indef.Dynamic.Tensor.Math.Reduce,-                        Torch.Indef.Dynamic.Tensor.Math.Scan,-                        Torch.Indef.Dynamic.Tensor.Mode,-                        Torch.Indef.Dynamic.Tensor.ScatterGather,-                        Torch.Indef.Dynamic.Tensor.Sort,-                        Torch.Indef.Dynamic.Tensor.TopK,-                        Torch.Indef.Static.Tensor,-                        Torch.Indef.Static.Tensor.Copy,-                        Torch.Indef.Static.Tensor.Index,-                        Torch.Indef.Static.Tensor.Masked,-                        Torch.Indef.Static.Tensor.Math,-                        Torch.Indef.Static.Tensor.Math.Compare,-                        Torch.Indef.Static.Tensor.Math.CompareT,-                        Torch.Indef.Static.Tensor.Math.Pairwise,-                        Torch.Indef.Static.Tensor.Math.Pointwise,-                        Torch.Indef.Static.Tensor.Math.Reduce,-                        Torch.Indef.Static.Tensor.Math.Scan,-                        Torch.Indef.Static.Tensor.Mode,-                        Torch.Indef.Static.Tensor.ScatterGather,-                        Torch.Indef.Static.Tensor.Sort,-                        Torch.Indef.Static.Tensor.TopK-    default-language: Haskell2010-    build-depends:-        base (==4.7 || >4.7) && <5,-        hasktorch-signatures-partial (==0.0.1 || >0.0.1) && <0.0.2,-        hasktorch-indef -any-    mixins: hasktorch-indef requires (Torch.Sig.NN as Torch.Undefined.NN, Torch.Sig.Types.NN as Torch.Undefined.Types.NN, Torch.Sig.Tensor.Math.Blas as Torch.Undefined.Tensor.Math.Blas, Torch.Sig.Tensor.Math.Floating as Torch.Undefined.Tensor.Math.Floating, Torch.Sig.Tensor.Math.Lapack as Torch.Undefined.Tensor.Math.Lapack, Torch.Sig.Tensor.Math.Pointwise.Signed as Torch.Undefined.Tensor.Math.Pointwise.Signed, Torch.Sig.Tensor.Math.Pointwise.Floating as Torch.Undefined.Tensor.Math.Pointwise.Floating, Torch.Sig.Tensor.Math.Reduce.Floating as Torch.Undefined.Tensor.Math.Reduce.Floating, Torch.Sig.Tensor.Math.Random.TH as Torch.Undefined.Tensor.Math.Random.TH, Torch.Sig.Tensor.Random.TH as Torch.Undefined.Tensor.Random.TH, Torch.Sig.Tensor.Random.THC as Torch.Undefined.Tensor.Random.THC)+benchmark runtime+  type: exitcode-stdio-1.0+  main-is: Runtime.hs+  hs-source-dirs: bench+  build-depends:+      base+    , criterion+    , deepseq+    , hmatrix+    , mwc-random+    , vector+    , matrix+    , split+    , primitive+    , hasktorch+    , libtorch-ffi+  default-language: Haskell2010+  ghc-options: -Wall -threaded -rtsopts -library hasktorch-indef-signed-    reexported-modules: Torch.Indef.Index,-                        Torch.Indef.Mask,-                        Torch.Indef.Types,-                        Torch.Indef.Storage,-                        Torch.Indef.Storage.Copy,-                        Torch.Indef.Dynamic.Print,-                        Torch.Indef.Dynamic.Tensor,-                        Torch.Indef.Dynamic.Tensor.Copy,-                        Torch.Indef.Dynamic.Tensor.Index,-                        Torch.Indef.Dynamic.Tensor.Masked,-                        Torch.Indef.Dynamic.Tensor.Math,-                        Torch.Indef.Dynamic.Tensor.Math.Compare,-                        Torch.Indef.Dynamic.Tensor.Math.CompareT,-                        Torch.Indef.Dynamic.Tensor.Math.Pairwise,-                        Torch.Indef.Dynamic.Tensor.Math.Pointwise,-                        Torch.Indef.Dynamic.Tensor.Math.Reduce,-                        Torch.Indef.Dynamic.Tensor.Math.Scan,-                        Torch.Indef.Dynamic.Tensor.Mode,-                        Torch.Indef.Dynamic.Tensor.ScatterGather,-                        Torch.Indef.Dynamic.Tensor.Sort,-                        Torch.Indef.Dynamic.Tensor.TopK,-                        Torch.Indef.Static.Tensor,-                        Torch.Indef.Static.Tensor.Copy,-                        Torch.Indef.Static.Tensor.Index,-                        Torch.Indef.Static.Tensor.Masked,-                        Torch.Indef.Static.Tensor.Math,-                        Torch.Indef.Static.Tensor.Math.Compare,-                        Torch.Indef.Static.Tensor.Math.CompareT,-                        Torch.Indef.Static.Tensor.Math.Pairwise,-                        Torch.Indef.Static.Tensor.Math.Pointwise,-                        Torch.Indef.Static.Tensor.Math.Reduce,-                        Torch.Indef.Static.Tensor.Math.Scan,-                        Torch.Indef.Static.Tensor.Mode,-                        Torch.Indef.Static.Tensor.ScatterGather,-                        Torch.Indef.Static.Tensor.Sort,-                        Torch.Indef.Static.Tensor.TopK,-                        Torch.Indef.Static.Tensor.Math.Pointwise.Signed,-                        Torch.Indef.Dynamic.Tensor.Math.Pointwise.Signed-    default-language: Haskell2010-    build-depends:-        base (==4.7 || >4.7) && <5,-        hasktorch-signatures-partial (==0.0.1 || >0.0.1) && <0.0.2,-        hasktorch-indef -any-    mixins: hasktorch-indef requires (Torch.Sig.NN as Torch.Undefined.NN, Torch.Sig.Types.NN as Torch.Undefined.Types.NN, Torch.Sig.Tensor.Math.Blas as Torch.Undefined.Tensor.Math.Blas, Torch.Sig.Tensor.Math.Floating as Torch.Undefined.Tensor.Math.Floating, Torch.Sig.Tensor.Math.Lapack as Torch.Undefined.Tensor.Math.Lapack, Torch.Sig.Tensor.Math.Pointwise.Floating as Torch.Undefined.Tensor.Math.Pointwise.Floating, Torch.Sig.Tensor.Math.Reduce.Floating as Torch.Undefined.Tensor.Math.Reduce.Floating, Torch.Sig.Tensor.Math.Random.TH as Torch.Undefined.Tensor.Math.Random.TH, Torch.Sig.Tensor.Random.TH as Torch.Undefined.Tensor.Random.TH, Torch.Sig.Tensor.Random.THC as Torch.Undefined.Tensor.Random.THC) -library hasktorch-indef-floating-    reexported-modules: Torch.Indef.Index,-                        Torch.Indef.Mask,-                        Torch.Indef.Types,-                        Torch.Indef.Storage,-                        Torch.Indef.Storage.Copy,-                        Torch.Indef.Dynamic.Print,-                        Torch.Indef.Dynamic.Tensor,-                        Torch.Indef.Dynamic.Tensor.Copy,-                        Torch.Indef.Dynamic.Tensor.Index,-                        Torch.Indef.Dynamic.Tensor.Masked,-                        Torch.Indef.Dynamic.Tensor.Math,-                        Torch.Indef.Dynamic.Tensor.Math.Compare,-                        Torch.Indef.Dynamic.Tensor.Math.CompareT,-                        Torch.Indef.Dynamic.Tensor.Math.Pairwise,-                        Torch.Indef.Dynamic.Tensor.Math.Pointwise,-                        Torch.Indef.Dynamic.Tensor.Math.Reduce,-                        Torch.Indef.Dynamic.Tensor.Math.Scan,-                        Torch.Indef.Dynamic.Tensor.Mode,-                        Torch.Indef.Dynamic.Tensor.ScatterGather,-                        Torch.Indef.Dynamic.Tensor.Sort,-                        Torch.Indef.Dynamic.Tensor.TopK,-                        Torch.Indef.Static.Tensor,-                        Torch.Indef.Static.Tensor.Copy,-                        Torch.Indef.Static.Tensor.Index,-                        Torch.Indef.Static.Tensor.Masked,-                        Torch.Indef.Static.Tensor.Math,-                        Torch.Indef.Static.Tensor.Math.Compare,-                        Torch.Indef.Static.Tensor.Math.CompareT,-                        Torch.Indef.Static.Tensor.Math.Pairwise,-                        Torch.Indef.Static.Tensor.Math.Pointwise,-                        Torch.Indef.Static.Tensor.Math.Reduce,-                        Torch.Indef.Static.Tensor.Math.Scan,-                        Torch.Indef.Static.Tensor.Mode,-                        Torch.Indef.Static.Tensor.ScatterGather,-                        Torch.Indef.Static.Tensor.Sort,-                        Torch.Indef.Static.Tensor.TopK,-                        Torch.Indef.Static.Tensor.Math.Pointwise.Signed,-                        Torch.Indef.Dynamic.Tensor.Math.Pointwise.Signed,-                        Torch.Indef.Dynamic.Tensor.Math.Blas,-                        Torch.Indef.Dynamic.Tensor.Math.Floating,-                        Torch.Indef.Dynamic.Tensor.Math.Lapack,-                        Torch.Indef.Dynamic.Tensor.Math.Pointwise.Floating,-                        Torch.Indef.Dynamic.Tensor.Math.Reduce.Floating,-                        Torch.Indef.Dynamic.Tensor.Random.TH,-                        Torch.Indef.Dynamic.Tensor.Random.THC,-                        Torch.Indef.Dynamic.Tensor.Math.Random.TH,-                        Torch.Indef.Static.Tensor.Math.Blas,-                        Torch.Indef.Static.Tensor.Math.Floating,-                        Torch.Indef.Static.Tensor.Math.Lapack,-                        Torch.Indef.Static.Tensor.Math.Pointwise.Floating,-                        Torch.Indef.Static.Tensor.Math.Reduce.Floating,-                        Torch.Indef.Static.Tensor.Random.TH,-                        Torch.Indef.Static.Tensor.Random.THC,-                        Torch.Indef.Static.Tensor.Math.Random.TH,-                        Torch.Indef.Dynamic.NN,-                        Torch.Indef.Dynamic.NN.Activation,-                        Torch.Indef.Dynamic.NN.Pooling,-                        Torch.Indef.Dynamic.NN.Criterion,-                        Torch.Indef.Static.NN,-                        Torch.Indef.Static.NN.Activation,-                        Torch.Indef.Static.NN.Backprop,-                        Torch.Indef.Static.NN.Conv1d,-                        Torch.Indef.Static.NN.Conv2d,-                        Torch.Indef.Static.NN.Criterion,-                        Torch.Indef.Static.NN.Layers,-                        Torch.Indef.Static.NN.Linear,-                        Torch.Indef.Static.NN.Math,-                        Torch.Indef.Static.NN.Padding,-                        Torch.Indef.Static.NN.Pooling,-                        Torch.Indef.Static.NN.Sampling,-                        Torch.Undefined.Tensor.Math.Random.TH,-                        Torch.Undefined.Tensor.Random.TH,-                        Torch.Undefined.Tensor.Random.THC-    default-language: Haskell2010-    build-depends:-        base (==4.7 || >4.7) && <5,-        hasktorch-indef -any,-        hasktorch-signatures-partial (==0.0.1 || >0.0.1) && <0.0.2--executable isdefinite-cpu-    main-is: Noop.hs-    hs-source-dirs: exe-    default-language: Haskell2010-    build-depends:-        base (==4.7 || >4.7) && <5,-        hasktorch-cpu -any--executable isdefinite-gpu-    main-is: Noop.hs-    hs-source-dirs: exe-    default-language: Haskell2010-    build-depends:-        base (==4.7 || >4.7) && <5,-        hasktorch-gpu -any--executable isdefinite-    main-is: Noop.hs-    hs-source-dirs: exe-    default-language: Haskell2010-    build-depends:-        base (==4.7 || >4.7) && <5,-        hasktorch -any--executable memcheck-    main-is: Memcheck.hs-    hs-source-dirs: exe-    default-language: Haskell2010-    build-depends:-        base (==4.7 || >4.7) && <5,-        hasktorch -any--test-suite spec-    type: exitcode-stdio-1.0-    main-is: Spec.hs-    hs-source-dirs: tests-    other-modules:-        Orphans-        MemorySpec-        RawLapackSVDSpec-        GarbageCollectionSpec-        Torch.Prelude.Extras-        Torch.Core.LogAddSpec-        Torch.Core.RandomSpec-        Torch.Static.NN.AbsSpec-        Torch.Static.NN.LinearSpec-    default-language: Haskell2010-    default-extensions: LambdaCase DataKinds TypeFamilies-                        TypeSynonymInstances ScopedTypeVariables FlexibleContexts CPP-    build-depends:-        QuickCheck ==2.11 || >2.11,-        backprop ==0.2.5 || >0.2.5,-        base (==4.7 || >4.7) && <5,-        dimensions ==1.0 || >1.0,-        ghc-typelits-natnormalise -any,-        hasktorch -any,-        hspec ==2.4.4 || >2.4.4,-        singletons ==2.2 || >2.2,-        -- text ==1.2.2 || >1.2.2,-        mtl ==2.2.2 || >2.2.2,-        microlens-platform ==0.3.10 || >0.3.10,-        monad-loops ==0.4.3 || >0.4.3,-        time ==1.8.0 || >1.8.0,-        transformers ==0.5.5 || >0.5.5,-        generic-lens -any-+benchmark alloc+  type: exitcode-stdio-1.0+  main-is: Alloc.hs+  hs-source-dirs: bench+  build-depends:+      base+    , deepseq+    , hmatrix+    , mwc-random+    , vector+    , weigh+    , split+    , primitive+    , hasktorch+    , libtorch-ffi+  default-language: Haskell2010+  ghc-options: -Wall -threaded -rtsopts
+ src/Torch.hs view
@@ -0,0 +1,35 @@+module Torch+  ( module Torch,+    module Torch.Autograd,+    module Torch.Data,+    module Torch.Device,+    module Torch.DType,+    module Torch.Functional,+    module Torch.NN,+    module Torch.Optim,+    module Torch.Random,+    module Torch.Scalar,+    module Torch.Serialize,+    module Torch.Tensor,+    module Torch.TensorFactories,+    module Torch.TensorOptions,+    module Torch.Script,+    module Torch.Index,+  )+where++import Torch.Autograd+import Torch.DType+import Torch.Data+import Torch.Device+import Torch.Functional+import Torch.Index+import Torch.NN+import Torch.Optim+import Torch.Random+import Torch.Scalar+import Torch.Script+import Torch.Serialize+import Torch.Tensor+import Torch.TensorFactories+import Torch.TensorOptions
+ src/Torch/Autograd.hs view
@@ -0,0 +1,54 @@+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE RecordWildCards #-}++module Torch.Autograd where++import Foreign.ForeignPtr+import GHC.Generics+import System.IO.Unsafe+import Torch.Internal.Cast+import Torch.Internal.Class+import qualified Torch.Internal.Managed.Autograd+import qualified Torch.Internal.Managed.Type.Tensor as ATen+import qualified Torch.Internal.Type as ATen+import Torch.Tensor+import Data.Default.Class+++-- | Note: to create an `IndependentTensor` use `makeIndependent`;+-- | otherwise, Torch will complain the parameter does not require a gradient.+newtype IndependentTensor = IndependentTensor+  { toDependent :: Tensor+  }+  deriving (Show, Generic)++data GradOptions = GradOptions+  { keepGraph :: Bool+  , createGraph :: Bool+  , accumulateGrad :: Bool+  }+  deriving (Show)++instance Default GradOptions where+  def = GradOptions True False False++grad :: Tensor -> [IndependentTensor] -> [Tensor]+grad y inputs = unsafePerformIO $ cast2 Torch.Internal.Managed.Autograd.grad y (map toDependent inputs)++gradWithOptions :: GradOptions -> Tensor -> [IndependentTensor] -> [Tensor]+gradWithOptions GradOptions{..} y inputs = unsafePerformIO $ cast5 Torch.Internal.Managed.Autograd.gradWithOptions keepGraph createGraph accumulateGrad y (map toDependent inputs)++requiresGrad :: Tensor -> Bool+requiresGrad t = unsafePerformIO $ cast1 ATen.tensor_requires_grad t++setRequiresGrad :: Bool -> Tensor -> Tensor+setRequiresGrad flag t = unsafePerformIO $ cast2 ATen.tensor_set_requires_grad_b t flag++makeIndependent :: Tensor -> IO IndependentTensor+makeIndependent tensor = makeIndependentWithRequiresGrad tensor True++makeIndependentWithRequiresGrad :: Tensor -> Bool -> IO IndependentTensor+makeIndependentWithRequiresGrad tensor requires_grad = IndependentTensor <$> cast2 Torch.Internal.Managed.Autograd.makeIndependent tensor requires_grad
+ src/Torch/Backend.hs view
@@ -0,0 +1,29 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}++module Torch.Backend where++import Torch.Internal.Class (Castable (..))+import qualified Torch.Internal.Const as ATen+import qualified Torch.Internal.Type as ATen++data Backend = CPU | CUDA | HIP | SparseCPU | SparseCUDA | XLA | MPS+  deriving (Eq, Show)++instance Castable Backend ATen.Backend where+  cast CPU f = f ATen.bCPU+  cast CUDA f = f ATen.bCUDA+  cast MPS f = f ATen.bMPS+  cast HIP f = f ATen.bHIP+  cast SparseCPU f = f ATen.bSparseCPU+  cast SparseCUDA f = f ATen.bSparseCUDA+  cast XLA f = f ATen.bXLA++  uncast x f+    | x == ATen.bCPU = f CPU+    | x == ATen.bCUDA = f CUDA+    | x == ATen.bMPS = f MPS+    | x == ATen.bHIP = f HIP+    | x == ATen.bSparseCPU = f SparseCPU+    | x == ATen.bSparseCUDA = f SparseCUDA+    | x == ATen.bXLA = f XLA
− src/Torch/Byte.hs
@@ -1,29 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Byte--- Copyright :  (c) Sam Stites 2017--- License   :  BSD3--- Maintainer:  sam@stites.io--- Stability :  experimental--- Portability: non-portable---------------------------------------------------------------------------------module Torch.Byte (module X) where--import Torch.Byte.Index as X-import Torch.Indef.Byte.Tensor as X-import Torch.Indef.Byte.Tensor.Copy as X-import Torch.Indef.Byte.Tensor.Index as X-import Torch.Indef.Byte.Tensor.Masked as X-import Torch.Indef.Byte.Tensor.Math as X-import Torch.Indef.Byte.Tensor.Math.Compare as X-import Torch.Indef.Byte.Tensor.Math.CompareT as X-import Torch.Indef.Byte.Tensor.Math.Pairwise as X-import Torch.Indef.Byte.Tensor.Math.Pointwise as X-import Torch.Indef.Byte.Tensor.Math.Reduce as X-import Torch.Indef.Byte.Tensor.Math.Scan as X-import Torch.Indef.Byte.Tensor.Mode as X-import Torch.Indef.Byte.Tensor.ScatterGather as X-import Torch.Indef.Byte.Tensor.Sort as X-import Torch.Indef.Byte.Tensor.TopK as X--
− src/Torch/Byte/Dynamic.hs
@@ -1,28 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Byte.Dynamic--- Copyright :  (c) Sam Stites 2017--- License   :  BSD3--- Maintainer:  sam@stites.io--- Stability :  experimental--- Portability: non-portable---------------------------------------------------------------------------------module Torch.Byte.Dynamic (module X) where--import Torch.Indef.Byte.Dynamic.Tensor as X-import Torch.Indef.Byte.Dynamic.Tensor.Copy as X-import Torch.Indef.Byte.Dynamic.Tensor.Index as X-import Torch.Indef.Byte.Dynamic.Tensor.Masked as X-import Torch.Indef.Byte.Dynamic.Tensor.Math as X-import Torch.Indef.Byte.Dynamic.Tensor.Math.Compare as X-import Torch.Indef.Byte.Dynamic.Tensor.Math.CompareT as X-import Torch.Indef.Byte.Dynamic.Tensor.Math.Pairwise as X-import Torch.Indef.Byte.Dynamic.Tensor.Math.Pointwise as X-import Torch.Indef.Byte.Dynamic.Tensor.Math.Reduce as X-import Torch.Indef.Byte.Dynamic.Tensor.Math.Scan as X-import Torch.Indef.Byte.Dynamic.Tensor.Mode as X-import Torch.Indef.Byte.Dynamic.Tensor.ScatterGather as X-import Torch.Indef.Byte.Dynamic.Tensor.Sort as X-import Torch.Indef.Byte.Dynamic.Tensor.TopK as X--
− src/Torch/Byte/Storage.hs
@@ -1,13 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Byte.Storage--- Copyright :  (c) Sam Stites 2017--- License   :  BSD3--- Maintainer:  sam@stites.io--- Stability :  experimental--- Portability: non-portable---------------------------------------------------------------------------------module Torch.Byte.Storage (module X) where--import Torch.Indef.Byte.Storage      as X-import Torch.Indef.Byte.Storage.Copy as X
+ src/Torch/Cast.hs view
@@ -0,0 +1,36 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE TypeFamilies #-}++module Torch.Cast where++import Foreign.ForeignPtr+import Torch.Internal.Cast+import Torch.Internal.Class+import Torch.Internal.Managed.Type.IntArray+import Torch.Internal.Type++-- define useful casts++instance CppTuple2 (ForeignPtr IntArray) where+  type A (ForeignPtr IntArray) = Int+  type B (ForeignPtr IntArray) = Int+  get0 = cast1 (`intArray_at_s` 0)+  get1 = cast1 (`intArray_at_s` 1)++instance CppTuple3 (ForeignPtr IntArray) where+  type C (ForeignPtr IntArray) = Int+  get2 = cast1 (`intArray_at_s` 2)++instance CppTuple4 (ForeignPtr IntArray) where+  type D (ForeignPtr IntArray) = Int+  get3 = cast1 (`intArray_at_s` 3)++instance CppTuple5 (ForeignPtr IntArray) where+  type E (ForeignPtr IntArray) = Int+  get4 = cast1 (`intArray_at_s` 4)++instance CppTuple6 (ForeignPtr IntArray) where+  type F (ForeignPtr IntArray) = Int+  get5 = cast1 (`intArray_at_s` 5)
− src/Torch/Char.hs
@@ -1,29 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Char--- Copyright :  (c) Sam Stites 2017--- License   :  BSD3--- Maintainer:  sam@stites.io--- Stability :  experimental--- Portability: non-portable---------------------------------------------------------------------------------module Torch.Char (module X) where--import Torch.Byte.Index as X-import Torch.Indef.Char.Tensor as X-import Torch.Indef.Char.Tensor.Copy as X-import Torch.Indef.Char.Tensor.Index as X-import Torch.Indef.Char.Tensor.Masked as X-import Torch.Indef.Char.Tensor.Math as X-import Torch.Indef.Char.Tensor.Math.Compare as X-import Torch.Indef.Char.Tensor.Math.CompareT as X-import Torch.Indef.Char.Tensor.Math.Pairwise as X-import Torch.Indef.Char.Tensor.Math.Pointwise as X-import Torch.Indef.Char.Tensor.Math.Reduce as X-import Torch.Indef.Char.Tensor.Math.Scan as X-import Torch.Indef.Char.Tensor.Mode as X-import Torch.Indef.Char.Tensor.ScatterGather as X-import Torch.Indef.Char.Tensor.Sort as X-import Torch.Indef.Char.Tensor.TopK as X--
− src/Torch/Char/Dynamic.hs
@@ -1,28 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Char.Dynamic--- Copyright :  (c) Sam Stites 2017--- License   :  BSD3--- Maintainer:  sam@stites.io--- Stability :  experimental--- Portability: non-portable---------------------------------------------------------------------------------module Torch.Char.Dynamic (module X) where--import Torch.Indef.Char.Dynamic.Tensor as X-import Torch.Indef.Char.Dynamic.Tensor.Copy as X-import Torch.Indef.Char.Dynamic.Tensor.Index as X-import Torch.Indef.Char.Dynamic.Tensor.Masked as X-import Torch.Indef.Char.Dynamic.Tensor.Math as X-import Torch.Indef.Char.Dynamic.Tensor.Math.Compare as X-import Torch.Indef.Char.Dynamic.Tensor.Math.CompareT as X-import Torch.Indef.Char.Dynamic.Tensor.Math.Pairwise as X-import Torch.Indef.Char.Dynamic.Tensor.Math.Pointwise as X-import Torch.Indef.Char.Dynamic.Tensor.Math.Reduce as X-import Torch.Indef.Char.Dynamic.Tensor.Math.Scan as X-import Torch.Indef.Char.Dynamic.Tensor.Mode as X-import Torch.Indef.Char.Dynamic.Tensor.ScatterGather as X-import Torch.Indef.Char.Dynamic.Tensor.Sort as X-import Torch.Indef.Char.Dynamic.Tensor.TopK as X--
− src/Torch/Char/Storage.hs
@@ -1,13 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Char.Storage--- Copyright :  (c) Sam Stites 2017--- License   :  BSD3--- Maintainer:  sam@stites.io--- Stability :  experimental--- Portability: non-portable---------------------------------------------------------------------------------module Torch.Char.Storage (module X) where--import Torch.Indef.Char.Storage      as X-import Torch.Indef.Char.Storage.Copy as X
− src/Torch/Cuda/Byte.hs
@@ -1,29 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Cuda.Byte--- Copyright :  (c) Sam Stites 2017--- License   :  BSD3--- Maintainer:  sam@stites.io--- Stability :  experimental--- Portability: non-portable---------------------------------------------------------------------------------module Torch.Cuda.Byte (module X) where--import Torch.Cuda.Byte.Index as X-import Torch.Indef.Cuda.Byte.Tensor as X-import Torch.Indef.Cuda.Byte.Tensor.Copy as X-import Torch.Indef.Cuda.Byte.Tensor.Index as X-import Torch.Indef.Cuda.Byte.Tensor.Masked as X-import Torch.Indef.Cuda.Byte.Tensor.Math as X-import Torch.Indef.Cuda.Byte.Tensor.Math.Compare as X-import Torch.Indef.Cuda.Byte.Tensor.Math.CompareT as X-import Torch.Indef.Cuda.Byte.Tensor.Math.Pairwise as X-import Torch.Indef.Cuda.Byte.Tensor.Math.Pointwise as X-import Torch.Indef.Cuda.Byte.Tensor.Math.Reduce as X-import Torch.Indef.Cuda.Byte.Tensor.Math.Scan as X-import Torch.Indef.Cuda.Byte.Tensor.Mode as X-import Torch.Indef.Cuda.Byte.Tensor.ScatterGather as X-import Torch.Indef.Cuda.Byte.Tensor.Sort as X-import Torch.Indef.Cuda.Byte.Tensor.TopK as X--
− src/Torch/Cuda/Byte/Dynamic.hs
@@ -1,28 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Cuda.Byte.Dynamic--- Copyright :  (c) Sam Stites 2017--- License   :  BSD3--- Maintainer:  sam@stites.io--- Stability :  experimental--- Portability: non-portable---------------------------------------------------------------------------------module Torch.Cuda.Byte.Dynamic (module X) where--import Torch.Indef.Cuda.Byte.Dynamic.Tensor as X-import Torch.Indef.Cuda.Byte.Dynamic.Tensor.Copy as X-import Torch.Indef.Cuda.Byte.Dynamic.Tensor.Index as X-import Torch.Indef.Cuda.Byte.Dynamic.Tensor.Masked as X-import Torch.Indef.Cuda.Byte.Dynamic.Tensor.Math as X-import Torch.Indef.Cuda.Byte.Dynamic.Tensor.Math.Compare as X-import Torch.Indef.Cuda.Byte.Dynamic.Tensor.Math.CompareT as X-import Torch.Indef.Cuda.Byte.Dynamic.Tensor.Math.Pairwise as X-import Torch.Indef.Cuda.Byte.Dynamic.Tensor.Math.Pointwise as X-import Torch.Indef.Cuda.Byte.Dynamic.Tensor.Math.Reduce as X-import Torch.Indef.Cuda.Byte.Dynamic.Tensor.Math.Scan as X-import Torch.Indef.Cuda.Byte.Dynamic.Tensor.Mode as X-import Torch.Indef.Cuda.Byte.Dynamic.Tensor.ScatterGather as X-import Torch.Indef.Cuda.Byte.Dynamic.Tensor.Sort as X-import Torch.Indef.Cuda.Byte.Dynamic.Tensor.TopK as X--
− src/Torch/Cuda/Byte/Storage.hs
@@ -1,13 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Cuda.Byte.Storage--- Copyright :  (c) Sam Stites 2017--- License   :  BSD3--- Maintainer:  sam@stites.io--- Stability :  experimental--- Portability: non-portable---------------------------------------------------------------------------------module Torch.Cuda.Byte.Storage (module X) where--import Torch.Indef.Cuda.Byte.Storage      as X-import Torch.Indef.Cuda.Byte.Storage.Copy as X
− src/Torch/Cuda/Char.hs
@@ -1,29 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Cuda.Char--- Copyright :  (c) Sam Stites 2017--- License   :  BSD3--- Maintainer:  sam@stites.io--- Stability :  experimental--- Portability: non-portable---------------------------------------------------------------------------------module Torch.Cuda.Char (module X) where--import Torch.Cuda.Char.Index as X-import Torch.Indef.Cuda.Char.Tensor as X-import Torch.Indef.Cuda.Char.Tensor.Copy as X-import Torch.Indef.Cuda.Char.Tensor.Index as X-import Torch.Indef.Cuda.Char.Tensor.Masked as X-import Torch.Indef.Cuda.Char.Tensor.Math as X-import Torch.Indef.Cuda.Char.Tensor.Math.Compare as X-import Torch.Indef.Cuda.Char.Tensor.Math.CompareT as X-import Torch.Indef.Cuda.Char.Tensor.Math.Pairwise as X-import Torch.Indef.Cuda.Char.Tensor.Math.Pointwise as X-import Torch.Indef.Cuda.Char.Tensor.Math.Reduce as X-import Torch.Indef.Cuda.Char.Tensor.Math.Scan as X-import Torch.Indef.Cuda.Char.Tensor.Mode as X-import Torch.Indef.Cuda.Char.Tensor.ScatterGather as X-import Torch.Indef.Cuda.Char.Tensor.Sort as X-import Torch.Indef.Cuda.Char.Tensor.TopK as X--
− src/Torch/Cuda/Char/Dynamic.hs
@@ -1,28 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Cuda.Char.Dynamic--- Copyright :  (c) Sam Stites 2017--- License   :  BSD3--- Maintainer:  sam@stites.io--- Stability :  experimental--- Portability: non-portable---------------------------------------------------------------------------------module Torch.Cuda.Char.Dynamic (module X) where--import Torch.Indef.Cuda.Char.Dynamic.Tensor as X-import Torch.Indef.Cuda.Char.Dynamic.Tensor.Copy as X-import Torch.Indef.Cuda.Char.Dynamic.Tensor.Index as X-import Torch.Indef.Cuda.Char.Dynamic.Tensor.Masked as X-import Torch.Indef.Cuda.Char.Dynamic.Tensor.Math as X-import Torch.Indef.Cuda.Char.Dynamic.Tensor.Math.Compare as X-import Torch.Indef.Cuda.Char.Dynamic.Tensor.Math.CompareT as X-import Torch.Indef.Cuda.Char.Dynamic.Tensor.Math.Pairwise as X-import Torch.Indef.Cuda.Char.Dynamic.Tensor.Math.Pointwise as X-import Torch.Indef.Cuda.Char.Dynamic.Tensor.Math.Reduce as X-import Torch.Indef.Cuda.Char.Dynamic.Tensor.Math.Scan as X-import Torch.Indef.Cuda.Char.Dynamic.Tensor.Mode as X-import Torch.Indef.Cuda.Char.Dynamic.Tensor.ScatterGather as X-import Torch.Indef.Cuda.Char.Dynamic.Tensor.Sort as X-import Torch.Indef.Cuda.Char.Dynamic.Tensor.TopK as X--
− src/Torch/Cuda/Char/Storage.hs
@@ -1,13 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Cuda.Char.Storage--- Copyright :  (c) Sam Stites 2017--- License   :  BSD3--- Maintainer:  sam@stites.io--- Stability :  experimental--- Portability: non-portable---------------------------------------------------------------------------------module Torch.Cuda.Char.Storage (module X) where--import Torch.Indef.Cuda.Char.Storage      as X-import Torch.Indef.Cuda.Char.Storage.Copy as X
− src/Torch/Cuda/Double.hs
@@ -1,84 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Cuda.Double--- Copyright :  (c) Sam Stites 2017--- License   :  BSD3--- Maintainer:  sam@stites.io--- Stability :  experimental--- Portability: non-portable---------------------------------------------------------------------------------{-# LANGUAGE InstanceSigs #-}-module Torch.Cuda.Double (module X) where--import Numeric.Dimensions as X-import Torch.Types.THC as X-import Torch.Cuda.Double.NN as X--import Torch.Cuda.Double.Types as X hiding (storage)-import Torch.Cuda.Double.Index as X hiding (withDynamicState)-import Torch.Cuda.Double.Mask  as X--import Torch.Indef.Cuda.Double.Tensor as X-import Torch.Indef.Cuda.Double.Tensor.Copy as X-import Torch.Indef.Cuda.Double.Tensor.Index as X-import Torch.Indef.Cuda.Double.Tensor.Masked as X-import Torch.Indef.Cuda.Double.Tensor.Math as X-import Torch.Indef.Cuda.Double.Tensor.Math.Compare as X-import Torch.Indef.Cuda.Double.Tensor.Math.CompareT as X-import Torch.Indef.Cuda.Double.Tensor.Math.Pairwise as X-import Torch.Indef.Cuda.Double.Tensor.Math.Pointwise as X-import Torch.Indef.Cuda.Double.Tensor.Math.Reduce as X-import Torch.Indef.Cuda.Double.Tensor.Math.Scan as X-import Torch.Indef.Cuda.Double.Tensor.Mode as X-import Torch.Indef.Cuda.Double.Tensor.ScatterGather as X-import Torch.Indef.Cuda.Double.Tensor.Sort as X-import Torch.Indef.Cuda.Double.Tensor.TopK as X--import Torch.Indef.Cuda.Double.Tensor.Math.Pointwise.Signed as X--import Torch.Indef.Cuda.Double.Tensor.Math.Blas as X-import Torch.Indef.Cuda.Double.Tensor.Math.Floating as X-import Torch.Indef.Cuda.Double.Tensor.Math.Lapack as X-import Torch.Indef.Cuda.Double.Tensor.Math.Pointwise.Floating as X-import Torch.Indef.Cuda.Double.Tensor.Math.Reduce.Floating as X--import Torch.Indef.Cuda.Double.Tensor.Random.THC as X-----------------------------------------------------------------------------------import System.IO.Unsafe--instance Dimensions d => Fractional (Tensor d) where-  fromRational = constant . fromRational--  (/) = (^/^)-  {-# NOINLINE (/) #-}--instance Dimensions d => Floating (Tensor d) where-  pi :: Tensor d-  pi = X.constant pi--  exp :: Tensor d -> Tensor d-  exp = X.exp--  log :: Tensor d -> Tensor d-  log = X.log--  sqrt :: Tensor d -> Tensor d-  sqrt = X.sqrt--  sin = X.sin--  cos = X.cos--  asin = X.asin--  acos = X.acos--  atan = X.atan--  sinh = X.sinh--  cosh = X.cosh--
− src/Torch/Cuda/Double/Dynamic.hs
@@ -1,28 +0,0 @@-module Torch.Cuda.Double.Dynamic (module X) where--import Torch.Indef.Cuda.Double.Dynamic.Tensor as X-import Torch.Indef.Cuda.Double.Dynamic.Tensor.Copy as X-import Torch.Indef.Cuda.Double.Dynamic.Tensor.Index as X--import Torch.Indef.Cuda.Double.Dynamic.Tensor.Masked as X-import Torch.Indef.Cuda.Double.Dynamic.Tensor.Math as X-import Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Compare as X-import Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.CompareT as X-import Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Pairwise as X-import Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Pointwise as X-import Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Reduce as X-import Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Scan as X-import Torch.Indef.Cuda.Double.Dynamic.Tensor.Mode as X-import Torch.Indef.Cuda.Double.Dynamic.Tensor.ScatterGather as X-import Torch.Indef.Cuda.Double.Dynamic.Tensor.Sort as X-import Torch.Indef.Cuda.Double.Dynamic.Tensor.TopK as X--import Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Pointwise.Signed as X--import Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Blas as X-import Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Floating as X-import Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Lapack as X-import Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Pointwise.Floating as X-import Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Reduce.Floating as X--
− src/Torch/Cuda/Double/Storage.hs
@@ -1,4 +0,0 @@-module Torch.Cuda.Double.Storage (module X) where--import Torch.Indef.Cuda.Double.Storage      as X-import Torch.Indef.Cuda.Double.Storage.Copy as X
− src/Torch/Cuda/Int.hs
@@ -1,29 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Cuda.Int--- Copyright :  (c) Sam Stites 2017--- License   :  BSD3--- Maintainer:  sam@stites.io--- Stability :  experimental--- Portability: non-portable---------------------------------------------------------------------------------module Torch.Cuda.Int (module X) where--import Torch.Cuda.Int.Index as X-import Torch.Indef.Cuda.Int.Tensor as X-import Torch.Indef.Cuda.Int.Tensor.Copy as X-import Torch.Indef.Cuda.Int.Tensor.Index as X-import Torch.Indef.Cuda.Int.Tensor.Masked as X-import Torch.Indef.Cuda.Int.Tensor.Math as X-import Torch.Indef.Cuda.Int.Tensor.Math.Compare as X-import Torch.Indef.Cuda.Int.Tensor.Math.CompareT as X-import Torch.Indef.Cuda.Int.Tensor.Math.Pairwise as X-import Torch.Indef.Cuda.Int.Tensor.Math.Pointwise as X-import Torch.Indef.Cuda.Int.Tensor.Math.Reduce as X-import Torch.Indef.Cuda.Int.Tensor.Math.Scan as X-import Torch.Indef.Cuda.Int.Tensor.Mode as X-import Torch.Indef.Cuda.Int.Tensor.ScatterGather as X-import Torch.Indef.Cuda.Int.Tensor.Sort as X-import Torch.Indef.Cuda.Int.Tensor.TopK as X--import Torch.Indef.Cuda.Int.Tensor.Math.Pointwise.Signed as X
− src/Torch/Cuda/Int/Dynamic.hs
@@ -1,28 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Cuda.Int.Dynamic--- Copyright :  (c) Sam Stites 2017--- License   :  BSD3--- Maintainer:  sam@stites.io--- Stability :  experimental--- Portability: non-portable---------------------------------------------------------------------------------module Torch.Cuda.Int.Dynamic (module X) where--import Torch.Indef.Cuda.Int.Dynamic.Tensor as X-import Torch.Indef.Cuda.Int.Dynamic.Tensor.Copy as X-import Torch.Indef.Cuda.Int.Dynamic.Tensor.Index as X-import Torch.Indef.Cuda.Int.Dynamic.Tensor.Masked as X-import Torch.Indef.Cuda.Int.Dynamic.Tensor.Math as X-import Torch.Indef.Cuda.Int.Dynamic.Tensor.Math.Compare as X-import Torch.Indef.Cuda.Int.Dynamic.Tensor.Math.CompareT as X-import Torch.Indef.Cuda.Int.Dynamic.Tensor.Math.Pairwise as X-import Torch.Indef.Cuda.Int.Dynamic.Tensor.Math.Pointwise as X-import Torch.Indef.Cuda.Int.Dynamic.Tensor.Math.Reduce as X-import Torch.Indef.Cuda.Int.Dynamic.Tensor.Math.Scan as X-import Torch.Indef.Cuda.Int.Dynamic.Tensor.Mode as X-import Torch.Indef.Cuda.Int.Dynamic.Tensor.ScatterGather as X-import Torch.Indef.Cuda.Int.Dynamic.Tensor.Sort as X-import Torch.Indef.Cuda.Int.Dynamic.Tensor.TopK as X--import Torch.Indef.Cuda.Int.Dynamic.Tensor.Math.Pointwise.Signed as X
− src/Torch/Cuda/Int/Storage.hs
@@ -1,13 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Cuda.Int.Storage--- Copyright :  (c) Sam Stites 2017--- License   :  BSD3--- Maintainer:  sam@stites.io--- Stability :  experimental--- Portability: non-portable---------------------------------------------------------------------------------module Torch.Cuda.Int.Storage (module X) where--import Torch.Indef.Cuda.Int.Storage      as X-import Torch.Indef.Cuda.Int.Storage.Copy as X
− src/Torch/Cuda/Long.hs
@@ -1,35 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Cuda.Long--- Copyright :  (c) Sam Stites 2017--- License   :  BSD3--- Maintainer:  sam@stites.io--- Stability :  experimental--- Portability: non-portable---------------------------------------------------------------------------------module Torch.Cuda.Long (module X) where--import Numeric.Dimensions-import Torch.Types.THC as X--import Torch.Cuda.Long.Types as X hiding (storage)-import Torch.Cuda.Long.Index as X hiding (withDynamicState)-import Torch.Cuda.Long.Mask  as X--import Torch.Indef.Cuda.Long.Tensor as X-import Torch.Indef.Cuda.Long.Tensor.Copy as X-import Torch.Indef.Cuda.Long.Tensor.Index as X-import Torch.Indef.Cuda.Long.Tensor.Masked as X-import Torch.Indef.Cuda.Long.Tensor.Math as X-import Torch.Indef.Cuda.Long.Tensor.Math.Compare as X-import Torch.Indef.Cuda.Long.Tensor.Math.CompareT as X-import Torch.Indef.Cuda.Long.Tensor.Math.Pairwise as X-import Torch.Indef.Cuda.Long.Tensor.Math.Pointwise as X-import Torch.Indef.Cuda.Long.Tensor.Math.Reduce as X-import Torch.Indef.Cuda.Long.Tensor.Math.Scan as X-import Torch.Indef.Cuda.Long.Tensor.Mode as X-import Torch.Indef.Cuda.Long.Tensor.ScatterGather as X-import Torch.Indef.Cuda.Long.Tensor.Sort as X-import Torch.Indef.Cuda.Long.Tensor.TopK as X--import Torch.Indef.Cuda.Long.Tensor.Math.Pointwise.Signed as X
− src/Torch/Cuda/Long/Dynamic.hs
@@ -1,28 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Cuda.Long.Dynamic--- Copyright :  (c) Sam Stites 2017--- License   :  BSD3--- Maintainer:  sam@stites.io--- Stability :  experimental--- Portability: non-portable---------------------------------------------------------------------------------module Torch.Cuda.Long.Dynamic (module X) where--import Torch.Indef.Cuda.Long.Dynamic.Tensor as X-import Torch.Indef.Cuda.Long.Dynamic.Tensor.Copy as X-import Torch.Indef.Cuda.Long.Dynamic.Tensor.Index as X-import Torch.Indef.Cuda.Long.Dynamic.Tensor.Masked as X-import Torch.Indef.Cuda.Long.Dynamic.Tensor.Math as X-import Torch.Indef.Cuda.Long.Dynamic.Tensor.Math.Compare as X-import Torch.Indef.Cuda.Long.Dynamic.Tensor.Math.CompareT as X-import Torch.Indef.Cuda.Long.Dynamic.Tensor.Math.Pairwise as X-import Torch.Indef.Cuda.Long.Dynamic.Tensor.Math.Pointwise as X-import Torch.Indef.Cuda.Long.Dynamic.Tensor.Math.Reduce as X-import Torch.Indef.Cuda.Long.Dynamic.Tensor.Math.Scan as X-import Torch.Indef.Cuda.Long.Dynamic.Tensor.Mode as X-import Torch.Indef.Cuda.Long.Dynamic.Tensor.ScatterGather as X-import Torch.Indef.Cuda.Long.Dynamic.Tensor.Sort as X-import Torch.Indef.Cuda.Long.Dynamic.Tensor.TopK as X--import Torch.Indef.Cuda.Long.Dynamic.Tensor.Math.Pointwise.Signed as X
− src/Torch/Cuda/Long/Storage.hs
@@ -1,13 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Cuda.Long.Storage--- Copyright :  (c) Sam Stites 2017--- License   :  BSD3--- Maintainer:  sam@stites.io--- Stability :  experimental--- Portability: non-portable---------------------------------------------------------------------------------module Torch.Cuda.Long.Storage (module X) where--import Torch.Indef.Cuda.Long.Storage      as X-import Torch.Indef.Cuda.Long.Storage.Copy as X
− src/Torch/Cuda/Short.hs
@@ -1,29 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Cuda.Short--- Copyright :  (c) Sam Stites 2017--- License   :  BSD3--- Maintainer:  sam@stites.io--- Stability :  experimental--- Portability: non-portable---------------------------------------------------------------------------------module Torch.Cuda.Short (module X) where--import Torch.Cuda.Short.Index as X-import Torch.Indef.Cuda.Short.Tensor as X-import Torch.Indef.Cuda.Short.Tensor.Copy as X-import Torch.Indef.Cuda.Short.Tensor.Index as X-import Torch.Indef.Cuda.Short.Tensor.Masked as X-import Torch.Indef.Cuda.Short.Tensor.Math as X-import Torch.Indef.Cuda.Short.Tensor.Math.Compare as X-import Torch.Indef.Cuda.Short.Tensor.Math.CompareT as X-import Torch.Indef.Cuda.Short.Tensor.Math.Pairwise as X-import Torch.Indef.Cuda.Short.Tensor.Math.Pointwise as X-import Torch.Indef.Cuda.Short.Tensor.Math.Reduce as X-import Torch.Indef.Cuda.Short.Tensor.Math.Scan as X-import Torch.Indef.Cuda.Short.Tensor.Mode as X-import Torch.Indef.Cuda.Short.Tensor.ScatterGather as X-import Torch.Indef.Cuda.Short.Tensor.Sort as X-import Torch.Indef.Cuda.Short.Tensor.TopK as X--import Torch.Indef.Cuda.Short.Tensor.Math.Pointwise.Signed as X
− src/Torch/Cuda/Short/Dynamic.hs
@@ -1,28 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Cuda.Short.Dynamic--- Copyright :  (c) Sam Stites 2017--- License   :  BSD3--- Maintainer:  sam@stites.io--- Stability :  experimental--- Portability: non-portable---------------------------------------------------------------------------------module Torch.Cuda.Short.Dynamic (module X) where--import Torch.Indef.Cuda.Short.Dynamic.Tensor as X-import Torch.Indef.Cuda.Short.Dynamic.Tensor.Copy as X-import Torch.Indef.Cuda.Short.Dynamic.Tensor.Index as X-import Torch.Indef.Cuda.Short.Dynamic.Tensor.Masked as X-import Torch.Indef.Cuda.Short.Dynamic.Tensor.Math as X-import Torch.Indef.Cuda.Short.Dynamic.Tensor.Math.Compare as X-import Torch.Indef.Cuda.Short.Dynamic.Tensor.Math.CompareT as X-import Torch.Indef.Cuda.Short.Dynamic.Tensor.Math.Pairwise as X-import Torch.Indef.Cuda.Short.Dynamic.Tensor.Math.Pointwise as X-import Torch.Indef.Cuda.Short.Dynamic.Tensor.Math.Reduce as X-import Torch.Indef.Cuda.Short.Dynamic.Tensor.Math.Scan as X-import Torch.Indef.Cuda.Short.Dynamic.Tensor.Mode as X-import Torch.Indef.Cuda.Short.Dynamic.Tensor.ScatterGather as X-import Torch.Indef.Cuda.Short.Dynamic.Tensor.Sort as X-import Torch.Indef.Cuda.Short.Dynamic.Tensor.TopK as X--import Torch.Indef.Cuda.Short.Dynamic.Tensor.Math.Pointwise.Signed as X
− src/Torch/Cuda/Short/Storage.hs
@@ -1,13 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Cuda.Short.Storage--- Copyright :  (c) Sam Stites 2017--- License   :  BSD3--- Maintainer:  sam@stites.io--- Stability :  experimental--- Portability: non-portable---------------------------------------------------------------------------------module Torch.Cuda.Short.Storage (module X) where--import Torch.Indef.Cuda.Short.Storage      as X-import Torch.Indef.Cuda.Short.Storage.Copy as X
+ src/Torch/DType.hs view
@@ -0,0 +1,214 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}++module Torch.DType where++import Data.Complex+import qualified Numeric.Half as N+import Data.Int+import Data.Reflection+import Data.Word+import Torch.Internal.Class (Castable (..))+import qualified Torch.Internal.Const as ATen+import qualified Torch.Internal.Type as ATen++data DType+  = -- | Bool+    Bool+  | -- | Byte+    UInt8+  | -- | Char+    Int8+  | -- | Short+    Int16+  | -- | Int+    Int32+  | -- | Long+    Int64+  | -- | Half+    Half+  | -- | Float+    Float+  | -- | Double+    Double+  | -- | ComplexHalf+    ComplexHalf+  | -- | ComplexFloat+    ComplexFloat+  | -- | ComplexDouble+    ComplexDouble+  | -- | QInt8+    QInt8+  | -- | QUInt8+    QUInt8+  | -- | QInt32+    QInt32+  | -- | BFloat16+    BFloat16+  deriving (Eq, Show, Read)++instance Reifies Bool DType where+  reflect _ = Bool++instance Reifies 'Bool DType where+  reflect _ = Bool++instance Reifies Word8 DType where+  reflect _ = UInt8++instance Reifies Int8 DType where+  reflect _ = Int8++instance Reifies 'Int8 DType where+  reflect _ = Int8++instance Reifies Int16 DType where+  reflect _ = Int16++instance Reifies 'Int16 DType where+  reflect _ = Int16++instance Reifies Int32 DType where+  reflect _ = Int32++instance Reifies 'Int32 DType where+  reflect _ = Int32++instance Reifies Int DType where+  reflect _ = Int64++instance Reifies Int64 DType where+  reflect _ = Int64++instance Reifies 'Int64 DType where+  reflect _ = Int64++instance Reifies N.Half DType where+  reflect _ = Half++instance Reifies 'Half DType where+  reflect _ = Half++instance Reifies Float DType where+  reflect _ = Float++instance Reifies 'Float DType where+  reflect _ = Float++instance Reifies Double DType where+  reflect _ = Double++instance Reifies 'Double DType where+  reflect _ = Double++instance Reifies (Complex N.Half) DType where+  reflect _ = ComplexHalf++instance Reifies 'ComplexHalf DType where+  reflect _ = ComplexHalf++instance Reifies (Complex Float) DType where+  reflect _ = ComplexFloat++instance Reifies 'ComplexFloat DType where+  reflect _ = ComplexFloat++instance Reifies (Complex Double) DType where+  reflect _ = ComplexDouble++instance Reifies 'ComplexDouble DType where+  reflect _ = ComplexDouble++instance Castable DType ATen.ScalarType where+  cast Bool f = f ATen.kBool+  cast UInt8 f = f ATen.kByte+  cast Int8 f = f ATen.kChar+  cast Int16 f = f ATen.kShort+  cast Int32 f = f ATen.kInt+  cast Int64 f = f ATen.kLong+  cast Half f = f ATen.kHalf+  cast Float f = f ATen.kFloat+  cast Double f = f ATen.kDouble+  cast ComplexHalf f = f ATen.kComplexHalf+  cast ComplexFloat f = f ATen.kComplexFloat+  cast ComplexDouble f = f ATen.kComplexDouble+  cast QInt8 f = f ATen.kQInt8+  cast QUInt8 f = f ATen.kQUInt8+  cast QInt32 f = f ATen.kQInt32+  cast BFloat16 f = f ATen.kBFloat16++  uncast x f+    | x == ATen.kBool = f Bool+    | x == ATen.kByte = f UInt8+    | x == ATen.kChar = f Int8+    | x == ATen.kShort = f Int16+    | x == ATen.kInt = f Int32+    | x == ATen.kLong = f Int64+    | x == ATen.kHalf = f Half+    | x == ATen.kFloat = f Float+    | x == ATen.kDouble = f Double+    | x == ATen.kComplexHalf = f ComplexHalf+    | x == ATen.kComplexFloat = f ComplexFloat+    | x == ATen.kComplexDouble = f ComplexDouble+    | x == ATen.kQInt8 = f QInt8+    | x == ATen.kQUInt8 = f QUInt8+    | x == ATen.kQInt32 = f QInt32+    | x == ATen.kBFloat16 = f BFloat16++isIntegral :: DType -> Bool+isIntegral Bool = True+isIntegral UInt8 = True+isIntegral Int8 = True+isIntegral Int16 = True+isIntegral Int32 = True+isIntegral Int64 = True+isIntegral Half = False+isIntegral Float = False+isIntegral Double = False+isIntegral ComplexHalf = False+isIntegral ComplexFloat = False+isIntegral ComplexDouble = False+isIntegral QInt8 = False+isIntegral QUInt8 = False+isIntegral QInt32 = False+isIntegral BFloat16 = False++isComplex :: DType -> Bool+isComplex Bool = False+isComplex UInt8 = False+isComplex Int8 = False+isComplex Int16 = False+isComplex Int32 = False+isComplex Int64 = False+isComplex Half = False+isComplex Float = False+isComplex Double = False+isComplex ComplexHalf = True+isComplex ComplexFloat = True+isComplex ComplexDouble = True+isComplex QInt8 = False+isComplex QUInt8 = False+isComplex QInt32 = False+isComplex BFloat16 = False++byteLength :: DType -> Int+byteLength dtype =+  case dtype of+    Bool -> 1+    UInt8 -> 1+    Int8 -> 1+    Int16 -> 2+    Int32 -> 4+    Int64 -> 8+    Half -> 2+    Float -> 4+    Double -> 8+    ComplexHalf -> 4+    ComplexFloat -> 8+    ComplexDouble -> 16+    QInt8 -> 1+    QUInt8 -> 1+    QInt32 -> 4+    BFloat16 -> 2
+ src/Torch/Data.hs view
@@ -0,0 +1,47 @@+-- |+-- Modules for defining datasets and how to efficiently iterate over them.+-- If you have an indexable (fixed-size) dataset, see "Torch.Data.Pipeline". If you+-- want to stream in your data then see "Torch.Data.StreamedPipeline". The "Torch.Data.Utils" module+-- provides some convienient functions for both indexable and streamed datasets.+--+-- The mnist examples show how to run data for a predefined dataset.+module Torch.Data+  ( -- * Running data+    -- $data+    module Torch.Data.Pipeline,+    module Torch.Data.StreamedPipeline,+    module Torch.Data.Utils,+  )+where++import Torch.Data.Pipeline+import Torch.Data.StreamedPipeline+import Torch.Data.Utils++-- $data+--+--+--  The preferred method for running data is the same for both 'Dataset' and 'Datastream'. The intended use is to+-- use the 'streamFrom' family of functions and run the continuation returned by those functions with a function+-- that specifies what to do with the given stream. Datasets are then a [pipes](https://hackage.haskell.org/package/pipes)+-- stream of samples, so anything that you can with a pipes stream you can do with a 'Dataset' or 'Datastream'. As+-- such you should have some basic familiarity with pipes streams, though+-- typically you'll want to a fold over the dataset, where "Pipes.Prelude" has convenient functions for folding streams.+--+--+-- > import qualified Pipes.Prelude as P+-- > import Pipes+-- >+-- > -- Take a model and a stream of data from a Dataset or Datastream,+-- > -- and train the model.+-- > train :: model -> ListT m sample -> m model+-- > train model = runEffect . P.foldM step begin done . enumerate+-- >   where+-- >       -- run a training step over a given sample from the dataset+-- >       step model batch = undefined+-- >       begin = pure model+-- >       done = pure+-- >+-- > runData = runContT (train model) $ streamFromMap (datasetOptions 1) myDataset+--+-- See the [foldl](https://hackage.haskell.org/package/foldl) library for the style of fold used here.
+ src/Torch/Data/CsvDatastream.hs view
@@ -0,0 +1,163 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-}++module Torch.Data.CsvDatastream+  ( BufferSize,+    NamedColumns (..),+    CsvDatastream' (..),+    CsvDatastream,+    CsvDatastreamNamed,+    csvDatastream,+    tsvDatastream,++    -- * Reexports+    FromField (..),+    FromRecord (..),+    FromNamedRecord (..),+  )+where++import qualified Control.Foldl as L+import Control.Monad+import Control.Monad.ST+import Data.Array.ST+import Data.Char (ord)+import Data.Csv (DecodeOptions (decDelimiter))+import Data.STRef+import Data.Vector (Vector)+import qualified Data.Vector as V+import Lens.Family (view)+import Pipes+import qualified Pipes.ByteString as B+import Pipes.Csv+import Pipes.Group (chunksOf, folds)+import qualified Pipes.Prelude as P+import qualified Pipes.Safe as Safe+import qualified Pipes.Safe.Prelude as Safe+import System.IO (IOMode (ReadMode))+import System.Random+import Torch.Data.StreamedPipeline++data NamedColumns = Unnamed | Named++type BufferSize = Int++-- TODO: implement more options++-- | A CSV datastream. The datastream instance of this type streams+-- samples of `batches` from a CSV file at the specified file path. Batches+-- are yielded in constant memory, but if shuffling is enabled, then there+-- will be at most @'BufferSize'@ records stored in memory.+data CsvDatastream' batches (named :: NamedColumns) = CsvDatastream'+  { -- | CSV file path.+    filePath :: FilePath,+    -- | Column delimiter.+    delimiter :: !B.Word8,+    -- | Does the file have a header?+    hasHeader :: HasHeader,+    -- | Batch size.+    -- , filter     :: Maybe (batches -> Bool)+    batchSize :: Int,+    -- | Buffered shuffle with specified buffer size.+    bufferedShuffle :: Maybe BufferSize,+    -- | Drop the last batch if it is less than batch size.+    dropLast :: Bool+  }++-- | A specialized version of CsvDatastream'. Use this type if you want to decode+-- a CSV file with records defined by the order of the columns.+type CsvDatastream batches = CsvDatastream' batches Unnamed++-- | A specialized version of CsvDatastream'. Use this type if you want to decode+-- a CSV file with records that have @'FromNamedRecord'@ instance. This decodes each field+-- of the record by the corresponding column with the given header name.+type CsvDatastreamNamed batches = CsvDatastream' batches Named++-- | Produce a CsvDatastream' from the given file with default options, and tab separated columns.+tsvDatastream :: forall (isNamed :: NamedColumns) batches. FilePath -> CsvDatastream' batches isNamed+tsvDatastream filePath = (csvDatastream filePath) {delimiter = fromIntegral $ ord '\t'}++-- | Produce a CsvDatastream' from the given file with default options, and comma separated columns.+csvDatastream :: forall (isNamed :: NamedColumns) batches. FilePath -> CsvDatastream' batches isNamed+csvDatastream filePath =+  CsvDatastream'+    { filePath = filePath,+      delimiter = fromIntegral $ ord ',',+      hasHeader = NoHeader,+      batchSize = 1,+      -- , filter = Nothing+      bufferedShuffle = Nothing,+      dropLast = True+    }++instance+  ( MonadBaseControl IO m,+    Safe.MonadSafe m,+    FromRecord batch+  ) =>+  Datastream m () (CsvDatastream batch) (Vector batch)+  where+  streamSamples csv@CsvDatastream' {..} _ = readCsv csv (decodeWith (defaultDecodeOptions {decDelimiter = delimiter}) hasHeader)++instance+  ( MonadBaseControl IO m,+    Safe.MonadSafe m,+    FromNamedRecord batch+  ) =>+  Datastream m () (CsvDatastreamNamed batch) (Vector batch)+  where+  streamSamples csv@CsvDatastream' {..} _ = readCsv csv (decodeByNameWith (defaultDecodeOptions {decDelimiter = delimiter}))++readCsv CsvDatastream' {..} decode = Select $+  Safe.withFile filePath ReadMode $ \fh ->+    -- this quietly discards errors in decoding right now, probably would like to log this+    if dropLast+      then streamRecords fh >-> P.filter (\v -> V.length v == batchSize)+      else streamRecords fh+  where+    streamRecords fh = case bufferedShuffle of+      Nothing -> L.purely folds L.vector $ view (chunksOf batchSize) $ decode (produceLine fh) >-> P.concat+      Just bufferSize ->+        L.purely folds L.vector $+          view (chunksOf batchSize) $+            (L.purely folds L.list $ view (chunksOf bufferSize) $ decode (produceLine fh) >-> P.concat) >-> shuffleRecords+    -- what's a good default chunk size?+    produceLine fh = B.hGetSome 1000 fh+    -- probably want a cleaner way of reyielding these chunks+    shuffleRecords = do+      chunks <- await+      std <- Torch.Data.StreamedPipeline.liftBase newStdGen+      mapM_ yield $ fst $ shuffle' chunks std++--  https://wiki.haskell.org/Random_shuffle+shuffle' :: [a] -> StdGen -> ([a], StdGen)+shuffle' xs gen =+  runST+    ( do+        g <- newSTRef gen+        let randomRST lohi = do+              (a, s') <- liftM (randomR lohi) (readSTRef g)+              writeSTRef g s'+              return a+        ar <- newArray n xs+        xs' <- forM [1 .. n] $ \i -> do+          j <- randomRST (i, n)+          vi <- readArray ar i+          vj <- readArray ar j+          writeArray ar j vi+          return vj+        gen' <- readSTRef g+        return (xs', gen')+    )+  where+    n = Prelude.length xs+    newArray :: Int -> [a] -> ST s (STArray s Int a)+    newArray n xs = newListArray (1, n) xs
+ src/Torch/Data/Dataset.hs view
@@ -0,0 +1,32 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}++module Torch.Data.Dataset where++import qualified Control.Foldl as L+import Lens.Family (view)+import Pipes (ListT (Select), Pipe, Producer, enumerate, (>->))+import Pipes.Group (chunksOf, folds)+import Torch.Data.StreamedPipeline++-- | This type is actually not very useful.+-- | It would actually be better to define a transform+-- | on top of another dataset, since then we can do this in parallel+data CollatedDataset m dataset batch collatedBatch = CollatedDataset+  { set :: dataset,+    chunkSize :: Int,+    collateFn :: Pipe [batch] collatedBatch m ()+  }++instance Datastream m seed dataset batch => Datastream m seed (CollatedDataset m dataset batch collatedBatch) collatedBatch where+  streamSamples CollatedDataset {..} =+    Select+      . (>-> collateFn)+      . L.purely folds L.list+      . view (chunksOf chunkSize)+      . enumerate+      . streamSamples set
+ src/Torch/Data/Internal.hs view
@@ -0,0 +1,89 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}++module Torch.Data.Internal where++import Control.Concurrent.Async.Lifted (concurrently)+import qualified Control.Concurrent.STM as STM+import Control.Exception.Safe (bracket, finally)+import Control.Monad (when)+import Control.Monad.Base (MonadBase (..))+import Control.Monad.Cont (ContT (ContT))+import Control.Monad.Trans.Control+import Pipes+import Pipes.Concurrent hiding (atomically)+import qualified Pipes.Prelude as P++runWithBuffer ::+  forall a m b.+  (MonadBaseControl IO m) =>+  Int ->+  (Output a -> m ()) ->+  -- ContT b m (ListT m (a, Int))+  ContT b m (ListT m a)+runWithBuffer bufferSize batchHandler = ContT $ \f ->+  snd+    <$> withBufferLifted+      (bounded bufferSize)+      (\batchOutput -> batchHandler batchOutput)+      -- (\input -> f . Select $ P.zip (fromInput' input) iters)+      (\input -> f . Select $ fromInput' input)++liftedBracket :: MonadBaseControl IO m => m a -> (a -> m b) -> (a -> m c) -> m c+liftedBracket acquire release action = control $ \runInIO ->+  bracket+    (runInIO acquire)+    (\saved -> runInIO (restoreM saved >>= release))+    (\saved -> runInIO (restoreM saved >>= action))++withBufferLifted ::+  (MonadBaseControl IO m) =>+  Buffer a ->+  (Output a -> m l) ->+  (Input a -> m r) ->+  m (l, r)+withBufferLifted buffer fOutput fInput =+  liftedBracket+    (liftBase $ spawn' buffer)+    (\(_, _, seal) -> liftBase $ atomically seal)+    ( \(output, input, seal) ->+        concurrently+          (fOutput output `liftedFinally` (liftBase $ atomically seal))+          (fInput input `liftedFinally` (liftBase $ atomically seal))+    )++fromInput' :: (MonadBase IO m) => Input a -> Producer' a m ()+fromInput' input = loop+  where+    loop = do+      ma <- liftBase $ atomically $ recv input+      case ma of+        Nothing -> return ()+        Just a -> do+          yield a+          loop++toOutput' :: (MonadBase IO m) => Output a -> Consumer' a m ()+toOutput' output = loop+  where+    loop = do+      a <- await+      alive <- liftBase $ atomically $ send output a+      when alive loop++liftedFinally :: MonadBaseControl IO m => m a -> m b -> m a+liftedFinally a sequel = control $ \runInIO ->+  finally+    (runInIO a)+    (runInIO sequel)++atomically :: MonadIO m => STM a -> m a+atomically = liftIO . STM.atomically++instance (MonadBase IO m) => MonadBase IO (Proxy a' a b' b m) where+  liftBase = lift . liftBase++---- make a runData function which just does runContT but zips that+---- the listT with the iteration! This is much better
+ src/Torch/Data/Pipeline.hs view
@@ -0,0 +1,163 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE PartialTypeSignatures #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TupleSections #-}+{-# LANGUAGE TypeOperators #-}++module Torch.Data.Pipeline+  ( -- * Defining a Dataset+    -- $dataset++    -- * Dataset+    Dataset (..),+    DatasetOptions (..),+    datasetOpts,+    Sample (..),++    -- * Dataloading+    streamFromMap,+  )+where++import Control.Concurrent.Async.Lifted+import Control.Concurrent.STM hiding (atomically)+import Control.Monad+import Control.Monad.Base (MonadBase)+import Control.Monad.Cont (ContT)+import Control.Monad.Trans.Control (MonadBaseControl (..))+import Data.IntMap (IntMap)+import qualified Data.IntMap as I+import Data.Set+import Pipes+import Pipes.Concurrent hiding (atomically)+import System.Random+import Torch.Data.Internal++-- $dataset+-- See the 'Torch.Vision' module which implements the MNIST dataset for a good example of how to define a dataset.++-- | The base dataset class. A dataset is capable of returning a sample+-- for a given key, and every 'Dataset' has a known set of keys.+class (Ord k) => Dataset m dataset k sample | dataset -> m, dataset -> sample, dataset -> k where+  getItem :: dataset -> k -> m sample+  keys :: dataset -> Set k++-- | Dataset options used when loading datasets. Specify shuffling behavior, the number of+-- threads to use, and the buffer size used to store retrieved samples in each thread.+data DatasetOptions = DatasetOptions+  { -- | Max number of samples stored in each buffer at a given time.+    dataBufferSize :: Int,+    -- | Number of threads retrieving samples.+    numWorkers :: Int,+    -- | The ordering of samples streamed.+    shuffle :: Sample+  }++-- | Default 'DatasetOptions'. The 'Int' parameter specifies the+-- number of workers, and sets the buffer size equal to the number of workers.+-- Sampling is sequential.+datasetOpts :: Int -> DatasetOptions+datasetOpts numWorkers =+  DatasetOptions+    { dataBufferSize = numWorkers,+      numWorkers = numWorkers,+      shuffle = Sequential+    }++-- | A 'Sample' determines the ordering of samples streamed out of a dataset.+-- You can either order sequentially, or supply a random generator to shuffle samples.+data Sample where+  Sequential :: Sample+  Shuffle :: RandomGen g => g -> Sample++---------------------- Workflow --------------------+-- - make a new map of keys to TVars of samples, possibly shuffled keys, tracking which keys have been sampled+-- - create a TQueue of keys (using pipes-concurrency wrapper)+-- - fork off workers which all pull from the TQueue and sample that key using the dataset,+--   then update the TVar associated with that key+-- have a worker waiting for each successive key to be updated in the list of (key, TVar)++-- | Return a stream of samples from the given dataset, along with a new 'Sample' value.+-- The returned stream contains every sample returned by @'getItem'@ for every key in the set of keys+-- associated with the given dataset. The returned 'Sample' value returns an updated 'Sample' value,+-- this will be identical to the original 'Sample' value if sampling is 'Sequential' but will return a new random number generator+-- if sampling is 'Shuffle'.+streamFromMap ::+  forall m dataset k sample r.+  (Dataset m dataset k sample, MonadIO m, MonadBaseControl IO m) =>+  DatasetOptions ->+  dataset ->+  ContT r m (ListT m sample, Sample)+streamFromMap DatasetOptions {..} dataset = do+  (keyOutput, keyInput, seal) <- liftIO $ spawn' unbounded++  let retrieveSet = liftIO $ keyTVarSet $ keys dataset+  (keyTVarSet, updatedSample) <- case shuffle of+    Sequential -> (,Sequential) <$> retrieveSet+    Shuffle g -> fmap Shuffle . fisherYates g <$> retrieveSet++  -- fill the queue with each key and associated TVar then seal it+  keyQueue keyOutput keyTVarSet+  liftIO $ atomically seal++  let workers = runWorkers numWorkers dataset keyInput+      datastream = awaitNextItem keyTVarSet+  listT <- runWithBuffer dataBufferSize $ \output -> concurrently_ workers (datastream output)+  pure (listT, updatedSample)++runWorkers ::+  (Dataset m dataset k sample, MonadIO m, MonadBaseControl IO m) =>+  Int ->+  dataset ->+  Input (k, TVar (Maybe sample)) ->+  m ()+runWorkers numWorkers dataset keyInput = replicateConcurrently_ numWorkers (runEffect $ fromInput' keyInput >-> runWorker)+  where+    runWorker = forever $ do+      (key, tvar) <- await+      item <- lift $ getItem dataset key+      atomically $ writeTVar tvar (Just item)++awaitNextItem ::+  (MonadBase IO m, MonadIO m) =>+  [(k, TVar (Maybe sample))] ->+  Output sample ->+  m ()+awaitNextItem tvars output = runEffect $ each tvars >-> readNextItem >-> toOutput' output+  where+    readNextItem = forever $ do+      (_, tvar) <- await+      item <- atomically $ do+        val <- readTVar tvar+        case val of+          Nothing -> retry+          Just item -> writeTVar tvar Nothing >> pure item -- reset the tvar once we get the sample out of it to save memory+      yield item++keyTVarSet :: MonadIO m => Set k -> m [(k, TVar (Maybe sample))]+keyTVarSet = atomically . mapM (\k -> (,) k <$> newTVar Nothing) . toList++keyQueue :: MonadBase IO m => Output (k, TVar (Maybe sample)) -> [(k, TVar (Maybe sample))] -> m ()+keyQueue keyOutput keyTVarSet = runEffect $ each keyTVarSet >-> toOutput' keyOutput++fisherYatesStep :: RandomGen g => (IntMap a, g) -> (Int, a) -> (IntMap a, g)+fisherYatesStep (m, gen) (i, x) = ((I.insert j x . I.insert i (m I.! j)) m, gen')+  where+    (j, gen') = randomR (0, i) gen++fisherYates :: RandomGen g => g -> [a] -> ([a], g)+fisherYates gen [] = ([], gen)+fisherYates gen l =+  toElems $ Prelude.foldl fisherYatesStep (initial (head l) gen) (numerate (tail l))+  where+    toElems (x, y) = (I.elems x, y)+    numerate = zip [1 ..]+    initial x gen = (I.singleton 0 x, gen)
+ src/Torch/Data/StreamedPipeline.hs view
@@ -0,0 +1,179 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE PartialTypeSignatures #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TupleSections #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}++module Torch.Data.StreamedPipeline+  ( -- * Defining a Datastream+    -- $dataset++    -- * Datastream+    Datastream (..),+    DatastreamOptions (..),+    datastreamOpts,++    -- * Dataloading+    streamFrom,+    streamFrom',++    -- * Reexports+    MonadBase (..),+    MonadBaseControl (..),+  )+where++import Control.Arrow (second)+import Control.Concurrent.Async.Lifted+import Control.Concurrent.STM hiding (atomically)+import Control.Foldl (FoldM)+import qualified Control.Foldl as L+import Control.Monad+import Control.Monad.Base (MonadBase, liftBase)+import Control.Monad.Cont (ContT (..))+import Control.Monad.Trans.Control+import qualified Data.Vector as V+import Pipes+import Pipes.Concurrent hiding (atomically)+import qualified Pipes.Prelude as P+import Torch.Data.Internal++-- $dataset+-- We will show how to retrieve the IMDB dataset as an example datastream.+-- The dataset used here can be found at https://ai.stanford.edu/~amaas/data/sentiment/+--+-- > import Pipes+-- > import qualified Pipes.Safe as Safe+-- > import qualified Pipes.Prelude as P+-- > import System.Directory+-- >+-- > newtype Imdb = Imdb { dataDir :: String }+-- >+-- > data Sentiment = Positive | Negative+-- >+-- > instance (MonadBaseControl IO m, MonadSafe m) => Datastream m Sentiment Imdb (Text, Sentiment) where+-- >   streamSamples Imdb{..} sent = Select $ do+-- >     rawFilePaths <- zip (repeat sent) <$> (liftIO $ listDirectory (dataDir </> sentToPath sent))+-- >     let filePaths = fmap (second $ mappend (dataDir </> sentToPath sent)) rawFilePaths+-- >     for (each filePaths) $ \(rev, fp) -> Safe.withFile fp ReadMode $ \fh ->+-- >       P.zip (PT.fromHandleLn fh) (yield rev)+-- >         where sentToPath Pos = "pos" ++ pure pathSeparator+-- >               sentToPath Neg = "neg" ++ pure pathSeparator+--+-- This streams in movie reviews from each file in either the positive review directory or+-- the negative review directory, depending on the seed value used.+--+-- This highlights a use of seed values that is more interesting than just specifying the thread count, but also has some problems.+-- When running this datastream with either 'streamFrom' or 'streamFrom\'', you need to supply both 'Positive' and 'Negative' values as seeds+-- to retrieve the entire IMDB dataset, and in this case positive and negative reviews will be streamed in concurrently.+-- The problem with designing a datastream in this fashion is you limit the amount of concurrency (2 threads in this case) without+-- duplicating data. Ultimately though seeds should be quite flexible and allow you to design the concurrency how you see fit. Be careful+-- not to use duplicate seed values unless you want duplicate data.++-- | The base datastream class. A dataset returns a stream of samples+-- based on a seed value.+class Monad m => Datastream m seed dataset sample | dataset -> sample where+  streamSamples :: dataset -> seed -> ListT m sample++-- | Datastream options used when looding datastreams. Currently only buffer size is configurable,+-- since thread count is controlled by the number of seeds (see @'streamFrom'@ functions).+newtype DatastreamOptions = DatastreamOptions+  { -- | Max number of samples stored in each buffer at a given time.+    bufferSize :: Int+  }++-- | Default dataloader options, you should override the fields in this record.+datastreamOpts :: DatastreamOptions+datastreamOpts = DatastreamOptions {bufferSize = 4} -- 4 is relatively arbitrary++-- | Return a stream of samples from the given dataset as a continuation.+-- A stream of samples is generated for every seed in the given stream of seeds, and all of these streams are merged+-- into the output stream in a non-deterministic order (if you need determinism see 'streamFrom\'').+-- Every stream created for each seed value is made in its own thread.+streamFrom ::+  forall sample m dataset seed b.+  (Datastream m seed dataset sample, MonadBaseControl IO m, MonadBase IO m) =>+  DatastreamOptions ->+  dataset ->+  ListT m seed ->+  ContT b m (ListT m sample)+streamFrom DatastreamOptions {..} dataset seeds = runWithBuffer bufferSize $ readSamples dataset seeds++-- | This function is the same as 'streamFrom' except the seeds are specified as+-- a 'Foldable', and the stream returned has a deterministic ordering. The results+-- from each given seed are interspersed in the order defined by the @'Foldable'@ of seeds.+streamFrom' ::+  forall sample m f dataset seed b.+  (Show sample, Datastream m seed dataset sample, MonadBaseControl IO m, MonadBase IO m, MonadIO m, Foldable f) =>+  DatastreamOptions ->+  dataset ->+  f seed ->+  ContT b m (ListT m sample)+streamFrom' DatastreamOptions {..} dataset seeds = do+  workerTracker <- atomically $ newTVar 0+  let consumeSeeds mailboxes o = do+        for (each mailboxes) $ \(_, input, _) -> fromInputOnce workerTracker input >-> toOutput' o+        keepReading <- lift $ atomically $ (\x -> x < V.length mailboxes) <$> readTVar workerTracker+        when keepReading $ consumeSeeds mailboxes o+  runWithBuffer bufferSize $ \o ->+    liftedBracket+      (L.foldM pairSeedWithBuffer seeds)+      (mapM_ (atomically . third . snd))+      ( \a ->+          let mailboxes = snd <$> a+              seedAndOutput = second fst3 <$> a+           in concurrently_+                (readSamplesDeterministic dataset seedAndOutput `liftedFinally` mapM_ (atomically . third) mailboxes)+                (runEffect (consumeSeeds mailboxes o) `liftedFinally` mapM_ (atomically . third) mailboxes)+      )+  where+    fst3 (a, _, _) = a+    third (_, _, c) = c++readSamples ::+  forall m seed dataset sample.+  (Datastream m seed dataset sample, MonadBaseControl IO m) =>+  dataset ->+  ListT m seed ->+  Output sample ->+  m ()+readSamples dataset seeds outputBox =+  let this = flip $ mappend . Concurrently . runEffect . (>-> toOutput' outputBox) . enumerate . streamSamples @m @seed @dataset @sample dataset+   in join . P.fold this mempty runConcurrently $ enumerate seeds++readSamplesDeterministic ::+  forall m seed f dataset sample.+  (Datastream m seed dataset sample, MonadBaseControl IO m, MonadIO m, Foldable f) =>+  dataset ->+  f (seed, Output sample) ->+  m ()+readSamplesDeterministic dataset seeds =+  let this c (seed, outputBox) =+        mappend c . Concurrently . runEffect . (>-> toOutput' outputBox) . enumerate $ streamSamples @m @seed @dataset @sample dataset seed+   in L.fold (L.Fold this mempty runConcurrently) seeds++pairSeedWithBuffer :: MonadIO m => FoldM m seed (V.Vector (seed, (Output a, Input a, STM ())))+pairSeedWithBuffer = L.premapM (\a -> (a,) <$> makeMailbox) $ L.generalize L.vector+  where+    makeMailbox = liftIO $ spawn' (bounded 1)++fromInputOnce :: MonadIO m => TVar Int -> Input a -> Producer a m ()+fromInputOnce workerTracker input = do+  ma <- atomically $ recv input+  case ma of+    Nothing -> do+      atomically $ readTVar workerTracker >>= writeTVar workerTracker . (+) 1+      return ()+    Just a -> do+      yield a+      return ()
+ src/Torch/Data/Utils.hs view
@@ -0,0 +1,94 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RecordWildCards #-}++module Torch.Data.Utils+  ( pmap,+    pmap',+    pmapGroup,+    bufferedCollate,+    collate,+    enumerateData,+    CachedDataset,+    cache,+  )+where++import qualified Control.Foldl as L+import Control.Monad.Cont+import Control.Monad.Trans.Control+import Data.Kind (Type)+import Data.IntMap.Strict (IntMap)+import qualified Data.IntMap.Strict as M+import qualified Data.Set as S+import Lens.Family+import Pipes+import Pipes.Concurrent+import Pipes.Group+import qualified Pipes.Prelude as P+import Torch.Data.Internal+import Torch.Data.Pipeline++-- | Run a map function in parallel over the given stream.+pmap :: (MonadIO m, MonadBaseControl IO m) => Buffer b -> (a -> b) -> ListT m a -> ContT r m (ListT m b)+pmap buffer f prod = ContT $ \cont ->+  snd+    <$> withBufferLifted+      buffer+      (\output -> runEffect $ enumerate prod >-> P.map f >-> toOutput' output)+      (\input -> cont $ Select $ fromInput' input)++-- | Run a pipe in parallel over the given stream.+pmap' :: (MonadIO m, MonadBaseControl IO m) => Buffer b -> Pipe a b m () -> ListT m a -> ContT r m (ListT m b)+pmap' buffer f prod = ContT $ \cont ->+  snd+    <$> withBufferLifted+      buffer+      (\output -> runEffect $ enumerate prod >-> f >-> toOutput' output)+      (\input -> cont $ Select $ fromInput' input)++-- | Map a ListT transform over the given the stream in parallel. This should be useful+-- for using functions which groups elements of a stream and yields them downstream.+pmapGroup :: (MonadIO m, MonadBaseControl IO m) => Buffer b -> (ListT m a -> ListT m b) -> ListT m a -> ContT r m (ListT m b)+pmapGroup buffer f prod = ContT $ \cont ->+  snd+    <$> withBufferLifted+      buffer+      (\output -> runEffect $ enumerate (f prod) >-> toOutput' output)+      (\input -> cont $ Select $ fromInput' input)++-- | Enumerate the given stream, zipping each element with an index.+enumerateData :: Monad m => ListT m a -> Producer (a, Int) m ()+enumerateData input = P.zip (enumerate input) (each [0 ..])++-- | Run a given batching function in parallel. See 'collate' for how the+-- given samples are batched.+bufferedCollate :: (MonadIO m, MonadBaseControl IO m) => Buffer batch -> Int -> ([sample] -> Maybe batch) -> ListT m sample -> ContT r m (ListT m batch)+bufferedCollate buffer batchSize collateFn = pmapGroup buffer (collate batchSize collateFn)++-- | Run a batching function with integer batch size over the given stream. The elements of the stream are+-- split into lists of the given batch size and are collated with the given function. Only Just values are yielded+-- downstream. If the last chunk of samples is less than the given batch size then the batching function will be passed a list+-- of length less than batch size.+collate :: Monad m => Int -> ([sample] -> Maybe batch) -> ListT m sample -> ListT m batch+collate batchSize collateFn = Select . (>-> P.mapFoldable collateFn) . L.purely folds L.list . view (chunksOf batchSize) . enumerate++-- | An In-Memory cached dataset. See the 'cache' function for+-- how to create a cached dataset.+newtype CachedDataset (m :: Type -> Type) sample = CachedDataset {cached :: IntMap sample}++-- | Enumerate a given stream and store it as a 'CachedDataset'. This function should+-- be used after a time consuming preprocessing pipeline and used in subsequent epochs+-- to avoid repeating the preprocessing pipeline.+cache :: Monad m => ListT m sample -> m (CachedDataset m sample)+cache datastream = P.fold step begin done . enumerate $ datastream+  where+    step (cacheMap, ix) sample = (M.insert ix sample cacheMap, ix + 1)+    begin = (M.empty, 0)+    done = CachedDataset . fst++instance Applicative m => Dataset m (CachedDataset m sample) Int sample where+  getItem CachedDataset {..} key = pure $ cached M.! key+  keys CachedDataset {..} = S.fromAscList [0 .. M.size cached]
+ src/Torch/Device.hs view
@@ -0,0 +1,25 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}++module Torch.Device where++import qualified Data.Int as I+import Torch.Internal.Class (Castable (..))+import qualified Torch.Internal.Const as ATen+import qualified Torch.Internal.Type as ATen++data DeviceType = CPU | CUDA | MPS+  deriving (Eq, Ord, Show)++data Device = Device {deviceType :: DeviceType, deviceIndex :: I.Int16}+  deriving (Eq, Ord, Show)++instance Castable DeviceType ATen.DeviceType where+  cast CPU f = f ATen.kCPU+  cast CUDA f = f ATen.kCUDA+  cast MPS f = f ATen.kMPS++  uncast x f+    | x == ATen.kCPU = f CPU+    | x == ATen.kCUDA = f CUDA+    | x == ATen.kMPS = f MPS
+ src/Torch/Dimname.hs view
@@ -0,0 +1,36 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables #-}++module Torch.Dimname where++import Data.String+import Foreign.ForeignPtr+import System.IO.Unsafe+import Torch.Internal.Class (Castable (..))+import qualified Torch.Internal.Const as ATen+import qualified Torch.Internal.Managed.Type.Dimname as ATen+import qualified Torch.Internal.Managed.Type.StdString as ATen+import qualified Torch.Internal.Managed.Type.Symbol as ATen+import qualified Torch.Internal.Type as ATen++newtype Dimname = Dimname (ForeignPtr ATen.Dimname)++instance IsString Dimname where+  fromString str = unsafePerformIO $ do+    str' <- ATen.newStdString_s str+    symbol <- ATen.dimname_s str'+    dimname <- ATen.fromSymbol_s symbol+    return $ Dimname dimname++instance Castable Dimname (ForeignPtr ATen.Dimname) where+  cast (Dimname dname) f = f dname+  uncast dname f = f $ Dimname dname++instance Castable [Dimname] (ForeignPtr ATen.DimnameList) where+  cast xs f = do+    ptr_list <- mapM (\x -> cast x return :: IO (ForeignPtr ATen.Dimname)) xs+    cast (map Dimname ptr_list) f+  uncast xs f = uncast xs $ \ptr_list -> do+    dname_list <- mapM ((\(x :: ForeignPtr ATen.Dimname) -> uncast x return) . (\(Dimname dname) -> dname)) ptr_list+    f dname_list
+ src/Torch/Distributions/Bernoulli.hs view
@@ -0,0 +1,58 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeApplications #-}++module Torch.Distributions.Bernoulli+  ( Bernoulli (..),+    fromProbs,+    fromLogits,+  )+where++import qualified Torch.DType as D+import qualified Torch.Distributions.Constraints as Constraints+import Torch.Distributions.Distribution+import qualified Torch.Functional as F+import qualified Torch.Functional.Internal as I+import Torch.Scalar+import qualified Torch.Tensor as D+import qualified Torch.TensorFactories as D+import Torch.TensorOptions+import Torch.Typed.Functional (reductionVal)++data Bernoulli = Bernoulli+  { probs :: D.Tensor,+    logits :: D.Tensor+  }+  deriving (Show)++instance Distribution Bernoulli where+  batchShape d = []+  eventShape _d = []+  expand d = fromProbs . F.expand (probs d) False+  support d = Constraints.boolean+  mean = probs+  variance d = p `F.mul` (D.onesLike p `F.sub` p)+    where+      p = probs d+  sample d = D.bernoulliIO' . F.expand (probs d) False . extendedShape d+  logProb d value = F.mulScalar (-1 :: Int) (bce' (logits d) value)+  entropy d = bce' (logits d) $ probs d+  enumerateSupport d doExpand =+    (if doExpand then \t -> F.expand t False ([-1] <> batchShape d) else id) values+    where+      values = D.reshape ([-1] <> replicate (length $ batchShape d) 1) $ D.asTensor [0.0, 1.0 :: Float]++bce' :: D.Tensor -> D.Tensor -> D.Tensor+bce' logits probs =+  I.binary_cross_entropy_with_logits+    logits+    probs+    (D.onesLike logits)+    (D.ones [D.size (-1) logits] D.float_opts)+    $ reductionVal @(F.ReduceNone)++fromProbs :: D.Tensor -> Bernoulli+fromProbs probs = Bernoulli probs $ probsToLogits False probs++fromLogits :: D.Tensor -> Bernoulli+fromLogits logits = Bernoulli (probsToLogits False logits) logits
+ src/Torch/Distributions/Categorical.hs view
@@ -0,0 +1,74 @@+module Torch.Distributions.Categorical+  ( Categorical (..),+    fromProbs,+    fromLogits,+  )+where++import qualified Torch.DType as D+import qualified Torch.Distributions.Constraints as Constraints+import Torch.Distributions.Distribution+import qualified Torch.Functional as F+import qualified Torch.Functional.Internal as I+import qualified Torch.Tensor as D+import qualified Torch.TensorFactories as D++-- | Creates a categorical distribution parameterized by either :attr:`probs` or+-- | :attr:`logits` (but not both).+-- | .. note::+-- |     It is equivalent to the distribution that :func:`torch.multinomial`+-- |     samples from.+-- | Samples are integers from :math:`\{0, \ldots, K-1\}` where `K` is ``probs.size(-1)``.+-- | If :attr:`probs` is 1D with length-`K`, each element is the relative+-- | probability of sampling the class at that index.+-- | If :attr:`probs` is 2D, it is treated as a batch of relative probability+-- | vectors.+-- | .. note:: :attr:`probs` must be non-negative, finite and have a non-zero sum,+-- |             and it will be normalized to sum to 1.+-- | See also: `torch.multinomial`+-- | Example::+-- |     >>> m = Categorical.fromProbs $ D.asTensor [ 0.25, 0.25, 0.25, 0.25 ]+-- |     >>> Distribution.sample m  -- equal probability of 0, 1, 2, 3+-- |     tensor(3)+data Categorical = Categorical+  { probs :: D.Tensor,+    logits :: D.Tensor+  }+  deriving (Show)++instance Distribution Categorical where+  batchShape d =+    if D.numel (probs d) > 1+      then init (D.shape $ probs d)+      else []+  eventShape _d = []+  expand d batchShape' = fromProbs $ F.expand (probs d) False (paramShape d)+    where+      paramShape d' = batchShape' <> [numEvents d']+  support d = Constraints.integerInterval 0 $ (numEvents d) - 1+  mean d = F.divScalar (0.0 :: Float) (D.ones (extendedShape d []) D.float_opts) -- all NaN+  variance d = F.divScalar (0.0 :: Float) (D.ones (extendedShape d []) D.float_opts) -- all NaN+  sample d sampleShape = do+    let probs2d = D.reshape [-1, (numEvents d)] $ probs d+    samples2d <- F.transpose2D <$> D.multinomialIO probs2d (product sampleShape) True+    return $ D.reshape (extendedShape d sampleShape) samples2d+  logProb d value =+    let value' = I.unsqueeze (F.toDType D.Int64 value) (-1 :: Int)+        value'' = D.select (-1) 0 value'+     in F.squeezeDim (-1) $ I.gather (logits d) (-1 :: Int) value'' False+  entropy d = F.mulScalar (-1.0 :: Float) (F.sumDim (F.Dim $ -1) F.RemoveDim (D.dtype pLogP) pLogP)+    where+      pLogP = logits d `F.mul` probs d+  enumerateSupport d doExpand =+    (if doExpand then \t -> F.expand t False ([-1] <> batchShape d) else id) values+    where+      values = D.reshape ([-1] <> replicate (length $ batchShape d) 1) $ D.asTensor [0.0, 1.0 :: Float]++numEvents :: Categorical -> Int+numEvents (Categorical ps _logits) = D.size (-1) ps++fromProbs :: D.Tensor -> Categorical+fromProbs ps = Categorical ps $ probsToLogits False ps++fromLogits :: D.Tensor -> Categorical+fromLogits logits' = Categorical (logitsToProbs False logits') logits'
+ src/Torch/Distributions/Constraints.hs view
@@ -0,0 +1,102 @@+{-# LANGUAGE DataKinds #-}++module Torch.Distributions.Constraints+  ( Constraint,+    dependent,+    boolean,+    integerInterval,+    integerLessThan,+    integerGreaterThan,+    integerLessThanEq,+    integerGreaterThanEq,+    real,+    greaterThan,+    greaterThanEq,+    lessThan,+    lessThanEq,+    interval,+    halfOpenInterval,+    simplex,+    nonNegativeInteger,+    positiveInteger,+    positive,+    unitInterval,+  )+where++import qualified Torch.Functional as F+import qualified Torch.Functional.Internal as I+import Torch.Scalar+import qualified Torch.Tensor as D+import qualified Torch.TensorFactories as D++type Constraint = D.Tensor -> D.Tensor++dependent :: Constraint+dependent _tensor = error "Cannot determine validity of dependent constraint"++boolean :: Constraint+boolean tensor = (tensor `F.eq` D.zerosLike tensor) `I.logical_or` (tensor `F.eq` D.onesLike tensor)++integerInterval :: Int -> Int -> Constraint+integerInterval lower_bound upper_bound tensor = (tensor `F.ge` fullLike' lower_bound tensor) `I.logical_and` (tensor `F.le` fullLike' upper_bound tensor)++integerLessThan :: Int -> Constraint+integerLessThan upper_bound tensor = tensor `F.lt` fullLike' upper_bound tensor++integerGreaterThan :: Int -> Constraint+integerGreaterThan lower_bound tensor = tensor `F.gt` fullLike' lower_bound tensor++integerLessThanEq :: Int -> Constraint+integerLessThanEq upper_bound tensor = tensor `F.le` fullLike' upper_bound tensor++integerGreaterThanEq :: Int -> Constraint+integerGreaterThanEq lower_bound tensor = tensor `F.ge` fullLike' lower_bound tensor++real :: Constraint+real = I.isfinite++greaterThan :: Float -> Constraint+greaterThan lower_bound tensor = tensor `F.gt` fullLike' lower_bound tensor++greaterThanEq :: Float -> Constraint+greaterThanEq lower_bound tensor = tensor `F.ge` fullLike' lower_bound tensor++lessThan :: Float -> Constraint+lessThan upper_bound tensor = tensor `F.lt` fullLike' upper_bound tensor++lessThanEq :: Float -> Constraint+lessThanEq upper_bound tensor = tensor `F.le` fullLike' upper_bound tensor++interval :: Float -> Float -> Constraint+interval lower_bound upper_bound tensor = (tensor `F.ge` fullLike' lower_bound tensor) `I.logical_and` (tensor `F.le` fullLike' upper_bound tensor)++halfOpenInterval :: Float -> Float -> Constraint+halfOpenInterval lower_bound upper_bound tensor = (tensor `F.ge` fullLike' lower_bound tensor) `I.logical_and` (tensor `F.lt` fullLike' upper_bound tensor)++simplex :: Constraint+simplex tensor = F.allDim (F.Dim $ -1) False (greaterThanEq 0.0 tensor) `I.logical_and` (lessThan 1e-6 $ F.abs $ summed `F.sub` D.onesLike summed)+  where+    summed = F.sumDim (F.Dim $ -1) F.RemoveDim (D.dtype tensor) tensor++-- TODO: lowerTriangular+-- TODO: lowerCholesky+-- TODO: positiveDefinite+-- TODO: realVector+-- TODO: cat+-- TODO: stack++nonNegativeInteger :: Constraint+nonNegativeInteger = integerGreaterThanEq 0++positiveInteger :: Constraint+positiveInteger = integerGreaterThanEq 1++positive :: Constraint+positive = greaterThan 0.0++unitInterval :: Constraint+unitInterval = interval 0.0 1.0++fullLike' :: (Scalar a) => a -> D.Tensor -> D.Tensor+fullLike' i t = F.mulScalar i $ D.onesLike t
+ src/Torch/Distributions/Distribution.hs view
@@ -0,0 +1,73 @@+module Torch.Distributions.Distribution+  ( Scale,+    Distribution (..),+    stddev,+    perplexity,+    logitsToProbs,+    clampProbs,+    probsToLogits,+    extendedShape,+  )+where++import Torch.Distributions.Constraints+import qualified Torch.Functional as F+import qualified Torch.Tensor as D+import Torch.TensorFactories (ones, onesLike)++data Scale = Probs | Logits++class Distribution a where+  batchShape :: a -> [Int]+  eventShape :: a -> [Int]+  expand :: a -> [Int] -> a+  support :: a -> Constraint+  mean :: a -> D.Tensor+  variance :: a -> D.Tensor+  sample :: a -> [Int] -> IO D.Tensor+  logProb :: a -> D.Tensor -> D.Tensor+  entropy :: a -> D.Tensor+  enumerateSupport :: a -> Bool -> D.Tensor -- (expand=True)++stddev :: (Distribution a) => a -> D.Tensor -- 'D.Float+stddev = F.sqrt . variance++-- Tensor device 'D.Float '[batchShape]+perplexity :: (Distribution a) => a -> D.Tensor+perplexity = F.exp . entropy++-- | Converts a tensor of logits into probabilities. Note that for the+-- | binary case, each value denotes log odds, whereas for the+-- | multi-dimensional case, the values along the last dimension denote+-- | the log probabilities (possibly unnormalized) of the events.+logitsToProbs :: Bool -> D.Tensor -> D.Tensor -- isBinary=False+logitsToProbs True = F.sigmoid+logitsToProbs False = F.softmax (F.Dim $ -1)++clampProbs :: D.Tensor -> D.Tensor+clampProbs probs =+  F.clamp eps (1.0 - eps) probs+  where+    eps = 0.000001 -- torch.finfo(probs.dtype).eps++-- | Converts a tensor of probabilities into logits. For the binary case,+-- | this denotes the probability of occurrence of the event indexed by `1`.+-- | For the multi-dimensional case, the values along the last dimension+-- | denote the probabilities of occurrence of each of the events.+probsToLogits :: Bool -> D.Tensor -> D.Tensor -- isBinary=False+probsToLogits isBinary probs =+  if isBinary+    then F.log10 psClamped `F.sub` F.log1p (F.mulScalar (-1.0 :: Float) psClamped)+    else F.log10 psClamped+  where+    psClamped = clampProbs probs++-- | Returns the size of the sample returned by the distribution, given+-- | a `sampleShape`. Note, that the batch and event shapes of a distribution+-- | instance are fixed at the time of construction. If this is empty, the+-- | returned shape is upcast to (1,).+-- | Args:+-- |     sampleShape (torch.Size): the size of the sample to be drawn.+extendedShape :: (Distribution a) => a -> [Int] -> [Int]+extendedShape d sampleShape =+  sampleShape <> batchShape d <> eventShape d
− src/Torch/Double.hs
@@ -1,60 +0,0 @@-{-# LANGUAGE TypeSynonymInstances #-}-module Torch.Double (module X) where--import Numeric.Dimensions as X-import Torch.Types.TH as X-import Torch.Double.NN as X--import Torch.Double.Types as X hiding (storage)-import Torch.Double.Index as X hiding (withDynamicState)-import Torch.Double.Mask as X--import Torch.Indef.Double.Tensor as X-import Torch.Indef.Double.Tensor.Copy as X-import Torch.Indef.Double.Tensor.Index as X-import Torch.Indef.Double.Tensor.Masked as X-import Torch.Indef.Double.Tensor.Math as X-import Torch.Indef.Double.Tensor.Math.Compare as X-import Torch.Indef.Double.Tensor.Math.CompareT as X-import Torch.Indef.Double.Tensor.Math.Pairwise as X-import Torch.Indef.Double.Tensor.Math.Pointwise as X-import Torch.Indef.Double.Tensor.Math.Reduce as X-import Torch.Indef.Double.Tensor.Math.Scan as X-import Torch.Indef.Double.Tensor.Mode as X-import Torch.Indef.Double.Tensor.ScatterGather as X-import Torch.Indef.Double.Tensor.Sort as X-import Torch.Indef.Double.Tensor.TopK as X--import Torch.Indef.Double.Tensor.Math.Pointwise.Signed as X--import Torch.Indef.Double.Tensor.Math.Blas as X-import Torch.Indef.Double.Tensor.Math.Floating as X-import Torch.Indef.Double.Tensor.Math.Lapack as X-import Torch.Indef.Double.Tensor.Math.Pointwise.Floating as X-import Torch.Indef.Double.Tensor.Math.Reduce.Floating as X--import Torch.Indef.Double.Tensor.Math.Random.TH as X-import Torch.Indef.Double.Tensor.Random.TH as X-import Torch.Core.Random as X (newRNG, seed, manualSeed, initialSeed)-----------------------------------------------------------------------------------import System.IO.Unsafe--instance Dimensions d => Fractional (Tensor d) where-  fromRational = constant . fromRational-  (/) = (^/^)--instance Dimensions d => Floating (Tensor d) where-  pi = X.constant pi-  exp = X.exp-  log = X.log-  sqrt = X.sqrt-  sin = X.sin-  cos = X.cos-  asin = X.asin-  acos = X.acos-  atan = X.atan-  sinh = X.sinh-  cosh = X.cosh-
− src/Torch/Double/Dynamic.hs
@@ -1,36 +0,0 @@-module Torch.Double.Dynamic (module X) where--import Torch.Types.TH as X-import Torch.Double.Types as X hiding (storage)-import Torch.Double.Index as X hiding (withDynamicState)-import Torch.Double.Mask as X--import Torch.Double.Dynamic.NN as X--import Torch.Indef.Double.Dynamic.Tensor as X-import Torch.Indef.Double.Dynamic.Tensor.Copy as X-import Torch.Indef.Double.Dynamic.Tensor.Index as X-import Torch.Indef.Double.Dynamic.Tensor.Masked as X-import Torch.Indef.Double.Dynamic.Tensor.Math as X-import Torch.Indef.Double.Dynamic.Tensor.Math.Compare as X-import Torch.Indef.Double.Dynamic.Tensor.Math.CompareT as X-import Torch.Indef.Double.Dynamic.Tensor.Math.Pairwise as X-import Torch.Indef.Double.Dynamic.Tensor.Math.Pointwise as X-import Torch.Indef.Double.Dynamic.Tensor.Math.Reduce as X-import Torch.Indef.Double.Dynamic.Tensor.Math.Scan as X-import Torch.Indef.Double.Dynamic.Tensor.Mode as X-import Torch.Indef.Double.Dynamic.Tensor.ScatterGather as X-import Torch.Indef.Double.Dynamic.Tensor.Sort as X-import Torch.Indef.Double.Dynamic.Tensor.TopK as X--import Torch.Indef.Double.Dynamic.Tensor.Math.Pointwise.Signed as X--import Torch.Indef.Double.Dynamic.Tensor.Math.Blas as X-import Torch.Indef.Double.Dynamic.Tensor.Math.Floating as X-import Torch.Indef.Double.Dynamic.Tensor.Math.Lapack as X-import Torch.Indef.Double.Dynamic.Tensor.Math.Pointwise.Floating as X-import Torch.Indef.Double.Dynamic.Tensor.Math.Reduce.Floating as X--import Torch.Indef.Double.Dynamic.Tensor.Math.Random.TH as X-import Torch.Indef.Double.Dynamic.Tensor.Random.TH as X-import Torch.Core.Random as X (newRNG, seed, manualSeed, initialSeed)
− src/Torch/Double/Storage.hs
@@ -1,6 +0,0 @@-module Torch.Double.Storage (module X) where--import Torch.Types.TH as X-import Torch.Double.Types as X-import Torch.Indef.Double.Storage      as X-import Torch.Indef.Double.Storage.Copy as X
− src/Torch/Float.hs
@@ -1,73 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Float--- Copyright :  (c) Sam Stites 2017--- License   :  BSD3--- Maintainer:  sam@stites.io--- Stability :  experimental--- Portability: non-portable------ Reexports of Float-specific code from hasktorch-indef.---------------------------------------------------------------------------------{-# OPTIONS_GHC -fno-cse #-}-{-# LANGUAGE TypeSynonymInstances #-}-module Torch.Float (module X) where--import Numeric.Dimensions-import Torch.Types.TH as X-import Torch.Float.NN as X--import Torch.Float.Types as X hiding (storage)-import Torch.Float.Index as X hiding (withDynamicState)-import Torch.Float.Mask  as X--import Torch.Indef.Float.Tensor as X-import Torch.Indef.Float.Tensor.Copy as X-import Torch.Indef.Float.Tensor.Index as X-import Torch.Indef.Float.Tensor.Masked as X-import Torch.Indef.Float.Tensor.Math as X-import Torch.Indef.Float.Tensor.Math.Compare as X-import Torch.Indef.Float.Tensor.Math.CompareT as X-import Torch.Indef.Float.Tensor.Math.Pairwise as X-import Torch.Indef.Float.Tensor.Math.Pointwise as X-import Torch.Indef.Float.Tensor.Math.Reduce as X-import Torch.Indef.Float.Tensor.Math.Scan as X-import Torch.Indef.Float.Tensor.Mode as X-import Torch.Indef.Float.Tensor.ScatterGather as X-import Torch.Indef.Float.Tensor.Sort as X-import Torch.Indef.Float.Tensor.TopK as X--import Torch.Indef.Float.Tensor.Math.Pointwise.Signed as X--import Torch.Indef.Float.Tensor.Math.Blas as X-import Torch.Indef.Float.Tensor.Math.Floating as X-import Torch.Indef.Float.Tensor.Math.Lapack as X-import Torch.Indef.Float.Tensor.Math.Pointwise.Floating as X-import Torch.Indef.Float.Tensor.Math.Reduce.Floating as X--import Torch.Indef.Float.Tensor.Math.Random.TH as X-import Torch.Indef.Float.Tensor.Random.TH as X-import Torch.Core.Random as X (newRNG, seed, manualSeed, initialSeed)-----------------------------------------------------------------------------------import System.IO.Unsafe--instance Dimensions d => Fractional (Tensor d) where-  fromRational = constant . fromRational-  (/) = (^/^)--instance Dimensions d => Floating (Tensor d) where-  pi = X.constant pi-  exp = X.exp-  log = X.log-  sqrt = X.sqrt-  sin = X.sin-  cos = X.cos-  asin = X.asin-  acos = X.acos-  atan = X.atan-  sinh = X.sinh-  cosh = X.cosh--
− src/Torch/Float/Dynamic.hs
@@ -1,37 +0,0 @@-module Torch.Float.Dynamic (module X) where--import Torch.Types.TH as X--import Torch.Float.Dynamic.NN as X--import Torch.Float.Types as X hiding (storage)-import Torch.Float.Index as X hiding (withDynamicState)-import Torch.Float.Mask  as X--import Torch.Indef.Float.Dynamic.Tensor as X-import Torch.Indef.Float.Dynamic.Tensor.Copy as X-import Torch.Indef.Float.Dynamic.Tensor.Index as X-import Torch.Indef.Float.Dynamic.Tensor.Masked as X-import Torch.Indef.Float.Dynamic.Tensor.Math as X-import Torch.Indef.Float.Dynamic.Tensor.Math.Compare as X-import Torch.Indef.Float.Dynamic.Tensor.Math.CompareT as X-import Torch.Indef.Float.Dynamic.Tensor.Math.Pairwise as X-import Torch.Indef.Float.Dynamic.Tensor.Math.Pointwise as X-import Torch.Indef.Float.Dynamic.Tensor.Math.Reduce as X-import Torch.Indef.Float.Dynamic.Tensor.Math.Scan as X-import Torch.Indef.Float.Dynamic.Tensor.Mode as X-import Torch.Indef.Float.Dynamic.Tensor.ScatterGather as X-import Torch.Indef.Float.Dynamic.Tensor.Sort as X-import Torch.Indef.Float.Dynamic.Tensor.TopK as X--import Torch.Indef.Float.Dynamic.Tensor.Math.Pointwise.Signed as X--import Torch.Indef.Float.Dynamic.Tensor.Math.Blas as X-import Torch.Indef.Float.Dynamic.Tensor.Math.Floating as X-import Torch.Indef.Float.Dynamic.Tensor.Math.Lapack as X-import Torch.Indef.Float.Dynamic.Tensor.Math.Pointwise.Floating as X-import Torch.Indef.Float.Dynamic.Tensor.Math.Reduce.Floating as X--import Torch.Indef.Float.Dynamic.Tensor.Math.Random.TH as X-import Torch.Indef.Float.Dynamic.Tensor.Random.TH as X-import Torch.Core.Random as X (newRNG, seed, manualSeed, initialSeed)
− src/Torch/Float/Storage.hs
@@ -1,4 +0,0 @@-module Torch.Float.Storage (module X) where--import Torch.Indef.Float.Storage      as X-import Torch.Indef.Float.Storage.Copy as X
+ src/Torch/Functional.hs view
@@ -0,0 +1,3275 @@+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE TypeApplications #-}++module Torch.Functional+  ( module Torch.Functional,+    Internal.acos,+    Internal.addmv,+    Internal.addr,+    Internal.allclose,+    Internal.argmin,+    Internal.asin,+    Internal.atan,+    Internal.baddbmm,+    Internal.bmm,+    Internal.conj,+    Internal.det,+    Internal.dot,+    Internal.einsum,+    Internal.expm1,+    Internal.ger,+    Internal.logdet,+    Internal.lstsq,+    Internal.mv,+    Internal.scaled_dot_product_attention,+    Internal.sumWithDimnames,+  )+where++import Data.Int+import Foreign.C.Types (CBool (..))+import Foreign.ForeignPtr+import System.IO.Unsafe+import Torch.DType+import Torch.Dimname+import qualified Torch.Functional.Internal as Internal+import Torch.Internal.Cast+import Torch.Internal.Class+import qualified Torch.Internal.Const as ATen+import qualified Torch.Internal.Managed.Cast+import qualified Torch.Internal.Managed.Native as ATen+import qualified Torch.Internal.Managed.Type.Scalar as ATen+import qualified Torch.Internal.Managed.Type.Tensor as ATen+import qualified Torch.Internal.Managed.Type.Tuple as ATen+import qualified Torch.Internal.Type as ATen+import Torch.Scalar+import Torch.Tensor+-- import Torch.Functional.Internal hiding (argmax, clamp, cosh, conv1d, linear, softmax)+import Torch.TensorFactories (ones', onesLike)+import Prelude hiding+  ( acos,+    acosh,+    all,+    any,+    asin,+    asinh,+    atan,+    atanh,+    ceil,+    cos,+    cosh,+    exp,+    floor,+    isNaN,+    log,+    max,+    min,+    round,+    sin,+    sinh,+    tan,+    tanh,+  )+import qualified Prelude as P++kOne :: ForeignPtr ATen.Scalar+kOne = unsafePerformIO $ ATen.newScalar_i 1+{-# NOINLINE kOne #-}++instance Num Tensor where+  (+) = add+  (-) = sub+  (*) = mul+  negate t = unsafePerformIO $ cast1 ATen.neg_t t+  abs t = unsafePerformIO $ cast1 ATen.abs_t t+  signum t = unsafePerformIO $ cast1 ATen.sign_t t+  fromInteger i = asTensor @Int $ fromInteger @Int i++instance Eq Tensor where+  (==) t t' = all (t `eq` t')++instance Fractional Tensor where+  a / b = unsafePerformIO $ cast2 ATen.div_tt a b+  recip t = unsafePerformIO $ cast1 ATen.reciprocal_t t+  fromRational i = asTensor @Float $ fromRational @Float i++-- Return upper or lower triangular matrices+data Tri = Upper | Lower deriving (Eq, Show)++-- Reductions, used by BCE loss, see -+-- https://github.com/pytorch/pytorch/blob/3762cf9cc63e2032410d50f218c1406668177c23/aten/src/ATen/core/Reduction.h+data Reduction = ReduceNone | ReduceMean | ReduceSum deriving (Eq, Show)++newtype Dim = Dim Int++data KeepDim = KeepDim | RemoveDim deriving (Eq, Show)++data CeilMode = Ceil | Floor deriving (Eq, Show)++instance Castable CeilMode CBool where -- Word8 == CBool+  cast Ceil f = f 1+  cast Floor f = f 0+  uncast 0 f = f Floor+  uncast 1 f = f Ceil++instance Castable Reduction Int64 where+  cast ReduceNone f = f 0+  cast ReduceMean f = f 1+  cast ReduceSum f = f 2+  uncast 0 f = f ReduceNone+  uncast 1 f = f ReduceMean+  uncast _ f = f ReduceSum++newtype Diag = Diag Int++isUpper Upper = True+isUpper Lower = False++-- | Returns the mean value of all elements in the input tensor.+mean ::+  -- | input+  Tensor ->+  -- | output+  Tensor+mean t = unsafePerformIO $ cast1 ATen.mean_t t++-- | Returns the standard deviation of all elements in the input tensor.+std ::+  -- | input+  Tensor ->+  -- | output+  Tensor+std t = unsafePerformIO $ cast1 ATen.std_t t++-- | Returns the variance of all elements in the input tensor.+var ::+  -- | input+  Tensor ->+  -- | output+  Tensor+var t = unsafePerformIO $ cast1 ATen.var_t t++-- | Returns the sum of all elements in the input tensor.+sumAll ::+  -- | input+  Tensor ->+  -- | output+  Tensor+sumAll t = unsafePerformIO $ cast1 ATen.sum_t t++-- | Computes the element-wise absolute value of the given input tensor.+abs ::+  -- | input+  Tensor ->+  -- | output+  Tensor+abs t = unsafePerformIO $ cast1 ATen.abs_t t++-- | Computes the fractional portion of each element in input.+-- out_i = input_i - (floor . abs) input_i * (sign input_i)+frac ::+  -- | input+  Tensor ->+  -- | output+  Tensor+frac _self = unsafePerformIO $ cast1 ATen.frac_t _self++keepdim KeepDim = True+keepdim RemoveDim = False++-- | Returns the indices of the maximum value of all elements in the input tensor.+argmax ::+  -- | the dimension to reduce+  Dim ->+  -- | whether the output tensor has dim retained or not+  KeepDim ->+  -- | input+  Tensor ->+  -- | output+  Tensor+argmax (Dim d) k t = unsafePerformIO $ cast3 ATen.argmax_tlb t d (keepdim k)++-- | Each element of the tensor other added to each element of the tensor input. The resulting tensor is returned.+add ::+  -- | input+  Tensor ->+  -- | other+  Tensor ->+  -- | output+  Tensor+add a b = unsafePerformIO $ cast3 ATen.add_tts a b kOne++-- | Multiplies each element of the tensor other to each element of the input tensor and returns a new resulting tensor.+mul ::+  -- | input+  Tensor ->+  -- | other+  Tensor ->+  -- | output+  Tensor+mul a b = unsafePerformIO $ cast2 ATen.mul_tt a b++-- | Element wise subtraction of other tensor from input tensor and returns a new resulting tensor+sub ::+  -- | input+  Tensor ->+  -- | other+  Tensor ->+  -- | output+  Tensor+sub a b = unsafePerformIO $ cast3 ATen.sub_tts a b kOne++-- | Element wise division of input tensor by other tensor and returns a new resulting tensor+div ::+  -- | input+  Tensor ->+  -- | other+  Tensor ->+  Tensor+div a b = unsafePerformIO $ cast2 ATen.div_tt a b++-- | ceil+ceil ::+  -- | input+  Tensor ->+  -- | output+  Tensor+ceil t = unsafePerformIO $ cast1 ATen.ceil_t t++-- | floor+floor ::+  -- | input+  Tensor ->+  -- | output+  Tensor+floor t = unsafePerformIO $ cast1 ATen.floor_t t++-- | min+min ::+  -- | input+  Tensor ->+  -- | output+  Tensor+min t = unsafePerformIO $ cast1 ATen.min_t t++-- | max+max ::+  -- | input+  Tensor ->+  -- | output+  Tensor+max t = unsafePerformIO $ cast1 ATen.max_t t++-- | median+median ::+  -- | input+  Tensor ->+  -- | output+  Tensor+median t = unsafePerformIO $ cast1 ATen.median_t t++-- | Adds each element of the input input with the scalar and returns a new resulting tensor.+addScalar ::+  Scalar a =>+  -- | summand+  a ->+  -- | input+  Tensor ->+  -- | output+  Tensor+addScalar a t = unsafePerformIO $ cast2 ATen.add_ts t a++-- | Subtracts each element of the input input with the scalar and returns a new resulting tensor.+subScalar ::+  Scalar a =>+  -- | subtrahend+  a ->+  -- | input+  Tensor ->+  -- | output+  Tensor+subScalar a t = unsafePerformIO $ cast2 ATen.sub_ts t a++-- | Multiplies each element of the input input with the scalar and returns a new resulting tensor.+mulScalar ::+  Scalar a =>+  -- | multiplier+  a ->+  -- | input+  Tensor ->+  -- | output+  Tensor+mulScalar a t = unsafePerformIO $ cast2 ATen.mul_ts t a++-- | Divides each element of the input input with the scalar and returns a new resulting tensor.+divScalar ::+  Scalar a =>+  -- | divisor+  a ->+  -- | input+  Tensor ->+  -- | output+  Tensor+divScalar a t = unsafePerformIO $ cast2 ATen.div_ts t a++-- |  Matrix product of two tensors.+--+-- The behavior depends on the dimensionality of the tensors as follows:+--+-- If both tensors are 1-dimensional, the dot product (scalar) is returned.+-- If both arguments are 2-dimensional, the matrix-matrix product is returned.+-- If the first argument is 1-dimensional and the second argument is 2-dimensional, a 1 is prepended to its dimension for the purpose of the matrix multiply. After the matrix multiply, the prepended dimension is removed.+-- If the first argument is 2-dimensional and the second argument is 1-dimensional, the matrix-vector product is returned.+-- If both arguments are at least 1-dimensional and at least one argument is N-dimensional (where N > 2), then a batched matrix multiply is returned. If the first argument is 1-dimensional, a 1 is prepended to its dimension for the purpose of the batched matrix multiply and removed after. If the second argument is 1-dimensional, a 1 is appended to its dimension for the purpose of the batched matrix multiple and removed after. The non-matrix (i.e. batch) dimensions are broadcasted (and thus must be broadcastable). For example, if input is a (j \times 1 \times n \times m)(j×1×n×m) tensor and other is a (k \times m \times p)(k×m×p) tensor, out will be an (j \times k \times n \times p)(j×k×n×p) tensor.+matmul ::+  -- | first tensor for matrix multiplication+  Tensor ->+  -- | second tensor for matrix multiplication+  Tensor ->+  -- | output+  Tensor+matmul a b = unsafePerformIO $ cast2 ATen.matmul_tt a b++-- | A simple lookup table that looks up embeddings in a fixed dictionary and size.+-- This module is often used to retrieve word embeddings using indices. The input to the module is a list of indices, and the embedding matrix, and the output is the corresponding word embeddings.+embedding ::+  -- | whether or not to scale the gradient by the frequencies+  Bool ->+  -- | whether or not the embedding is sparse+  Bool ->+  -- | weights+  Tensor ->+  -- | padding+  Int ->+  -- | indices+  Tensor ->+  -- | output+  Tensor+embedding scaleByGradFreq sparse weights paddingIdx indices =+  unsafePerformIO $+    cast5+      ATen.embedding_ttlbb+      weights+      indices+      paddingIdx+      scaleByGradFreq+      sparse++embedding' ::+  -- | weights+  Tensor ->+  -- | indices+  Tensor ->+  -- | output+  Tensor+embedding' weights indices =+  unsafePerformIO $+    cast5+      ATen.embedding_ttlbb+      weights+      indices+      (-1 :: Int)+      False+      False++-- | A one hot encoding of the given input. The encoding is based on the given number of+-- classes.+oneHot ::+  -- | number of classes+  Int ->+  -- | input+  Tensor ->+  Tensor+oneHot numClasses t = unsafePerformIO $ cast2 ATen.one_hot_tl t numClasses++--+-- element-wise transformations / non-linearities+--++-- | Computes the error function of each element+erf ::+  -- | input+  Tensor ->+  -- | output+  Tensor+erf t = unsafePerformIO $ cast1 ATen.erf_t t++-- | Computes the complementary error function of each element of input+erfc ::+  -- | input+  Tensor ->+  -- | output+  Tensor+erfc t = unsafePerformIO $ cast1 ATen.erfc_t t++-- | Computes the inverse error function of each element of input. The inverse error function is defined in the range (-1, 1)(−1,1) as: erfinv(erf(x)) = x+erfinv ::+  -- | input+  Tensor ->+  -- | output+  Tensor+erfinv t = unsafePerformIO $ cast1 ATen.erfinv_t t++-- | Computes the logarithm of the gamma function on input.+lgamma ::+  -- | input+  Tensor ->+  -- | output+  Tensor+lgamma t = unsafePerformIO $ cast1 ATen.lgamma_t t++-- | Computes the logarithmic derivative of the gamma function on input.+digamma ::+  -- | input+  Tensor ->+  -- | output+  Tensor+digamma t = unsafePerformIO $ cast1 ATen.digamma_t t++-- | Computes the nth derivative of the digamma function on input. n \geq 0n≥0 is called the order of the polygamma function.+polygamma ::+  -- | n+  Int ->+  -- | input+  Tensor ->+  -- | output+  Tensor+polygamma n t = unsafePerformIO $ cast2 ATen.polygamma_lt n t++-- | Computes the multivariate log-gamma function with dimension pp element-wise. All elements must be greater than (p-1)/2, otherwise an error would be thrown.+mvlgamma ::+  -- | p+  Int ->+  -- | input+  Tensor ->+  -- | output+  Tensor+mvlgamma p t = unsafePerformIO $ cast2 ATen.mvlgamma_tl t p++-- | Returns a new tensor with the exponential of the elements of the input tensor input.+exp ::+  -- | input+  Tensor ->+  -- | output+  Tensor+exp t = unsafePerformIO $ cast1 ATen.exp_t t++-- | Returns a new tensor with the natural logarithm of (1 + input).+log1p ::+  Tensor -> Tensor+log1p t = unsafePerformIO $ cast1 ATen.log1p_t t++-- | Returns a new tensor with the logarithm to the base 2 of the elements of input.+log2 ::+  -- | input+  Tensor ->+  -- | output+  Tensor+log2 t = unsafePerformIO $ cast1 ATen.log2_t t++-- | Returns a new tensor with the natural logarithm of the elements of input.+log ::+  -- | input+  Tensor ->+  -- | output+  Tensor+log _self = unsafePerformIO $ cast1 ATen.log_t _self++-- | Returns a new tensor with the logarithm to the base 10 of the elements of input.+log10 ::+  -- | input+  Tensor ->+  -- | output+  Tensor+log10 t = unsafePerformIO $ cast1 ATen.log10_t t++-- | Takes the power of each element in input with exponent and returns a tensor with the result.+pow ::+  Scalar a =>+  -- | exponent+  a ->+  -- | input+  Tensor ->+  -- | output+  Tensor+pow s t = unsafePerformIO $ cast2 ATen.pow_ts t s++-- | Takes the power of each element in input with exponent and returns a tensor with the result.+-- Exponent is a tensor with the same number of elements as input.+powt ::+  -- | input+  Tensor ->+  -- | exponent+  Tensor ->+  -- | output+  Tensor+powt t t' = unsafePerformIO $ cast2 ATen.pow_tt t t'++-- | Applies the rectified linear unit function element-wise.+relu ::+  -- | input+  Tensor ->+  -- | output+  Tensor+relu t = unsafePerformIO $ cast1 ATen.relu_t t++-- | Applies Exponential linear unit function element-wise, with alpha input, \(\text{ELU}(x) = \max(0,x) + \min(0, \alpha * (\exp(x) - 1))\)+elu ::+  Scalar s =>+  -- | alpha value for ELU formulation+  s ->+  -- | input+  Tensor ->+  -- | output+  Tensor+elu a t = unsafePerformIO $ cast2 ATen.elu_ts t a++-- | Applies exponential linear unit function element wise with default alpha value = 1+elu' ::+  -- | input+  Tensor ->+  -- | output+  Tensor+elu' t = unsafePerformIO $ cast1 ATen.elu_t t++-- | Applies element-wise, \(\text{SELU}(x) = scale * (\max(0,x) + \min(0, \alpha * (\exp(x) - 1))\) , with α=1.6732632423543772848170429916717 and scale=1.0507009873554804934193349852946.+selu ::+  -- | input+  Tensor ->+  -- | output+  Tensor+selu t = unsafePerformIO $ cast1 ATen.selu_t t++-- | Applies element-wise, \(\text{CELU}(x) = \max(0,x) + \min(0, \alpha * (\exp(x/\alpha) - 1))\).+celu ::+  -- | alpha+  Float ->+  -- | input+  Tensor ->+  -- | output+  Tensor+celu _alpha _self = unsafePerformIO $ cast2 ATen.celu_ts _self _alpha++-- | Applies the element-wise function sigmoid.+sigmoid ::+  -- | input+  Tensor ->+  -- | output+  Tensor+sigmoid t = unsafePerformIO $ cast1 ATen.sigmoid_t t++-- | Applies a softmax function.+-- It is applied to all slices along dim, and will re-scale them so that the elements lie in the range [0, 1] and sum to 1.+softmax ::+  -- | dimension+  Dim ->+  -- | input+  Tensor ->+  -- | output+  Tensor+softmax (Dim d) input =+  unsafePerformIO $+    cast3+      ATen.softmax_tls+      input+      d+      (dtype input)++-- | Applies a softmax followed by a logarithm.+-- While mathematically equivalent to log(softmax(x)), doing these two operations separately is slower, and numerically unstable. This function uses an alternative formulation to compute the output and gradient correctly.+logSoftmax ::+  -- | dimension+  Dim ->+  -- | input+  Tensor ->+  -- | output+  Tensor+logSoftmax (Dim d) input =+  unsafePerformIO $+    cast3+      ATen.log_softmax_tls+      input+      d+      (dtype input)++-- | Thresholds each element of the input Tensor.+threshold ::+  -- | threshold+  Float ->+  -- | value+  Float ->+  -- | input+  Tensor ->+  -- | output+  Tensor+threshold threshold value self =+  unsafePerformIO $ cast3 ATen.threshold_tss self threshold value++-- | Returns a new tensor with the sine of the elements of input.+sin ::+  -- | input+  Tensor ->+  -- | output+  Tensor+sin t = unsafePerformIO $ cast1 ATen.sin_t t++-- | Returns a new tensor with the cos of the elements of input.+cos ::+  -- | input+  Tensor ->+  -- | output+  Tensor+cos t = unsafePerformIO $ cast1 ATen.cos_t t++-- | Returns a new tensor with the tangent of the elements of input.+tan ::+  -- | input+  Tensor ->+  -- | output+  Tensor+tan t = unsafePerformIO $ cast1 ATen.tan_t t++-- | Returns a new tensor with the hyperbolic sine of the elements of input.+sinh ::+  -- | input+  Tensor ->+  -- | output+  Tensor+sinh t = unsafePerformIO $ cast1 ATen.sinh_t t++-- | Returns a new tensor with the hyperbolic cosine of the elements of input.+cosh ::+  -- | input+  Tensor ->+  -- | output+  Tensor+cosh t = unsafePerformIO $ cast1 ATen.cosh_t t++-- | Returns a new tensor with the hyperbolic tangent of the elements of input.+tanh ::+  -- | input+  Tensor ->+  -- | output+  Tensor+tanh t = unsafePerformIO $ cast1 ATen.tanh_t t++-- | Returns a new tensor with the square-root of the elements of input.+sqrt ::+  -- | input+  Tensor ->+  -- | output+  Tensor+sqrt t = unsafePerformIO $ cast1 ATen.sqrt_t t++--+-- infix operators+--++-- | Computes input > other element-wise.+-- The second argument can be a number or a tensor whose shape is broadcastable with the first argument.+gt ::+  -- | input+  Tensor ->+  -- | output+  Tensor ->+  -- | other+  Tensor+gt a b = unsafePerformIO $ cast2 ATen.gt_tt a b++(>.) = gt++-- | Computes input < other element-wise.+-- The second argument can be a number or a tensor whose shape is broadcastable with the first argument.+lt ::+  -- | input+  Tensor ->+  -- | other+  Tensor ->+  -- | output+  Tensor+lt a b = unsafePerformIO $ cast2 ATen.lt_tt a b++(<.) = lt++-- | Computes input >= other element-wise.+-- The second argument can be a number or a tensor whose shape is broadcastable with the first argument.+ge ::+  -- | input+  Tensor ->+  -- | other+  Tensor ->+  -- | output+  Tensor+ge a b = unsafePerformIO $ cast2 ATen.ge_tt a b++(>=.) = ge++-- | Computes input <= other element-wise.+-- The second argument can be a number or a tensor whose shape is broadcastable with the first argument.+le ::+  -- | input+  Tensor ->+  -- | other+  Tensor ->+  -- | output+  Tensor+le a b = unsafePerformIO $ cast2 ATen.le_tt a b++(<=.) = le++-- | Computes input == other element-wise.+-- The second argument can be a number or a tensor whose shape is broadcastable with the first argument.+eq ::+  -- | input+  Tensor ->+  -- | other+  Tensor ->+  -- | output+  Tensor+eq a b = unsafePerformIO $ cast2 ATen.eq_tt a b++(==.) = eq++-- | Computes input > scalar element-wise.+-- The second argument is a scalar value that is compared against each element of the tensor.+gtScalar ::+  -- | input+  Tensor ->+  -- | scalar+  Float ->+  -- | output+  Tensor+gtScalar = Internal.gtScalar++(.>) = gtScalar++-- | Computes input < scalar element-wise.+-- The second argument is a scalar value that is compared against each element of the tensor.+ltScalar ::+  -- | input+  Tensor ->+  -- | scalar+  Float ->+  -- | output+  Tensor+ltScalar = Internal.ltScalar++(.<) = ltScalar++-- | Computes input >= scalar element-wise.+-- The second argument is a scalar value that is compared against each element of the tensor.+geScalar ::+  -- | input+  Tensor ->+  -- | scalar+  Float ->+  -- | output+  Tensor+geScalar = Internal.geScalar++(.>=) = geScalar++-- | Computes input <= scalar element-wise.+-- The second argument is a scalar value that is compared against each element of the tensor.+leScalar ::+  -- | input+  Tensor ->+  -- | scalar+  Float ->+  -- | output+  Tensor+leScalar = Internal.leScalar++(.<=) = leScalar++-- | Computes input == scalar element-wise.+-- The second argument is a scalar value that is compared against each element of the tensor.+eqScalar ::+  -- | input+  Tensor ->+  -- | scalar+  Float ->+  -- | output+  Tensor+eqScalar = Internal.eqScalar++(.==) = eqScalar++-- | Computes input /= scalar element-wise.+-- The second argument is a scalar value that is compared against each element of the tensor.+neScalar ::+  -- | input+  Tensor ->+  -- | scalar+  Float ->+  -- | output+  Tensor+neScalar = Internal.neScalar++(./=) = neScalar++-- | Returns a new tensor with the elements of input at the given indices. The input tensor is treated as if it were viewed as a 1-D tensor. The result takes the same shape as the indices.+take ::+  -- | index+  Tensor ->+  -- | input+  Tensor ->+  -- | output+  Tensor+take _index _self = unsafePerformIO $ cast2 ATen.take_tt _self _index++-- | Returns a new 1-D tensor which indexes the input tensor according to the boolean mask mask which is a BoolTensor.+-- The shapes of the mask tensor and the input tensor don’t need to match, but they must be broadcastable.+maskedSelect ::+  -- | mask+  Tensor ->+  -- | input+  Tensor ->+  -- | output+  Tensor+maskedSelect _mask _self = unsafePerformIO $ cast2 ATen.masked_select_tt _self _mask++-- | Returns a tuple of 1-D tensors, one for each dimension in input, each containing the indices (in that dimension) of all non-zero elements of input .+nonzero ::+  -- | input+  Tensor ->+  -- | output+  Tensor+nonzero _self = unsafePerformIO $ cast1 ATen.nonzero_t _self++isclose ::+  -- | rtol+  Double ->+  -- | atol+  Double ->+  -- | equal_nan+  Bool ->+  -- | self+  Tensor ->+  -- | other+  Tensor ->+  Tensor+isclose rtol atol equalNan self other = unsafePerformIO $ cast5 ATen.isclose_ttddb self other rtol atol equalNan++isnan ::+  -- | self+  Tensor ->+  Tensor -- a new tensor with boolean elements representing if each element is NaN or not.+isnan t = unsafePerformIO $ cast1 ATen.isnan_t t++isNonzero ::+  -- | self+  Tensor ->+  Bool+isNonzero _self = unsafePerformIO $ cast1 ATen.is_nonzero_t _self++isSameSize ::+  -- | self+  Tensor ->+  -- | other+  Tensor ->+  Bool+isSameSize self other = unsafePerformIO $ cast2 ATen.is_same_size_tt self other++isSigned ::+  -- | input+  Tensor ->+  -- | True if the data type of input is a signed type+  Bool+isSigned t = unsafePerformIO $ cast1 ATen.is_signed_t t++-- | Computes input /= other element-wise.+-- The second argument can be a number or a tensor whose shape is broadcastable with the first argument.+ne ::+  -- | input+  Tensor ->+  -- | other+  Tensor ->+  -- | output+  Tensor+ne a b = unsafePerformIO $ cast2 ATen.ne_tt a b++(/=.) = ne++-- | Casting to given 'Dtype', where 'Dtype' is an object that represents the data type of a tensor in hasktorch.+toDType ::+  -- | data type to cast to+  DType ->+  -- | input+  Tensor ->+  -- | output+  Tensor+toDType dtype t = unsafePerformIO $ cast4 ATen.tensor_to_sbb t dtype False False++-- | squeezeAll+squeezeAll ::+  -- | input+  Tensor ->+  -- | output+  Tensor+squeezeAll t = unsafePerformIO $ cast1 ATen.squeeze_t t++-- | squeezeDim+squeezeDim ::+  -- | dim+  Int ->+  -- | input+  Tensor ->+  -- | output+  Tensor+squeezeDim dim t = unsafePerformIO $ cast2 ATen.squeeze_tl t dim++--+-- Cumulative operations+--++-- | Returns a tuple (values, indices) where values is the cumulative maximum of elements of input in the dimension dim. And indices is the index location of each maximum value found in the dimension dim.+cummax ::+  -- | dim+  Int ->+  -- | input+  Tensor ->+  -- | output (values, indices)+  (Tensor, Tensor)+cummax _dim _self = unsafePerformIO $ cast2 ATen.cummax_tl _self _dim++-- | Returns a tuple (values, indices) where values is the cumulative minimum of elements of input in the dimension dim. And indices is the index location of each maximum value found in the dimension dim.+cummin ::+  -- | dim+  Int ->+  -- | input+  Tensor ->+  -- | output (values, indices)+  (Tensor, Tensor)+cummin _dim _self = unsafePerformIO $ cast2 ATen.cummin_tl _self _dim++-- | Returns the cumulative product of elements of input in the dimension dim.+-- For example, if input is a vector of size N, the result will also be a vector of size N, with elements.+cumprod ::+  -- | dim+  Int ->+  -- | dtype+  DType ->+  -- | input+  Tensor ->+  -- | output+  Tensor+cumprod _dim _dtype _self = unsafePerformIO $ cast3 ATen.cumprod_tls _self _dim _dtype++-- | Returns the cumulative sum of elements of input in the dimension dim.+-- For example, if input is a vector of size N, the result will also be a vector of size N, with elements.+cumsum ::+  -- | dim+  Int ->+  -- | dtype+  DType ->+  -- | input+  Tensor ->+  -- | output+  Tensor+cumsum _dim _dtype _self = unsafePerformIO $ cast3 ATen.cumsum_tls _self _dim _dtype++--+-- Loss Functions+--++-- | Function that measures the Binary Cross Entropy between the target and the output.+binaryCrossEntropyLoss ::+  -- | Specifies the reduction to apply to the output+  Reduction ->+  -- | target+  Tensor ->+  -- | weight+  Tensor ->+  -- | input+  Tensor ->+  -- | output+  Tensor+binaryCrossEntropyLoss reduction target weight t = unsafePerformIO $ cast4 ATen.binary_cross_entropy_tttl t target weight reduction++-- | Binary Cross Entropy with weights defaulted to 1.0 & reduction defaulted to ReduceMean+binaryCrossEntropyLoss' ::+  -- | target+  Tensor ->+  -- | input+  Tensor ->+  -- | output+  Tensor+binaryCrossEntropyLoss' target t = unsafePerformIO $ cast4 ATen.binary_cross_entropy_tttl t target (onesLike target) ReduceMean++-- | This loss combines a Sigmoid layer and the BCELoss in one single class. This version is more numerically stable than using a plain Sigmoid followed by a BCELoss as, by combining the operations into one layer, we take advantage of the log-sum-exp trick for numerical stability.+binaryCrossEntropyWithLogits ::+  -- | Specifies the reduction to apply to the output+  Reduction ->+  -- | target+  Tensor ->+  -- | weight+  Tensor ->+  -- | pos_weight+  Tensor ->+  -- | input+  Tensor ->+  -- | output+  Tensor+binaryCrossEntropyWithLogits reduction target weight pos_weight input = unsafePerformIO $ cast5 ATen.binary_cross_entropy_with_logits_ttttl input target weight pos_weight reduction++-- | Creates a criterion that measures the mean squared error (squared L2 norm) between each element in the @input@ and @target@.+mseLoss ::+  -- | target tensor+  Tensor ->+  -- | input+  Tensor ->+  -- | output+  Tensor+mseLoss target t = unsafePerformIO $ cast3 ATen.mse_loss_ttl t target ATen.kMean++-- | The negative log likelihood loss.+nllLoss' ::+  -- | target tensor+  Tensor ->+  -- | input+  Tensor ->+  -- | output+  Tensor+nllLoss' target t = unsafePerformIO $ cast5 ATen.nll_loss_tttll t target weight ReduceMean (-100 :: Int)+  where+    nClass = shape t !! 1 -- TODO: nicer runtime error if input dimensions don't conform+    weight = toDType (dtype t) $ _toDevice (device target) $ ones' [nClass]++-- | Returns cosine similarity between x1 and x2, computed along dim.+cosineSimilarity ::+  -- | dimension of vectors (default=1)+  Dim ->+  -- | small value to avoid division by 0 (default=1e-8)+  Double ->+  -- | x1+  Tensor ->+  -- | x2+  Tensor ->+  -- | output+  Tensor+cosineSimilarity (Dim dim) eps x1 x2 =+  unsafePerformIO $ cast4 ATen.cosine_similarity_ttld x1 x2 dim eps++-- | Returns cosine similarity with defaulted options.+cosineSimilarity' ::+  -- | x1+  Tensor ->+  -- | x2+  Tensor ->+  -- | output+  Tensor+cosineSimilarity' x1 x2 =+  unsafePerformIO $+    cast4 ATen.cosine_similarity_ttld x1 x2 (1 :: Int) (1e-8 :: Double)++-- | The Connectionist Temporal Classification loss.+-- Calculates loss between a continuous (unsegmented) time series and a target sequence.+-- CTCLoss sums over the probability of possible alignments of input to target,+-- producing a loss value which is differentiable with respect to each input node.+-- The alignment of input to target is assumed to be “many-to-one”, which limits+-- the length of the target sequence such that it must be \leq≤ the input length.+ctcLoss ::+  -- | zero_infinity - Whether to zero infinite losses and the associated gradients (False by default). Infinite losses mainly occur when the inputs are too short to be aligned to the targets.+  Bool ->+  -- | blank label+  Int ->+  -- | reduction+  Reduction ->+  -- | input_lengths+  [Int] ->+  -- | target_lengths+  [Int] ->+  -- | log_probs+  Tensor ->+  -- | targets+  Tensor ->+  -- | output+  Tensor+ctcLoss zeroInfinity blank reduction inputLengths targetLengths logProbs targets = unsafePerformIO $ cast7 ATen.ctc_loss_ttllllb logProbs targets inputLengths targetLengths blank reduction zeroInfinity++-- | Returns CTC loss with defaulted options.+ctcLoss' ::+  -- | reduction+  Reduction ->+  -- | input lengths+  [Int] ->+  -- | target lengths+  [Int] ->+  -- | log probs+  Tensor ->+  -- | targets+  Tensor ->+  -- | output+  Tensor+ctcLoss' reduction inputLengths targetLengths logProbs targets = unsafePerformIO $ cast7 ATen.ctc_loss_ttllllb logProbs targets inputLengths targetLengths blank reduction zeroInfinity+  where+    blank = 0 :: Int+    zeroInfinity = False++-- | Returns the p-norm of (input - other)+-- The shapes of input and other must be broadcastable.+dist ::+  -- | p+  Float ->+  -- | other+  Tensor ->+  -- | input+  Tensor ->+  -- | output+  Tensor+dist _p _other _self = unsafePerformIO $ cast3 ATen.dist_tts _self _other _p++-- | Measures the loss given an input tensor xx and a labels tensor yy (containing 1 or -1).+-- This is usually used for measuring whether two inputs are similar or dissimilar,+-- e.g. using the L1 pairwise distance as xx,+-- and is typically used for learning nonlinear embeddings or semi-supervised learning.+hingeEmbeddingLoss ::+  -- | margin+  Double ->+  -- | reduction+  Reduction ->+  -- | target+  Tensor ->+  -- | self+  Tensor ->+  -- | output+  Tensor+hingeEmbeddingLoss margin reduction target t = unsafePerformIO $ cast4 ATen.hinge_embedding_loss_ttdl t target margin reduction++marginRankingLoss ::+  -- | input1+  Tensor ->+  -- | input2+  Tensor ->+  -- | target+  Tensor ->+  -- | margin+  Double ->+  -- | reduction+  Reduction ->+  -- | output+  Tensor+marginRankingLoss input1 input2 target margin reduction = unsafePerformIO $ cast5 ATen.margin_ranking_loss_tttdl input1 input2 target margin reduction++-- | The 2D negative log likelihood loss+nllLoss2D ::+  Reduction -> -- reduction+  Int -> -- ignore_index+  Tensor -> -- input+  Tensor -> -- target+  Tensor -> -- weight+  Tensor -- output+nllLoss2D reduction ignoreindex input target weight = unsafePerformIO $ cast5 ATen.nll_loss2d_tttll input target weight reduction ignoreindex++-- | Creates a criterion that optimizes a multi-class classification hinge loss (margin-based loss) between input \(x\) (a 2D mini-batch Tensor) and output \(y\) (which is a 1D tensor of target class indices)+multiMarginLoss ::+  -- | reduction+  Reduction ->+  -- | p+  Float ->+  -- | margin+  Float ->+  -- | input+  Tensor ->+  -- | target+  Tensor ->+  -- | weight+  Tensor ->+  -- | output+  Tensor+multiMarginLoss reduction p margin input target weight = unsafePerformIO $ cast6 ATen.multi_margin_loss_ttsstl input target p margin weight reduction++-- | Creates a criterion that optimizes a multi-label one-versus-all loss based on max-entropy, between input \(x\) and target \(y\) of size \((N,C)\) .+multiLabelMarginLoss ::+  Reduction -> -- reduction+  Tensor -> -- input+  Tensor -> -- target+  Tensor -- output+multiLabelMarginLoss reduction input target = unsafePerformIO $ cast3 ATen.multilabel_margin_loss_ttl input target reduction++-- | The Kullback-Leibler divergence Loss+-- KL divergence is a useful distance measure for continuous distributions and is often useful when performing direct regression over the space of (discretely sampled) continuous output distributions.+-- As with NLLLoss, the input given is expected to contain log-probabilities and is not restricted to a 2D Tensor. The targets are interpreted as probabilities by default, but could be considered as log-probabilities with log_target set to True.+-- This criterion expects a target Tensor of the same size as the input Tensor.+klDiv ::+  Reduction ->+  -- | self+  Tensor ->+  -- | target+  Tensor ->+  -- | output+  Tensor+klDiv reduction self target = unsafePerformIO $ cast3 ATen.kl_div_ttl self target reduction++-- | Creates a criterion that uses a squared term if the absolute element-wise+--  error falls below 1 and an L1 term otherwise. It is less sensitive to+-- outliers than the MSELoss and in some cases prevents exploding gradients+-- (e.g. see Fast R-CNN paper by Ross Girshick). Also known as the Huber loss.+smoothL1Loss ::+  -- | reduction+  Reduction ->+  -- | self+  Tensor ->+  -- | target+  Tensor ->+  -- | output+  Tensor+smoothL1Loss reduction self target = unsafePerformIO $ cast3 ATen.smooth_l1_loss_ttl self target reduction++-- | Creates a criterion that optimizes a two-class classification logistic loss+--  between input tensor \(x\) and target tensor \(y\) (containing 1 or -1).+softMarginLoss ::+  -- | reduction+  Reduction ->+  -- | input+  Tensor ->+  -- | target+  Tensor ->+  -- | output+  Tensor+softMarginLoss reduction input target = unsafePerformIO $ cast3 ATen.soft_margin_loss_ttl input target reduction++--+-- Pooling+--++-- | Applies a 1D adaptive max pooling over an input signal composed of several input planes.+adaptiveMaxPool1d ::+  -- | output size+  Int ->+  -- | input+  Tensor ->+  -- | output+  (Tensor, Tensor)+adaptiveMaxPool1d outputSize self =+  unsafePerformIO $+    cast2+      ATen.adaptive_max_pool1d_tl+      self+      outputSize++-- | Applies a 2D adaptive max pooling over an input signal composed of several input planes.+adaptiveMaxPool2d ::+  -- | output size+  (Int, Int) ->+  -- | input+  Tensor ->+  -- | output+  (Tensor, Tensor)+adaptiveMaxPool2d outputSize self =+  unsafePerformIO $+    cast2+      ATen.adaptive_max_pool2d_tl+      self+      outputSize++-- | Applies a 3D adaptive max pooling over an input signal composed of several input planes+adaptiveMaxPool3d ::+  -- | output size+  (Int, Int) ->+  -- | input+  Tensor ->+  (Tensor, Tensor)+adaptiveMaxPool3d outputSize input = unsafePerformIO $ cast2 ATen.adaptive_max_pool3d_tl input outputSize++-- | maxPool1dWithIndices+maxPool1dWithIndices ::+  -- | kernel size+  Int ->+  -- | stride+  Int ->+  -- | padding+  Int ->+  -- | dilation+  Int ->+  -- | ceil mode+  CeilMode ->+  -- | input+  Tensor ->+  -- | output, indices+  (Tensor, Tensor)+maxPool1dWithIndices kernelSize stride padding dilation ceilMode self =+  unsafePerformIO $+    cast6+      ATen.max_pool1d_with_indices_tllllb+      self+      kernelSize+      stride+      padding+      dilation+      ceilMode++-- | Applies a 1D max pooling over an input signal composed of several input planes.+maxPool1d ::+  -- | kernel size+  Int ->+  -- | stride+  Int ->+  -- | padding+  Int ->+  -- | dilation+  Int ->+  -- | ceil mode+  CeilMode ->+  -- | input+  Tensor ->+  -- | output+  Tensor+maxPool1d kernelSize stride padding dilation ceilMode self =+  unsafePerformIO $+    cast6+      ATen.max_pool1d_tllllb+      self+      kernelSize+      stride+      padding+      dilation+      ceilMode++-- | Applies a 2D max pooling over an input signal composed of several input planes.+maxPool2d ::+  -- | kernel size+  (Int, Int) ->+  -- | stride+  (Int, Int) ->+  -- | padding+  (Int, Int) ->+  -- | dilation+  (Int, Int) ->+  -- | ceil mode+  CeilMode ->+  -- | input+  Tensor ->+  -- | output+  Tensor+maxPool2d kernelSize stride padding dilation ceilMode self =+  unsafePerformIO $+    cast6+      ATen.max_pool2d_tllllb+      self+      (asList kernelSize)+      (asList stride)+      (asList padding)+      (asList dilation)+      ceilMode+  where+    asList :: (Int, Int) -> [Int]+    asList (a0, a1) = [a0, a1]++-- | Applies a 3D max pooling over an input signal composed of several input planes.+maxPool3d ::+  -- | kernel size+  (Int, Int, Int) ->+  -- | stride+  (Int, Int, Int) ->+  -- | padding+  (Int, Int, Int) ->+  -- | dilation+  (Int, Int, Int) ->+  -- | ceil mode+  CeilMode ->+  -- | input+  Tensor ->+  -- | output+  Tensor+maxPool3d kernelSize stride padding dilation ceilMode self =+  unsafePerformIO $+    cast6+      ATen.max_pool3d_tllllb+      self+      kernelSize+      stride+      padding+      dilation+      ceilMode++-- | Calculates resulting dimensions from a 2d maxpool operation+-- see https://pytorch.org/docs/master/generated/torch.nn.MaxPool2d.html#torch.nn.MaxPool2d+maxPool2dDim ::+  -- | kernel size+  (Int, Int) ->+  -- | stride+  (Int, Int) ->+  -- | padding+  (Int, Int) ->+  -- | dilation+  (Int, Int) ->+  -- | Ceiling or Floor+  CeilMode ->+  -- | image dimensions+  (Int, Int) ->+  -- | height, width after maxPool+  (Int, Int)+maxPool2dDim kernelSize stride padding dilation ceilMode imgDim =+  (calc fst, calc snd)+  where+    trunc Ceil = P.ceiling+    trunc Floor = P.floor+    calc f' =+      let f = (fromIntegral . f' :: (Int, Int) -> Float)+       in trunc ceilMode $+            ( f imgDim+                + 2 * f padding+                - f dilation * (f kernelSize - 1)+                - 1+            )+              / f stride+              + 1++-- | Applies a 1D average pooling over an input signal composed of several input planes.+avgPool1d ::+  -- | kernel size+  Int ->+  -- | stride+  Int ->+  -- | padding+  Int ->+  -- | ceil mode+  CeilMode ->+  -- | count include pad+  Bool ->+  -- | input+  Tensor ->+  -- | output+  Tensor+avgPool1d kernelSize stride padding ceilMode countIncludePad input =+  unsafePerformIO $+    cast6+      ATen.avg_pool1d_tlllbb+      input+      kernelSize+      stride+      padding+      ceilMode+      countIncludePad++avgPool1d' ::+  -- | kernel size+  Int ->+  -- | stride+  Int ->+  -- | padding+  Int ->+  -- | input+  Tensor ->+  -- | output+  Tensor+avgPool1d' kernelSize stride padding = avgPool1d kernelSize stride padding Floor True++-- | Applies a 1D adaptive average pooling over an input signal composed of several input planes.+adaptiveAvgPool1d ::+  Int -> -- outputSize++  -- | input+  Tensor ->+  -- | output+  Tensor+adaptiveAvgPool1d outputSize input =+  unsafePerformIO $+    cast2 ATen.adaptive_avg_pool1d_tl input outputSize++-- | Applies a 2D adaptive average pooling over an input signal composed of several input planes.+adaptiveAvgPool2d ::+  -- | output size (Height * Width)+  (Int, Int) ->+  -- | input+  Tensor ->+  -- | output+  Tensor+adaptiveAvgPool2d (outputHeight, outputWidth) input =+  unsafePerformIO $+    cast2+      ATen.adaptive_avg_pool2d_tl+      input+      ([outputHeight, outputWidth] :: [Int])++-- | Applies a 3D adaptive average pooling over an input signal composed of several input planes.+adaptiveAvgPool3d ::+  -- | output size (Depth * Height * Width)+  (Int, Int, Int) ->+  -- | input+  Tensor ->+  -- | output+  Tensor+adaptiveAvgPool3d _output_size _self = unsafePerformIO $ cast2 ATen.adaptive_avg_pool3d_tl _self _output_size++--+-- matrix solvers+--++-- | Takes the inverse of the square matrix input. @input@ can be batches of 2D square tensors, in which case this function would return a tensor composed of individual inverses.+inverse ::+  -- | input+  Tensor ->+  -- | output+  Tensor+inverse t = unsafePerformIO $ cast1 ATen.inverse_t t++-- | Solves a system of equations with a triangular coefficient matrix AA and multiple right-hand sides bb+triangularSolve ::+  -- | A+  Tensor ->+  -- | upper+  Bool ->+  -- | transpose+  Bool ->+  -- | unitriangular+  Bool ->+  -- | input+  Tensor ->+  -- | output+  (Tensor, Tensor)+triangularSolve _A _upper _transpose _unitriangular _self = unsafePerformIO $ cast5 ATen.triangular_solve_ttbbb _self _A _upper _transpose _unitriangular++-- | This function returns eigenvalues and eigenvectors of a real symmetric matrix input or a batch of real symmetric matrices, represented by a namedtuple (eigenvalues, eigenvectors).+symeig ::+  -- | bool which controls whether eigenvectors have to be computed+  Bool ->+  -- | controls whether to consider upper-triangular or lower-triangular region+  Tri ->+  -- | input tensor+  Tensor ->+  -- | output tensors+  (Tensor, Tensor)+symeig eigenvectors upper t = unsafePerformIO $ cast3 ATen._linalg_eigh_tsb t boolUpper eigenvectors+  where+    boolUpper =+      case upper of+        Upper -> "U"+        Lower -> "L"++-- | Computes the eigenvalues and eigenvectors of a real square matrix+eig ::+  -- | input (square matrix) for which the eigen values and eigen vectors are to be computed+  Tensor ->+  -- | output tensors+  (Tensor, Tensor)+eig t = unsafePerformIO $ cast1 ATen.linalg_eig_t t++-- | This function returns a namedtuple (U, S, V) which is the singular value decomposition of a input real matrix or batches of real matrices input such that input = U * diag(S) * V^T+svd ::+  -- | controls the shape of returned U and V+  Bool ->+  -- | option whether to compute U and V or not+  Bool ->+  -- | input+  Tensor ->+  -- | output tuple of tensors+  (Tensor, Tensor, Tensor)+svd some compute_uv t = unsafePerformIO $ cast3 ATen.svd_tbb t some compute_uv++-- | Computes the Cholesky decomposition of a symmetric positive-definite matrix AA or for batches of symmetric positive-definite matrices.+cholesky ::+  -- | flag that indicates whether to return a upper or lower triangular matrix.+  Tri ->+  -- | input+  Tensor ->+  -- | output+  Tensor+cholesky upper t = unsafePerformIO $ cast2 ATen.cholesky_tb t boolUpper+  where+    boolUpper = isUpper upper++-- | Solves a linear system of equations with a positive semidefinite matrix to be inverted given its Cholesky factor matrix uu .+choleskySolve ::+  -- | bool whether to consider the Cholesky factor as a lower or upper triangular matrix+  Tri ->+  -- | input matrix b+  Tensor ->+  -- | input matrix u+  Tensor ->+  -- | output+  Tensor+choleskySolve upper t1 t2 = unsafePerformIO $ cast3 ATen.cholesky_solve_ttb t1 t2 boolUpper+  where+    boolUpper = isUpper upper++-- | This function returns the solution to the system of linear equations represented by AX = BAX=B and the LU factorization of A, in order as a namedtuple solution.+solve ::+  -- | input matrix+  Tensor ->+  -- | input square matrix+  Tensor ->+  -- | output solution+  Tensor+solve b a = fst $ ((unsafePerformIO $ cast2 ATen.linalg_solve_ex_tt a b) :: (Tensor, Tensor))++-- | Solves a linear system of equations with a positive semidefinite matrix to be inverted given its Cholesky factor matrix uu .+choleskyInverse ::+  -- | upper or lower triangle+  Tri ->+  -- | input+  Tensor ->+  -- | solution+  Tensor+choleskyInverse upper t = unsafePerformIO $ cast2 ATen.cholesky_inverse_tb t boolUpper+  where+    boolUpper = isUpper upper++-- pstrf :: Bool -> Double -> Tensor -> (Tensor, Tensor)+-- pstrf upper tol t = unsafePerformIO $ cast3 ATen.pstrf_tbs t upper tol++-- qr :: Tensor -> (Tensor, Tensor)+-- qr t = unsafePerformIO $ cast1 ATen.qr_t t++-- | This is a low-level function for calling LAPACK directly. This function returns a namedtuple (a, tau) as defined in LAPACK documentation for geqrf.+geqrf ::+  -- | input+  Tensor ->+  -- | a, tau output matrices (see https://software.intel.com/en-us/node/521004)+  (Tensor, Tensor)+geqrf t = unsafePerformIO $ cast1 ATen.geqrf_t t++-- | Computes the orthogonal matrix Q of a QR factorization, from the @(input, input2)@ tuple returned by 'geqrf' function.+-- This directly calls the underlying LAPACK function @?orgqr@. See LAPACK documentation for @orgqr@ for further details.+orgqr ::+  -- | the @a@ from @geqrf@ function+  Tensor ->+  -- | the @tau@ from @geqrf@ function+  Tensor ->+  -- | output+  Tensor+orgqr b a = unsafePerformIO $ cast2 ATen.orgqr_tt b a++-- | Multiplies mat (given by input3) by the orthogonal Q matrix of the QR factorization formed by torch.geqrf() that is represented by (a, tau) (given by (input, input2)).+-- This directly calls the underlying LAPACK function ?ormqr. See LAPACK documentation for ormqr for further details.+ormqr ::+  -- | input2+  Tensor ->+  -- | input3+  Tensor ->+  -- | left+  Bool ->+  -- | transpose+  Bool ->+  -- | input+  Tensor ->+  -- | output+  Tensor+ormqr _input2 _input3 _left _transpose _self = unsafePerformIO $ cast5 ATen.ormqr_tttbb _self _input2 _input3 _left _transpose++-- | Returns the LU solve of the linear system Ax = bAx=b using the partially pivoted LU factorization of A from torch.lu().+luSolve ::+  -- | LU_data+  Tensor ->+  -- | LU_pivots+  Tensor ->+  -- | input+  Tensor ->+  -- | output+  Tensor+luSolve _LU_data _LU_pivots _self = unsafePerformIO $ cast3 ATen.lu_solve_ttt _self _LU_data _LU_pivots++--+-- dropout+--++-- | During training, randomly zeroes some of the elements of the input tensor with probability p using samples from a Bernoulli distribution.+dropout ::+  -- | dropout probability+  Double ->+  -- | whether or not to activate dropout+  Bool ->+  -- | input+  Tensor ->+  -- | output+  IO Tensor+dropout p train input = cast3 ATen.dropout_tdb input p train++featureDropout ::+  -- | dropout probability+  Double ->+  -- | whether or not to activate dropout+  Bool ->+  -- | input+  Tensor ->+  -- | output+  IO Tensor+featureDropout p train input =+  cast3 ATen.feature_dropout_tdb input p train++-- | Applies alpha dropout to the input.+alphaDropout ::+  -- | dropout probability+  Double ->+  -- | whether or not to activate dropout+  Bool ->+  -- | input+  Tensor ->+  -- | output+  IO Tensor+alphaDropout p train input =+  cast3 ATen.alpha_dropout_tdb input p train++featureAlphaDropout ::+  -- | dropout probability+  Double ->+  -- | whether or not to activate dropout+  Bool ->+  -- | input+  Tensor ->+  -- | output+  IO Tensor+featureAlphaDropout p train input =+  cast3 ATen.feature_alpha_dropout_tdb input p train++--+-- Element-wise logical operators+--++-- | Computes the bitwise NOT of the given input tensor. The input tensor must be of integral or Boolean types. For bool tensors, it computes the logical NOT.+bitwiseNot ::+  -- | input+  Tensor ->+  -- | output+  Tensor+bitwiseNot input = unsafePerformIO $ cast1 ATen.bitwise_not_t input++-- | Computes the element-wise logical NOT of the given input tensor. If not specified, the output tensor will have the bool dtype. If the input tensor is not a bool tensor, zeros are treated as False and non-zeros are treated as True.+logicalNot ::+  -- | input+  Tensor ->+  -- | output+  Tensor+logicalNot t = unsafePerformIO $ cast1 ATen.logical_not_t t++logicalXor ::+  -- | self+  Tensor ->+  -- | other+  Tensor ->+  Tensor+logicalXor self other = unsafePerformIO $ cast2 ATen.logical_xor_tt self other++logicalAnd ::+  -- | self+  Tensor ->+  -- | other+  Tensor ->+  Tensor+logicalAnd self other = unsafePerformIO $ cast2 ATen.logical_and_tt self other++logicalOr ::+  -- | self+  Tensor ->+  -- | other+  Tensor ->+  Tensor+logicalOr self other = unsafePerformIO $ cast2 ATen.logical_or_tt self other++-- | Concatenates the given sequence of seq tensors in the given dimension. All tensors must either have the same shape (except in the concatenating dimension) or be empty.+cat ::+  -- | dimension+  Dim ->+  -- | list of tensors to concatenate+  [Tensor] ->+  -- | output tensor+  Tensor+cat (Dim d) tensors = unsafePerformIO $ cast2 ATen.cat_ll tensors d++index ::+  -- | indices+  [Tensor] ->+  -- | input+  Tensor ->+  -- | output+  Tensor+index _indices _self = unsafePerformIO $ cast2 ATen.index_tl _self _indices++-- Copies the elements of tensor into the self tensor (out-of-place) by selecting the indices in the order given in index.+-- For example, if dim == 0 and index[i] == j, then the ith row of tensor is copied to the jth row of self.+-- The dimth dimension of tensor must have the same size as the length of index (which must be a vector), and all other dimensions must match self, or an error will be raised.+indexCopy ::+  -- | dim+  Int ->+  -- | index+  Tensor ->+  -- | source+  Tensor ->+  -- | input+  Tensor ->+  -- | output+  Tensor+indexCopy dim index source t = unsafePerformIO $ cast4 ATen.index_copy_tltt t dim index source++indexCopyWithDimname ::+  -- | dim+  Dimname ->+  -- | index+  Tensor ->+  -- | source+  Tensor ->+  -- | input+  Tensor ->+  -- | output+  Tensor+indexCopyWithDimname dim index source t = unsafePerformIO $ cast4 ATen.index_copy_tntt t dim index source++-- | Puts values from the tensor value into the input tensor (out-of-place)+-- using the indices specified in indices (which is a tuple of Tensors).+-- The expression tensor.index_put_(indices, value) is equivalent to tensor[indices] = value.+-- If accumulate is True, the elements in value are added to self. If accumulate is False, the behavior is undefined if indices contain duplicate elements.+indexPut ::+  -- | accumulate+  Bool ->+  -- | indices+  [Tensor] ->+  -- | values+  Tensor ->+  -- | input+  Tensor ->+  -- | output+  Tensor+indexPut accumulate indices values self = unsafePerformIO $ cast4 ATen.index_put_tltb self indices values accumulate++-- | Splits a tensor into a specific number of chunks.+-- Last chunk will be smaller if the tensor size along the given dimension dim is not divisible by chunks.+chunk ::+  -- | chunks+  Int ->+  -- | dim+  Dim ->+  -- | input tensor+  Tensor ->+  -- | output list of tensors+  [Tensor]+chunk chunks (Dim d) input =+  unsafePerformIO $+    cast3 ATen.chunk_tll input chunks d++-- | Clamp all elements in input into the range [ min, max ] and return a resulting tensor.+clamp ::+  -- | minimum value+  Float ->+  -- | maximum value+  Float ->+  -- | input+  Tensor ->+  -- | output+  Tensor+clamp min max input = unsafePerformIO $ cast3 ATen.clamp_tss input min max++-- | Clamps all elements in input to be smaller or equal max.+clampMax ::+  -- | maximum value+  Float ->+  -- | input+  Tensor ->+  -- | output+  Tensor+clampMax max input = unsafePerformIO $ cast2 ATen.clamp_max_ts input max++-- | Clamps all elements in input to be larger or equal min.+clampMin ::+  -- | minimum value+  Float ->+  -- | input+  Tensor ->+  -- | output+  Tensor+clampMin min input = unsafePerformIO $ cast2 ATen.clamp_min_ts input min++cudnnIsAcceptable ::+  -- | input+  Tensor ->+  -- | output+  Bool+cudnnIsAcceptable input =+  unsafePerformIO $ cast1 ATen.cudnn_is_acceptable_t input++-- | Pads the input tensor boundaries with a constant value.+constantPadNd1d ::+  -- | list of padding per dimension+  [Int] ->+  -- | value+  Float ->+  -- | input+  Tensor ->+  -- | ouptut+  Tensor+constantPadNd1d padding value input =+  unsafePerformIO $+    cast3+      ATen.constant_pad_nd_tls+      input+      padding+      value++--+-- convolutions+--++-- | Applies a 1D convolution over an input signal composed of several input planes.+conv1d ::+  -- | weight+  Tensor ->+  -- | bias+  Tensor ->+  -- | stride+  Int ->+  -- | padding+  Int ->+  -- | dilation+  Int ->+  -- | groups+  Int ->+  -- | input+  Tensor ->+  -- | output+  Tensor+conv1d weight bias stride padding dilation groups input =+  unsafePerformIO $+    cast7+      ATen.conv1d_tttllll+      input+      weight+      bias+      stride+      padding+      dilation+      groups++conv1d' ::+  -- | weight+  Tensor ->+  -- | bias+  Tensor ->+  -- | strides+  Int ->+  -- | padding+  Int ->+  -- | input+  Tensor ->+  -- | output+  Tensor+conv1d' weight bias stride padding = conv1d weight bias stride padding 1 1++-- | Applies a 2D convolution over an input signal composed of several input planes.+conv2d ::+  -- | weight+  Tensor ->+  -- | bias+  Tensor ->+  -- | strides+  (Int, Int) ->+  -- | padding+  (Int, Int) ->+  -- | dilation+  (Int, Int) ->+  -- | groups+  Int ->+  -- | input+  Tensor ->+  -- | output+  Tensor+conv2d weight bias (stride0, stride1) (padding0, padding1) (dilation0, dilation1) groups input =+  unsafePerformIO $+    cast7+      ATen.conv2d_tttllll+      input+      weight+      bias+      ([stride0, stride1] :: [Int])+      ([padding0, padding1] :: [Int])+      ([dilation0, dilation1] :: [Int])+      groups++conv2d' ::+  -- | weight+  Tensor ->+  -- | bias+  Tensor ->+  -- | strides+  (Int, Int) ->+  -- | padding+  (Int, Int) ->+  -- | input+  Tensor ->+  -- | output+  Tensor+conv2d' weight bias stride padding =+  conv2d+    weight+    bias+    stride+    padding+    (1, 1) -- dilation+    (1 :: Int) -- groups++-- | Applies a 3D convolution over an input signal composed of several input planes.+conv3d ::+  -- | weight+  Tensor ->+  -- | bias+  Tensor ->+  -- | strides+  (Int, Int, Int) ->+  -- | padding+  (Int, Int, Int) ->+  -- | dilation+  (Int, Int, Int) ->+  -- | groups+  Int ->+  -- | input+  Tensor ->+  -- | output+  Tensor+conv3d weight bias (stride0, stride1, stride2) (padding0, padding1, padding2) (dilation0, dilation1, dilation2) groups input =+  unsafePerformIO $+    cast7+      ATen.conv3d_tttllll+      input+      weight+      bias+      ([stride0, stride1, stride2] :: [Int])+      ([padding0, padding1, padding2] :: [Int])+      ([dilation0, dilation1, dilation2] :: [Int])+      groups++conv3d' ::+  -- | weight+  Tensor ->+  -- | bias+  Tensor ->+  -- | strides+  (Int, Int, Int) ->+  -- | padding+  (Int, Int, Int) ->+  -- | input+  Tensor ->+  -- | output+  Tensor+conv3d' weight bias stride padding =+  conv3d+    weight+    bias+    stride+    padding+    (1, 1, 1) -- dilation+    (1 :: Int) -- groups++-- | Applies a 1D transposed convolution over an input signal composed of several input planes+convTranspose1d ::+  -- | weight+  Tensor ->+  -- | bias+  Tensor ->+  -- | strides+  Int ->+  -- | padding+  Int ->+  -- | output padding+  Int ->+  -- | groups+  Int ->+  -- | input+  Tensor ->+  -- | output+  Tensor+convTranspose1d weight bias stride padding outPadding groups input =+  unsafePerformIO $+    cast7+      ATen.conv_transpose1d_tttllll+      input+      weight+      bias+      (stride :: Int)+      (padding :: Int)+      (outPadding :: Int)+      groups++convTranspose1d' ::+  -- | weight+  Tensor ->+  -- | bias+  Tensor ->+  -- | strides+  Int ->+  -- | padding+  Int ->+  -- | input+  Tensor ->+  -- | output+  Tensor+convTranspose1d' weight bias stride padding =+  convTranspose1d+    weight+    bias+    stride+    padding+    0+    (1 :: Int)++-- | Applies a 2D transposed convolution over an input signal composed of several input planes+convTranspose2d ::+  -- | weight+  Tensor ->+  -- | bias+  Tensor ->+  -- | strides+  (Int, Int) ->+  -- | padding+  (Int, Int) ->+  -- | output padding+  (Int, Int) ->+  -- | groups+  Int ->+  -- | input+  Tensor ->+  -- | output+  Tensor+convTranspose2d weight bias (stride0, stride1) (padding0, padding1) (outPadding0, outPadding1) groups input =+  unsafePerformIO $+    cast7+      ATen.conv_transpose2d_tttllll+      input+      weight+      bias+      ([stride0, stride1] :: [Int])+      ([padding0, padding1] :: [Int])+      ([outPadding0, outPadding1] :: [Int])+      groups++convTranspose2d' ::+  -- | weight+  Tensor ->+  -- | bias+  Tensor ->+  -- | strides+  (Int, Int) ->+  -- | padding+  (Int, Int) ->+  -- | input+  Tensor ->+  -- | output+  Tensor+convTranspose2d' weight bias stride padding =+  convTranspose2d+    weight+    bias+    stride+    padding+    (0, 0)+    (1 :: Int)++-- | Applies a 3D transposed convolution over an input signal composed of several input planes+convTranspose3d ::+  -- | weight+  Tensor ->+  -- | bias+  Tensor ->+  -- | strides+  (Int, Int, Int) ->+  -- | padding+  (Int, Int, Int) ->+  -- | output padding+  (Int, Int, Int) ->+  -- | groups+  Int ->+  -- | input+  Tensor ->+  -- | output+  Tensor+convTranspose3d weight bias (stride0, stride1, stride2) (padding0, padding1, padding2) (outPadding0, outPadding1, outPadding2) groups input =+  unsafePerformIO $+    cast7+      ATen.conv_transpose3d_tttllll+      input+      weight+      bias+      ([stride0, stride1, stride2] :: [Int])+      ([padding0, padding1, padding2] :: [Int])+      ([outPadding0, outPadding1, outPadding2] :: [Int])+      groups++convTranspose3d' ::+  -- | weight+  Tensor ->+  -- | bias+  Tensor ->+  -- | strides+  (Int, Int, Int) ->+  -- | padding+  (Int, Int, Int) ->+  -- | input+  Tensor ->+  -- | output+  Tensor+convTranspose3d' weight bias stride padding =+  convTranspose3d+    weight+    bias+    stride+    padding+    (0, 0, 0)+    (1 :: Int)++-- | Returns a new tensor with the signs of the elements of @input@+sign ::+  -- | input+  Tensor ->+  -- | output+  Tensor+sign t = unsafePerformIO $ cast1 ATen.sign_t t++-- | Returns a tensor that is a transposed version of @input@. The given dimensions @dim0@ and @dim1@ are swapped.+transpose ::+  -- | dim1+  Dim ->+  -- | dim2+  Dim ->+  -- | input+  Tensor ->+  -- | output+  Tensor+transpose (Dim d1) (Dim d2) t = unsafePerformIO $ cast3 ATen.transpose_tll t d1 d2++-- | transpose special case for a 2D tensor+transpose2D ::+  -- | input+  Tensor ->+  -- | output+  Tensor+transpose2D = transpose (Dim 0) (Dim 1)++-- | Returns a tensor with the elements of input as the diagonal.+-- The second argument controls which diagonal to consider:+--        If Int = 0, it is the main diagonal.+--        If Int > 0, it is above the main diagonal.+--        If Int < 0, it is below the main diagonal.+diag ::+  -- | diagonal+  Diag ->+  -- | input+  Tensor ->+  -- | output+  Tensor+diag (Diag index) t = unsafePerformIO $ cast2 ATen.tensor_diag_l t index++--+diagEmbed ::+  -- | offset+  Diag ->+  -- | dim1+  Dim ->+  -- | dim2+  Dim ->+  -- | self+  Tensor ->+  Tensor+diagEmbed (Diag offset) (Dim dim1) (Dim dim2) t = unsafePerformIO $ cast4 ATen.diag_embed_tlll t offset dim1 dim2++-- | If input is a vector (1-D tensor), then returns a 2-D square tensor with the elements of input as the diagonal.+-- If input is a tensor with more than one dimension, then returns a 2-D tensor with diagonal elements equal to a flattened input.+-- The argument offset controls which diagonal to consider:+--  If offset = 0, it is the main diagonal.+--  If offset > 0, it is above the main diagonal.+--  If offset < 0, it is below the main diagonal.+diagflat ::+  -- | offset+  Diag ->+  -- | self+  Tensor ->+  -- | output+  Tensor+diagflat (Diag offset) t = unsafePerformIO $ cast2 ATen.diagflat_tl t offset++-- | Returns a partial view of input with the its diagonal elements with respect to dim1 and dim2 appended as a dimension at the end of the shape.+-- Applying diagEmbed to the output of this function with the same arguments yields a diagonal matrix with the diagonal entries of the input. However, diagEmbed has different default dimensions, so those need to be explicitly specified.+diagonal ::+  -- | offset+  Diag ->+  -- | dim1+  Dim ->+  -- | dim2+  Dim ->+  -- | input+  Tensor ->+  -- | output+  Tensor+diagonal (Diag offset) (Dim dim1) (Dim dim2) t = unsafePerformIO $ cast4 ATen.diagonal_tlll t offset dim1 dim2++-- | Returns True if all elements in the tensor are True, False otherwise.+all ::+  -- | input+  Tensor ->+  -- | output+  Bool+all t = toInt (unsafePerformIO $ cast1 ATen.all_t t) == 1++-- | Returns True if any elements in the tensor are True, False otherwise.+any ::+  -- | input+  Tensor ->+  -- | output+  Bool+any t = toInt (unsafePerformIO $ cast1 ATen.any_t t) == 1++-- | Returns True if all elements in each row of the tensor in the given dimension dim are True, False otherwise.+-- If keepdim is True, the output tensor is of the same size as input except in the dimension dim where it is of size 1. Otherwise, dim is squeezed, resulting in the output tensor having 1 fewer dimension than input.+allDim ::+  -- | dimension+  Dim ->+  -- | boolean corresponding to keepdim+  Bool ->+  -- | input+  Tensor ->+  -- | output+  Tensor+allDim (Dim d) keepdim t = unsafePerformIO $ cast3 ATen.all_tlb t d keepdim++-- | Returns True if any elements in each row of the tensor in the given dimension dim are True, False otherwise.+-- If keepdim is True, the output tensor is of the same size as input except in the dimension dim where it is of size 1. Otherwise, dim is squeezed, resulting in the output tensor having 1 fewer dimension than input.+anyDim ::+  -- | dimension+  Dim ->+  -- | boolean corresponding to keepdim+  Bool ->+  -- | input+  Tensor ->+  Tensor -- output+anyDim (Dim d) keepdim t = unsafePerformIO $ cast3 ATen.any_tlb t d keepdim++-- | Permute the dimensions of this tensor.+permute ::+  -- | list corresponding to ordering of dimensions to permute with+  [Int] ->+  -- | input+  Tensor ->+  Tensor -- output+permute dims t = unsafePerformIO $ cast2 ATen.tensor_permute_l t dims++-- | expand+-- TODO: figure out what the `implicit` boolean value does+expand ::+  -- | input+  Tensor ->+  -- | some boolean value with unknown function+  Bool ->+  -- | the desired expanded size+  [Int] ->+  -- | output+  Tensor+expand t someBool dims = unsafePerformIO $ cast3 ATen.tensor_expand_lb t dims someBool++-- | flatten+flatten ::+  -- | startDim+  Dim ->+  -- | endDim+  Dim ->+  -- | self+  Tensor ->+  -- | output+  Tensor+flatten (Dim startDim) (Dim endDim) t = unsafePerformIO $ cast3 ATen.flatten_tll t startDim endDim++-- | flattenAll+flattenAll ::+  -- | input+  Tensor ->+  -- | output+  Tensor+flattenAll t =+  unsafePerformIO $ cast3 ATen.flatten_tll t (0 :: Int) (-1 :: Int)++lstm ::+  -- | input+  Tensor ->+  -- | hx+  [Tensor] ->+  -- | params+  [Tensor] ->+  -- | has_biases+  Bool ->+  -- | num_layers+  Int ->+  -- | dropout+  Double ->+  -- | train+  Bool ->+  -- | bidirectional+  Bool ->+  -- | batch_first+  Bool ->+  (Tensor, Tensor, Tensor)+lstm _input _hx _params _has_biases _num_layers _dropout _train _bidirectional _batch_first = unsafePerformIO $ cast9 ATen.lstm_tllbldbbb _input _hx _params _has_biases _num_layers _dropout _train _bidirectional _batch_first++lstm' ::+  -- | batch_sizes+  Tensor ->+  -- | hx+  [Tensor] ->+  -- | params+  [Tensor] ->+  -- | has_biases+  Bool ->+  -- | num_layers+  Int ->+  -- | dropout+  Double ->+  -- | train+  Bool ->+  -- | bidirectional+  Bool ->+  -- | data+  Tensor ->+  (Tensor, Tensor, Tensor)+lstm' _batch_sizes _hx _params _has_biases _num_layers _dropout _train _bidirectional _data = unsafePerformIO $ cast9 ATen.lstm_ttllbldbb _data _batch_sizes _hx _params _has_biases _num_layers _dropout _train _bidirectional++gru ::+  -- | hx+  Tensor ->+  -- | params+  [Tensor] ->+  -- | has_biases+  Bool ->+  -- | num_layers+  Int ->+  -- | dropout+  Double ->+  -- | train+  Bool ->+  -- | bidirectional+  Bool ->+  -- | batch_first+  Bool ->+  -- | input+  Tensor ->+  (Tensor, Tensor)+gru _hx _params _has_biases _num_layers _dropout _train _bidirectional _batch_first _input = unsafePerformIO $ cast9 ATen.gru_ttlbldbbb _input _hx _params _has_biases _num_layers _dropout _train _bidirectional _batch_first++gru' ::+  -- | batch_sizes+  Tensor ->+  -- | hx+  Tensor ->+  -- | params+  [Tensor] ->+  -- | has_biases+  Bool ->+  -- | num_layers+  Int ->+  -- | dropout+  Double ->+  -- | train+  Bool ->+  -- | bidirectional+  Bool ->+  -- | data+  Tensor ->+  (Tensor, Tensor)+gru' _batch_sizes _hx _params _has_biases _num_layers _dropout _train _bidirectional _data = unsafePerformIO $ cast9 ATen.gru_tttlbldbb _data _batch_sizes _hx _params _has_biases _num_layers _dropout _train _bidirectional++rnnTanh ::+  -- | hx+  Tensor ->+  -- | params+  [Tensor] ->+  -- | has_biases+  Bool ->+  -- | num_layers+  Int ->+  -- | dropout+  Double ->+  -- | train+  Bool ->+  -- | bidirectional+  Bool ->+  -- | batch_first+  Bool ->+  -- | input+  Tensor ->+  (Tensor, Tensor)+rnnTanh _hx _params _has_biases _num_layers _dropout _train _bidirectional _batch_first _input = unsafePerformIO $ cast9 ATen.rnn_tanh_ttlbldbbb _input _hx _params _has_biases _num_layers _dropout _train _bidirectional _batch_first++rnnTanh' ::+  -- | batch_sizes+  Tensor ->+  -- | hx+  Tensor ->+  -- | params+  [Tensor] ->+  -- | has_biases+  Bool ->+  -- | num_layers+  Int ->+  -- | dropout+  Double ->+  -- | train+  Bool ->+  -- | bidirectional+  Bool ->+  -- | data+  Tensor ->+  (Tensor, Tensor)+rnnTanh' _batch_sizes _hx _params _has_biases _num_layers _dropout _train _bidirectional _data = unsafePerformIO $ cast9 ATen.rnn_tanh_tttlbldbb _data _batch_sizes _hx _params _has_biases _num_layers _dropout _train _bidirectional++rnnRelu ::+  -- | hx+  Tensor ->+  -- | params+  [Tensor] ->+  -- | has_biases+  Bool ->+  -- | num_layers+  Int ->+  -- | dropout+  Double ->+  -- | train+  Bool ->+  -- | bidirectional+  Bool ->+  -- | batch_first+  Bool ->+  -- | input+  Tensor ->+  (Tensor, Tensor)+rnnRelu _hx _params _has_biases _num_layers _dropout _train _bidirectional _batch_first _input = unsafePerformIO $ cast9 ATen.rnn_relu_ttlbldbbb _input _hx _params _has_biases _num_layers _dropout _train _bidirectional _batch_first++rnnRelu' ::+  -- | data+  Tensor ->+  -- | batch_sizes+  Tensor ->+  -- | hx+  Tensor ->+  -- | params+  [Tensor] ->+  -- | has_biases+  Bool ->+  -- | num_layers+  Int ->+  -- | dropout+  Double ->+  -- | train+  Bool ->+  -- | bidirectional+  Bool ->+  (Tensor, Tensor)+rnnRelu' _data _batch_sizes _hx _params _has_biases _num_layers _dropout _train _bidirectional = unsafePerformIO $ cast9 ATen.rnn_relu_tttlbldbb _data _batch_sizes _hx _params _has_biases _num_layers _dropout _train _bidirectional++-- | A long short-term memory (LSTM) cell.+lstmCell ::+  -- | input-hidden weights (4*hidden_size, input_size)+  Tensor ->+  -- | hidden-hidden weights (4*hidden_size, hidden_size)+  Tensor ->+  -- | input-hidden bias (4*hidden_size)+  Tensor ->+  -- | hidden-hidden bias, of shape (4*hidden_size)+  Tensor ->+  -- | hidden state+  (Tensor, Tensor) ->+  -- | input+  Tensor ->+  (Tensor, Tensor) -- next hidden state, next cell state+lstmCell _w_ih _w_hh _b_ih _b_hh (_hx, _cx) _input =+  unsafePerformIO $+    cast6+      ATen.lstm_cell_tltttt+      _input+      ([_hx, _cx] :: [Tensor])+      _w_ih+      _w_hh+      _b_ih+      _b_hh -- TODO: make cast work with 2-tuples++-- | A gated recurrent unit (GRU) cell+gruCell ::+  -- | input-hidden weights+  Tensor ->+  -- | hidden-hidden weights+  Tensor ->+  -- | input-hidden bias+  Tensor ->+  -- | hidden-hidden bias+  Tensor ->+  -- | hidden state+  Tensor ->+  -- | input+  Tensor ->+  -- | output+  Tensor+gruCell _w_ih _w_hh _b_ih _b_hh _hx _input =+  unsafePerformIO $+    cast6+      ATen.gru_cell_tttttt+      _input+      _hx+      _w_ih+      _w_hh+      _b_ih+      _b_hh++-- | An Elman RNN cell with tanh non-linearity+rnnTanhCell ::+  -- | input-hidden weights+  Tensor ->+  -- | hidden-hidden weights+  Tensor ->+  -- | input-hidden bias+  Tensor ->+  -- | hidden-hidden bias+  Tensor ->+  -- | hidden state+  Tensor ->+  -- | input+  Tensor ->+  -- | output+  Tensor+rnnTanhCell _w_ih _w_hh _b_ih _b_hh _hx _input =+  unsafePerformIO $ cast6 ATen.rnn_tanh_cell_tttttt _input _hx _w_ih _w_hh _b_ih _b_hh++-- | An Elman RNN cell with ReLU non-linearity+rnnReluCell ::+  -- | input-hidden weights+  Tensor ->+  -- | hidden-hidden weights+  Tensor ->+  -- | input-hidden bias+  Tensor ->+  -- | hidden-hidden bias+  Tensor ->+  -- | hidden state+  Tensor ->+  -- | input+  Tensor ->+  -- | output+  Tensor+rnnReluCell _w_ih _w_hh _b_ih _b_hh _hx _input =+  unsafePerformIO $ cast6 ATen.rnn_relu_cell_tttttt _input _hx _w_ih _w_hh _b_ih _b_hh++-- | A quantized long short-term memory (LSTM) cell.+quantizedLstmCell ::+  -- | input-hidden weights+  Tensor ->+  -- | hidden-hidden weights+  Tensor ->+  -- | input-hidden bias+  Tensor ->+  -- | hidden-hidden bias+  Tensor ->+  -- | input-hidden packed+  Tensor ->+  -- | hidden-hidden packed+  Tensor ->+  -- | input-hidden column offsets+  Tensor ->+  -- | hidden-hidden column offsets+  Tensor ->+  -- | input-hidden scale+  Float ->+  -- | hidden-hidden scale+  Float ->+  -- | input-hidden zero point+  Float ->+  -- | hidden-hidden zero point+  Float ->+  -- | hidden state+  (Tensor, Tensor) ->+  -- | input+  Tensor ->+  -- | output+  (Tensor, Tensor)+quantizedLstmCell _w_ih _w_hh _b_ih _b_hh _packed_ih _packed_hh _col_offsets_ih _col_offsets_hh _scale_ih _scale_hh _zero_point_ih _zero_point_hh (_hx, _cx) _input =+  unsafePerformIO $+    cast14+      ATen.quantized_lstm_cell_tlttttttttssss+      _input+      ([_hx, _cx] :: [Tensor])+      _w_ih+      _w_hh+      _b_ih+      _b_hh+      _packed_ih+      _packed_hh+      _col_offsets_ih+      _col_offsets_hh+      _scale_ih+      _scale_hh+      _zero_point_ih+      _zero_point_hh++-- | A quantized long gated recurrent unit (GRU) cell.+quantizedGruCell ::+  -- | input-hidden weights+  Tensor ->+  -- | hidden-hidden weights+  Tensor ->+  -- | input-hidden bias+  Tensor ->+  -- | hidden-hidden bias+  Tensor ->+  -- | input-hidden packed+  Tensor ->+  -- | hidden-hidden packed+  Tensor ->+  -- | input-hidden column offsets+  Tensor ->+  -- | hidden-hidden column offsets+  Tensor ->+  -- | input-hidden scale+  Float ->+  -- | hidden-hidden scale+  Float ->+  -- | input-hidden zero point+  Float ->+  -- | hidden-hidden zero point+  Float ->+  -- | hidden state+  Tensor ->+  -- | input+  Tensor ->+  -- | output+  Tensor+quantizedGruCell _w_ih _w_hh _b_ih _b_hh _packed_ih _packed_hh _col_offsets_ih _col_offsets_hh _scale_ih _scale_hh _zero_point_ih _zero_point_hh _hx _input =+  unsafePerformIO $ cast14 ATen.quantized_gru_cell_ttttttttttssss _input _hx _w_ih _w_hh _b_ih _b_hh _packed_ih _packed_hh _col_offsets_ih _col_offsets_hh _scale_ih _scale_hh _zero_point_ih _zero_point_hh++-- | A quantized Elman RNN cell with relu non-linearity+quantizedRnnReluCell ::+  -- | input-hidden weights+  Tensor ->+  -- | hidden-hidden weights+  Tensor ->+  -- | input-hidden bias+  Tensor ->+  -- | hidden-hidden bias+  Tensor ->+  -- | input-hidden packed+  Tensor ->+  -- | hidden-hidden packed+  Tensor ->+  -- | input-hidden column offsets+  Tensor ->+  -- | hidden-hidden column offsets+  Tensor ->+  -- | input-hidden scale+  Float ->+  -- | hidden-hidden scale+  Float ->+  -- | input-hidden zero point+  Float ->+  -- | hidden-hidden zero point+  Float ->+  -- | hidden state+  Tensor ->+  -- | input+  Tensor ->+  -- | output+  Tensor+quantizedRnnReluCell _w_ih _w_hh _b_ih _b_hh _packed_ih _packed_hh _col_offsets_ih _col_offsets_hh _scale_ih _scale_hh _zero_point_ih _zero_point_hh _hx _input =+  unsafePerformIO $ cast14 ATen.quantized_rnn_relu_cell_ttttttttttssss _input _hx _w_ih _w_hh _b_ih _b_hh _packed_ih _packed_hh _col_offsets_ih _col_offsets_hh _scale_ih _scale_hh _zero_point_ih _zero_point_hh++-- | A quantized Elman RNN cell with tanh non-linearity+quantizedRnnTanhCell ::+  -- | input-hidden weights+  Tensor ->+  -- | hidden-hidden weights+  Tensor ->+  -- | input-hidden bias+  Tensor ->+  -- | hidden-hidden bias+  Tensor ->+  -- | input-hidden packed+  Tensor ->+  -- | hidden-hidden packed+  Tensor ->+  -- | input-hidden column offsets+  Tensor ->+  -- | hidden-hidden column offsets+  Tensor ->+  -- | input-hidden scale+  Float ->+  -- | hidden-hidden scale+  Float ->+  -- | input-hidden zero point+  Float ->+  -- | hidden-hidden zero point+  Float ->+  -- | hidden state+  Tensor ->+  -- | input+  Tensor ->+  -- | output+  Tensor+quantizedRnnTanhCell _w_ih _w_hh _b_ih _b_hh _packed_ih _packed_hh _col_offsets_ih _col_offsets_hh _scale_ih _scale_hh _zero_point_ih _zero_point_hh _hx _input =+  unsafePerformIO $ cast14 ATen.quantized_rnn_tanh_cell_ttttttttttssss _input _hx _w_ih _w_hh _b_ih _b_hh _packed_ih _packed_hh _col_offsets_ih _col_offsets_hh _scale_ih _scale_hh _zero_point_ih _zero_point_hh++-- | Applies the soft shrinkage function elementwise+softShrink ::+  -- | lambda+  Float ->+  -- | input+  Tensor ->+  -- | output+  Tensor+softShrink lambda input = unsafePerformIO $ cast2 ATen.softshrink_ts input lambda++-- | Concatenates sequence of tensors along a new dimension.+-- All tensors need to be of the same size.+stack ::+  -- | dim+  Dim ->+  -- | input+  [Tensor] ->+  -- | output+  Tensor+stack (Dim d) tensors = unsafePerformIO $ cast2 ATen.stack_ll tensors d++-- | Returns the sum of each row of the input tensor in the given dimension dim.+-- If keepdim is True, the output tensor is of the same size as input except in the dimension(s) dim where it is of size 1.+-- Otherwise, dim is squeezed, resulting in the output tensor having 1 (or len(dim)) fewer dimension(s).+sumDim ::+  -- | dim to sum along+  Dim ->+  -- | whether the output tensor has dim retained or not+  KeepDim ->+  -- | datatype+  DType ->+  -- | input+  Tensor ->+  -- | output+  Tensor+sumDim (Dim d) k dtype input = unsafePerformIO $ cast4 ATen.sum_tlbs input d (keepdim k) dtype++-- | Returns the k largest elements of the given input tensor along a given dimension.+-- If largest is False then the k smallest elements are returned.+-- The boolean option sorted if True, will make sure that the returned k elements are themselves sorted+-- A tuple of (values, indices) is returned, where the indices are the indices of the elements in the original input tensor.+topK ::+  -- | k+  Int ->+  -- | dim to find topK along+  Dim ->+  -- | largest+  Bool ->+  -- | sorted+  Bool ->+  -- | input+  Tensor ->+  -- | output+  (Tensor, Tensor)+topK k (Dim d) largest sorted input = unsafePerformIO $ cast5 ATen.topk_tllbb input k d largest sorted++-- | Returns the log of summed exponentials of each row of the input tensor in the given dimension dim. The computation is numerically stabilized.+logsumexp ::+  -- | keepdim+  Bool ->+  -- | dim+  Int ->+  -- | input+  Tensor ->+  -- | output+  Tensor+logsumexp keepdim dim t = unsafePerformIO $ cast3 ATen.logsumexp_tlb t dim keepdim++-- | Returns the upper triangular part of a matrix (2-D tensor) or batch of matrices input, the other elements of the result tensor out are set to 0.+-- The upper triangular part of the matrix is defined as the elements on and above the diagonal.+-- The argument diagonal controls which diagonal to consider. If diagonal = 0, all elements on and above the main diagonal are retained.+-- A positive value excludes just as many diagonals above the main diagonal, and similarly a negative value includes just as many diagonals below the main diagonal.+-- The main diagonal are the set of indices \((i,i)\) for \(i\) \(\in [0,\min(d_1,d_2)-1]\) where \(d_1\) and \(d_2 \) are the dimensions of the matrix.+triu ::+  -- | diagonal+  Diag ->+  -- | input+  Tensor ->+  -- | output+  Tensor+triu (Diag diagonal) input = unsafePerformIO $ cast2 ATen.triu_tl input diagonal++-- | Returns the lower triangular part of the matrix (2-D tensor) or batch of matrices input, the other elements of the result tensor out are set to 0.+-- The lower triangular part of the matrix is defined as the elements on and below the diagonal.+-- The argument diagonal controls which diagonal to consider. If diagonal = 0, all elements on and below the main diagonal are retained.+-- A positive value includes just as many diagonals above the main diagonal, and similarly a negative value excludes just as many diagonals below the main diagonal.+-- The main diagonals are the set of indices \((i,i)\) for \(i\) \(\in [0,\min(d_1,d_2)-1]\) where \(d_1\) and \(d_2 \) are the dimensions of the matrix.+tril ::+  -- | diagonal+  Diag ->+  -- | input+  Tensor ->+  -- | output+  Tensor+tril (Diag diagonal) input = unsafePerformIO $ cast2 ATen.tril_tl input diagonal++-- | Returns a new tensor with the truncated integer values of the elements of input.+trunc ::+  -- | input+  Tensor ->+  -- | output+  Tensor+trunc input = unsafePerformIO $ cast1 ATen.trunc_t input++-- | Returns the unique elements of the input tensor along a dimension.+uniqueDim ::+  -- | dim+  Int ->+  -- | sorted+  Bool ->+  -- | return_inverse+  Bool ->+  -- | return_counts+  Bool ->+  -- | input+  Tensor ->+  -- | output+  (Tensor, Tensor, Tensor)+uniqueDim dim sorted returnInverse returnCounts self = unsafePerformIO $ cast5 ATen.unique_dim_tlbbb self dim sorted returnInverse returnCounts++-- | Eliminates all but the first element from every consecutive group of equivalent elements.+-- This function is different from uniqueDim in the sense that this function only eliminates consecutive duplicate values.+uniqueConsecutive ::+  -- | return_inverse+  Bool ->+  -- | return_counts+  Bool ->+  -- | dim+  Int ->+  -- | input+  Tensor ->+  -- | output+  (Tensor, Tensor, Tensor)+uniqueConsecutive returnInverse returnCounts dim self = unsafePerformIO $ cast4 ATen.unique_consecutive_tbbl self returnInverse returnCounts dim++-- | Eliminates all but the first element from every consecutive group of equivalent elements along a dimension.+-- This function is different from uniqueDim in the sense that this function only eliminates consecutive duplicate values.+uniqueDimConsecutive ::+  -- | dim+  Int ->+  -- | return_inverse+  Bool ->+  -- | return_counts+  Bool ->+  -- | input+  Tensor ->+  -- | output+  (Tensor, Tensor, Tensor)+uniqueDimConsecutive dim returnInverse returnCounts self = unsafePerformIO $ cast4 ATen.unique_dim_consecutive_tlbb self dim returnInverse returnCounts++-- | Returns a new tensor with a dimension of size one inserted at the specified position.+-- The returned tensor shares the same underlying data with this tensor.+-- A dim value within the range [(dim input) - 1, (dim input) + 1)] can be used. Negative dim will correspond to unsqueeze applied at dim = dim + (dim input) + 1+unsqueeze ::+  -- | dim+  Dim ->+  -- | input+  Tensor ->+  -- | output+  Tensor+unsqueeze (Dim d) input = unsafePerformIO $ cast2 ATen.unsqueeze_tl input d++-- | Upsamples the input, using bilinear upsampling. Expected inputs are spatial (4 dimensional).+upsampleBilinear2d ::+  -- | output-size+  (Int, Int) ->+  -- | align corners+  Bool ->+  -- | self+  Tensor ->+  Tensor+upsampleBilinear2d (outputHeight, outputWidth) alignCorners input = unsafePerformIO $ cast3 ATen.upsample_bilinear2d_tlb input [outputHeight, outputWidth] alignCorners++-- | Applies a 2D nearest neighbor upsampling to an input signal composed of several input channels.+upsampleNearest2d ::+  -- | output_size+  (Int, Int) ->+  -- | scales_h+  Double ->+  -- | scales_w+  Double ->+  -- | self+  Tensor ->+  Tensor+upsampleNearest2d (outputHeight, outputWidth) scales_h scales_w self = unsafePerformIO $ cast4 ATen.upsample_nearest2d_tldd self [outputHeight, outputWidth] scales_h scales_w++-- | Splits the tensor into chunks of given size if possible.+split ::+  -- | split-size+  Int ->+  -- | dim+  Dim ->+  -- | self+  Tensor ->+  [Tensor]+split splitSize (Dim d) input = unsafePerformIO $ cast3 ATen.split_tll input splitSize d++-- | Creates a criterion that measures the mean absolute error (MAE) between each element in the input \(x\) and target \(y\) .+l1Loss ::+  -- | reduction+  Reduction ->+  -- | input+  Tensor ->+  -- | target+  Tensor ->+  -- | output+  Tensor+l1Loss reduction input target = unsafePerformIO $ cast3 ATen.l1_loss_ttl input target reduction++-- | Applies the element-wise function:+-- \(\text{LeakyReLU}(x) = \max(0,x) + \text{negative_slope} ∗ \min(0,x)\)+leakyRelu ::+  -- | negative slope+  Float ->+  -- | input+  Tensor ->+  -- | output+  Tensor+leakyRelu negSlope input = unsafePerformIO $ cast2 ATen.leaky_relu_ts input negSlope++-- | Applies the element-wise function:+-- \(\text{LogSigmoid}(x) = \log(\frac{ 1 }{ 1 + \exp(-x)})\)+logSigmoid ::+  -- | input+  Tensor ->+  -- | output+  Tensor+logSigmoid input = unsafePerformIO $ cast1 ATen.log_sigmoid_t input++-- | Returns a namedtuple (values, indices) where values is the maximum value of each row of the input tensor in the given dimension dim.+-- And indices is the index location of each maximum value found (argmax).+-- If keepdim is True, the output tensors are of the same size as input except in the dimension dim where they are of size 1.+-- Otherwise, dim is squeezed , resulting in the output tensors having 1 fewer dimension than input.+maxDim ::+  -- | dimension+  Dim ->+  -- | keepdim+  KeepDim ->+  -- | input+  Tensor ->+  -- | output+  (Tensor, Tensor)+maxDim (Dim d) k input = unsafePerformIO $ cast3 ATen.max_tlb input d (keepdim k)++-- | Returns a namedtuple (values, indices) where values is the minimum value of each row of the input tensor in the given dimension dim.+-- And indices is the index location of each minimum value found (argmin).+-- If keepdim is True, the output tensors are of the same size as input except in the dimension dim where they are of size 1.+-- Otherwise, dim is squeezed, resulting in the output tensors having 1 fewer dimension than input.+minDim ::+  -- | dimension+  Dim ->+  -- | keepdim+  KeepDim ->+  -- | input+  Tensor ->+  (Tensor, Tensor)+minDim (Dim d) k input = unsafePerformIO $ cast3 ATen.min_tlb input d (keepdim k)++-- | Returns the mean value of each row of the input tensor in the given dimension dim. If dim is a list of dimensions, reduce over all of them.+-- If keepdim is True, the output tensor is of the same size as input except in the dimension(s) dim where it is of size 1.+-- Otherwise, dim is squeezed (see torch.squeeze()), resulting in the output tensor having 1 (or len(dim)) fewer dimension(s).+meanDim ::+  -- | dimension+  Dim ->+  -- | keepdim+  KeepDim ->+  -- | dtype+  DType ->+  -- | input+  Tensor ->+  -- | output+  Tensor+meanDim (Dim d) k dtype input = unsafePerformIO $ cast4 ATen.mean_tlbs input d (keepdim k) dtype++-- | Returns a namedtuple (values, indices) where values is the median value of each row of the input tensor in the given dimension dim.+-- And indices is the index location of each median value found.+-- By default, dim is the last dimension of the input tensor.+-- If keepdim is True, the output tensors are of the same size as input except in the dimension dim where they are of size 1.+-- Otherwise, dim is squeezed (see torch.squeeze()), resulting in the outputs tensor having 1 fewer dimension than input.+medianDim ::+  -- | dimension+  Dim ->+  -- | keepdim+  KeepDim ->+  -- | input+  Tensor ->+  -- | output+  (Tensor, Tensor)+medianDim (Dim d) k input = unsafePerformIO $ cast3 ATen.median_tlb input d (keepdim k)++-- | Returns the matrix product of the NN 2-D tensors.+-- This product is efficiently computed using the matrix chain order algorithm which selects the order in which incurs the lowest cost in terms of arithmetic operations.+-- Note that since this is a function to compute the product, NN needs to be greater than or equal to 2; if equal to 2 then a trivial matrix-matrix product is returned.+-- If NN is 1, then this is a no-op - the original matrix is returned as is.+chainMatmul ::+  -- | list of tensors+  [Tensor] ->+  -- | output+  Tensor+chainMatmul tensors = unsafePerformIO $ cast1 ATen.chain_matmul_l tensors++-- | Applies element-wise the function \(\text{GELU}(x) = x * \Phi(x)\)+-- where \(\Phi(x)\) is the Cumulative Distribution Function for Gaussian Distribution.+gelu ::+  -- | input+  Tensor ->+  -- | output+  Tensor+gelu input = unsafePerformIO $ cast1 ATen.gelu_t input++-- | The gated linear unit. Computes:+-- \(\text{GLU}(a, b) = a \otimes \sigma(b)\)+-- where input is split in half along dim to form a and b, \(\sigma\) is the sigmoid function and \(\otimes\) is the element-wise product between matrices.+glu ::+  -- | dimension+  Dim ->+  -- | input+  Tensor ->+  -- | output+  Tensor+glu (Dim d) input = unsafePerformIO $ cast2 ATen.glu_tl input d++-- | Returns the standard-deviation and mean of all elements in the input tensor.+-- If unbiased is False, then the standard-deviation will be calculated via the biased estimator. Otherwise, Bessel’s correction will be used.+stdMean ::+  -- | unbiased+  Bool ->+  -- | input+  Tensor ->+  -- | output+  (Tensor, Tensor)+stdMean unbiased input = unsafePerformIO $ cast2 ATen.std_mean_tb input unbiased++-- | Returns the standard-deviation and mean of each row of the input tensor in the dimension dim. If dim is a list of dimensions, reduce over all of them.+-- If keepdim is True, the output tensor is of the same size as input except in the dimension(s) dim where it is of size 1.+-- Otherwise, dim is squeezed, resulting in the output tensor having 1 (or len(dim)) fewer dimension(s).+-- If unbiased is False, then the standard-deviation will be calculated via the biased estimator. Otherwise, Bessel’s correction will be used.+stdMeanDim ::+  -- | dimension+  Dim ->+  -- | unbiased+  Bool ->+  -- | whether the output tensor has dim retained or not+  KeepDim ->+  -- | input+  Tensor ->+  -- | output+  (Tensor, Tensor)+stdMeanDim (Dim d) unbiased k input = unsafePerformIO $ cast4 ATen.std_mean_tlbb input d unbiased (keepdim k)++-- | Returns a copy of input. Output tensor keeps a computational graph and a requires_grad value of input tensor.+-- https://discuss.pytorch.org/t/clone-and-detach-in-v0-4-0/16861/41+clone ::+  -- | input+  Tensor ->+  -- | output+  IO Tensor+clone input = cast1 ATen.clone_t input++-- | Returns a copy of input. Output tensor does not keep a computational graph and a requires_grad value of input tensor.+detach ::+  -- | input+  Tensor ->+  -- | output+  IO Tensor+detach input = cast1 ATen.detach_t input++-- | Returns a new tensor with the same data as the input tensor but of a different shape.+view ::+  -- | the desired size+  [Int] ->+  -- | input+  Tensor ->+  -- | output+  Tensor+view dims t = unsafePerformIO $ (cast2 ATen.tensor_view_l) t dims++-- | Repeats this tensor along the specified dimensions.+repeat ::+  -- | The number of times to repeat this tensor along each dimension+  [Int] ->+  -- | input+  Tensor ->+  -- | output+  Tensor+repeat a t = unsafePerformIO $ (cast2 ATen.tensor_repeat_l) t a++batchNormIO ::+  -- | weight+  Tensor ->+  -- | bias+  Tensor ->+  -- | running_mean+  MutableTensor ->+  -- | running_var+  MutableTensor ->+  -- | training+  Bool ->+  -- | momentum+  Double ->+  -- | eps+  Double ->+  -- | input+  Tensor ->+  -- | output+  IO Tensor+batchNormIO weight bias (MutableTensor running_mean) (MutableTensor running_var) training momentum eps input =+  cast9+    ATen.batch_norm_tttttbddb+    input+    weight+    bias+    running_mean+    running_var+    training+    momentum+    eps+    True++instanceNormIO ::+  -- | weight+  Tensor ->+  -- | bias+  Tensor ->+  -- | running_mean+  MutableTensor ->+  -- | running_var+  MutableTensor ->+  -- | training+  Bool ->+  -- | momentum+  Double ->+  -- | eps+  Double ->+  -- | input+  Tensor ->+  -- | output+  IO Tensor+instanceNormIO weight bias (MutableTensor running_mean) (MutableTensor running_var) training momentum eps input =+  cast9+    ATen.instance_norm_tttttbddb+    input+    weight+    bias+    running_mean+    running_var+    training+    momentum+    eps+    True++repeatInterleaveRange ::+  -- | repeats+  Tensor ->+  Tensor+repeatInterleaveRange _repeats = unsafePerformIO $ (cast1 ATen.repeat_interleave_t) _repeats++repeatInterleave ::+  -- | self+  Tensor ->+  -- | repeats+  Tensor ->+  -- | dim+  Int ->+  Tensor+repeatInterleave _self _repeats _dim = unsafePerformIO $ (cast3 ATen.repeat_interleave_ttl) _self _repeats _dim++repeatInterleaveScalar ::+  -- | self+  Tensor ->+  -- | repeats+  Int ->+  -- | dim+  Int ->+  Tensor+repeatInterleaveScalar _self _repeats _dim = unsafePerformIO $ (cast3 ATen.repeat_interleave_tll) _self _repeats _dim
+ src/Torch/Functional/Internal.hs view
@@ -0,0 +1,6808 @@++-- generated by using spec/Declarations.yaml++{-# LANGUAGE DataKinds #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE OverloadedStrings #-}++module Torch.Functional.Internal where+++import System.IO.Unsafe+import Foreign.ForeignPtr++import qualified Torch.Internal.Managed.Native as ATen+import qualified Torch.Internal.Managed.Type.Tensor as ATen+import qualified Torch.Internal.Managed.Type.Scalar as ATen+import qualified Torch.Internal.Managed.Type.Tuple as ATen+import qualified Torch.Internal.Const as ATen+import qualified Torch.Internal.Type as ATen+import qualified Torch.Internal.Managed.Cast+import Torch.Internal.Cast++import Torch.Tensor+import Torch.Scalar+import Torch.Dimname+import Torch.DType+import Torch.Cast+++align_tensors+  :: [Tensor] -- ^ tensors+  -> [Tensor]+align_tensors _tensors = unsafePerformIO $ (cast1 ATen.align_tensors_l) _tensors++native_dropout+  :: Tensor -- ^ input+  -> Double -- ^ p+  -> Bool -- ^ train+  -> (Tensor,Tensor)+native_dropout _input _p _train = unsafePerformIO $ (cast3 ATen.native_dropout_tdb) _input _p _train++dropout+  :: Tensor -- ^ input+  -> Double -- ^ p+  -> Bool -- ^ train+  -> Tensor+dropout _input _p _train = unsafePerformIO $ (cast3 ATen.dropout_tdb) _input _p _train++feature_dropout+  :: Tensor -- ^ input+  -> Double -- ^ p+  -> Bool -- ^ train+  -> Tensor+feature_dropout _input _p _train = unsafePerformIO $ (cast3 ATen.feature_dropout_tdb) _input _p _train++alpha_dropout+  :: Tensor -- ^ input+  -> Double -- ^ p+  -> Bool -- ^ train+  -> Tensor+alpha_dropout _input _p _train = unsafePerformIO $ (cast3 ATen.alpha_dropout_tdb) _input _p _train++feature_alpha_dropout+  :: Tensor -- ^ input+  -> Double -- ^ p+  -> Bool -- ^ train+  -> Tensor+feature_alpha_dropout _input _p _train = unsafePerformIO $ (cast3 ATen.feature_alpha_dropout_tdb) _input _p _train++abs+  :: Tensor -- ^ self+  -> Tensor+abs _self = unsafePerformIO $ (cast1 ATen.abs_t) _self++absolute+  :: Tensor -- ^ self+  -> Tensor+absolute _self = unsafePerformIO $ (cast1 ATen.absolute_t) _self++angle+  :: Tensor -- ^ self+  -> Tensor+angle _self = unsafePerformIO $ (cast1 ATen.angle_t) _self++view_as_real+  :: Tensor -- ^ self+  -> Tensor+view_as_real _self = unsafePerformIO $ (cast1 ATen.view_as_real_t) _self++view_as_complex+  :: Tensor -- ^ self+  -> Tensor+view_as_complex _self = unsafePerformIO $ (cast1 ATen.view_as_complex_t) _self++sgn+  :: Tensor -- ^ self+  -> Tensor+sgn _self = unsafePerformIO $ (cast1 ATen.sgn_t) _self++real+  :: Tensor -- ^ self+  -> Tensor+real _self = unsafePerformIO $ (cast1 ATen.real_t) _self++imag+  :: Tensor -- ^ self+  -> Tensor+imag _self = unsafePerformIO $ (cast1 ATen.imag_t) _self++conj+  :: Tensor -- ^ self+  -> Tensor+conj _self = unsafePerformIO $ (cast1 ATen.conj_t) _self++conj_physical+  :: Tensor -- ^ self+  -> Tensor+conj_physical _self = unsafePerformIO $ (cast1 ATen.conj_physical_t) _self++resolve_conj+  :: Tensor -- ^ self+  -> Tensor+resolve_conj _self = unsafePerformIO $ (cast1 ATen.resolve_conj_t) _self++resolve_neg+  :: Tensor -- ^ self+  -> Tensor+resolve_neg _self = unsafePerformIO $ (cast1 ATen.resolve_neg_t) _self++acos+  :: Tensor -- ^ self+  -> Tensor+acos _self = unsafePerformIO $ (cast1 ATen.acos_t) _self++arccos+  :: Tensor -- ^ self+  -> Tensor+arccos _self = unsafePerformIO $ (cast1 ATen.arccos_t) _self++avg_pool1d+  :: Tensor -- ^ self+  -> Int -- ^ kernel_size+  -> Int -- ^ stride+  -> Int -- ^ padding+  -> Bool -- ^ ceil_mode+  -> Bool -- ^ count_include_pad+  -> Tensor+avg_pool1d _self _kernel_size _stride _padding _ceil_mode _count_include_pad = unsafePerformIO $ (cast6 ATen.avg_pool1d_tlllbb) _self _kernel_size _stride _padding _ceil_mode _count_include_pad++adaptive_avg_pool1d+  :: Tensor -- ^ self+  -> Int -- ^ output_size+  -> Tensor+adaptive_avg_pool1d _self _output_size = unsafePerformIO $ (cast2 ATen.adaptive_avg_pool1d_tl) _self _output_size++adaptive_max_pool1d+  :: Tensor -- ^ self+  -> Int -- ^ output_size+  -> (Tensor,Tensor)+adaptive_max_pool1d _self _output_size = unsafePerformIO $ (cast2 ATen.adaptive_max_pool1d_tl) _self _output_size++add+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Float -- ^ alpha+  -> Tensor+add _self _other _alpha = unsafePerformIO $ (cast3 ATen.add_tts) _self _other _alpha++addScalar+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> Float -- ^ alpha+  -> Tensor+addScalar _self _other _alpha = unsafePerformIO $ (cast3 ATen.add_tss) _self _other _alpha++addmv+  :: Tensor -- ^ self+  -> Tensor -- ^ mat+  -> Tensor -- ^ vec+  -> Float -- ^ beta+  -> Float -- ^ alpha+  -> Tensor+addmv _self _mat _vec _beta _alpha = unsafePerformIO $ (cast5 ATen.addmv_tttss) _self _mat _vec _beta _alpha++addr+  :: Tensor -- ^ self+  -> Tensor -- ^ vec1+  -> Tensor -- ^ vec2+  -> Float -- ^ beta+  -> Float -- ^ alpha+  -> Tensor+addr _self _vec1 _vec2 _beta _alpha = unsafePerformIO $ (cast5 ATen.addr_tttss) _self _vec1 _vec2 _beta _alpha++affine_grid_generator+  :: Tensor -- ^ theta+  -> [Int] -- ^ size+  -> Bool -- ^ align_corners+  -> Tensor+affine_grid_generator _theta _size _align_corners = unsafePerformIO $ (cast3 ATen.affine_grid_generator_tlb) _theta _size _align_corners++allDim+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Bool -- ^ keepdim+  -> Tensor+allDim _self _dim _keepdim = unsafePerformIO $ (cast3 ATen.all_tlb) _self _dim _keepdim++allWithDimname+  :: Tensor -- ^ self+  -> Dimname -- ^ dim+  -> Bool -- ^ keepdim+  -> Tensor+allWithDimname _self _dim _keepdim = unsafePerformIO $ (cast3 ATen.all_tnb) _self _dim _keepdim++allclose+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Double -- ^ rtol+  -> Double -- ^ atol+  -> Bool -- ^ equal_nan+  -> Bool+allclose _self _other _rtol _atol _equal_nan = unsafePerformIO $ (cast5 ATen.allclose_ttddb) _self _other _rtol _atol _equal_nan++anyDim+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Bool -- ^ keepdim+  -> Tensor+anyDim _self _dim _keepdim = unsafePerformIO $ (cast3 ATen.any_tlb) _self _dim _keepdim++anyWithDimname+  :: Tensor -- ^ self+  -> Dimname -- ^ dim+  -> Bool -- ^ keepdim+  -> Tensor+anyWithDimname _self _dim _keepdim = unsafePerformIO $ (cast3 ATen.any_tnb) _self _dim _keepdim++argmax+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Bool -- ^ keepdim+  -> Tensor+argmax _self _dim _keepdim = unsafePerformIO $ (cast3 ATen.argmax_tlb) _self _dim _keepdim++argmin+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Bool -- ^ keepdim+  -> Tensor+argmin _self _dim _keepdim = unsafePerformIO $ (cast3 ATen.argmin_tlb) _self _dim _keepdim++acosh+  :: Tensor -- ^ self+  -> Tensor+acosh _self = unsafePerformIO $ (cast1 ATen.acosh_t) _self++arccosh+  :: Tensor -- ^ self+  -> Tensor+arccosh _self = unsafePerformIO $ (cast1 ATen.arccosh_t) _self++asinh+  :: Tensor -- ^ self+  -> Tensor+asinh _self = unsafePerformIO $ (cast1 ATen.asinh_t) _self++arcsinh+  :: Tensor -- ^ self+  -> Tensor+arcsinh _self = unsafePerformIO $ (cast1 ATen.arcsinh_t) _self++atanh+  :: Tensor -- ^ self+  -> Tensor+atanh _self = unsafePerformIO $ (cast1 ATen.atanh_t) _self++arctanh+  :: Tensor -- ^ self+  -> Tensor+arctanh _self = unsafePerformIO $ (cast1 ATen.arctanh_t) _self++as_strided+  :: Tensor -- ^ self+  -> [Int] -- ^ size+  -> [Int] -- ^ stride+  -> Int -- ^ storage_offset+  -> Tensor+as_strided _self _size _stride _storage_offset = unsafePerformIO $ (cast4 ATen.as_strided_tlll) _self _size _stride _storage_offset++asin+  :: Tensor -- ^ self+  -> Tensor+asin _self = unsafePerformIO $ (cast1 ATen.asin_t) _self++arcsin+  :: Tensor -- ^ self+  -> Tensor+arcsin _self = unsafePerformIO $ (cast1 ATen.arcsin_t) _self++atan+  :: Tensor -- ^ self+  -> Tensor+atan _self = unsafePerformIO $ (cast1 ATen.atan_t) _self++arctan+  :: Tensor -- ^ self+  -> Tensor+arctan _self = unsafePerformIO $ (cast1 ATen.arctan_t) _self++atleast_1d_t+  :: Tensor -- ^ self+  -> Tensor+atleast_1d_t _self = unsafePerformIO $ (cast1 ATen.atleast_1d_t) _self++atleast_1d_l+  :: [Tensor] -- ^ tensors+  -> [Tensor]+atleast_1d_l _tensors = unsafePerformIO $ (cast1 ATen.atleast_1d_l) _tensors++atleast_2d_t+  :: Tensor -- ^ self+  -> Tensor+atleast_2d_t _self = unsafePerformIO $ (cast1 ATen.atleast_2d_t) _self++atleast_2d_l+  :: [Tensor] -- ^ tensors+  -> [Tensor]+atleast_2d_l _tensors = unsafePerformIO $ (cast1 ATen.atleast_2d_l) _tensors++atleast_3d_t+  :: Tensor -- ^ self+  -> Tensor+atleast_3d_t _self = unsafePerformIO $ (cast1 ATen.atleast_3d_t) _self++atleast_3d_l+  :: [Tensor] -- ^ tensors+  -> [Tensor]+atleast_3d_l _tensors = unsafePerformIO $ (cast1 ATen.atleast_3d_l) _tensors++baddbmm+  :: Tensor -- ^ self+  -> Tensor -- ^ batch1+  -> Tensor -- ^ batch2+  -> Float -- ^ beta+  -> Float -- ^ alpha+  -> Tensor+baddbmm _self _batch1 _batch2 _beta _alpha = unsafePerformIO $ (cast5 ATen.baddbmm_tttss) _self _batch1 _batch2 _beta _alpha++batch_norm+  :: Tensor -- ^ input+  -> Tensor -- ^ weight+  -> Tensor -- ^ bias+  -> Tensor -- ^ running_mean+  -> Tensor -- ^ running_var+  -> Bool -- ^ training+  -> Double -- ^ momentum+  -> Double -- ^ eps+  -> Bool -- ^ cudnn_enabled+  -> Tensor+batch_norm _input _weight _bias _running_mean _running_var _training _momentum _eps _cudnn_enabled = unsafePerformIO $ (cast9 ATen.batch_norm_tttttbddb) _input _weight _bias _running_mean _running_var _training _momentum _eps _cudnn_enabled++quantized_batch_norm+  :: Tensor -- ^ input+  -> Tensor -- ^ weight+  -> Tensor -- ^ bias+  -> Tensor -- ^ mean+  -> Tensor -- ^ var+  -> Double -- ^ eps+  -> Double -- ^ output_scale+  -> Int -- ^ output_zero_point+  -> Tensor+quantized_batch_norm _input _weight _bias _mean _var _eps _output_scale _output_zero_point = unsafePerformIO $ (cast8 ATen.quantized_batch_norm_tttttddl) _input _weight _bias _mean _var _eps _output_scale _output_zero_point++bilinear+  :: Tensor -- ^ input1+  -> Tensor -- ^ input2+  -> Tensor -- ^ weight+  -> Tensor -- ^ bias+  -> Tensor+bilinear _input1 _input2 _weight _bias = unsafePerformIO $ (cast4 ATen.bilinear_tttt) _input1 _input2 _weight _bias++binary_cross_entropy+  :: Tensor -- ^ self+  -> Tensor -- ^ target+  -> Tensor -- ^ weight+  -> Int -- ^ reduction+  -> Tensor+binary_cross_entropy _self _target _weight _reduction = unsafePerformIO $ (cast4 ATen.binary_cross_entropy_tttl) _self _target _weight _reduction++binary_cross_entropy_with_logits+  :: Tensor -- ^ self+  -> Tensor -- ^ target+  -> Tensor -- ^ weight+  -> Tensor -- ^ pos_weight+  -> Int -- ^ reduction+  -> Tensor+binary_cross_entropy_with_logits _self _target _weight _pos_weight _reduction = unsafePerformIO $ (cast5 ATen.binary_cross_entropy_with_logits_ttttl) _self _target _weight _pos_weight _reduction++bincount+  :: Tensor -- ^ self+  -> Tensor -- ^ weights+  -> Int -- ^ minlength+  -> Tensor+bincount _self _weights _minlength = unsafePerformIO $ (cast3 ATen.bincount_ttl) _self _weights _minlength++bitwise_not+  :: Tensor -- ^ self+  -> Tensor+bitwise_not _self = unsafePerformIO $ (cast1 ATen.bitwise_not_t) _self++copysign_tt+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+copysign_tt _self _other = unsafePerformIO $ (cast2 ATen.copysign_tt) _self _other++copysign_ts+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> Tensor+copysign_ts _self _other = unsafePerformIO $ (cast2 ATen.copysign_ts) _self _other++logical_not+  :: Tensor -- ^ self+  -> Tensor+logical_not _self = unsafePerformIO $ (cast1 ATen.logical_not_t) _self++logical_xor+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+logical_xor _self _other = unsafePerformIO $ (cast2 ATen.logical_xor_tt) _self _other++logical_and+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+logical_and _self _other = unsafePerformIO $ (cast2 ATen.logical_and_tt) _self _other++logical_or+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+logical_or _self _other = unsafePerformIO $ (cast2 ATen.logical_or_tt) _self _other++bmm+  :: Tensor -- ^ self+  -> Tensor -- ^ mat2+  -> Tensor+bmm _self _mat2 = unsafePerformIO $ (cast2 ATen.bmm_tt) _self _mat2++broadcast_tensors+  :: [Tensor] -- ^ tensors+  -> [Tensor]+broadcast_tensors _tensors = unsafePerformIO $ (cast1 ATen.broadcast_tensors_l) _tensors++broadcast_to+  :: Tensor -- ^ self+  -> [Int] -- ^ size+  -> Tensor+broadcast_to _self _size = unsafePerformIO $ (cast2 ATen.broadcast_to_tl) _self _size++cat+  :: [Tensor] -- ^ tensors+  -> Int -- ^ dim+  -> Tensor+cat _tensors _dim = unsafePerformIO $ (cast2 ATen.cat_ll) _tensors _dim++catWithDimname+  :: [Tensor] -- ^ tensors+  -> Dimname -- ^ dim+  -> Tensor+catWithDimname _tensors _dim = unsafePerformIO $ (cast2 ATen.cat_ln) _tensors _dim++concat_ll+  :: [Tensor] -- ^ tensors+  -> Int -- ^ dim+  -> Tensor+concat_ll _tensors _dim = unsafePerformIO $ (cast2 ATen.concat_ll) _tensors _dim++concat_ln+  :: [Tensor] -- ^ tensors+  -> Dimname -- ^ dim+  -> Tensor+concat_ln _tensors _dim = unsafePerformIO $ (cast2 ATen.concat_ln) _tensors _dim++concatenate_ll+  :: [Tensor] -- ^ tensors+  -> Int -- ^ dim+  -> Tensor+concatenate_ll _tensors _dim = unsafePerformIO $ (cast2 ATen.concatenate_ll) _tensors _dim++concatenate_ln+  :: [Tensor] -- ^ tensors+  -> Dimname -- ^ dim+  -> Tensor+concatenate_ln _tensors _dim = unsafePerformIO $ (cast2 ATen.concatenate_ln) _tensors _dim++block_diag+  :: [Tensor] -- ^ tensors+  -> Tensor+block_diag _tensors = unsafePerformIO $ (cast1 ATen.block_diag_l) _tensors++ceil+  :: Tensor -- ^ self+  -> Tensor+ceil _self = unsafePerformIO $ (cast1 ATen.ceil_t) _self++chain_matmul+  :: [Tensor] -- ^ matrices+  -> Tensor+chain_matmul _matrices = unsafePerformIO $ (cast1 ATen.chain_matmul_l) _matrices++unsafe_chunk+  :: Tensor -- ^ self+  -> Int -- ^ chunks+  -> Int -- ^ dim+  -> [Tensor]+unsafe_chunk _self _chunks _dim = unsafePerformIO $ (cast3 ATen.unsafe_chunk_tll) _self _chunks _dim++chunk+  :: Tensor -- ^ self+  -> Int -- ^ chunks+  -> Int -- ^ dim+  -> [Tensor]+chunk _self _chunks _dim = unsafePerformIO $ (cast3 ATen.chunk_tll) _self _chunks _dim++tensor_split_tll+  :: Tensor -- ^ self+  -> Int -- ^ sections+  -> Int -- ^ dim+  -> [Tensor]+tensor_split_tll _self _sections _dim = unsafePerformIO $ (cast3 ATen.tensor_split_tll) _self _sections _dim++-- tensor_split_tll+--   :: Tensor -- ^ self+--   -> [Int] -- ^ indices+--   -> Int -- ^ dim+--   -> [Tensor]+-- tensor_split_tll _self _indices _dim = unsafePerformIO $ (cast3 ATen.tensor_split_tll) _self _indices _dim++tensor_split_ttl+  :: Tensor -- ^ self+  -> Tensor -- ^ tensor_indices_or_sections+  -> Int -- ^ dim+  -> [Tensor]+tensor_split_ttl _self _tensor_indices_or_sections _dim = unsafePerformIO $ (cast3 ATen.tensor_split_ttl) _self _tensor_indices_or_sections _dim++clamp_tss+  :: Tensor -- ^ self+  -> Float -- ^ min+  -> Float -- ^ max+  -> Tensor+clamp_tss _self _min _max = unsafePerformIO $ (cast3 ATen.clamp_tss) _self _min _max++clamp_ttt+  :: Tensor -- ^ self+  -> Tensor -- ^ min+  -> Tensor -- ^ max+  -> Tensor+clamp_ttt _self _min _max = unsafePerformIO $ (cast3 ATen.clamp_ttt) _self _min _max++clamp_max_ts+  :: Tensor -- ^ self+  -> Float -- ^ max+  -> Tensor+clamp_max_ts _self _max = unsafePerformIO $ (cast2 ATen.clamp_max_ts) _self _max++clamp_max_tt+  :: Tensor -- ^ self+  -> Tensor -- ^ max+  -> Tensor+clamp_max_tt _self _max = unsafePerformIO $ (cast2 ATen.clamp_max_tt) _self _max++clamp_min_ts+  :: Tensor -- ^ self+  -> Float -- ^ min+  -> Tensor+clamp_min_ts _self _min = unsafePerformIO $ (cast2 ATen.clamp_min_ts) _self _min++clamp_min_tt+  :: Tensor -- ^ self+  -> Tensor -- ^ min+  -> Tensor+clamp_min_tt _self _min = unsafePerformIO $ (cast2 ATen.clamp_min_tt) _self _min++clip_tss+  :: Tensor -- ^ self+  -> Float -- ^ min+  -> Float -- ^ max+  -> Tensor+clip_tss _self _min _max = unsafePerformIO $ (cast3 ATen.clip_tss) _self _min _max++clip_ttt+  :: Tensor -- ^ self+  -> Tensor -- ^ min+  -> Tensor -- ^ max+  -> Tensor+clip_ttt _self _min _max = unsafePerformIO $ (cast3 ATen.clip_ttt) _self _min _max++cudnn_is_acceptable+  :: Tensor -- ^ self+  -> Bool+cudnn_is_acceptable _self = unsafePerformIO $ (cast1 ATen.cudnn_is_acceptable_t) _self++complex+  :: Tensor -- ^ real+  -> Tensor -- ^ imag+  -> Tensor+complex _real _imag = unsafePerformIO $ (cast2 ATen.complex_tt) _real _imag++polar+  :: Tensor -- ^ abs+  -> Tensor -- ^ angle+  -> Tensor+polar _abs _angle = unsafePerformIO $ (cast2 ATen.polar_tt) _abs _angle++constant_pad_nd+  :: Tensor -- ^ self+  -> [Int] -- ^ pad+  -> Float -- ^ value+  -> Tensor+constant_pad_nd _self _pad _value = unsafePerformIO $ (cast3 ATen.constant_pad_nd_tls) _self _pad _value++convolution+  :: Tensor -- ^ input+  -> Tensor -- ^ weight+  -> Tensor -- ^ bias+  -> [Int] -- ^ stride+  -> [Int] -- ^ padding+  -> [Int] -- ^ dilation+  -> Bool -- ^ transposed+  -> [Int] -- ^ output_padding+  -> Int -- ^ groups+  -> Tensor+convolution _input _weight _bias _stride _padding _dilation _transposed _output_padding _groups = unsafePerformIO $ (cast9 ATen.convolution_tttlllbll) _input _weight _bias _stride _padding _dilation _transposed _output_padding _groups++convolution_overrideable+  :: Tensor -- ^ input+  -> Tensor -- ^ weight+  -> Tensor -- ^ bias+  -> [Int] -- ^ stride+  -> [Int] -- ^ padding+  -> [Int] -- ^ dilation+  -> Bool -- ^ transposed+  -> [Int] -- ^ output_padding+  -> Int -- ^ groups+  -> Tensor+convolution_overrideable _input _weight _bias _stride _padding _dilation _transposed _output_padding _groups = unsafePerformIO $ (cast9 ATen.convolution_overrideable_tttlllbll) _input _weight _bias _stride _padding _dilation _transposed _output_padding _groups++convolution_backward_overrideable+  :: Tensor -- ^ grad_output+  -> Tensor -- ^ input+  -> Tensor -- ^ weight+  -> [Int] -- ^ stride+  -> [Int] -- ^ padding+  -> [Int] -- ^ dilation+  -> Bool -- ^ transposed+  -> [Int] -- ^ output_padding+  -> Int -- ^ groups+  -> (Bool,Bool,Bool) -- ^ output_mask+  -> (Tensor,Tensor,Tensor)+convolution_backward_overrideable _grad_output _input _weight _stride _padding _dilation _transposed _output_padding _groups _output_mask = unsafePerformIO $ (cast10 ATen.convolution_backward_overrideable_tttlllblla) _grad_output _input _weight _stride _padding _dilation _transposed _output_padding _groups _output_mask++conv1d_tttllll+  :: Tensor -- ^ input+  -> Tensor -- ^ weight+  -> Tensor -- ^ bias+  -> Int -- ^ stride+  -> Int -- ^ padding+  -> Int -- ^ dilation+  -> Int -- ^ groups+  -> Tensor+conv1d_tttllll _input _weight _bias _stride _padding _dilation _groups = unsafePerformIO $ (cast7 ATen.conv1d_tttllll) _input _weight _bias _stride _padding _dilation _groups++conv2d+  :: Tensor -- ^ input+  -> Tensor -- ^ weight+  -> Tensor -- ^ bias+  -> (Int,Int) -- ^ stride+  -> (Int,Int) -- ^ padding+  -> (Int,Int) -- ^ dilation+  -> Int -- ^ groups+  -> Tensor+conv2d _input _weight _bias _stride _padding _dilation _groups = unsafePerformIO $ (cast7 ATen.conv2d_tttllll) _input _weight _bias _stride _padding _dilation _groups++conv3d_tttllll+  :: Tensor -- ^ input+  -> Tensor -- ^ weight+  -> Tensor -- ^ bias+  -> (Int,Int,Int) -- ^ stride+  -> (Int,Int,Int) -- ^ padding+  -> (Int,Int,Int) -- ^ dilation+  -> Int -- ^ groups+  -> Tensor+conv3d_tttllll _input _weight _bias _stride _padding _dilation _groups = unsafePerformIO $ (cast7 ATen.conv3d_tttllll) _input _weight _bias _stride _padding _dilation _groups++conv1d_tttlsll+  :: Tensor -- ^ input+  -> Tensor -- ^ weight+  -> Tensor -- ^ bias+  -> Int -- ^ stride+  -> String -- ^ padding+  -> Int -- ^ dilation+  -> Int -- ^ groups+  -> Tensor+conv1d_tttlsll _input _weight _bias _stride _padding _dilation _groups = unsafePerformIO $ (cast7 ATen.conv1d_tttlsll) _input _weight _bias _stride _padding _dilation _groups++conv2d_tttlsll+  :: Tensor -- ^ input+  -> Tensor -- ^ weight+  -> Tensor -- ^ bias+  -> (Int,Int) -- ^ stride+  -> String -- ^ padding+  -> (Int,Int) -- ^ dilation+  -> Int -- ^ groups+  -> Tensor+conv2d_tttlsll _input _weight _bias _stride _padding _dilation _groups = unsafePerformIO $ (cast7 ATen.conv2d_tttlsll) _input _weight _bias _stride _padding _dilation _groups++conv3d_tttlsll+  :: Tensor -- ^ input+  -> Tensor -- ^ weight+  -> Tensor -- ^ bias+  -> (Int,Int,Int) -- ^ stride+  -> String -- ^ padding+  -> (Int,Int,Int) -- ^ dilation+  -> Int -- ^ groups+  -> Tensor+conv3d_tttlsll _input _weight _bias _stride _padding _dilation _groups = unsafePerformIO $ (cast7 ATen.conv3d_tttlsll) _input _weight _bias _stride _padding _dilation _groups++conv_tbc+  :: Tensor -- ^ self+  -> Tensor -- ^ weight+  -> Tensor -- ^ bias+  -> Int -- ^ pad+  -> Tensor+conv_tbc _self _weight _bias _pad = unsafePerformIO $ (cast4 ATen.conv_tbc_tttl) _self _weight _bias _pad++conv_transpose1d+  :: Tensor -- ^ input+  -> Tensor -- ^ weight+  -> Tensor -- ^ bias+  -> Int -- ^ stride+  -> Int -- ^ padding+  -> Int -- ^ output_padding+  -> Int -- ^ groups+  -> Int -- ^ dilation+  -> Tensor+conv_transpose1d _input _weight _bias _stride _padding _output_padding _groups _dilation = unsafePerformIO $ (cast8 ATen.conv_transpose1d_tttlllll) _input _weight _bias _stride _padding _output_padding _groups _dilation++conv_transpose2d+  :: Tensor -- ^ input+  -> Tensor -- ^ weight+  -> Tensor -- ^ bias+  -> (Int,Int) -- ^ stride+  -> (Int,Int) -- ^ padding+  -> (Int,Int) -- ^ output_padding+  -> Int -- ^ groups+  -> (Int,Int) -- ^ dilation+  -> Tensor+conv_transpose2d _input _weight _bias _stride _padding _output_padding _groups _dilation = unsafePerformIO $ (cast8 ATen.conv_transpose2d_tttlllll) _input _weight _bias _stride _padding _output_padding _groups _dilation++conv_transpose3d+  :: Tensor -- ^ input+  -> Tensor -- ^ weight+  -> Tensor -- ^ bias+  -> (Int,Int,Int) -- ^ stride+  -> (Int,Int,Int) -- ^ padding+  -> (Int,Int,Int) -- ^ output_padding+  -> Int -- ^ groups+  -> (Int,Int,Int) -- ^ dilation+  -> Tensor+conv_transpose3d _input _weight _bias _stride _padding _output_padding _groups _dilation = unsafePerformIO $ (cast8 ATen.conv_transpose3d_tttlllll) _input _weight _bias _stride _padding _output_padding _groups _dilation++copy+  :: Tensor -- ^ self+  -> Tensor -- ^ src+  -> Bool -- ^ non_blocking+  -> Tensor+copy _self _src _non_blocking = unsafePerformIO $ (cast3 ATen.copy_ttb) _self _src _non_blocking++cos+  :: Tensor -- ^ self+  -> Tensor+cos _self = unsafePerformIO $ (cast1 ATen.cos_t) _self++cosh+  :: Tensor -- ^ self+  -> Tensor+cosh _self = unsafePerformIO $ (cast1 ATen.cosh_t) _self++cosine_embedding_loss+  :: Tensor -- ^ input1+  -> Tensor -- ^ input2+  -> Tensor -- ^ target+  -> Double -- ^ margin+  -> Int -- ^ reduction+  -> Tensor+cosine_embedding_loss _input1 _input2 _target _margin _reduction = unsafePerformIO $ (cast5 ATen.cosine_embedding_loss_tttdl) _input1 _input2 _target _margin _reduction++-- count_nonzero_tl+--   :: Tensor -- ^ self+--   -> [Int] -- ^ dim+--   -> Tensor+-- count_nonzero_tl _self _dim = unsafePerformIO $ (cast2 ATen.count_nonzero_tl) _self _dim++count_nonzero_tl+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Tensor+count_nonzero_tl _self _dim = unsafePerformIO $ (cast2 ATen.count_nonzero_tl) _self _dim++cov+  :: Tensor -- ^ self+  -> Int -- ^ correction+  -> Tensor -- ^ fweights+  -> Tensor -- ^ aweights+  -> Tensor+cov _self _correction _fweights _aweights = unsafePerformIO $ (cast4 ATen.cov_tltt) _self _correction _fweights _aweights++corrcoef+  :: Tensor -- ^ self+  -> Tensor+corrcoef _self = unsafePerformIO $ (cast1 ATen.corrcoef_t) _self++cudnn_affine_grid_generator+  :: Tensor -- ^ theta+  -> Int -- ^ N+  -> Int -- ^ C+  -> Int -- ^ H+  -> Int -- ^ W+  -> Tensor+cudnn_affine_grid_generator _theta _N _C _H _W = unsafePerformIO $ (cast5 ATen.cudnn_affine_grid_generator_tllll) _theta _N _C _H _W++cudnn_batch_norm+  :: Tensor -- ^ input+  -> Tensor -- ^ weight+  -> Tensor -- ^ bias+  -> Tensor -- ^ running_mean+  -> Tensor -- ^ running_var+  -> Bool -- ^ training+  -> Double -- ^ exponential_average_factor+  -> Double -- ^ epsilon+  -> (Tensor,Tensor,Tensor,Tensor)+cudnn_batch_norm _input _weight _bias _running_mean _running_var _training _exponential_average_factor _epsilon = unsafePerformIO $ (cast8 ATen.cudnn_batch_norm_tttttbdd) _input _weight _bias _running_mean _running_var _training _exponential_average_factor _epsilon++cudnn_convolution+  :: Tensor -- ^ self+  -> Tensor -- ^ weight+  -> [Int] -- ^ padding+  -> [Int] -- ^ stride+  -> [Int] -- ^ dilation+  -> Int -- ^ groups+  -> Bool -- ^ benchmark+  -> Bool -- ^ deterministic+  -> Bool -- ^ allow_tf32+  -> Tensor+cudnn_convolution _self _weight _padding _stride _dilation _groups _benchmark _deterministic _allow_tf32 = unsafePerformIO $ (cast9 ATen.cudnn_convolution_ttllllbbb) _self _weight _padding _stride _dilation _groups _benchmark _deterministic _allow_tf32++cudnn_convolution_transpose+  :: Tensor -- ^ self+  -> Tensor -- ^ weight+  -> [Int] -- ^ padding+  -> [Int] -- ^ output_padding+  -> [Int] -- ^ stride+  -> [Int] -- ^ dilation+  -> Int -- ^ groups+  -> Bool -- ^ benchmark+  -> Bool -- ^ deterministic+  -> Bool -- ^ allow_tf32+  -> Tensor+cudnn_convolution_transpose _self _weight _padding _output_padding _stride _dilation _groups _benchmark _deterministic _allow_tf32 = unsafePerformIO $ (cast10 ATen.cudnn_convolution_transpose_ttlllllbbb) _self _weight _padding _output_padding _stride _dilation _groups _benchmark _deterministic _allow_tf32++cudnn_convolution_relu+  :: Tensor -- ^ self+  -> Tensor -- ^ weight+  -> Tensor -- ^ bias+  -> [Int] -- ^ stride+  -> [Int] -- ^ padding+  -> [Int] -- ^ dilation+  -> Int -- ^ groups+  -> Tensor+cudnn_convolution_relu _self _weight _bias _stride _padding _dilation _groups = unsafePerformIO $ (cast7 ATen.cudnn_convolution_relu_tttllll) _self _weight _bias _stride _padding _dilation _groups++cudnn_convolution_add_relu+  :: Tensor -- ^ self+  -> Tensor -- ^ weight+  -> Tensor -- ^ z+  -> Float -- ^ alpha+  -> Tensor -- ^ bias+  -> [Int] -- ^ stride+  -> [Int] -- ^ padding+  -> [Int] -- ^ dilation+  -> Int -- ^ groups+  -> Tensor+cudnn_convolution_add_relu _self _weight _z _alpha _bias _stride _padding _dilation _groups = unsafePerformIO $ (cast9 ATen.cudnn_convolution_add_relu_tttstllll) _self _weight _z _alpha _bias _stride _padding _dilation _groups++cudnn_grid_sampler+  :: Tensor -- ^ self+  -> Tensor -- ^ grid+  -> Tensor+cudnn_grid_sampler _self _grid = unsafePerformIO $ (cast2 ATen.cudnn_grid_sampler_tt) _self _grid++cummax_tl+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> (Tensor,Tensor)+cummax_tl _self _dim = unsafePerformIO $ (cast2 ATen.cummax_tl) _self _dim++cummax_tn+  :: Tensor -- ^ self+  -> Dimname -- ^ dim+  -> (Tensor,Tensor)+cummax_tn _self _dim = unsafePerformIO $ (cast2 ATen.cummax_tn) _self _dim++cummin_tl+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> (Tensor,Tensor)+cummin_tl _self _dim = unsafePerformIO $ (cast2 ATen.cummin_tl) _self _dim++cummin_tn+  :: Tensor -- ^ self+  -> Dimname -- ^ dim+  -> (Tensor,Tensor)+cummin_tn _self _dim = unsafePerformIO $ (cast2 ATen.cummin_tn) _self _dim++cumprod+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> DType -- ^ dtype+  -> Tensor+cumprod _self _dim _dtype = unsafePerformIO $ (cast3 ATen.cumprod_tls) _self _dim _dtype++cumprodWithDimname+  :: Tensor -- ^ self+  -> Dimname -- ^ dim+  -> DType -- ^ dtype+  -> Tensor+cumprodWithDimname _self _dim _dtype = unsafePerformIO $ (cast3 ATen.cumprod_tns) _self _dim _dtype++cumsum+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> DType -- ^ dtype+  -> Tensor+cumsum _self _dim _dtype = unsafePerformIO $ (cast3 ATen.cumsum_tls) _self _dim _dtype++cumsumWithDimname+  :: Tensor -- ^ self+  -> Dimname -- ^ dim+  -> DType -- ^ dtype+  -> Tensor+cumsumWithDimname _self _dim _dtype = unsafePerformIO $ (cast3 ATen.cumsum_tns) _self _dim _dtype++cumulative_trapezoid_ttl+  :: Tensor -- ^ y+  -> Tensor -- ^ x+  -> Int -- ^ dim+  -> Tensor+cumulative_trapezoid_ttl _y _x _dim = unsafePerformIO $ (cast3 ATen.cumulative_trapezoid_ttl) _y _x _dim++cumulative_trapezoid_tsl+  :: Tensor -- ^ y+  -> Float -- ^ dx+  -> Int -- ^ dim+  -> Tensor+cumulative_trapezoid_tsl _y _dx _dim = unsafePerformIO $ (cast3 ATen.cumulative_trapezoid_tsl) _y _dx _dim++ctcLoss'+  :: Tensor -- ^ log_probs+  -> Tensor -- ^ targets+  -> [Int] -- ^ input_lengths+  -> [Int] -- ^ target_lengths+  -> Int -- ^ blank+  -> Int -- ^ reduction+  -> Bool -- ^ zero_infinity+  -> Tensor+ctcLoss' _log_probs _targets _input_lengths _target_lengths _blank _reduction _zero_infinity = unsafePerformIO $ (cast7 ATen.ctc_loss_ttllllb) _log_probs _targets _input_lengths _target_lengths _blank _reduction _zero_infinity++ctcLoss+  :: Tensor -- ^ log_probs+  -> Tensor -- ^ targets+  -> Tensor -- ^ input_lengths+  -> Tensor -- ^ target_lengths+  -> Int -- ^ blank+  -> Int -- ^ reduction+  -> Bool -- ^ zero_infinity+  -> Tensor+ctcLoss _log_probs _targets _input_lengths _target_lengths _blank _reduction _zero_infinity = unsafePerformIO $ (cast7 ATen.ctc_loss_ttttllb) _log_probs _targets _input_lengths _target_lengths _blank _reduction _zero_infinity++diag_embed+  :: Tensor -- ^ self+  -> Int -- ^ offset+  -> Int -- ^ dim1+  -> Int -- ^ dim2+  -> Tensor+diag_embed _self _offset _dim1 _dim2 = unsafePerformIO $ (cast4 ATen.diag_embed_tlll) _self _offset _dim1 _dim2++diagflat+  :: Tensor -- ^ self+  -> Int -- ^ offset+  -> Tensor+diagflat _self _offset = unsafePerformIO $ (cast2 ATen.diagflat_tl) _self _offset++diagonal_tlll+  :: Tensor -- ^ self+  -> Int -- ^ offset+  -> Int -- ^ dim1+  -> Int -- ^ dim2+  -> Tensor+diagonal_tlll _self _offset _dim1 _dim2 = unsafePerformIO $ (cast4 ATen.diagonal_tlll) _self _offset _dim1 _dim2++linalg_diagonal+  :: Tensor -- ^ A+  -> Int -- ^ offset+  -> Int -- ^ dim1+  -> Int -- ^ dim2+  -> Tensor+linalg_diagonal _A _offset _dim1 _dim2 = unsafePerformIO $ (cast4 ATen.linalg_diagonal_tlll) _A _offset _dim1 _dim2++diagonal_tnnnl+  :: Tensor -- ^ self+  -> Dimname -- ^ outdim+  -> Dimname -- ^ dim1+  -> Dimname -- ^ dim2+  -> Int -- ^ offset+  -> Tensor+diagonal_tnnnl _self _outdim _dim1 _dim2 _offset = unsafePerformIO $ (cast5 ATen.diagonal_tnnnl) _self _outdim _dim1 _dim2 _offset++diff+  :: Tensor -- ^ self+  -> Int -- ^ n+  -> Int -- ^ dim+  -> Tensor -- ^ prepend+  -> Tensor -- ^ append+  -> Tensor+diff _self _n _dim _prepend _append = unsafePerformIO $ (cast5 ATen.diff_tlltt) _self _n _dim _prepend _append++gradient_tsll+  :: Tensor -- ^ self+  -> Float -- ^ spacing+  -> Int -- ^ dim+  -> Int -- ^ edge_order+  -> [Tensor]+gradient_tsll _self _spacing _dim _edge_order = unsafePerformIO $ (cast4 ATen.gradient_tsll) _self _spacing _dim _edge_order++-- gradient_tsll+--   :: Tensor -- ^ self+--   -> Float -- ^ spacing+--   -> [Int] -- ^ dim+--   -> Int -- ^ edge_order+--   -> [Tensor]+-- gradient_tsll _self _spacing _dim _edge_order = unsafePerformIO $ (cast4 ATen.gradient_tsll) _self _spacing _dim _edge_order++gradient_tll+  :: Tensor -- ^ self+  -> [Int] -- ^ dim+  -> Int -- ^ edge_order+  -> [Tensor]+gradient_tll _self _dim _edge_order = unsafePerformIO $ (cast3 ATen.gradient_tll) _self _dim _edge_order++-- gradient_tAll+--   :: Tensor -- ^ self+--   -> [Scalar] -- ^ spacing+--   -> Int -- ^ dim+--   -> Int -- ^ edge_order+--   -> [Tensor]+-- gradient_tAll _self _spacing _dim _edge_order = unsafePerformIO $ (cast4 ATen.gradient_tAll) _self _spacing _dim _edge_order++-- gradient_tAll+--   :: Tensor -- ^ self+--   -> [Scalar] -- ^ spacing+--   -> [Int] -- ^ dim+--   -> Int -- ^ edge_order+--   -> [Tensor]+-- gradient_tAll _self _spacing _dim _edge_order = unsafePerformIO $ (cast4 ATen.gradient_tAll) _self _spacing _dim _edge_order++-- gradient_tlll+--   :: Tensor -- ^ self+--   -> [Tensor] -- ^ spacing+--   -> Int -- ^ dim+--   -> Int -- ^ edge_order+--   -> [Tensor]+-- gradient_tlll _self _spacing _dim _edge_order = unsafePerformIO $ (cast4 ATen.gradient_tlll) _self _spacing _dim _edge_order++-- gradient_tlll+--   :: Tensor -- ^ self+--   -> [Tensor] -- ^ spacing+--   -> [Int] -- ^ dim+--   -> Int -- ^ edge_order+--   -> [Tensor]+-- gradient_tlll _self _spacing _dim _edge_order = unsafePerformIO $ (cast4 ATen.gradient_tlll) _self _spacing _dim _edge_order++div+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+div _self _other = unsafePerformIO $ (cast2 ATen.div_tt) _self _other++div_tts+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> String -- ^ rounding_mode+  -> Tensor+div_tts _self _other _rounding_mode = unsafePerformIO $ (cast3 ATen.div_tts) _self _other _rounding_mode++divScalar+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> Tensor+divScalar _self _other = unsafePerformIO $ (cast2 ATen.div_ts) _self _other++div_tss+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> String -- ^ rounding_mode+  -> Tensor+div_tss _self _other _rounding_mode = unsafePerformIO $ (cast3 ATen.div_tss) _self _other _rounding_mode++divide_tt+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+divide_tt _self _other = unsafePerformIO $ (cast2 ATen.divide_tt) _self _other++divide_ts+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> Tensor+divide_ts _self _other = unsafePerformIO $ (cast2 ATen.divide_ts) _self _other++divide_tts+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> String -- ^ rounding_mode+  -> Tensor+divide_tts _self _other _rounding_mode = unsafePerformIO $ (cast3 ATen.divide_tts) _self _other _rounding_mode++divide_tss+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> String -- ^ rounding_mode+  -> Tensor+divide_tss _self _other _rounding_mode = unsafePerformIO $ (cast3 ATen.divide_tss) _self _other _rounding_mode++true_divide_tt+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+true_divide_tt _self _other = unsafePerformIO $ (cast2 ATen.true_divide_tt) _self _other++true_divide_ts+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> Tensor+true_divide_ts _self _other = unsafePerformIO $ (cast2 ATen.true_divide_ts) _self _other++dot+  :: Tensor -- ^ self+  -> Tensor -- ^ tensor+  -> Tensor+dot _self _tensor = unsafePerformIO $ (cast2 ATen.dot_tt) _self _tensor++vdot+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+vdot _self _other = unsafePerformIO $ (cast2 ATen.vdot_tt) _self _other++einsum+  :: String -- ^ equation+  -> [Tensor] -- ^ tensors+  -> [Int] -- ^ path+  -> Tensor+einsum _equation _tensors _path = unsafePerformIO $ (cast3 ATen.einsum_sll) _equation _tensors _path++embedding+  :: Tensor -- ^ weight+  -> Tensor -- ^ indices+  -> Int -- ^ padding_idx+  -> Bool -- ^ scale_grad_by_freq+  -> Bool -- ^ sparse+  -> Tensor+embedding _weight _indices _padding_idx _scale_grad_by_freq _sparse = unsafePerformIO $ (cast5 ATen.embedding_ttlbb) _weight _indices _padding_idx _scale_grad_by_freq _sparse++row_stack+  :: [Tensor] -- ^ tensors+  -> Tensor+row_stack _tensors = unsafePerformIO $ (cast1 ATen.row_stack_l) _tensors++embedding_bag_tttblbtb+  :: Tensor -- ^ weight+  -> Tensor -- ^ indices+  -> Tensor -- ^ offsets+  -> Bool -- ^ scale_grad_by_freq+  -> Int -- ^ mode+  -> Bool -- ^ sparse+  -> Tensor -- ^ per_sample_weights+  -> Bool -- ^ include_last_offset+  -> (Tensor,Tensor,Tensor,Tensor)+embedding_bag_tttblbtb _weight _indices _offsets _scale_grad_by_freq _mode _sparse _per_sample_weights _include_last_offset = unsafePerformIO $ (cast8 ATen.embedding_bag_tttblbtb) _weight _indices _offsets _scale_grad_by_freq _mode _sparse _per_sample_weights _include_last_offset++embedding_bag_tttblbtbl+  :: Tensor -- ^ weight+  -> Tensor -- ^ indices+  -> Tensor -- ^ offsets+  -> Bool -- ^ scale_grad_by_freq+  -> Int -- ^ mode+  -> Bool -- ^ sparse+  -> Tensor -- ^ per_sample_weights+  -> Bool -- ^ include_last_offset+  -> Int -- ^ padding_idx+  -> (Tensor,Tensor,Tensor,Tensor)+embedding_bag_tttblbtbl _weight _indices _offsets _scale_grad_by_freq _mode _sparse _per_sample_weights _include_last_offset _padding_idx = unsafePerformIO $ (cast9 ATen.embedding_bag_tttblbtbl) _weight _indices _offsets _scale_grad_by_freq _mode _sparse _per_sample_weights _include_last_offset _padding_idx++erf+  :: Tensor -- ^ self+  -> Tensor+erf _self = unsafePerformIO $ (cast1 ATen.erf_t) _self++erfc+  :: Tensor -- ^ self+  -> Tensor+erfc _self = unsafePerformIO $ (cast1 ATen.erfc_t) _self++exp+  :: Tensor -- ^ self+  -> Tensor+exp _self = unsafePerformIO $ (cast1 ATen.exp_t) _self++exp2+  :: Tensor -- ^ self+  -> Tensor+exp2 _self = unsafePerformIO $ (cast1 ATen.exp2_t) _self++expm1+  :: Tensor -- ^ self+  -> Tensor+expm1 _self = unsafePerformIO $ (cast1 ATen.expm1_t) _self++flatten+  :: Tensor -- ^ self+  -> Int -- ^ start_dim+  -> Int -- ^ end_dim+  -> Tensor+flatten _self _start_dim _end_dim = unsafePerformIO $ (cast3 ATen.flatten_tll) _self _start_dim _end_dim++flattenTo+  :: Tensor -- ^ self+  -> Int -- ^ start_dim+  -> Int -- ^ end_dim+  -> Dimname -- ^ out_dim+  -> Tensor+flattenTo _self _start_dim _end_dim _out_dim = unsafePerformIO $ (cast4 ATen.flatten_tlln) _self _start_dim _end_dim _out_dim++flattenToWithDimname+  :: Tensor -- ^ self+  -> Dimname -- ^ start_dim+  -> Dimname -- ^ end_dim+  -> Dimname -- ^ out_dim+  -> Tensor+flattenToWithDimname _self _start_dim _end_dim _out_dim = unsafePerformIO $ (cast4 ATen.flatten_tnnn) _self _start_dim _end_dim _out_dim++flattenToWithDimnames+  :: Tensor -- ^ self+  -> [Dimname] -- ^ dims+  -> Dimname -- ^ out_dim+  -> Tensor+flattenToWithDimnames _self _dims _out_dim = unsafePerformIO $ (cast3 ATen.flatten_tNn) _self _dims _out_dim++unflatten_tll+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> [Int] -- ^ sizes+  -> Tensor+unflatten_tll _self _dim _sizes = unsafePerformIO $ (cast3 ATen.unflatten_tll) _self _dim _sizes++unflatten_tnlN+  :: Tensor -- ^ self+  -> Dimname -- ^ dim+  -> [Int] -- ^ sizes+  -> [Dimname] -- ^ names+  -> Tensor+unflatten_tnlN _self _dim _sizes _names = unsafePerformIO $ (cast4 ATen.unflatten_tnlN) _self _dim _sizes _names++fill_ts+  :: Tensor -- ^ self+  -> Float -- ^ value+  -> Tensor+fill_ts _self _value = unsafePerformIO $ (cast2 ATen.fill_ts) _self _value++fill_tt+  :: Tensor -- ^ self+  -> Tensor -- ^ value+  -> Tensor+fill_tt _self _value = unsafePerformIO $ (cast2 ATen.fill_tt) _self _value++floor+  :: Tensor -- ^ self+  -> Tensor+floor _self = unsafePerformIO $ (cast1 ATen.floor_t) _self++floor_divide_tt+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+floor_divide_tt _self _other = unsafePerformIO $ (cast2 ATen.floor_divide_tt) _self _other++floor_divide_ts+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> Tensor+floor_divide_ts _self _other = unsafePerformIO $ (cast2 ATen.floor_divide_ts) _self _other++frac+  :: Tensor -- ^ self+  -> Tensor+frac _self = unsafePerformIO $ (cast1 ATen.frac_t) _self++gcd+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+gcd _self _other = unsafePerformIO $ (cast2 ATen.gcd_tt) _self _other++lcm+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+lcm _self _other = unsafePerformIO $ (cast2 ATen.lcm_tt) _self _other++grid_sampler+  :: Tensor -- ^ input+  -> Tensor -- ^ grid+  -> Int -- ^ interpolation_mode+  -> Int -- ^ padding_mode+  -> Bool -- ^ align_corners+  -> Tensor+grid_sampler _input _grid _interpolation_mode _padding_mode _align_corners = unsafePerformIO $ (cast5 ATen.grid_sampler_ttllb) _input _grid _interpolation_mode _padding_mode _align_corners++grid_sampler_2d+  :: Tensor -- ^ input+  -> Tensor -- ^ grid+  -> Int -- ^ interpolation_mode+  -> Int -- ^ padding_mode+  -> Bool -- ^ align_corners+  -> Tensor+grid_sampler_2d _input _grid _interpolation_mode _padding_mode _align_corners = unsafePerformIO $ (cast5 ATen.grid_sampler_2d_ttllb) _input _grid _interpolation_mode _padding_mode _align_corners++grid_sampler_3d+  :: Tensor -- ^ input+  -> Tensor -- ^ grid+  -> Int -- ^ interpolation_mode+  -> Int -- ^ padding_mode+  -> Bool -- ^ align_corners+  -> Tensor+grid_sampler_3d _input _grid _interpolation_mode _padding_mode _align_corners = unsafePerformIO $ (cast5 ATen.grid_sampler_3d_ttllb) _input _grid _interpolation_mode _padding_mode _align_corners++hinge_embedding_loss+  :: Tensor -- ^ self+  -> Tensor -- ^ target+  -> Double -- ^ margin+  -> Int -- ^ reduction+  -> Tensor+hinge_embedding_loss _self _target _margin _reduction = unsafePerformIO $ (cast4 ATen.hinge_embedding_loss_ttdl) _self _target _margin _reduction++group_norm+  :: Tensor -- ^ input+  -> Int -- ^ num_groups+  -> Tensor -- ^ weight+  -> Tensor -- ^ bias+  -> Double -- ^ eps+  -> Bool -- ^ cudnn_enabled+  -> Tensor+group_norm _input _num_groups _weight _bias _eps _cudnn_enabled = unsafePerformIO $ (cast6 ATen.group_norm_tlttdb) _input _num_groups _weight _bias _eps _cudnn_enabled++native_group_norm+  :: Tensor -- ^ input+  -> Tensor -- ^ weight+  -> Tensor -- ^ bias+  -> Int -- ^ N+  -> Int -- ^ C+  -> Int -- ^ HxW+  -> Int -- ^ group+  -> Double -- ^ eps+  -> (Tensor,Tensor,Tensor)+native_group_norm _input _weight _bias _N _C _HxW _group _eps = unsafePerformIO $ (cast8 ATen.native_group_norm_tttlllld) _input _weight _bias _N _C _HxW _group _eps++index+  :: Tensor -- ^ self+  -> [Tensor] -- ^ indices+  -> Tensor+index _self _indices = unsafePerformIO $ (cast2 ATen.index_tl) _self _indices++indexCopy+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Tensor -- ^ index+  -> Tensor -- ^ source+  -> Tensor+indexCopy _self _dim _index _source = unsafePerformIO $ (cast4 ATen.index_copy_tltt) _self _dim _index _source++indexCopyWithDimname+  :: Tensor -- ^ self+  -> Dimname -- ^ dim+  -> Tensor -- ^ index+  -> Tensor -- ^ source+  -> Tensor+indexCopyWithDimname _self _dim _index _source = unsafePerformIO $ (cast4 ATen.index_copy_tntt) _self _dim _index _source++index_put+  :: Tensor -- ^ self+  -> [Tensor] -- ^ indices+  -> Tensor -- ^ values+  -> Bool -- ^ accumulate+  -> Tensor+index_put _self _indices _values _accumulate = unsafePerformIO $ (cast4 ATen.index_put_tltb) _self _indices _values _accumulate++instance_norm+  :: Tensor -- ^ input+  -> Tensor -- ^ weight+  -> Tensor -- ^ bias+  -> Tensor -- ^ running_mean+  -> Tensor -- ^ running_var+  -> Bool -- ^ use_input_stats+  -> Double -- ^ momentum+  -> Double -- ^ eps+  -> Bool -- ^ cudnn_enabled+  -> Tensor+instance_norm _input _weight _bias _running_mean _running_var _use_input_stats _momentum _eps _cudnn_enabled = unsafePerformIO $ (cast9 ATen.instance_norm_tttttbddb) _input _weight _bias _running_mean _running_var _use_input_stats _momentum _eps _cudnn_enabled++isclose+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Double -- ^ rtol+  -> Double -- ^ atol+  -> Bool -- ^ equal_nan+  -> Tensor+isclose _self _other _rtol _atol _equal_nan = unsafePerformIO $ (cast5 ATen.isclose_ttddb) _self _other _rtol _atol _equal_nan++isin_ttbb+  :: Tensor -- ^ elements+  -> Tensor -- ^ test_elements+  -> Bool -- ^ assume_unique+  -> Bool -- ^ invert+  -> Tensor+isin_ttbb _elements _test_elements _assume_unique _invert = unsafePerformIO $ (cast4 ATen.isin_ttbb) _elements _test_elements _assume_unique _invert++isin_tsbb+  :: Tensor -- ^ elements+  -> Float -- ^ test_element+  -> Bool -- ^ assume_unique+  -> Bool -- ^ invert+  -> Tensor+isin_tsbb _elements _test_element _assume_unique _invert = unsafePerformIO $ (cast4 ATen.isin_tsbb) _elements _test_element _assume_unique _invert++isin_stbb+  :: Float -- ^ element+  -> Tensor -- ^ test_elements+  -> Bool -- ^ assume_unique+  -> Bool -- ^ invert+  -> Tensor+isin_stbb _element _test_elements _assume_unique _invert = unsafePerformIO $ (cast4 ATen.isin_stbb) _element _test_elements _assume_unique _invert++isnan+  :: Tensor -- ^ self+  -> Tensor+isnan _self = unsafePerformIO $ (cast1 ATen.isnan_t) _self++is_distributed+  :: Tensor -- ^ self+  -> Bool+is_distributed _self = unsafePerformIO $ (cast1 ATen.is_distributed_t) _self++is_floating_point+  :: Tensor -- ^ self+  -> Bool+is_floating_point _self = unsafePerformIO $ (cast1 ATen.is_floating_point_t) _self++is_complex+  :: Tensor -- ^ self+  -> Bool+is_complex _self = unsafePerformIO $ (cast1 ATen.is_complex_t) _self++is_conj+  :: Tensor -- ^ self+  -> Bool+is_conj _self = unsafePerformIO $ (cast1 ATen.is_conj_t) _self++is_neg+  :: Tensor -- ^ self+  -> Bool+is_neg _self = unsafePerformIO $ (cast1 ATen.is_neg_t) _self++isreal+  :: Tensor -- ^ self+  -> Tensor+isreal _self = unsafePerformIO $ (cast1 ATen.isreal_t) _self++is_nonzero+  :: Tensor -- ^ self+  -> Bool+is_nonzero _self = unsafePerformIO $ (cast1 ATen.is_nonzero_t) _self++is_same_size+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Bool+is_same_size _self _other = unsafePerformIO $ (cast2 ATen.is_same_size_tt) _self _other++is_signed+  :: Tensor -- ^ self+  -> Bool+is_signed _self = unsafePerformIO $ (cast1 ATen.is_signed_t) _self++is_inference+  :: Tensor -- ^ self+  -> Bool+is_inference _self = unsafePerformIO $ (cast1 ATen.is_inference_t) _self++kl_div+  :: Tensor -- ^ self+  -> Tensor -- ^ target+  -> Int -- ^ reduction+  -> Bool -- ^ log_target+  -> Tensor+kl_div _self _target _reduction _log_target = unsafePerformIO $ (cast4 ATen.kl_div_ttlb) _self _target _reduction _log_target++kron+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+kron _self _other = unsafePerformIO $ (cast2 ATen.kron_tt) _self _other++kthvalue+  :: Tensor -- ^ self+  -> Int -- ^ k+  -> Int -- ^ dim+  -> Bool -- ^ keepdim+  -> (Tensor,Tensor)+kthvalue _self _k _dim _keepdim = unsafePerformIO $ (cast4 ATen.kthvalue_tllb) _self _k _dim _keepdim++kthvalueWithDimname+  :: Tensor -- ^ self+  -> Int -- ^ k+  -> Dimname -- ^ dim+  -> Bool -- ^ keepdim+  -> (Tensor,Tensor)+kthvalueWithDimname _self _k _dim _keepdim = unsafePerformIO $ (cast4 ATen.kthvalue_tlnb) _self _k _dim _keepdim++layer_norm+  :: Tensor -- ^ input+  -> [Int] -- ^ normalized_shape+  -> Tensor -- ^ weight+  -> Tensor -- ^ bias+  -> Double -- ^ eps+  -> Bool -- ^ cudnn_enable+  -> Tensor+layer_norm _input _normalized_shape _weight _bias _eps _cudnn_enable = unsafePerformIO $ (cast6 ATen.layer_norm_tlttdb) _input _normalized_shape _weight _bias _eps _cudnn_enable++native_layer_norm+  :: Tensor -- ^ input+  -> [Int] -- ^ normalized_shape+  -> Tensor -- ^ weight+  -> Tensor -- ^ bias+  -> Double -- ^ eps+  -> (Tensor,Tensor,Tensor)+native_layer_norm _input _normalized_shape _weight _bias _eps = unsafePerformIO $ (cast5 ATen.native_layer_norm_tlttd) _input _normalized_shape _weight _bias _eps++nan_to_num+  :: Tensor -- ^ self+  -> Double -- ^ nan+  -> Double -- ^ posinf+  -> Double -- ^ neginf+  -> Tensor+nan_to_num _self _nan _posinf _neginf = unsafePerformIO $ (cast4 ATen.nan_to_num_tddd) _self _nan _posinf _neginf++linear+  :: Tensor -- ^ input+  -> Tensor -- ^ weight+  -> Tensor -- ^ bias+  -> Tensor+linear _input _weight _bias = unsafePerformIO $ (cast3 ATen.linear_ttt) _input _weight _bias++mkldnn_linear+  :: Tensor -- ^ self+  -> Tensor -- ^ weight+  -> Tensor -- ^ bias+  -> Tensor+mkldnn_linear _self _weight _bias = unsafePerformIO $ (cast3 ATen.mkldnn_linear_ttt) _self _weight _bias++mkldnn_linear_backward_input+  :: [Int] -- ^ input_size+  -> Tensor -- ^ grad_output+  -> Tensor -- ^ weight+  -> Tensor+mkldnn_linear_backward_input _input_size _grad_output _weight = unsafePerformIO $ (cast3 ATen.mkldnn_linear_backward_input_ltt) _input_size _grad_output _weight++mkldnn_linear_backward_weights+  :: Tensor -- ^ grad_output+  -> Tensor -- ^ input+  -> Tensor -- ^ weight+  -> Bool -- ^ bias_defined+  -> (Tensor,Tensor)+mkldnn_linear_backward_weights _grad_output _input _weight _bias_defined = unsafePerformIO $ (cast4 ATen.mkldnn_linear_backward_weights_tttb) _grad_output _input _weight _bias_defined++fbgemm_linear_int8_weight_fp32_activation+  :: Tensor -- ^ input+  -> Tensor -- ^ weight+  -> Tensor -- ^ packed+  -> Tensor -- ^ col_offsets+  -> Float -- ^ weight_scale+  -> Float -- ^ weight_zero_point+  -> Tensor -- ^ bias+  -> Tensor+fbgemm_linear_int8_weight_fp32_activation _input _weight _packed _col_offsets _weight_scale _weight_zero_point _bias = unsafePerformIO $ (cast7 ATen.fbgemm_linear_int8_weight_fp32_activation_ttttsst) _input _weight _packed _col_offsets _weight_scale _weight_zero_point _bias++fbgemm_linear_int8_weight+  :: Tensor -- ^ input+  -> Tensor -- ^ weight+  -> Tensor -- ^ packed+  -> Tensor -- ^ col_offsets+  -> Float -- ^ weight_scale+  -> Float -- ^ weight_zero_point+  -> Tensor -- ^ bias+  -> Tensor+fbgemm_linear_int8_weight _input _weight _packed _col_offsets _weight_scale _weight_zero_point _bias = unsafePerformIO $ (cast7 ATen.fbgemm_linear_int8_weight_ttttsst) _input _weight _packed _col_offsets _weight_scale _weight_zero_point _bias++fbgemm_linear_quantize_weight+  :: Tensor -- ^ input+  -> (Tensor,Tensor,Double,Int)+fbgemm_linear_quantize_weight _input = unsafePerformIO $ (cast1 ATen.fbgemm_linear_quantize_weight_t) _input++fbgemm_pack_gemm_matrix_fp16+  :: Tensor -- ^ input+  -> Tensor+fbgemm_pack_gemm_matrix_fp16 _input = unsafePerformIO $ (cast1 ATen.fbgemm_pack_gemm_matrix_fp16_t) _input++fbgemm_linear_fp16_weight_fp32_activation+  :: Tensor -- ^ input+  -> Tensor -- ^ packed_weight+  -> Tensor -- ^ bias+  -> Tensor+fbgemm_linear_fp16_weight_fp32_activation _input _packed_weight _bias = unsafePerformIO $ (cast3 ATen.fbgemm_linear_fp16_weight_fp32_activation_ttt) _input _packed_weight _bias++fbgemm_linear_fp16_weight+  :: Tensor -- ^ input+  -> Tensor -- ^ packed_weight+  -> Tensor -- ^ bias+  -> Tensor+fbgemm_linear_fp16_weight _input _packed_weight _bias = unsafePerformIO $ (cast3 ATen.fbgemm_linear_fp16_weight_ttt) _input _packed_weight _bias++quantizeFbgemm'+  :: Tensor -- ^ input+  -> Tensor+quantizeFbgemm' _input = unsafePerformIO $ (cast1 ATen.fbgemm_pack_quantized_matrix_t) _input++quantizeFbgemm+  :: Tensor -- ^ input+  -> Int -- ^ K+  -> Int -- ^ N+  -> Tensor+quantizeFbgemm _input _K _N = unsafePerformIO $ (cast3 ATen.fbgemm_pack_quantized_matrix_tll) _input _K _N++ldexp+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+ldexp _self _other = unsafePerformIO $ (cast2 ATen.ldexp_tt) _self _other++log+  :: Tensor -- ^ self+  -> Tensor+log _self = unsafePerformIO $ (cast1 ATen.log_t) _self++log10+  :: Tensor -- ^ self+  -> Tensor+log10 _self = unsafePerformIO $ (cast1 ATen.log10_t) _self++log1p+  :: Tensor -- ^ self+  -> Tensor+log1p _self = unsafePerformIO $ (cast1 ATen.log1p_t) _self++log2+  :: Tensor -- ^ self+  -> Tensor+log2 _self = unsafePerformIO $ (cast1 ATen.log2_t) _self++logaddexp+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+logaddexp _self _other = unsafePerformIO $ (cast2 ATen.logaddexp_tt) _self _other++logaddexp2+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+logaddexp2 _self _other = unsafePerformIO $ (cast2 ATen.logaddexp2_tt) _self _other++xlogy_tt+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+xlogy_tt _self _other = unsafePerformIO $ (cast2 ATen.xlogy_tt) _self _other++xlogy_st+  :: Float -- ^ self+  -> Tensor -- ^ other+  -> Tensor+xlogy_st _self _other = unsafePerformIO $ (cast2 ATen.xlogy_st) _self _other++xlogy_ts+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> Tensor+xlogy_ts _self _other = unsafePerformIO $ (cast2 ATen.xlogy_ts) _self _other++logSoftmax+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> DType -- ^ dtype+  -> Tensor+logSoftmax _self _dim _dtype = unsafePerformIO $ (cast3 ATen.log_softmax_tls) _self _dim _dtype++logSoftmaxWithDimname+  :: Tensor -- ^ self+  -> Dimname -- ^ dim+  -> DType -- ^ dtype+  -> Tensor+logSoftmaxWithDimname _self _dim _dtype = unsafePerformIO $ (cast3 ATen.log_softmax_tns) _self _dim _dtype++logcumsumexp_tl+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Tensor+logcumsumexp_tl _self _dim = unsafePerformIO $ (cast2 ATen.logcumsumexp_tl) _self _dim++logcumsumexp_tn+  :: Tensor -- ^ self+  -> Dimname -- ^ dim+  -> Tensor+logcumsumexp_tn _self _dim = unsafePerformIO $ (cast2 ATen.logcumsumexp_tn) _self _dim++logsumexp+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Bool -- ^ keepdim+  -> Tensor+logsumexp _self _dim _keepdim = unsafePerformIO $ (cast3 ATen.logsumexp_tlb) _self _dim _keepdim++logsumexpWithDimnameList+  :: Tensor -- ^ self+  -> [Dimname] -- ^ dim+  -> Bool -- ^ keepdim+  -> Tensor+logsumexpWithDimnameList _self _dim _keepdim = unsafePerformIO $ (cast3 ATen.logsumexp_tNb) _self _dim _keepdim++margin_ranking_loss+  :: Tensor -- ^ input1+  -> Tensor -- ^ input2+  -> Tensor -- ^ target+  -> Double -- ^ margin+  -> Int -- ^ reduction+  -> Tensor+margin_ranking_loss _input1 _input2 _target _margin _reduction = unsafePerformIO $ (cast5 ATen.margin_ranking_loss_tttdl) _input1 _input2 _target _margin _reduction++matmul+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+matmul _self _other = unsafePerformIO $ (cast2 ATen.matmul_tt) _self _other++matrix_power+  :: Tensor -- ^ self+  -> Int -- ^ n+  -> Tensor+matrix_power _self _n = unsafePerformIO $ (cast2 ATen.matrix_power_tl) _self _n++matrix_exp+  :: Tensor -- ^ self+  -> Tensor+matrix_exp _self = unsafePerformIO $ (cast1 ATen.matrix_exp_t) _self++aminmax+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Bool -- ^ keepdim+  -> (Tensor,Tensor)+aminmax _self _dim _keepdim = unsafePerformIO $ (cast3 ATen.aminmax_tlb) _self _dim _keepdim++maxDim+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Bool -- ^ keepdim+  -> (Tensor,Tensor)+maxDim _self _dim _keepdim = unsafePerformIO $ (cast3 ATen.max_tlb) _self _dim _keepdim++maxWithDimname+  :: Tensor -- ^ self+  -> Dimname -- ^ dim+  -> Bool -- ^ keepdim+  -> (Tensor,Tensor)+maxWithDimname _self _dim _keepdim = unsafePerformIO $ (cast3 ATen.max_tnb) _self _dim _keepdim++amax+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Bool -- ^ keepdim+  -> Tensor+amax _self _dim _keepdim = unsafePerformIO $ (cast3 ATen.amax_tlb) _self _dim _keepdim++max_pool1d_with_indices+  :: Tensor -- ^ self+  -> Int -- ^ kernel_size+  -> Int -- ^ stride+  -> Int -- ^ padding+  -> Int -- ^ dilation+  -> Bool -- ^ ceil_mode+  -> (Tensor,Tensor)+max_pool1d_with_indices _self _kernel_size _stride _padding _dilation _ceil_mode = unsafePerformIO $ (cast6 ATen.max_pool1d_with_indices_tllllb) _self _kernel_size _stride _padding _dilation _ceil_mode++max_pool1d+  :: Tensor -- ^ self+  -> Int -- ^ kernel_size+  -> Int -- ^ stride+  -> Int -- ^ padding+  -> Int -- ^ dilation+  -> Bool -- ^ ceil_mode+  -> Tensor+max_pool1d _self _kernel_size _stride _padding _dilation _ceil_mode = unsafePerformIO $ (cast6 ATen.max_pool1d_tllllb) _self _kernel_size _stride _padding _dilation _ceil_mode++max_pool2d+  :: Tensor -- ^ self+  -> (Int,Int) -- ^ kernel_size+  -> (Int,Int) -- ^ stride+  -> (Int,Int) -- ^ padding+  -> (Int,Int) -- ^ dilation+  -> Bool -- ^ ceil_mode+  -> Tensor+max_pool2d _self _kernel_size _stride _padding _dilation _ceil_mode = unsafePerformIO $ (cast6 ATen.max_pool2d_tllllb) _self _kernel_size _stride _padding _dilation _ceil_mode++mkldnn_max_pool2d+  :: Tensor -- ^ self+  -> (Int,Int) -- ^ kernel_size+  -> (Int,Int) -- ^ stride+  -> (Int,Int) -- ^ padding+  -> (Int,Int) -- ^ dilation+  -> Bool -- ^ ceil_mode+  -> Tensor+mkldnn_max_pool2d _self _kernel_size _stride _padding _dilation _ceil_mode = unsafePerformIO $ (cast6 ATen.mkldnn_max_pool2d_tllllb) _self _kernel_size _stride _padding _dilation _ceil_mode++mkldnn_max_pool3d+  :: Tensor -- ^ self+  -> (Int,Int,Int) -- ^ kernel_size+  -> (Int,Int,Int) -- ^ stride+  -> (Int,Int,Int) -- ^ padding+  -> (Int,Int,Int) -- ^ dilation+  -> Bool -- ^ ceil_mode+  -> Tensor+mkldnn_max_pool3d _self _kernel_size _stride _padding _dilation _ceil_mode = unsafePerformIO $ (cast6 ATen.mkldnn_max_pool3d_tllllb) _self _kernel_size _stride _padding _dilation _ceil_mode++quantized_max_pool1d+  :: Tensor -- ^ self+  -> Int -- ^ kernel_size+  -> Int -- ^ stride+  -> Int -- ^ padding+  -> Int -- ^ dilation+  -> Bool -- ^ ceil_mode+  -> Tensor+quantized_max_pool1d _self _kernel_size _stride _padding _dilation _ceil_mode = unsafePerformIO $ (cast6 ATen.quantized_max_pool1d_tllllb) _self _kernel_size _stride _padding _dilation _ceil_mode++quantized_max_pool2d+  :: Tensor -- ^ self+  -> (Int,Int) -- ^ kernel_size+  -> (Int,Int) -- ^ stride+  -> (Int,Int) -- ^ padding+  -> (Int,Int) -- ^ dilation+  -> Bool -- ^ ceil_mode+  -> Tensor+quantized_max_pool2d _self _kernel_size _stride _padding _dilation _ceil_mode = unsafePerformIO $ (cast6 ATen.quantized_max_pool2d_tllllb) _self _kernel_size _stride _padding _dilation _ceil_mode++max_pool3d+  :: Tensor -- ^ self+  -> (Int,Int,Int) -- ^ kernel_size+  -> (Int,Int,Int) -- ^ stride+  -> (Int,Int,Int) -- ^ padding+  -> (Int,Int,Int) -- ^ dilation+  -> Bool -- ^ ceil_mode+  -> Tensor+max_pool3d _self _kernel_size _stride _padding _dilation _ceil_mode = unsafePerformIO $ (cast6 ATen.max_pool3d_tllllb) _self _kernel_size _stride _padding _dilation _ceil_mode++meanAll+  :: Tensor -- ^ self+  -> DType -- ^ dtype+  -> Tensor+meanAll _self _dtype = unsafePerformIO $ (cast2 ATen.mean_ts) _self _dtype++meanDim+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Bool -- ^ keepdim+  -> DType -- ^ dtype+  -> Tensor+meanDim _self _dim _keepdim _dtype = unsafePerformIO $ (cast4 ATen.mean_tlbs) _self _dim _keepdim _dtype++meanWithDimnames+  :: Tensor -- ^ self+  -> [Dimname] -- ^ dim+  -> Bool -- ^ keepdim+  -> DType -- ^ dtype+  -> Tensor+meanWithDimnames _self _dim _keepdim _dtype = unsafePerformIO $ (cast4 ATen.mean_tNbs) _self _dim _keepdim _dtype++nanmean+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Bool -- ^ keepdim+  -> DType -- ^ dtype+  -> Tensor+nanmean _self _dim _keepdim _dtype = unsafePerformIO $ (cast4 ATen.nanmean_tlbs) _self _dim _keepdim _dtype++medianAll+  :: Tensor -- ^ self+  -> Tensor+medianAll _self = unsafePerformIO $ (cast1 ATen.median_t) _self++medianDim+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Bool -- ^ keepdim+  -> (Tensor,Tensor)+medianDim _self _dim _keepdim = unsafePerformIO $ (cast3 ATen.median_tlb) _self _dim _keepdim++medianWithDimname+  :: Tensor -- ^ self+  -> Dimname -- ^ dim+  -> Bool -- ^ keepdim+  -> (Tensor,Tensor)+medianWithDimname _self _dim _keepdim = unsafePerformIO $ (cast3 ATen.median_tnb) _self _dim _keepdim++nanmedian_t+  :: Tensor -- ^ self+  -> Tensor+nanmedian_t _self = unsafePerformIO $ (cast1 ATen.nanmedian_t) _self++nanmedian_tlb+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Bool -- ^ keepdim+  -> (Tensor,Tensor)+nanmedian_tlb _self _dim _keepdim = unsafePerformIO $ (cast3 ATen.nanmedian_tlb) _self _dim _keepdim++nanmedian_tnb+  :: Tensor -- ^ self+  -> Dimname -- ^ dim+  -> Bool -- ^ keepdim+  -> (Tensor,Tensor)+nanmedian_tnb _self _dim _keepdim = unsafePerformIO $ (cast3 ATen.nanmedian_tnb) _self _dim _keepdim++minDim+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Bool -- ^ keepdim+  -> (Tensor,Tensor)+minDim _self _dim _keepdim = unsafePerformIO $ (cast3 ATen.min_tlb) _self _dim _keepdim++minWithDimname+  :: Tensor -- ^ self+  -> Dimname -- ^ dim+  -> Bool -- ^ keepdim+  -> (Tensor,Tensor)+minWithDimname _self _dim _keepdim = unsafePerformIO $ (cast3 ATen.min_tnb) _self _dim _keepdim++amin+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Bool -- ^ keepdim+  -> Tensor+amin _self _dim _keepdim = unsafePerformIO $ (cast3 ATen.amin_tlb) _self _dim _keepdim++mkldnn_convolution+  :: Tensor -- ^ self+  -> Tensor -- ^ weight+  -> Tensor -- ^ bias+  -> [Int] -- ^ padding+  -> [Int] -- ^ stride+  -> [Int] -- ^ dilation+  -> Int -- ^ groups+  -> Tensor+mkldnn_convolution _self _weight _bias _padding _stride _dilation _groups = unsafePerformIO $ (cast7 ATen.mkldnn_convolution_tttllll) _self _weight _bias _padding _stride _dilation _groups++mkldnn_rnn_layer+  :: Tensor -- ^ input+  -> Tensor -- ^ weight0+  -> Tensor -- ^ weight1+  -> Tensor -- ^ weight2+  -> Tensor -- ^ weight3+  -> Tensor -- ^ hx_+  -> Tensor -- ^ cx_+  -> Bool -- ^ reverse+  -> [Int] -- ^ batch_sizes+  -> Int -- ^ mode+  -> Int -- ^ hidden_size+  -> Int -- ^ num_layers+  -> Bool -- ^ has_biases+  -> Bool -- ^ bidirectional+  -> Bool -- ^ batch_first+  -> Bool -- ^ train+  -> (Tensor,Tensor,Tensor,Tensor)+mkldnn_rnn_layer _input _weight0 _weight1 _weight2 _weight3 _hx_ _cx_ _reverse _batch_sizes _mode _hidden_size _num_layers _has_biases _bidirectional _batch_first _train = unsafePerformIO $ (cast16 ATen.mkldnn_rnn_layer_tttttttbllllbbbb) _input _weight0 _weight1 _weight2 _weight3 _hx_ _cx_ _reverse _batch_sizes _mode _hidden_size _num_layers _has_biases _bidirectional _batch_first _train++miopen_batch_norm+  :: Tensor -- ^ input+  -> Tensor -- ^ weight+  -> Tensor -- ^ bias+  -> Tensor -- ^ running_mean+  -> Tensor -- ^ running_var+  -> Bool -- ^ training+  -> Double -- ^ exponential_average_factor+  -> Double -- ^ epsilon+  -> (Tensor,Tensor,Tensor)+miopen_batch_norm _input _weight _bias _running_mean _running_var _training _exponential_average_factor _epsilon = unsafePerformIO $ (cast8 ATen.miopen_batch_norm_tttttbdd) _input _weight _bias _running_mean _running_var _training _exponential_average_factor _epsilon++miopen_convolution+  :: Tensor -- ^ self+  -> Tensor -- ^ weight+  -> Tensor -- ^ bias+  -> [Int] -- ^ padding+  -> [Int] -- ^ stride+  -> [Int] -- ^ dilation+  -> Int -- ^ groups+  -> Bool -- ^ benchmark+  -> Bool -- ^ deterministic+  -> Tensor+miopen_convolution _self _weight _bias _padding _stride _dilation _groups _benchmark _deterministic = unsafePerformIO $ (cast9 ATen.miopen_convolution_tttllllbb) _self _weight _bias _padding _stride _dilation _groups _benchmark _deterministic++miopen_convolution_transpose+  :: Tensor -- ^ self+  -> Tensor -- ^ weight+  -> Tensor -- ^ bias+  -> [Int] -- ^ padding+  -> [Int] -- ^ output_padding+  -> [Int] -- ^ stride+  -> [Int] -- ^ dilation+  -> Int -- ^ groups+  -> Bool -- ^ benchmark+  -> Bool -- ^ deterministic+  -> Tensor+miopen_convolution_transpose _self _weight _bias _padding _output_padding _stride _dilation _groups _benchmark _deterministic = unsafePerformIO $ (cast10 ATen.miopen_convolution_transpose_tttlllllbb) _self _weight _bias _padding _output_padding _stride _dilation _groups _benchmark _deterministic++miopen_depthwise_convolution+  :: Tensor -- ^ self+  -> Tensor -- ^ weight+  -> Tensor -- ^ bias+  -> [Int] -- ^ padding+  -> [Int] -- ^ stride+  -> [Int] -- ^ dilation+  -> Int -- ^ groups+  -> Bool -- ^ benchmark+  -> Bool -- ^ deterministic+  -> Tensor+miopen_depthwise_convolution _self _weight _bias _padding _stride _dilation _groups _benchmark _deterministic = unsafePerformIO $ (cast9 ATen.miopen_depthwise_convolution_tttllllbb) _self _weight _bias _padding _stride _dilation _groups _benchmark _deterministic++miopen_convolution_relu+  :: Tensor -- ^ self+  -> Tensor -- ^ weight+  -> Tensor -- ^ bias+  -> [Int] -- ^ stride+  -> [Int] -- ^ padding+  -> [Int] -- ^ dilation+  -> Int -- ^ groups+  -> Tensor+miopen_convolution_relu _self _weight _bias _stride _padding _dilation _groups = unsafePerformIO $ (cast7 ATen.miopen_convolution_relu_tttllll) _self _weight _bias _stride _padding _dilation _groups++miopen_convolution_add_relu+  :: Tensor -- ^ self+  -> Tensor -- ^ weight+  -> Tensor -- ^ z+  -> Float -- ^ alpha+  -> Tensor -- ^ bias+  -> [Int] -- ^ stride+  -> [Int] -- ^ padding+  -> [Int] -- ^ dilation+  -> Int -- ^ groups+  -> Tensor+miopen_convolution_add_relu _self _weight _z _alpha _bias _stride _padding _dilation _groups = unsafePerformIO $ (cast9 ATen.miopen_convolution_add_relu_tttstllll) _self _weight _z _alpha _bias _stride _padding _dilation _groups++miopen_rnn+  :: Tensor -- ^ input+  -> [Tensor] -- ^ weight+  -> Int -- ^ weight_stride0+  -> Tensor -- ^ hx+  -> Tensor -- ^ cx+  -> Int -- ^ mode+  -> Int -- ^ hidden_size+  -> Int -- ^ num_layers+  -> Bool -- ^ batch_first+  -> Double -- ^ dropout+  -> Bool -- ^ train+  -> Bool -- ^ bidirectional+  -> [Int] -- ^ batch_sizes+  -> Tensor -- ^ dropout_state+  -> (Tensor,Tensor,Tensor,Tensor,Tensor)+miopen_rnn _input _weight _weight_stride0 _hx _cx _mode _hidden_size _num_layers _batch_first _dropout _train _bidirectional _batch_sizes _dropout_state = unsafePerformIO $ (cast14 ATen.miopen_rnn_tllttlllbdbblt) _input _weight _weight_stride0 _hx _cx _mode _hidden_size _num_layers _batch_first _dropout _train _bidirectional _batch_sizes _dropout_state++mm+  :: Tensor -- ^ self+  -> Tensor -- ^ mat2+  -> Tensor+mm _self _mat2 = unsafePerformIO $ (cast2 ATen.mm_tt) _self _mat2++mode+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Bool -- ^ keepdim+  -> (Tensor,Tensor)+mode _self _dim _keepdim = unsafePerformIO $ (cast3 ATen.mode_tlb) _self _dim _keepdim++modeWithDimname+  :: Tensor -- ^ self+  -> Dimname -- ^ dim+  -> Bool -- ^ keepdim+  -> (Tensor,Tensor)+modeWithDimname _self _dim _keepdim = unsafePerformIO $ (cast3 ATen.mode_tnb) _self _dim _keepdim++mul+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+mul _self _other = unsafePerformIO $ (cast2 ATen.mul_tt) _self _other++mulScalar+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> Tensor+mulScalar _self _other = unsafePerformIO $ (cast2 ATen.mul_ts) _self _other++multiply_tt+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+multiply_tt _self _other = unsafePerformIO $ (cast2 ATen.multiply_tt) _self _other++multiply_ts+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> Tensor+multiply_ts _self _other = unsafePerformIO $ (cast2 ATen.multiply_ts) _self _other++mv+  :: Tensor -- ^ self+  -> Tensor -- ^ vec+  -> Tensor+mv _self _vec = unsafePerformIO $ (cast2 ATen.mv_tt) _self _vec++mvlgamma+  :: Tensor -- ^ self+  -> Int -- ^ p+  -> Tensor+mvlgamma _self _p = unsafePerformIO $ (cast2 ATen.mvlgamma_tl) _self _p++narrow_copy+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Int -- ^ start+  -> Int -- ^ length+  -> Tensor+narrow_copy _self _dim _start _length = unsafePerformIO $ (cast4 ATen.narrow_copy_tlll) _self _dim _start _length++narrow_tlll+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Int -- ^ start+  -> Int -- ^ length+  -> Tensor+narrow_tlll _self _dim _start _length = unsafePerformIO $ (cast4 ATen.narrow_tlll) _self _dim _start _length++narrow_tltl+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Tensor -- ^ start+  -> Int -- ^ length+  -> Tensor+narrow_tltl _self _dim _start _length = unsafePerformIO $ (cast4 ATen.narrow_tltl) _self _dim _start _length++native_batch_norm+  :: Tensor -- ^ input+  -> Tensor -- ^ weight+  -> Tensor -- ^ bias+  -> Tensor -- ^ running_mean+  -> Tensor -- ^ running_var+  -> Bool -- ^ training+  -> Double -- ^ momentum+  -> Double -- ^ eps+  -> (Tensor,Tensor,Tensor)+native_batch_norm _input _weight _bias _running_mean _running_var _training _momentum _eps = unsafePerformIO $ (cast8 ATen.native_batch_norm_tttttbdd) _input _weight _bias _running_mean _running_var _training _momentum _eps++batch_norm_stats+  :: Tensor -- ^ input+  -> Double -- ^ eps+  -> (Tensor,Tensor)+batch_norm_stats _input _eps = unsafePerformIO $ (cast2 ATen.batch_norm_stats_td) _input _eps++batch_norm_elemt+  :: Tensor -- ^ input+  -> Tensor -- ^ weight+  -> Tensor -- ^ bias+  -> Tensor -- ^ mean+  -> Tensor -- ^ invstd+  -> Double -- ^ eps+  -> Tensor+batch_norm_elemt _input _weight _bias _mean _invstd _eps = unsafePerformIO $ (cast6 ATen.batch_norm_elemt_tttttd) _input _weight _bias _mean _invstd _eps++batch_norm_gather_stats+  :: Tensor -- ^ input+  -> Tensor -- ^ mean+  -> Tensor -- ^ invstd+  -> Tensor -- ^ running_mean+  -> Tensor -- ^ running_var+  -> Double -- ^ momentum+  -> Double -- ^ eps+  -> Int -- ^ count+  -> (Tensor,Tensor)+batch_norm_gather_stats _input _mean _invstd _running_mean _running_var _momentum _eps _count = unsafePerformIO $ (cast8 ATen.batch_norm_gather_stats_tttttddl) _input _mean _invstd _running_mean _running_var _momentum _eps _count++batch_norm_gather_stats_with_counts+  :: Tensor -- ^ input+  -> Tensor -- ^ mean+  -> Tensor -- ^ invstd+  -> Tensor -- ^ running_mean+  -> Tensor -- ^ running_var+  -> Double -- ^ momentum+  -> Double -- ^ eps+  -> Tensor -- ^ counts+  -> (Tensor,Tensor)+batch_norm_gather_stats_with_counts _input _mean _invstd _running_mean _running_var _momentum _eps _counts = unsafePerformIO $ (cast8 ATen.batch_norm_gather_stats_with_counts_tttttddt) _input _mean _invstd _running_mean _running_var _momentum _eps _counts++batch_norm_backward_reduce+  :: Tensor -- ^ grad_out+  -> Tensor -- ^ input+  -> Tensor -- ^ mean+  -> Tensor -- ^ invstd+  -> Tensor -- ^ weight+  -> Bool -- ^ input_g+  -> Bool -- ^ weight_g+  -> Bool -- ^ bias_g+  -> (Tensor,Tensor,Tensor,Tensor)+batch_norm_backward_reduce _grad_out _input _mean _invstd _weight _input_g _weight_g _bias_g = unsafePerformIO $ (cast8 ATen.batch_norm_backward_reduce_tttttbbb) _grad_out _input _mean _invstd _weight _input_g _weight_g _bias_g++batch_norm_backward_elemt+  :: Tensor -- ^ grad_out+  -> Tensor -- ^ input+  -> Tensor -- ^ mean+  -> Tensor -- ^ invstd+  -> Tensor -- ^ weight+  -> Tensor -- ^ mean_dy+  -> Tensor -- ^ mean_dy_xmu+  -> Tensor -- ^ count+  -> Tensor+batch_norm_backward_elemt _grad_out _input _mean _invstd _weight _mean_dy _mean_dy_xmu _count = unsafePerformIO $ (cast8 ATen.batch_norm_backward_elemt_tttttttt) _grad_out _input _mean _invstd _weight _mean_dy _mean_dy_xmu _count++batch_norm_update_stats+  :: Tensor -- ^ input+  -> Tensor -- ^ running_mean+  -> Tensor -- ^ running_var+  -> Double -- ^ momentum+  -> (Tensor,Tensor)+batch_norm_update_stats _input _running_mean _running_var _momentum = unsafePerformIO $ (cast4 ATen.batch_norm_update_stats_tttd) _input _running_mean _running_var _momentum++is_vulkan_available+  :: Bool+is_vulkan_available  = unsafePerformIO $ (cast0 ATen.is_vulkan_available) ++pairwise_distance+  :: Tensor -- ^ x1+  -> Tensor -- ^ x2+  -> Double -- ^ p+  -> Double -- ^ eps+  -> Bool -- ^ keepdim+  -> Tensor+pairwise_distance _x1 _x2 _p _eps _keepdim = unsafePerformIO $ (cast5 ATen.pairwise_distance_ttddb) _x1 _x2 _p _eps _keepdim++cdist+  :: Tensor -- ^ x1+  -> Tensor -- ^ x2+  -> Double -- ^ p+  -> Int -- ^ compute_mode+  -> Tensor+cdist _x1 _x2 _p _compute_mode = unsafePerformIO $ (cast4 ATen.cdist_ttdl) _x1 _x2 _p _compute_mode++pdist+  :: Tensor -- ^ self+  -> Double -- ^ p+  -> Tensor+pdist _self _p = unsafePerformIO $ (cast2 ATen.pdist_td) _self _p++cosine_similarity+  :: Tensor -- ^ x1+  -> Tensor -- ^ x2+  -> Int -- ^ dim+  -> Double -- ^ eps+  -> Tensor+cosine_similarity _x1 _x2 _dim _eps = unsafePerformIO $ (cast4 ATen.cosine_similarity_ttld) _x1 _x2 _dim _eps++permute+  :: Tensor -- ^ self+  -> [Int] -- ^ dims+  -> Tensor+permute _self _dims = unsafePerformIO $ (cast2 ATen.permute_tl) _self _dims++-- movedim_tll+--   :: Tensor -- ^ self+--   -> [Int] -- ^ source+--   -> [Int] -- ^ destination+--   -> Tensor+-- movedim_tll _self _source _destination = unsafePerformIO $ (cast3 ATen.movedim_tll) _self _source _destination++movedim_tll+  :: Tensor -- ^ self+  -> Int -- ^ source+  -> Int -- ^ destination+  -> Tensor+movedim_tll _self _source _destination = unsafePerformIO $ (cast3 ATen.movedim_tll) _self _source _destination++-- moveaxis_tll+--   :: Tensor -- ^ self+--   -> [Int] -- ^ source+--   -> [Int] -- ^ destination+--   -> Tensor+-- moveaxis_tll _self _source _destination = unsafePerformIO $ (cast3 ATen.moveaxis_tll) _self _source _destination++moveaxis_tll+  :: Tensor -- ^ self+  -> Int -- ^ source+  -> Int -- ^ destination+  -> Tensor+moveaxis_tll _self _source _destination = unsafePerformIO $ (cast3 ATen.moveaxis_tll) _self _source _destination++adjoint+  :: Tensor -- ^ self+  -> Tensor+adjoint _self = unsafePerformIO $ (cast1 ATen.adjoint_t) _self++pixel_shuffle+  :: Tensor -- ^ self+  -> Int -- ^ upscale_factor+  -> Tensor+pixel_shuffle _self _upscale_factor = unsafePerformIO $ (cast2 ATen.pixel_shuffle_tl) _self _upscale_factor++pixel_unshuffle+  :: Tensor -- ^ self+  -> Int -- ^ downscale_factor+  -> Tensor+pixel_unshuffle _self _downscale_factor = unsafePerformIO $ (cast2 ATen.pixel_unshuffle_tl) _self _downscale_factor++channel_shuffle+  :: Tensor -- ^ self+  -> Int -- ^ groups+  -> Tensor+channel_shuffle _self _groups = unsafePerformIO $ (cast2 ATen.channel_shuffle_tl) _self _groups++native_channel_shuffle+  :: Tensor -- ^ self+  -> Int -- ^ groups+  -> Tensor+native_channel_shuffle _self _groups = unsafePerformIO $ (cast2 ATen.native_channel_shuffle_tl) _self _groups++pinverse+  :: Tensor -- ^ self+  -> Double -- ^ rcond+  -> Tensor+pinverse _self _rcond = unsafePerformIO $ (cast2 ATen.pinverse_td) _self _rcond++poisson_nll_loss+  :: Tensor -- ^ input+  -> Tensor -- ^ target+  -> Bool -- ^ log_input+  -> Bool -- ^ full+  -> Double -- ^ eps+  -> Int -- ^ reduction+  -> Tensor+poisson_nll_loss _input _target _log_input _full _eps _reduction = unsafePerformIO $ (cast6 ATen.poisson_nll_loss_ttbbdl) _input _target _log_input _full _eps _reduction++rad2deg+  :: Tensor -- ^ self+  -> Tensor+rad2deg _self = unsafePerformIO $ (cast1 ATen.rad2deg_t) _self++deg2rad+  :: Tensor -- ^ self+  -> Tensor+deg2rad _self = unsafePerformIO $ (cast1 ATen.deg2rad_t) _self++ravel+  :: Tensor -- ^ self+  -> Tensor+ravel _self = unsafePerformIO $ (cast1 ATen.ravel_t) _self++reciprocal+  :: Tensor -- ^ self+  -> Tensor+reciprocal _self = unsafePerformIO $ (cast1 ATen.reciprocal_t) _self++neg+  :: Tensor -- ^ self+  -> Tensor+neg _self = unsafePerformIO $ (cast1 ATen.neg_t) _self++negative+  :: Tensor -- ^ self+  -> Tensor+negative _self = unsafePerformIO $ (cast1 ATen.negative_t) _self++repeat_interleave_tl+  :: Tensor -- ^ repeats+  -> Int -- ^ output_size+  -> Tensor+repeat_interleave_tl _repeats _output_size = unsafePerformIO $ (cast2 ATen.repeat_interleave_tl) _repeats _output_size++repeat_interleave_ttll+  :: Tensor -- ^ self+  -> Tensor -- ^ repeats+  -> Int -- ^ dim+  -> Int -- ^ output_size+  -> Tensor+repeat_interleave_ttll _self _repeats _dim _output_size = unsafePerformIO $ (cast4 ATen.repeat_interleave_ttll) _self _repeats _dim _output_size++repeat_interleave_tlll+  :: Tensor -- ^ self+  -> Int -- ^ repeats+  -> Int -- ^ dim+  -> Int -- ^ output_size+  -> Tensor+repeat_interleave_tlll _self _repeats _dim _output_size = unsafePerformIO $ (cast4 ATen.repeat_interleave_tlll) _self _repeats _dim _output_size++reshape+  :: Tensor -- ^ self+  -> [Int] -- ^ shape+  -> Tensor+reshape _self _shape = unsafePerformIO $ (cast2 ATen.reshape_tl) _self _shape++round_t+  :: Tensor -- ^ self+  -> Tensor+round_t _self = unsafePerformIO $ (cast1 ATen.round_t) _self++round_tl+  :: Tensor -- ^ self+  -> Int -- ^ decimals+  -> Tensor+round_tl _self _decimals = unsafePerformIO $ (cast2 ATen.round_tl) _self _decimals++relu+  :: Tensor -- ^ self+  -> Tensor+relu _self = unsafePerformIO $ (cast1 ATen.relu_t) _self++relu6+  :: Tensor -- ^ self+  -> Tensor+relu6 _self = unsafePerformIO $ (cast1 ATen.relu6_t) _self++prelu+  :: Tensor -- ^ self+  -> Tensor -- ^ weight+  -> Tensor+prelu _self _weight = unsafePerformIO $ (cast2 ATen.prelu_tt) _self _weight++gelu+  :: Tensor -- ^ self+  -> String -- ^ approximate+  -> Tensor+gelu _self _approximate = unsafePerformIO $ (cast2 ATen.gelu_ts) _self _approximate++hardshrink+  :: Tensor -- ^ self+  -> Float -- ^ lambd+  -> Tensor+hardshrink _self _lambd = unsafePerformIO $ (cast2 ATen.hardshrink_ts) _self _lambd++rsqrt+  :: Tensor -- ^ self+  -> Tensor+rsqrt _self = unsafePerformIO $ (cast1 ATen.rsqrt_t) _self++selectWithDimname+  :: Tensor -- ^ self+  -> Dimname -- ^ dim+  -> Int -- ^ index+  -> Tensor+selectWithDimname _self _dim _index = unsafePerformIO $ (cast3 ATen.select_tnl) _self _dim _index++select+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Int -- ^ index+  -> Tensor+select _self _dim _index = unsafePerformIO $ (cast3 ATen.select_tll) _self _dim _index++selu+  :: Tensor -- ^ self+  -> Tensor+selu _self = unsafePerformIO $ (cast1 ATen.selu_t) _self++celu+  :: Tensor -- ^ self+  -> Float -- ^ alpha+  -> Tensor+celu _self _alpha = unsafePerformIO $ (cast2 ATen.celu_ts) _self _alpha++silu+  :: Tensor -- ^ self+  -> Tensor+silu _self = unsafePerformIO $ (cast1 ATen.silu_t) _self++mish+  :: Tensor -- ^ self+  -> Tensor+mish _self = unsafePerformIO $ (cast1 ATen.mish_t) _self++sigmoid+  :: Tensor -- ^ self+  -> Tensor+sigmoid _self = unsafePerformIO $ (cast1 ATen.sigmoid_t) _self++logit+  :: Tensor -- ^ self+  -> Double -- ^ eps+  -> Tensor+logit _self _eps = unsafePerformIO $ (cast2 ATen.logit_td) _self _eps++sin+  :: Tensor -- ^ self+  -> Tensor+sin _self = unsafePerformIO $ (cast1 ATen.sin_t) _self++sinc+  :: Tensor -- ^ self+  -> Tensor+sinc _self = unsafePerformIO $ (cast1 ATen.sinc_t) _self++sinh+  :: Tensor -- ^ self+  -> Tensor+sinh _self = unsafePerformIO $ (cast1 ATen.sinh_t) _self++size+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Int+size _self _dim = unsafePerformIO $ (cast2 ATen.size_tl) _self _dim++sizeWithDimname+  :: Tensor -- ^ self+  -> Dimname -- ^ dim+  -> Int+sizeWithDimname _self _dim = unsafePerformIO $ (cast2 ATen.size_tn) _self _dim++slice+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Int -- ^ start+  -> Int -- ^ end+  -> Int -- ^ step+  -> Tensor+slice _self _dim _start _end _step = unsafePerformIO $ (cast5 ATen.slice_tllll) _self _dim _start _end _step++slice_scatter+  :: Tensor -- ^ self+  -> Tensor -- ^ src+  -> Int -- ^ dim+  -> Int -- ^ start+  -> Int -- ^ end+  -> Int -- ^ step+  -> Tensor+slice_scatter _self _src _dim _start _end _step = unsafePerformIO $ (cast6 ATen.slice_scatter_ttllll) _self _src _dim _start _end _step++select_scatter+  :: Tensor -- ^ self+  -> Tensor -- ^ src+  -> Int -- ^ dim+  -> Int -- ^ index+  -> Tensor+select_scatter _self _src _dim _index = unsafePerformIO $ (cast4 ATen.select_scatter_ttll) _self _src _dim _index++diagonal_scatter+  :: Tensor -- ^ self+  -> Tensor -- ^ src+  -> Int -- ^ offset+  -> Int -- ^ dim1+  -> Int -- ^ dim2+  -> Tensor+diagonal_scatter _self _src _offset _dim1 _dim2 = unsafePerformIO $ (cast5 ATen.diagonal_scatter_ttlll) _self _src _offset _dim1 _dim2++as_strided_scatter+  :: Tensor -- ^ self+  -> Tensor -- ^ src+  -> [Int] -- ^ size+  -> [Int] -- ^ stride+  -> Int -- ^ storage_offset+  -> Tensor+as_strided_scatter _self _src _size _stride _storage_offset = unsafePerformIO $ (cast5 ATen.as_strided_scatter_ttlll) _self _src _size _stride _storage_offset++smm+  :: Tensor -- ^ self+  -> Tensor -- ^ mat2+  -> Tensor+smm _self _mat2 = unsafePerformIO $ (cast2 ATen.smm_tt) _self _mat2++softmax+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> DType -- ^ dtype+  -> Tensor+softmax _self _dim _dtype = unsafePerformIO $ (cast3 ATen.softmax_tls) _self _dim _dtype++softmaxWithDimname+  :: Tensor -- ^ self+  -> Dimname -- ^ dim+  -> DType -- ^ dtype+  -> Tensor+softmaxWithDimname _self _dim _dtype = unsafePerformIO $ (cast3 ATen.softmax_tns) _self _dim _dtype++unsafe_split+  :: Tensor -- ^ self+  -> Int -- ^ split_size+  -> Int -- ^ dim+  -> [Tensor]+unsafe_split _self _split_size _dim = unsafePerformIO $ (cast3 ATen.unsafe_split_tll) _self _split_size _dim++split_tll+  :: Tensor -- ^ self+  -> Int -- ^ split_size+  -> Int -- ^ dim+  -> [Tensor]+split_tll _self _split_size _dim = unsafePerformIO $ (cast3 ATen.split_tll) _self _split_size _dim++-- split_tll+--   :: Tensor -- ^ self+--   -> [Int] -- ^ split_size+--   -> Int -- ^ dim+--   -> [Tensor]+-- split_tll _self _split_size _dim = unsafePerformIO $ (cast3 ATen.split_tll) _self _split_size _dim++unsafe_split_with_sizes+  :: Tensor -- ^ self+  -> [Int] -- ^ split_sizes+  -> Int -- ^ dim+  -> [Tensor]+unsafe_split_with_sizes _self _split_sizes _dim = unsafePerformIO $ (cast3 ATen.unsafe_split_with_sizes_tll) _self _split_sizes _dim++split_with_sizes+  :: Tensor -- ^ self+  -> [Int] -- ^ split_sizes+  -> Int -- ^ dim+  -> [Tensor]+split_with_sizes _self _split_sizes _dim = unsafePerformIO $ (cast3 ATen.split_with_sizes_tll) _self _split_sizes _dim++hsplit_tl+  :: Tensor -- ^ self+  -> Int -- ^ sections+  -> [Tensor]+hsplit_tl _self _sections = unsafePerformIO $ (cast2 ATen.hsplit_tl) _self _sections++-- hsplit_tl+--   :: Tensor -- ^ self+--   -> [Int] -- ^ indices+--   -> [Tensor]+-- hsplit_tl _self _indices = unsafePerformIO $ (cast2 ATen.hsplit_tl) _self _indices++vsplit_tl+  :: Tensor -- ^ self+  -> Int -- ^ sections+  -> [Tensor]+vsplit_tl _self _sections = unsafePerformIO $ (cast2 ATen.vsplit_tl) _self _sections++-- vsplit_tl+--   :: Tensor -- ^ self+--   -> [Int] -- ^ indices+--   -> [Tensor]+-- vsplit_tl _self _indices = unsafePerformIO $ (cast2 ATen.vsplit_tl) _self _indices++dsplit_tl+  :: Tensor -- ^ self+  -> Int -- ^ sections+  -> [Tensor]+dsplit_tl _self _sections = unsafePerformIO $ (cast2 ATen.dsplit_tl) _self _sections++-- dsplit_tl+--   :: Tensor -- ^ self+--   -> [Int] -- ^ indices+--   -> [Tensor]+-- dsplit_tl _self _indices = unsafePerformIO $ (cast2 ATen.dsplit_tl) _self _indices++squeezeAll+  :: Tensor -- ^ self+  -> Tensor+squeezeAll _self = unsafePerformIO $ (cast1 ATen.squeeze_t) _self++squeezeDim+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Tensor+squeezeDim _self _dim = unsafePerformIO $ (cast2 ATen.squeeze_tl) _self _dim++squeezeWithDimname+  :: Tensor -- ^ self+  -> Dimname -- ^ dim+  -> Tensor+squeezeWithDimname _self _dim = unsafePerformIO $ (cast2 ATen.squeeze_tn) _self _dim++-- squeezeDim+--   :: Tensor -- ^ self+--   -> [Int] -- ^ dim+--   -> Tensor+-- squeezeDim _self _dim = unsafePerformIO $ (cast2 ATen.squeeze_tl) _self _dim++sspaddmm+  :: Tensor -- ^ self+  -> Tensor -- ^ mat1+  -> Tensor -- ^ mat2+  -> Float -- ^ beta+  -> Float -- ^ alpha+  -> Tensor+sspaddmm _self _mat1 _mat2 _beta _alpha = unsafePerformIO $ (cast5 ATen.sspaddmm_tttss) _self _mat1 _mat2 _beta _alpha++stack+  :: [Tensor] -- ^ tensors+  -> Int -- ^ dim+  -> Tensor+stack _tensors _dim = unsafePerformIO $ (cast2 ATen.stack_ll) _tensors _dim++hstack+  :: [Tensor] -- ^ tensors+  -> Tensor+hstack _tensors = unsafePerformIO $ (cast1 ATen.hstack_l) _tensors++vstack+  :: [Tensor] -- ^ tensors+  -> Tensor+vstack _tensors = unsafePerformIO $ (cast1 ATen.vstack_l) _tensors++dstack+  :: [Tensor] -- ^ tensors+  -> Tensor+dstack _tensors = unsafePerformIO $ (cast1 ATen.dstack_l) _tensors++stft_tllltbbb+  :: Tensor -- ^ self+  -> Int -- ^ n_fft+  -> Int -- ^ hop_length+  -> Int -- ^ win_length+  -> Tensor -- ^ window+  -> Bool -- ^ normalized+  -> Bool -- ^ onesided+  -> Bool -- ^ return_complex+  -> Tensor+stft_tllltbbb _self _n_fft _hop_length _win_length _window _normalized _onesided _return_complex = unsafePerformIO $ (cast8 ATen.stft_tllltbbb) _self _n_fft _hop_length _win_length _window _normalized _onesided _return_complex++stft_tllltbsbbb+  :: Tensor -- ^ self+  -> Int -- ^ n_fft+  -> Int -- ^ hop_length+  -> Int -- ^ win_length+  -> Tensor -- ^ window+  -> Bool -- ^ center+  -> String -- ^ pad_mode+  -> Bool -- ^ normalized+  -> Bool -- ^ onesided+  -> Bool -- ^ return_complex+  -> Tensor+stft_tllltbsbbb _self _n_fft _hop_length _win_length _window _center _pad_mode _normalized _onesided _return_complex = unsafePerformIO $ (cast10 ATen.stft_tllltbsbbb) _self _n_fft _hop_length _win_length _window _center _pad_mode _normalized _onesided _return_complex++istft+  :: Tensor -- ^ self+  -> Int -- ^ n_fft+  -> Int -- ^ hop_length+  -> Int -- ^ win_length+  -> Tensor -- ^ window+  -> Bool -- ^ center+  -> Bool -- ^ normalized+  -> Bool -- ^ onesided+  -> Int -- ^ length+  -> Bool -- ^ return_complex+  -> Tensor+istft _self _n_fft _hop_length _win_length _window _center _normalized _onesided _length _return_complex = unsafePerformIO $ (cast10 ATen.istft_tllltbbblb) _self _n_fft _hop_length _win_length _window _center _normalized _onesided _length _return_complex++stride+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Int+stride _self _dim = unsafePerformIO $ (cast2 ATen.stride_tl) _self _dim++strideWithDimname+  :: Tensor -- ^ self+  -> Dimname -- ^ dim+  -> Int+strideWithDimname _self _dim = unsafePerformIO $ (cast2 ATen.stride_tn) _self _dim++sumAll+  :: Tensor -- ^ self+  -> DType -- ^ dtype+  -> Tensor+sumAll _self _dtype = unsafePerformIO $ (cast2 ATen.sum_ts) _self _dtype++sumDim+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Bool -- ^ keepdim+  -> DType -- ^ dtype+  -> Tensor+sumDim _self _dim _keepdim _dtype = unsafePerformIO $ (cast4 ATen.sum_tlbs) _self _dim _keepdim _dtype++sumWithDimnames+  :: Tensor -- ^ self+  -> [Dimname] -- ^ dim+  -> Bool -- ^ keepdim+  -> DType -- ^ dtype+  -> Tensor+sumWithDimnames _self _dim _keepdim _dtype = unsafePerformIO $ (cast4 ATen.sum_tNbs) _self _dim _keepdim _dtype++nansum+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Bool -- ^ keepdim+  -> DType -- ^ dtype+  -> Tensor+nansum _self _dim _keepdim _dtype = unsafePerformIO $ (cast4 ATen.nansum_tlbs) _self _dim _keepdim _dtype++sqrt+  :: Tensor -- ^ self+  -> Tensor+sqrt _self = unsafePerformIO $ (cast1 ATen.sqrt_t) _self++square+  :: Tensor -- ^ self+  -> Tensor+square _self = unsafePerformIO $ (cast1 ATen.square_t) _self++stdAll+  :: Tensor -- ^ self+  -> Bool -- ^ unbiased+  -> Tensor+stdAll _self _unbiased = unsafePerformIO $ (cast2 ATen.std_tb) _self _unbiased++stdDim+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Bool -- ^ unbiased+  -> Bool -- ^ keepdim+  -> Tensor+stdDim _self _dim _unbiased _keepdim = unsafePerformIO $ (cast4 ATen.std_tlbb) _self _dim _unbiased _keepdim++std_tllb+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Int -- ^ correction+  -> Bool -- ^ keepdim+  -> Tensor+std_tllb _self _dim _correction _keepdim = unsafePerformIO $ (cast4 ATen.std_tllb) _self _dim _correction _keepdim++stdMeanAll+  :: Tensor -- ^ self+  -> Bool -- ^ unbiased+  -> (Tensor,Tensor)+stdMeanAll _self _unbiased = unsafePerformIO $ (cast2 ATen.std_mean_tb) _self _unbiased++stdMeanDim+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Bool -- ^ unbiased+  -> Bool -- ^ keepdim+  -> (Tensor,Tensor)+stdMeanDim _self _dim _unbiased _keepdim = unsafePerformIO $ (cast4 ATen.std_mean_tlbb) _self _dim _unbiased _keepdim++std_mean_tllb+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Int -- ^ correction+  -> Bool -- ^ keepdim+  -> (Tensor,Tensor)+std_mean_tllb _self _dim _correction _keepdim = unsafePerformIO $ (cast4 ATen.std_mean_tllb) _self _dim _correction _keepdim++stdMeanWithDimnames+  :: Tensor -- ^ self+  -> [Dimname] -- ^ dim+  -> Bool -- ^ unbiased+  -> Bool -- ^ keepdim+  -> (Tensor,Tensor)+stdMeanWithDimnames _self _dim _unbiased _keepdim = unsafePerformIO $ (cast4 ATen.std_mean_tNbb) _self _dim _unbiased _keepdim++std_mean_tNlb+  :: Tensor -- ^ self+  -> [Dimname] -- ^ dim+  -> Int -- ^ correction+  -> Bool -- ^ keepdim+  -> (Tensor,Tensor)+std_mean_tNlb _self _dim _correction _keepdim = unsafePerformIO $ (cast4 ATen.std_mean_tNlb) _self _dim _correction _keepdim++stdWithDimnames+  :: Tensor -- ^ self+  -> [Dimname] -- ^ dim+  -> Bool -- ^ unbiased+  -> Bool -- ^ keepdim+  -> Tensor+stdWithDimnames _self _dim _unbiased _keepdim = unsafePerformIO $ (cast4 ATen.std_tNbb) _self _dim _unbiased _keepdim++std_tNlb+  :: Tensor -- ^ self+  -> [Dimname] -- ^ dim+  -> Int -- ^ correction+  -> Bool -- ^ keepdim+  -> Tensor+std_tNlb _self _dim _correction _keepdim = unsafePerformIO $ (cast4 ATen.std_tNlb) _self _dim _correction _keepdim++prodAll+  :: Tensor -- ^ self+  -> DType -- ^ dtype+  -> Tensor+prodAll _self _dtype = unsafePerformIO $ (cast2 ATen.prod_ts) _self _dtype++prodDim+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Bool -- ^ keepdim+  -> DType -- ^ dtype+  -> Tensor+prodDim _self _dim _keepdim _dtype = unsafePerformIO $ (cast4 ATen.prod_tlbs) _self _dim _keepdim _dtype++prodWithDimnames+  :: Tensor -- ^ self+  -> Dimname -- ^ dim+  -> Bool -- ^ keepdim+  -> DType -- ^ dtype+  -> Tensor+prodWithDimnames _self _dim _keepdim _dtype = unsafePerformIO $ (cast4 ATen.prod_tnbs) _self _dim _keepdim _dtype++t+  :: Tensor -- ^ self+  -> Tensor+t _self = unsafePerformIO $ (cast1 ATen.t_t) _self++tan+  :: Tensor -- ^ self+  -> Tensor+tan _self = unsafePerformIO $ (cast1 ATen.tan_t) _self++tanh+  :: Tensor -- ^ self+  -> Tensor+tanh _self = unsafePerformIO $ (cast1 ATen.tanh_t) _self++tensordot+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> [Int] -- ^ dims_self+  -> [Int] -- ^ dims_other+  -> Tensor+tensordot _self _other _dims_self _dims_other = unsafePerformIO $ (cast4 ATen.tensordot_ttll) _self _other _dims_self _dims_other++threshold+  :: Tensor -- ^ self+  -> Float -- ^ threshold+  -> Float -- ^ value+  -> Tensor+threshold _self _threshold _value = unsafePerformIO $ (cast3 ATen.threshold_tss) _self _threshold _value++tile+  :: Tensor -- ^ self+  -> [Int] -- ^ dims+  -> Tensor+tile _self _dims = unsafePerformIO $ (cast2 ATen.tile_tl) _self _dims++transpose+  :: Tensor -- ^ self+  -> Int -- ^ dim0+  -> Int -- ^ dim1+  -> Tensor+transpose _self _dim0 _dim1 = unsafePerformIO $ (cast3 ATen.transpose_tll) _self _dim0 _dim1++transposeWithDimname+  :: Tensor -- ^ self+  -> Dimname -- ^ dim0+  -> Dimname -- ^ dim1+  -> Tensor+transposeWithDimname _self _dim0 _dim1 = unsafePerformIO $ (cast3 ATen.transpose_tnn) _self _dim0 _dim1++one_hot+  :: Tensor -- ^ self+  -> Int -- ^ num_classes+  -> Tensor+one_hot _self _num_classes = unsafePerformIO $ (cast2 ATen.one_hot_tl) _self _num_classes++flip+  :: Tensor -- ^ self+  -> [Int] -- ^ dims+  -> Tensor+flip _self _dims = unsafePerformIO $ (cast2 ATen.flip_tl) _self _dims++fliplr+  :: Tensor -- ^ self+  -> Tensor+fliplr _self = unsafePerformIO $ (cast1 ATen.fliplr_t) _self++flipud+  :: Tensor -- ^ self+  -> Tensor+flipud _self = unsafePerformIO $ (cast1 ATen.flipud_t) _self++roll+  :: Tensor -- ^ self+  -> Int -- ^ shifts+  -> Int -- ^ dims+  -> Tensor+roll _self _shifts _dims = unsafePerformIO $ (cast3 ATen.roll_tll) _self _shifts _dims++rot90+  :: Tensor -- ^ self+  -> Int -- ^ k+  -> [Int] -- ^ dims+  -> Tensor+rot90 _self _k _dims = unsafePerformIO $ (cast3 ATen.rot90_tll) _self _k _dims++trapezoid_ttl+  :: Tensor -- ^ y+  -> Tensor -- ^ x+  -> Int -- ^ dim+  -> Tensor+trapezoid_ttl _y _x _dim = unsafePerformIO $ (cast3 ATen.trapezoid_ttl) _y _x _dim++trapezoid_tsl+  :: Tensor -- ^ y+  -> Float -- ^ dx+  -> Int -- ^ dim+  -> Tensor+trapezoid_tsl _y _dx _dim = unsafePerformIO $ (cast3 ATen.trapezoid_tsl) _y _dx _dim++trapz+  :: Tensor -- ^ y+  -> Tensor -- ^ x+  -> Int -- ^ dim+  -> Tensor+trapz _y _x _dim = unsafePerformIO $ (cast3 ATen.trapz_ttl) _y _x _dim++trapzScalar+  :: Tensor -- ^ y+  -> Double -- ^ dx+  -> Int -- ^ dim+  -> Tensor+trapzScalar _y _dx _dim = unsafePerformIO $ (cast3 ATen.trapz_tdl) _y _dx _dim++triplet_margin_loss+  :: Tensor -- ^ anchor+  -> Tensor -- ^ positive+  -> Tensor -- ^ negative+  -> Double -- ^ margin+  -> Double -- ^ p+  -> Double -- ^ eps+  -> Bool -- ^ swap+  -> Int -- ^ reduction+  -> Tensor+triplet_margin_loss _anchor _positive _negative _margin _p _eps _swap _reduction = unsafePerformIO $ (cast8 ATen.triplet_margin_loss_tttdddbl) _anchor _positive _negative _margin _p _eps _swap _reduction++trunc+  :: Tensor -- ^ self+  -> Tensor+trunc _self = unsafePerformIO $ (cast1 ATen.trunc_t) _self++fix+  :: Tensor -- ^ self+  -> Tensor+fix _self = unsafePerformIO $ (cast1 ATen.fix_t) _self++unique_dim+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Bool -- ^ sorted+  -> Bool -- ^ return_inverse+  -> Bool -- ^ return_counts+  -> (Tensor,Tensor,Tensor)+unique_dim _self _dim _sorted _return_inverse _return_counts = unsafePerformIO $ (cast5 ATen.unique_dim_tlbbb) _self _dim _sorted _return_inverse _return_counts++unique_consecutive+  :: Tensor -- ^ self+  -> Bool -- ^ return_inverse+  -> Bool -- ^ return_counts+  -> Int -- ^ dim+  -> (Tensor,Tensor,Tensor)+unique_consecutive _self _return_inverse _return_counts _dim = unsafePerformIO $ (cast4 ATen.unique_consecutive_tbbl) _self _return_inverse _return_counts _dim++unique_dim_consecutive+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Bool -- ^ return_inverse+  -> Bool -- ^ return_counts+  -> (Tensor,Tensor,Tensor)+unique_dim_consecutive _self _dim _return_inverse _return_counts = unsafePerformIO $ (cast4 ATen.unique_dim_consecutive_tlbb) _self _dim _return_inverse _return_counts++unsqueeze+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Tensor+unsqueeze _self _dim = unsafePerformIO $ (cast2 ATen.unsqueeze_tl) _self _dim++vander+  :: Tensor -- ^ x+  -> Int -- ^ N+  -> Bool -- ^ increasing+  -> Tensor+vander _x _N _increasing = unsafePerformIO $ (cast3 ATen.vander_tlb) _x _N _increasing++var+  :: Tensor -- ^ self+  -> Bool -- ^ unbiased+  -> Tensor+var _self _unbiased = unsafePerformIO $ (cast2 ATen.var_tb) _self _unbiased++varDim+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Bool -- ^ unbiased+  -> Bool -- ^ keepdim+  -> Tensor+varDim _self _dim _unbiased _keepdim = unsafePerformIO $ (cast4 ATen.var_tlbb) _self _dim _unbiased _keepdim++var_tllb+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Int -- ^ correction+  -> Bool -- ^ keepdim+  -> Tensor+var_tllb _self _dim _correction _keepdim = unsafePerformIO $ (cast4 ATen.var_tllb) _self _dim _correction _keepdim++varWithDimnames+  :: Tensor -- ^ self+  -> [Dimname] -- ^ dim+  -> Bool -- ^ unbiased+  -> Bool -- ^ keepdim+  -> Tensor+varWithDimnames _self _dim _unbiased _keepdim = unsafePerformIO $ (cast4 ATen.var_tNbb) _self _dim _unbiased _keepdim++var_tNlb+  :: Tensor -- ^ self+  -> [Dimname] -- ^ dim+  -> Int -- ^ correction+  -> Bool -- ^ keepdim+  -> Tensor+var_tNlb _self _dim _correction _keepdim = unsafePerformIO $ (cast4 ATen.var_tNlb) _self _dim _correction _keepdim++varMean+  :: Tensor -- ^ self+  -> Bool -- ^ unbiased+  -> (Tensor,Tensor)+varMean _self _unbiased = unsafePerformIO $ (cast2 ATen.var_mean_tb) _self _unbiased++varMeanDim+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Bool -- ^ unbiased+  -> Bool -- ^ keepdim+  -> (Tensor,Tensor)+varMeanDim _self _dim _unbiased _keepdim = unsafePerformIO $ (cast4 ATen.var_mean_tlbb) _self _dim _unbiased _keepdim++var_mean_tllb+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Int -- ^ correction+  -> Bool -- ^ keepdim+  -> (Tensor,Tensor)+var_mean_tllb _self _dim _correction _keepdim = unsafePerformIO $ (cast4 ATen.var_mean_tllb) _self _dim _correction _keepdim++varMeanWithDimnames+  :: Tensor -- ^ self+  -> [Dimname] -- ^ dim+  -> Bool -- ^ unbiased+  -> Bool -- ^ keepdim+  -> (Tensor,Tensor)+varMeanWithDimnames _self _dim _unbiased _keepdim = unsafePerformIO $ (cast4 ATen.var_mean_tNbb) _self _dim _unbiased _keepdim++var_mean_tNlb+  :: Tensor -- ^ self+  -> [Dimname] -- ^ dim+  -> Int -- ^ correction+  -> Bool -- ^ keepdim+  -> (Tensor,Tensor)+var_mean_tNlb _self _dim _correction _keepdim = unsafePerformIO $ (cast4 ATen.var_mean_tNlb) _self _dim _correction _keepdim++where'+  :: Tensor -- ^ condition+  -> Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+where' _condition _self _other = unsafePerformIO $ (cast3 ATen.where_ttt) _condition _self _other++where_tst+  :: Tensor -- ^ condition+  -> Float -- ^ self+  -> Tensor -- ^ other+  -> Tensor+where_tst _condition _self _other = unsafePerformIO $ (cast3 ATen.where_tst) _condition _self _other++where_tts+  :: Tensor -- ^ condition+  -> Tensor -- ^ self+  -> Float -- ^ other+  -> Tensor+where_tts _condition _self _other = unsafePerformIO $ (cast3 ATen.where_tts) _condition _self _other++where_tss+  :: Tensor -- ^ condition+  -> Float -- ^ self+  -> Float -- ^ other+  -> Tensor+where_tss _condition _self _other = unsafePerformIO $ (cast3 ATen.where_tss) _condition _self _other++isNonZero+  :: Tensor -- ^ condition+  -> [Tensor]+isNonZero _condition = unsafePerformIO $ (cast1 ATen.where_t) _condition++norm_except_dim+  :: Tensor -- ^ v+  -> Int -- ^ pow+  -> Int -- ^ dim+  -> Tensor+norm_except_dim _v _pow _dim = unsafePerformIO $ (cast3 ATen.norm_except_dim_tll) _v _pow _dim++native_norm_ts+  :: Tensor -- ^ self+  -> Float -- ^ p+  -> Tensor+native_norm_ts _self _p = unsafePerformIO $ (cast2 ATen.native_norm_ts) _self _p++native_norm_tslbs+  :: Tensor -- ^ self+  -> Float -- ^ p+  -> Int -- ^ dim+  -> Bool -- ^ keepdim+  -> DType -- ^ dtype+  -> Tensor+native_norm_tslbs _self _p _dim _keepdim _dtype = unsafePerformIO $ (cast5 ATen.native_norm_tslbs) _self _p _dim _keepdim _dtype++normCastAll+  :: Tensor -- ^ self+  -> Float -- ^ p+  -> DType -- ^ dtype+  -> Tensor+normCastAll _self _p _dtype = unsafePerformIO $ (cast3 ATen.norm_tss) _self _p _dtype++normAll+  :: Tensor -- ^ self+  -> Float -- ^ p+  -> Tensor+normAll _self _p = unsafePerformIO $ (cast2 ATen.norm_ts) _self _p++normCastDim+  :: Tensor -- ^ self+  -> Float -- ^ p+  -> Int -- ^ dim+  -> Bool -- ^ keepdim+  -> DType -- ^ dtype+  -> Tensor+normCastDim _self _p _dim _keepdim _dtype = unsafePerformIO $ (cast5 ATen.norm_tslbs) _self _p _dim _keepdim _dtype++normDim+  :: Tensor -- ^ self+  -> Float -- ^ p+  -> Int -- ^ dim+  -> Bool -- ^ keepdim+  -> Tensor+normDim _self _p _dim _keepdim = unsafePerformIO $ (cast4 ATen.norm_tslb) _self _p _dim _keepdim++norm_tsNbs+  :: Tensor -- ^ self+  -> Float -- ^ p+  -> [Dimname] -- ^ dim+  -> Bool -- ^ keepdim+  -> DType -- ^ dtype+  -> Tensor+norm_tsNbs _self _p _dim _keepdim _dtype = unsafePerformIO $ (cast5 ATen.norm_tsNbs) _self _p _dim _keepdim _dtype++norm_tsNb+  :: Tensor -- ^ self+  -> Float -- ^ p+  -> [Dimname] -- ^ dim+  -> Bool -- ^ keepdim+  -> Tensor+norm_tsNb _self _p _dim _keepdim = unsafePerformIO $ (cast4 ATen.norm_tsNb) _self _p _dim _keepdim++frexp+  :: Tensor -- ^ self+  -> (Tensor,Tensor)+frexp _self = unsafePerformIO $ (cast1 ATen.frexp_t) _self++frobenius_norm+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Bool -- ^ keepdim+  -> Tensor+frobenius_norm _self _dim _keepdim = unsafePerformIO $ (cast3 ATen.frobenius_norm_tlb) _self _dim _keepdim++nuclearNormAll+  :: Tensor -- ^ self+  -> Bool -- ^ keepdim+  -> Tensor+nuclearNormAll _self _keepdim = unsafePerformIO $ (cast2 ATen.nuclear_norm_tb) _self _keepdim++nuclearNormDim+  :: Tensor -- ^ self+  -> (Int,Int) -- ^ dim+  -> Bool -- ^ keepdim+  -> Tensor+nuclearNormDim _self _dim _keepdim = unsafePerformIO $ (cast3 ATen.nuclear_norm_tlb) _self _dim _keepdim++clone+  :: Tensor -- ^ self+  -> ATen.MemoryFormat -- ^ memory_format+  -> Tensor+clone _self _memory_format = unsafePerformIO $ (cast2 ATen.clone_tM) _self _memory_format++positive+  :: Tensor -- ^ self+  -> Tensor+positive _self = unsafePerformIO $ (cast1 ATen.positive_t) _self++sub+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Float -- ^ alpha+  -> Tensor+sub _self _other _alpha = unsafePerformIO $ (cast3 ATen.sub_tts) _self _other _alpha++subScalar+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> Float -- ^ alpha+  -> Tensor+subScalar _self _other _alpha = unsafePerformIO $ (cast3 ATen.sub_tss) _self _other _alpha++subtract_tts+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Float -- ^ alpha+  -> Tensor+subtract_tts _self _other _alpha = unsafePerformIO $ (cast3 ATen.subtract_tts) _self _other _alpha++subtract_tss+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> Float -- ^ alpha+  -> Tensor+subtract_tss _self _other _alpha = unsafePerformIO $ (cast3 ATen.subtract_tss) _self _other _alpha++rsub+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Float -- ^ alpha+  -> Tensor+rsub _self _other _alpha = unsafePerformIO $ (cast3 ATen.rsub_tts) _self _other _alpha++heaviside+  :: Tensor -- ^ self+  -> Tensor -- ^ values+  -> Tensor+heaviside _self _values = unsafePerformIO $ (cast2 ATen.heaviside_tt) _self _values++rsubScalar+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> Float -- ^ alpha+  -> Tensor+rsubScalar _self _other _alpha = unsafePerformIO $ (cast3 ATen.rsub_tss) _self _other _alpha++sparse_sampled_addmm+  :: Tensor -- ^ self+  -> Tensor -- ^ mat1+  -> Tensor -- ^ mat2+  -> Float -- ^ beta+  -> Float -- ^ alpha+  -> Tensor+sparse_sampled_addmm _self _mat1 _mat2 _beta _alpha = unsafePerformIO $ (cast5 ATen.sparse_sampled_addmm_tttss) _self _mat1 _mat2 _beta _alpha++addmm+  :: Tensor -- ^ self+  -> Tensor -- ^ mat1+  -> Tensor -- ^ mat2+  -> Float -- ^ beta+  -> Float -- ^ alpha+  -> Tensor+addmm _self _mat1 _mat2 _beta _alpha = unsafePerformIO $ (cast5 ATen.addmm_tttss) _self _mat1 _mat2 _beta _alpha++hspmm+  :: Tensor -- ^ mat1+  -> Tensor -- ^ mat2+  -> Tensor+hspmm _mat1 _mat2 = unsafePerformIO $ (cast2 ATen.hspmm_tt) _mat1 _mat2++unbind+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> [Tensor]+unbind _self _dim = unsafePerformIO $ (cast2 ATen.unbind_tl) _self _dim++unbindWithDimname+  :: Tensor -- ^ self+  -> Dimname -- ^ dim+  -> [Tensor]+unbindWithDimname _self _dim = unsafePerformIO $ (cast2 ATen.unbind_tn) _self _dim++mkldnn_reorder_conv2d_weight+  :: Tensor -- ^ self+  -> (Int,Int) -- ^ padding+  -> (Int,Int) -- ^ stride+  -> (Int,Int) -- ^ dilation+  -> Int -- ^ groups+  -> [Int] -- ^ input_size+  -> Tensor+mkldnn_reorder_conv2d_weight _self _padding _stride _dilation _groups _input_size = unsafePerformIO $ (cast6 ATen.mkldnn_reorder_conv2d_weight_tlllll) _self _padding _stride _dilation _groups _input_size++mkldnn_reorder_conv3d_weight+  :: Tensor -- ^ self+  -> (Int,Int,Int) -- ^ padding+  -> (Int,Int,Int) -- ^ stride+  -> (Int,Int,Int) -- ^ dilation+  -> Int -- ^ groups+  -> Tensor+mkldnn_reorder_conv3d_weight _self _padding _stride _dilation _groups = unsafePerformIO $ (cast5 ATen.mkldnn_reorder_conv3d_weight_tllll) _self _padding _stride _dilation _groups++quantize_per_tensor_dynamic+  :: Tensor -- ^ self+  -> DType -- ^ dtype+  -> Bool -- ^ reduce_range+  -> Tensor+quantize_per_tensor_dynamic _self _dtype _reduce_range = unsafePerformIO $ (cast3 ATen.quantize_per_tensor_dynamic_tsb) _self _dtype _reduce_range++quantize_per_tensor_tdls+  :: Tensor -- ^ self+  -> Double -- ^ scale+  -> Int -- ^ zero_point+  -> DType -- ^ dtype+  -> Tensor+quantize_per_tensor_tdls _self _scale _zero_point _dtype = unsafePerformIO $ (cast4 ATen.quantize_per_tensor_tdls) _self _scale _zero_point _dtype++quantize_per_tensor_ttts+  :: Tensor -- ^ self+  -> Tensor -- ^ scale+  -> Tensor -- ^ zero_point+  -> DType -- ^ dtype+  -> Tensor+quantize_per_tensor_ttts _self _scale _zero_point _dtype = unsafePerformIO $ (cast4 ATen.quantize_per_tensor_ttts) _self _scale _zero_point _dtype++quantize_per_tensor_ltts+  :: [Tensor] -- ^ tensors+  -> Tensor -- ^ scales+  -> Tensor -- ^ zero_points+  -> DType -- ^ dtype+  -> [Tensor]+quantize_per_tensor_ltts _tensors _scales _zero_points _dtype = unsafePerformIO $ (cast4 ATen.quantize_per_tensor_ltts) _tensors _scales _zero_points _dtype++quantize_per_channel+  :: Tensor -- ^ self+  -> Tensor -- ^ scales+  -> Tensor -- ^ zero_points+  -> Int -- ^ axis+  -> DType -- ^ dtype+  -> Tensor+quantize_per_channel _self _scales _zero_points _axis _dtype = unsafePerformIO $ (cast5 ATen.quantize_per_channel_tttls) _self _scales _zero_points _axis _dtype++dequantize_t+  :: Tensor -- ^ self+  -> Tensor+dequantize_t _self = unsafePerformIO $ (cast1 ATen.dequantize_t) _self++dequantize_l+  :: [Tensor] -- ^ tensors+  -> [Tensor]+dequantize_l _tensors = unsafePerformIO $ (cast1 ATen.dequantize_l) _tensors++q_scale+  :: Tensor -- ^ self+  -> Double+q_scale _self = unsafePerformIO $ (cast1 ATen.q_scale_t) _self++q_zero_point+  :: Tensor -- ^ self+  -> Int+q_zero_point _self = unsafePerformIO $ (cast1 ATen.q_zero_point_t) _self++q_per_channel_scales+  :: Tensor -- ^ self+  -> Tensor+q_per_channel_scales _self = unsafePerformIO $ (cast1 ATen.q_per_channel_scales_t) _self++q_per_channel_zero_points+  :: Tensor -- ^ self+  -> Tensor+q_per_channel_zero_points _self = unsafePerformIO $ (cast1 ATen.q_per_channel_zero_points_t) _self++q_per_channel_axis+  :: Tensor -- ^ self+  -> Int+q_per_channel_axis _self = unsafePerformIO $ (cast1 ATen.q_per_channel_axis_t) _self++int_repr+  :: Tensor -- ^ self+  -> Tensor+int_repr _self = unsafePerformIO $ (cast1 ATen.int_repr_t) _self++fake_quantize_per_tensor_affine_tdlll+  :: Tensor -- ^ self+  -> Double -- ^ scale+  -> Int -- ^ zero_point+  -> Int -- ^ quant_min+  -> Int -- ^ quant_max+  -> Tensor+fake_quantize_per_tensor_affine_tdlll _self _scale _zero_point _quant_min _quant_max = unsafePerformIO $ (cast5 ATen.fake_quantize_per_tensor_affine_tdlll) _self _scale _zero_point _quant_min _quant_max++fake_quantize_per_tensor_affine_tttll+  :: Tensor -- ^ self+  -> Tensor -- ^ scale+  -> Tensor -- ^ zero_point+  -> Int -- ^ quant_min+  -> Int -- ^ quant_max+  -> Tensor+fake_quantize_per_tensor_affine_tttll _self _scale _zero_point _quant_min _quant_max = unsafePerformIO $ (cast5 ATen.fake_quantize_per_tensor_affine_tttll) _self _scale _zero_point _quant_min _quant_max++fake_quantize_per_tensor_affine_cachemask+  :: Tensor -- ^ self+  -> Double -- ^ scale+  -> Int -- ^ zero_point+  -> Int -- ^ quant_min+  -> Int -- ^ quant_max+  -> (Tensor,Tensor)+fake_quantize_per_tensor_affine_cachemask _self _scale _zero_point _quant_min _quant_max = unsafePerformIO $ (cast5 ATen.fake_quantize_per_tensor_affine_cachemask_tdlll) _self _scale _zero_point _quant_min _quant_max++fake_quantize_per_channel_affine+  :: Tensor -- ^ self+  -> Tensor -- ^ scale+  -> Tensor -- ^ zero_point+  -> Int -- ^ axis+  -> Int -- ^ quant_min+  -> Int -- ^ quant_max+  -> Tensor+fake_quantize_per_channel_affine _self _scale _zero_point _axis _quant_min _quant_max = unsafePerformIO $ (cast6 ATen.fake_quantize_per_channel_affine_tttlll) _self _scale _zero_point _axis _quant_min _quant_max++fake_quantize_per_channel_affine_cachemask+  :: Tensor -- ^ self+  -> Tensor -- ^ scale+  -> Tensor -- ^ zero_point+  -> Int -- ^ axis+  -> Int -- ^ quant_min+  -> Int -- ^ quant_max+  -> (Tensor,Tensor)+fake_quantize_per_channel_affine_cachemask _self _scale _zero_point _axis _quant_min _quant_max = unsafePerformIO $ (cast6 ATen.fake_quantize_per_channel_affine_cachemask_tttlll) _self _scale _zero_point _axis _quant_min _quant_max++fused_moving_avg_obs_fake_quant+  :: Tensor -- ^ self+  -> Tensor -- ^ observer_on+  -> Tensor -- ^ fake_quant_on+  -> Tensor -- ^ running_min+  -> Tensor -- ^ running_max+  -> Tensor -- ^ scale+  -> Tensor -- ^ zero_point+  -> Double -- ^ averaging_const+  -> Int -- ^ quant_min+  -> Int -- ^ quant_max+  -> Int -- ^ ch_axis+  -> Bool -- ^ per_row_fake_quant+  -> Bool -- ^ symmetric_quant+  -> Tensor+fused_moving_avg_obs_fake_quant _self _observer_on _fake_quant_on _running_min _running_max _scale _zero_point _averaging_const _quant_min _quant_max _ch_axis _per_row_fake_quant _symmetric_quant = unsafePerformIO $ (cast13 ATen.fused_moving_avg_obs_fake_quant_tttttttdlllbb) _self _observer_on _fake_quant_on _running_min _running_max _scale _zero_point _averaging_const _quant_min _quant_max _ch_axis _per_row_fake_quant _symmetric_quant++choose_qparams_optimized+  :: Tensor -- ^ input+  -> Int -- ^ numel+  -> Int -- ^ n_bins+  -> Double -- ^ ratio+  -> Int -- ^ bit_width+  -> (Tensor,Tensor)+choose_qparams_optimized _input _numel _n_bins _ratio _bit_width = unsafePerformIO $ (cast5 ATen.choose_qparams_optimized_tlldl) _input _numel _n_bins _ratio _bit_width++meshgrid_l+  :: [Tensor] -- ^ tensors+  -> [Tensor]+meshgrid_l _tensors = unsafePerformIO $ (cast1 ATen.meshgrid_l) _tensors++meshgrid_ls+  :: [Tensor] -- ^ tensors+  -> String -- ^ indexing+  -> [Tensor]+meshgrid_ls _tensors _indexing = unsafePerformIO $ (cast2 ATen.meshgrid_ls) _tensors _indexing++cartesian_prod+  :: [Tensor] -- ^ tensors+  -> Tensor+cartesian_prod _tensors = unsafePerformIO $ (cast1 ATen.cartesian_prod_l) _tensors++combinations+  :: Tensor -- ^ self+  -> Int -- ^ r+  -> Bool -- ^ with_replacement+  -> Tensor+combinations _self _r _with_replacement = unsafePerformIO $ (cast3 ATen.combinations_tlb) _self _r _with_replacement++resultType+  :: Tensor -- ^ tensor+  -> Tensor -- ^ other+  -> DType+resultType _tensor _other = unsafePerformIO $ (cast2 ATen.result_type_tt) _tensor _other++resultTypeScalar+  :: Tensor -- ^ tensor+  -> Float -- ^ other+  -> DType+resultTypeScalar _tensor _other = unsafePerformIO $ (cast2 ATen.result_type_ts) _tensor _other++resultTypeScalar'+  :: Float -- ^ scalar+  -> Tensor -- ^ tensor+  -> DType+resultTypeScalar' _scalar _tensor = unsafePerformIO $ (cast2 ATen.result_type_st) _scalar _tensor++resultTypeScalars+  :: Float -- ^ scalar1+  -> Float -- ^ scalar2+  -> DType+resultTypeScalars _scalar1 _scalar2 = unsafePerformIO $ (cast2 ATen.result_type_ss) _scalar1 _scalar2++can_cast+  :: DType -- ^ from+  -> DType -- ^ to+  -> Bool+can_cast _from _to = unsafePerformIO $ (cast2 ATen.can_cast_ss) _from _to++promote_types+  :: DType -- ^ type1+  -> DType -- ^ type2+  -> DType+promote_types _type1 _type2 = unsafePerformIO $ (cast2 ATen.promote_types_ss) _type1 _type2++lstm+  :: Tensor -- ^ input+  -> [Tensor] -- ^ hx+  -> [Tensor] -- ^ params+  -> Bool -- ^ has_biases+  -> Int -- ^ num_layers+  -> Double -- ^ dropout+  -> Bool -- ^ train+  -> Bool -- ^ bidirectional+  -> Bool -- ^ batch_first+  -> (Tensor,Tensor,Tensor)+lstm _input _hx _params _has_biases _num_layers _dropout _train _bidirectional _batch_first = unsafePerformIO $ (cast9 ATen.lstm_tllbldbbb) _input _hx _params _has_biases _num_layers _dropout _train _bidirectional _batch_first++lstm'+  :: Tensor -- ^ data+  -> Tensor -- ^ batch_sizes+  -> [Tensor] -- ^ hx+  -> [Tensor] -- ^ params+  -> Bool -- ^ has_biases+  -> Int -- ^ num_layers+  -> Double -- ^ dropout+  -> Bool -- ^ train+  -> Bool -- ^ bidirectional+  -> (Tensor,Tensor,Tensor)+lstm' _data _batch_sizes _hx _params _has_biases _num_layers _dropout _train _bidirectional = unsafePerformIO $ (cast9 ATen.lstm_ttllbldbb) _data _batch_sizes _hx _params _has_biases _num_layers _dropout _train _bidirectional++gru+  :: Tensor -- ^ input+  -> Tensor -- ^ hx+  -> [Tensor] -- ^ params+  -> Bool -- ^ has_biases+  -> Int -- ^ num_layers+  -> Double -- ^ dropout+  -> Bool -- ^ train+  -> Bool -- ^ bidirectional+  -> Bool -- ^ batch_first+  -> (Tensor,Tensor)+gru _input _hx _params _has_biases _num_layers _dropout _train _bidirectional _batch_first = unsafePerformIO $ (cast9 ATen.gru_ttlbldbbb) _input _hx _params _has_biases _num_layers _dropout _train _bidirectional _batch_first++gru'+  :: Tensor -- ^ data+  -> Tensor -- ^ batch_sizes+  -> Tensor -- ^ hx+  -> [Tensor] -- ^ params+  -> Bool -- ^ has_biases+  -> Int -- ^ num_layers+  -> Double -- ^ dropout+  -> Bool -- ^ train+  -> Bool -- ^ bidirectional+  -> (Tensor,Tensor)+gru' _data _batch_sizes _hx _params _has_biases _num_layers _dropout _train _bidirectional = unsafePerformIO $ (cast9 ATen.gru_tttlbldbb) _data _batch_sizes _hx _params _has_biases _num_layers _dropout _train _bidirectional++rnnTanh+  :: Tensor -- ^ input+  -> Tensor -- ^ hx+  -> [Tensor] -- ^ params+  -> Bool -- ^ has_biases+  -> Int -- ^ num_layers+  -> Double -- ^ dropout+  -> Bool -- ^ train+  -> Bool -- ^ bidirectional+  -> Bool -- ^ batch_first+  -> (Tensor,Tensor)+rnnTanh _input _hx _params _has_biases _num_layers _dropout _train _bidirectional _batch_first = unsafePerformIO $ (cast9 ATen.rnn_tanh_ttlbldbbb) _input _hx _params _has_biases _num_layers _dropout _train _bidirectional _batch_first++rnnTanh'+  :: Tensor -- ^ data+  -> Tensor -- ^ batch_sizes+  -> Tensor -- ^ hx+  -> [Tensor] -- ^ params+  -> Bool -- ^ has_biases+  -> Int -- ^ num_layers+  -> Double -- ^ dropout+  -> Bool -- ^ train+  -> Bool -- ^ bidirectional+  -> (Tensor,Tensor)+rnnTanh' _data _batch_sizes _hx _params _has_biases _num_layers _dropout _train _bidirectional = unsafePerformIO $ (cast9 ATen.rnn_tanh_tttlbldbb) _data _batch_sizes _hx _params _has_biases _num_layers _dropout _train _bidirectional++rnnRelu+  :: Tensor -- ^ input+  -> Tensor -- ^ hx+  -> [Tensor] -- ^ params+  -> Bool -- ^ has_biases+  -> Int -- ^ num_layers+  -> Double -- ^ dropout+  -> Bool -- ^ train+  -> Bool -- ^ bidirectional+  -> Bool -- ^ batch_first+  -> (Tensor,Tensor)+rnnRelu _input _hx _params _has_biases _num_layers _dropout _train _bidirectional _batch_first = unsafePerformIO $ (cast9 ATen.rnn_relu_ttlbldbbb) _input _hx _params _has_biases _num_layers _dropout _train _bidirectional _batch_first++rnnRelu'+  :: Tensor -- ^ data+  -> Tensor -- ^ batch_sizes+  -> Tensor -- ^ hx+  -> [Tensor] -- ^ params+  -> Bool -- ^ has_biases+  -> Int -- ^ num_layers+  -> Double -- ^ dropout+  -> Bool -- ^ train+  -> Bool -- ^ bidirectional+  -> (Tensor,Tensor)+rnnRelu' _data _batch_sizes _hx _params _has_biases _num_layers _dropout _train _bidirectional = unsafePerformIO $ (cast9 ATen.rnn_relu_tttlbldbb) _data _batch_sizes _hx _params _has_biases _num_layers _dropout _train _bidirectional++lstm_cell+  :: Tensor -- ^ input+  -> [Tensor] -- ^ hx+  -> Tensor -- ^ w_ih+  -> Tensor -- ^ w_hh+  -> Tensor -- ^ b_ih+  -> Tensor -- ^ b_hh+  -> (Tensor,Tensor)+lstm_cell _input _hx _w_ih _w_hh _b_ih _b_hh = unsafePerformIO $ (cast6 ATen.lstm_cell_tltttt) _input _hx _w_ih _w_hh _b_ih _b_hh++gru_cell+  :: Tensor -- ^ input+  -> Tensor -- ^ hx+  -> Tensor -- ^ w_ih+  -> Tensor -- ^ w_hh+  -> Tensor -- ^ b_ih+  -> Tensor -- ^ b_hh+  -> Tensor+gru_cell _input _hx _w_ih _w_hh _b_ih _b_hh = unsafePerformIO $ (cast6 ATen.gru_cell_tttttt) _input _hx _w_ih _w_hh _b_ih _b_hh++rnn_tanh_cell+  :: Tensor -- ^ input+  -> Tensor -- ^ hx+  -> Tensor -- ^ w_ih+  -> Tensor -- ^ w_hh+  -> Tensor -- ^ b_ih+  -> Tensor -- ^ b_hh+  -> Tensor+rnn_tanh_cell _input _hx _w_ih _w_hh _b_ih _b_hh = unsafePerformIO $ (cast6 ATen.rnn_tanh_cell_tttttt) _input _hx _w_ih _w_hh _b_ih _b_hh++rnn_relu_cell+  :: Tensor -- ^ input+  -> Tensor -- ^ hx+  -> Tensor -- ^ w_ih+  -> Tensor -- ^ w_hh+  -> Tensor -- ^ b_ih+  -> Tensor -- ^ b_hh+  -> Tensor+rnn_relu_cell _input _hx _w_ih _w_hh _b_ih _b_hh = unsafePerformIO $ (cast6 ATen.rnn_relu_cell_tttttt) _input _hx _w_ih _w_hh _b_ih _b_hh++quantized_lstm_cell+  :: Tensor -- ^ input+  -> [Tensor] -- ^ hx+  -> Tensor -- ^ w_ih+  -> Tensor -- ^ w_hh+  -> Tensor -- ^ b_ih+  -> Tensor -- ^ b_hh+  -> Tensor -- ^ packed_ih+  -> Tensor -- ^ packed_hh+  -> Tensor -- ^ col_offsets_ih+  -> Tensor -- ^ col_offsets_hh+  -> Float -- ^ scale_ih+  -> Float -- ^ scale_hh+  -> Float -- ^ zero_point_ih+  -> Float -- ^ zero_point_hh+  -> (Tensor,Tensor)+quantized_lstm_cell _input _hx _w_ih _w_hh _b_ih _b_hh _packed_ih _packed_hh _col_offsets_ih _col_offsets_hh _scale_ih _scale_hh _zero_point_ih _zero_point_hh = unsafePerformIO $ (cast14 ATen.quantized_lstm_cell_tlttttttttssss) _input _hx _w_ih _w_hh _b_ih _b_hh _packed_ih _packed_hh _col_offsets_ih _col_offsets_hh _scale_ih _scale_hh _zero_point_ih _zero_point_hh++quantized_gru_cell+  :: Tensor -- ^ input+  -> Tensor -- ^ hx+  -> Tensor -- ^ w_ih+  -> Tensor -- ^ w_hh+  -> Tensor -- ^ b_ih+  -> Tensor -- ^ b_hh+  -> Tensor -- ^ packed_ih+  -> Tensor -- ^ packed_hh+  -> Tensor -- ^ col_offsets_ih+  -> Tensor -- ^ col_offsets_hh+  -> Float -- ^ scale_ih+  -> Float -- ^ scale_hh+  -> Float -- ^ zero_point_ih+  -> Float -- ^ zero_point_hh+  -> Tensor+quantized_gru_cell _input _hx _w_ih _w_hh _b_ih _b_hh _packed_ih _packed_hh _col_offsets_ih _col_offsets_hh _scale_ih _scale_hh _zero_point_ih _zero_point_hh = unsafePerformIO $ (cast14 ATen.quantized_gru_cell_ttttttttttssss) _input _hx _w_ih _w_hh _b_ih _b_hh _packed_ih _packed_hh _col_offsets_ih _col_offsets_hh _scale_ih _scale_hh _zero_point_ih _zero_point_hh++quantized_rnn_relu_cell+  :: Tensor -- ^ input+  -> Tensor -- ^ hx+  -> Tensor -- ^ w_ih+  -> Tensor -- ^ w_hh+  -> Tensor -- ^ b_ih+  -> Tensor -- ^ b_hh+  -> Tensor -- ^ packed_ih+  -> Tensor -- ^ packed_hh+  -> Tensor -- ^ col_offsets_ih+  -> Tensor -- ^ col_offsets_hh+  -> Float -- ^ scale_ih+  -> Float -- ^ scale_hh+  -> Float -- ^ zero_point_ih+  -> Float -- ^ zero_point_hh+  -> Tensor+quantized_rnn_relu_cell _input _hx _w_ih _w_hh _b_ih _b_hh _packed_ih _packed_hh _col_offsets_ih _col_offsets_hh _scale_ih _scale_hh _zero_point_ih _zero_point_hh = unsafePerformIO $ (cast14 ATen.quantized_rnn_relu_cell_ttttttttttssss) _input _hx _w_ih _w_hh _b_ih _b_hh _packed_ih _packed_hh _col_offsets_ih _col_offsets_hh _scale_ih _scale_hh _zero_point_ih _zero_point_hh++quantized_rnn_tanh_cell+  :: Tensor -- ^ input+  -> Tensor -- ^ hx+  -> Tensor -- ^ w_ih+  -> Tensor -- ^ w_hh+  -> Tensor -- ^ b_ih+  -> Tensor -- ^ b_hh+  -> Tensor -- ^ packed_ih+  -> Tensor -- ^ packed_hh+  -> Tensor -- ^ col_offsets_ih+  -> Tensor -- ^ col_offsets_hh+  -> Float -- ^ scale_ih+  -> Float -- ^ scale_hh+  -> Float -- ^ zero_point_ih+  -> Float -- ^ zero_point_hh+  -> Tensor+quantized_rnn_tanh_cell _input _hx _w_ih _w_hh _b_ih _b_hh _packed_ih _packed_hh _col_offsets_ih _col_offsets_hh _scale_ih _scale_hh _zero_point_ih _zero_point_hh = unsafePerformIO $ (cast14 ATen.quantized_rnn_tanh_cell_ttttttttttssss) _input _hx _w_ih _w_hh _b_ih _b_hh _packed_ih _packed_hh _col_offsets_ih _col_offsets_hh _scale_ih _scale_hh _zero_point_ih _zero_point_hh++lift+  :: Tensor -- ^ self+  -> Tensor+lift _self = unsafePerformIO $ (cast1 ATen.lift_t) _self++lift_fresh+  :: Tensor -- ^ self+  -> Tensor+lift_fresh _self = unsafePerformIO $ (cast1 ATen.lift_fresh_t) _self++lift_fresh_copy+  :: Tensor -- ^ self+  -> Tensor+lift_fresh_copy _self = unsafePerformIO $ (cast1 ATen.lift_fresh_copy_t) _self++maskedFillScalar+  :: Tensor -- ^ self+  -> Tensor -- ^ mask+  -> Float -- ^ value+  -> Tensor+maskedFillScalar _self _mask _value = unsafePerformIO $ (cast3 ATen.masked_fill_tts) _self _mask _value++maskedFill+  :: Tensor -- ^ self+  -> Tensor -- ^ mask+  -> Tensor -- ^ value+  -> Tensor+maskedFill _self _mask _value = unsafePerformIO $ (cast3 ATen.masked_fill_ttt) _self _mask _value++masked_scatter+  :: Tensor -- ^ self+  -> Tensor -- ^ mask+  -> Tensor -- ^ source+  -> Tensor+masked_scatter _self _mask _source = unsafePerformIO $ (cast3 ATen.masked_scatter_ttt) _self _mask _source++put+  :: Tensor -- ^ self+  -> Tensor -- ^ index+  -> Tensor -- ^ source+  -> Bool -- ^ accumulate+  -> Tensor+put _self _index _source _accumulate = unsafePerformIO $ (cast4 ATen.put_tttb) _self _index _source _accumulate++index_add_tltts+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Tensor -- ^ index+  -> Tensor -- ^ source+  -> Float -- ^ alpha+  -> Tensor+index_add_tltts _self _dim _index _source _alpha = unsafePerformIO $ (cast5 ATen.index_add_tltts) _self _dim _index _source _alpha++index_add_tntts+  :: Tensor -- ^ self+  -> Dimname -- ^ dim+  -> Tensor -- ^ index+  -> Tensor -- ^ source+  -> Float -- ^ alpha+  -> Tensor+index_add_tntts _self _dim _index _source _alpha = unsafePerformIO $ (cast5 ATen.index_add_tntts) _self _dim _index _source _alpha++index_reduce+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Tensor -- ^ index+  -> Tensor -- ^ source+  -> String -- ^ reduce+  -> Bool -- ^ include_self+  -> Tensor+index_reduce _self _dim _index _source _reduce _include_self = unsafePerformIO $ (cast6 ATen.index_reduce_tlttsb) _self _dim _index _source _reduce _include_self++indexFillScalar+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Tensor -- ^ index+  -> Float -- ^ value+  -> Tensor+indexFillScalar _self _dim _index _value = unsafePerformIO $ (cast4 ATen.index_fill_tlts) _self _dim _index _value++indexFill+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Tensor -- ^ index+  -> Tensor -- ^ value+  -> Tensor+indexFill _self _dim _index _value = unsafePerformIO $ (cast4 ATen.index_fill_tltt) _self _dim _index _value++indexFillScalarWithDimname+  :: Tensor -- ^ self+  -> Dimname -- ^ dim+  -> Tensor -- ^ index+  -> Float -- ^ value+  -> Tensor+indexFillScalarWithDimname _self _dim _index _value = unsafePerformIO $ (cast4 ATen.index_fill_tnts) _self _dim _index _value++indexFillWithDimname+  :: Tensor -- ^ self+  -> Dimname -- ^ dim+  -> Tensor -- ^ index+  -> Tensor -- ^ value+  -> Tensor+indexFillWithDimname _self _dim _index _value = unsafePerformIO $ (cast4 ATen.index_fill_tntt) _self _dim _index _value++scatter+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Tensor -- ^ index+  -> Tensor -- ^ src+  -> Tensor+scatter _self _dim _index _src = unsafePerformIO $ (cast4 ATen.scatter_tltt) _self _dim _index _src++scatterScalar+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Tensor -- ^ index+  -> Float -- ^ value+  -> Tensor+scatterScalar _self _dim _index _value = unsafePerformIO $ (cast4 ATen.scatter_tlts) _self _dim _index _value++scatter_tltts+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Tensor -- ^ index+  -> Tensor -- ^ src+  -> String -- ^ reduce+  -> Tensor+scatter_tltts _self _dim _index _src _reduce = unsafePerformIO $ (cast5 ATen.scatter_tltts) _self _dim _index _src _reduce++scatter_tltss+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Tensor -- ^ index+  -> Float -- ^ value+  -> String -- ^ reduce+  -> Tensor+scatter_tltss _self _dim _index _value _reduce = unsafePerformIO $ (cast5 ATen.scatter_tltss) _self _dim _index _value _reduce++scatterWithDimname+  :: Tensor -- ^ self+  -> Dimname -- ^ dim+  -> Tensor -- ^ index+  -> Tensor -- ^ src+  -> Tensor+scatterWithDimname _self _dim _index _src = unsafePerformIO $ (cast4 ATen.scatter_tntt) _self _dim _index _src++scatterScalarWithDimname+  :: Tensor -- ^ self+  -> Dimname -- ^ dim+  -> Tensor -- ^ index+  -> Float -- ^ value+  -> Tensor+scatterScalarWithDimname _self _dim _index _value = unsafePerformIO $ (cast4 ATen.scatter_tnts) _self _dim _index _value++scatterAdd+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Tensor -- ^ index+  -> Tensor -- ^ src+  -> Tensor+scatterAdd _self _dim _index _src = unsafePerformIO $ (cast4 ATen.scatter_add_tltt) _self _dim _index _src++scatterAddWithDimname+  :: Tensor -- ^ self+  -> Dimname -- ^ dim+  -> Tensor -- ^ index+  -> Tensor -- ^ src+  -> Tensor+scatterAddWithDimname _self _dim _index _src = unsafePerformIO $ (cast4 ATen.scatter_add_tntt) _self _dim _index _src++scatter_reduce+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Tensor -- ^ index+  -> Tensor -- ^ src+  -> String -- ^ reduce+  -> Bool -- ^ include_self+  -> Tensor+scatter_reduce _self _dim _index _src _reduce _include_self = unsafePerformIO $ (cast6 ATen.scatter_reduce_tlttsb) _self _dim _index _src _reduce _include_self++bitwise_and_ts+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> Tensor+bitwise_and_ts _self _other = unsafePerformIO $ (cast2 ATen.bitwise_and_ts) _self _other++bitwise_and_st+  :: Float -- ^ self+  -> Tensor -- ^ other+  -> Tensor+bitwise_and_st _self _other = unsafePerformIO $ (cast2 ATen.bitwise_and_st) _self _other++bitwise_and_tt+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+bitwise_and_tt _self _other = unsafePerformIO $ (cast2 ATen.bitwise_and_tt) _self _other++bitwise_or_ts+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> Tensor+bitwise_or_ts _self _other = unsafePerformIO $ (cast2 ATen.bitwise_or_ts) _self _other++bitwise_or_st+  :: Float -- ^ self+  -> Tensor -- ^ other+  -> Tensor+bitwise_or_st _self _other = unsafePerformIO $ (cast2 ATen.bitwise_or_st) _self _other++bitwise_or_tt+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+bitwise_or_tt _self _other = unsafePerformIO $ (cast2 ATen.bitwise_or_tt) _self _other++bitwiseXorScalar+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> Tensor+bitwiseXorScalar _self _other = unsafePerformIO $ (cast2 ATen.bitwise_xor_ts) _self _other++bitwise_xor_st+  :: Float -- ^ self+  -> Tensor -- ^ other+  -> Tensor+bitwise_xor_st _self _other = unsafePerformIO $ (cast2 ATen.bitwise_xor_st) _self _other++bitwiseXor+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+bitwiseXor _self _other = unsafePerformIO $ (cast2 ATen.bitwise_xor_tt) _self _other++bitwise_left_shift_tt+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+bitwise_left_shift_tt _self _other = unsafePerformIO $ (cast2 ATen.bitwise_left_shift_tt) _self _other++bitwise_left_shift_ts+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> Tensor+bitwise_left_shift_ts _self _other = unsafePerformIO $ (cast2 ATen.bitwise_left_shift_ts) _self _other++bitwise_left_shift_st+  :: Float -- ^ self+  -> Tensor -- ^ other+  -> Tensor+bitwise_left_shift_st _self _other = unsafePerformIO $ (cast2 ATen.bitwise_left_shift_st) _self _other++bitwise_right_shift_tt+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+bitwise_right_shift_tt _self _other = unsafePerformIO $ (cast2 ATen.bitwise_right_shift_tt) _self _other++bitwise_right_shift_ts+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> Tensor+bitwise_right_shift_ts _self _other = unsafePerformIO $ (cast2 ATen.bitwise_right_shift_ts) _self _other++bitwise_right_shift_st+  :: Float -- ^ self+  -> Tensor -- ^ other+  -> Tensor+bitwise_right_shift_st _self _other = unsafePerformIO $ (cast2 ATen.bitwise_right_shift_st) _self _other++addbmm+  :: Tensor -- ^ self+  -> Tensor -- ^ batch1+  -> Tensor -- ^ batch2+  -> Float -- ^ beta+  -> Float -- ^ alpha+  -> Tensor+addbmm _self _batch1 _batch2 _beta _alpha = unsafePerformIO $ (cast5 ATen.addbmm_tttss) _self _batch1 _batch2 _beta _alpha++diag+  :: Tensor -- ^ self+  -> Int -- ^ diagonal+  -> Tensor+diag _self _diagonal = unsafePerformIO $ (cast2 ATen.diag_tl) _self _diagonal++cross+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Int -- ^ dim+  -> Tensor+cross _self _other _dim = unsafePerformIO $ (cast3 ATen.cross_ttl) _self _other _dim++triu+  :: Tensor -- ^ self+  -> Int -- ^ diagonal+  -> Tensor+triu _self _diagonal = unsafePerformIO $ (cast2 ATen.triu_tl) _self _diagonal++tril+  :: Tensor -- ^ self+  -> Int -- ^ diagonal+  -> Tensor+tril _self _diagonal = unsafePerformIO $ (cast2 ATen.tril_tl) _self _diagonal++trace+  :: Tensor -- ^ self+  -> Tensor+trace _self = unsafePerformIO $ (cast1 ATen.trace_t) _self++neScalar+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> Tensor+neScalar _self _other = unsafePerformIO $ (cast2 ATen.ne_ts) _self _other++ne+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+ne _self _other = unsafePerformIO $ (cast2 ATen.ne_tt) _self _other++not_equal_ts+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> Tensor+not_equal_ts _self _other = unsafePerformIO $ (cast2 ATen.not_equal_ts) _self _other++not_equal_tt+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+not_equal_tt _self _other = unsafePerformIO $ (cast2 ATen.not_equal_tt) _self _other++eqScalar+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> Tensor+eqScalar _self _other = unsafePerformIO $ (cast2 ATen.eq_ts) _self _other++eq+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+eq _self _other = unsafePerformIO $ (cast2 ATen.eq_tt) _self _other++geScalar+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> Tensor+geScalar _self _other = unsafePerformIO $ (cast2 ATen.ge_ts) _self _other++ge+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+ge _self _other = unsafePerformIO $ (cast2 ATen.ge_tt) _self _other++greater_equal_ts+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> Tensor+greater_equal_ts _self _other = unsafePerformIO $ (cast2 ATen.greater_equal_ts) _self _other++greater_equal_tt+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+greater_equal_tt _self _other = unsafePerformIO $ (cast2 ATen.greater_equal_tt) _self _other++leScalar+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> Tensor+leScalar _self _other = unsafePerformIO $ (cast2 ATen.le_ts) _self _other++le+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+le _self _other = unsafePerformIO $ (cast2 ATen.le_tt) _self _other++less_equal_ts+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> Tensor+less_equal_ts _self _other = unsafePerformIO $ (cast2 ATen.less_equal_ts) _self _other++less_equal_tt+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+less_equal_tt _self _other = unsafePerformIO $ (cast2 ATen.less_equal_tt) _self _other++gtScalar+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> Tensor+gtScalar _self _other = unsafePerformIO $ (cast2 ATen.gt_ts) _self _other++gt+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+gt _self _other = unsafePerformIO $ (cast2 ATen.gt_tt) _self _other++greater_ts+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> Tensor+greater_ts _self _other = unsafePerformIO $ (cast2 ATen.greater_ts) _self _other++greater_tt+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+greater_tt _self _other = unsafePerformIO $ (cast2 ATen.greater_tt) _self _other++ltScalar+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> Tensor+ltScalar _self _other = unsafePerformIO $ (cast2 ATen.lt_ts) _self _other++lt+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+lt _self _other = unsafePerformIO $ (cast2 ATen.lt_tt) _self _other++less_ts+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> Tensor+less_ts _self _other = unsafePerformIO $ (cast2 ATen.less_ts) _self _other++less_tt+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+less_tt _self _other = unsafePerformIO $ (cast2 ATen.less_tt) _self _other++take+  :: Tensor -- ^ self+  -> Tensor -- ^ index+  -> Tensor+take _self _index = unsafePerformIO $ (cast2 ATen.take_tt) _self _index++take_along_dim+  :: Tensor -- ^ self+  -> Tensor -- ^ indices+  -> Int -- ^ dim+  -> Tensor+take_along_dim _self _indices _dim = unsafePerformIO $ (cast3 ATen.take_along_dim_ttl) _self _indices _dim++indexSelect+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Tensor -- ^ index+  -> Tensor+indexSelect _self _dim _index = unsafePerformIO $ (cast3 ATen.index_select_tlt) _self _dim _index++indexSelectWithDimname+  :: Tensor -- ^ self+  -> Dimname -- ^ dim+  -> Tensor -- ^ index+  -> Tensor+indexSelectWithDimname _self _dim _index = unsafePerformIO $ (cast3 ATen.index_select_tnt) _self _dim _index++masked_select+  :: Tensor -- ^ self+  -> Tensor -- ^ mask+  -> Tensor+masked_select _self _mask = unsafePerformIO $ (cast2 ATen.masked_select_tt) _self _mask++nonzero+  :: Tensor -- ^ self+  -> Tensor+nonzero _self = unsafePerformIO $ (cast1 ATen.nonzero_t) _self++nonzero_numpy+  :: Tensor -- ^ self+  -> [Tensor]+nonzero_numpy _self = unsafePerformIO $ (cast1 ATen.nonzero_numpy_t) _self++argwhere+  :: Tensor -- ^ self+  -> Tensor+argwhere _self = unsafePerformIO $ (cast1 ATen.argwhere_t) _self++gather+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Tensor -- ^ index+  -> Bool -- ^ sparse_grad+  -> Tensor+gather _self _dim _index _sparse_grad = unsafePerformIO $ (cast4 ATen.gather_tltb) _self _dim _index _sparse_grad++gatherWithDimname+  :: Tensor -- ^ self+  -> Dimname -- ^ dim+  -> Tensor -- ^ index+  -> Bool -- ^ sparse_grad+  -> Tensor+gatherWithDimname _self _dim _index _sparse_grad = unsafePerformIO $ (cast4 ATen.gather_tntb) _self _dim _index _sparse_grad++addcmul+  :: Tensor -- ^ self+  -> Tensor -- ^ tensor1+  -> Tensor -- ^ tensor2+  -> Float -- ^ value+  -> Tensor+addcmul _self _tensor1 _tensor2 _value = unsafePerformIO $ (cast4 ATen.addcmul_ttts) _self _tensor1 _tensor2 _value++addcdiv+  :: Tensor -- ^ self+  -> Tensor -- ^ tensor1+  -> Tensor -- ^ tensor2+  -> Float -- ^ value+  -> Tensor+addcdiv _self _tensor1 _tensor2 _value = unsafePerformIO $ (cast4 ATen.addcdiv_ttts) _self _tensor1 _tensor2 _value++cross_entropy_loss+  :: Tensor -- ^ self+  -> Tensor -- ^ target+  -> Tensor -- ^ weight+  -> Int -- ^ reduction+  -> Int -- ^ ignore_index+  -> Double -- ^ label_smoothing+  -> Tensor+cross_entropy_loss _self _target _weight _reduction _ignore_index _label_smoothing = unsafePerformIO $ (cast6 ATen.cross_entropy_loss_tttlld) _self _target _weight _reduction _ignore_index _label_smoothing++triangular_solve+  :: Tensor -- ^ self+  -> Tensor -- ^ A+  -> Bool -- ^ upper+  -> Bool -- ^ transpose+  -> Bool -- ^ unitriangular+  -> (Tensor,Tensor)+triangular_solve _self _A _upper _transpose _unitriangular = unsafePerformIO $ (cast5 ATen.triangular_solve_ttbbb) _self _A _upper _transpose _unitriangular++linalg_solve_triangular+  :: Tensor -- ^ self+  -> Tensor -- ^ B+  -> Bool -- ^ upper+  -> Bool -- ^ left+  -> Bool -- ^ unitriangular+  -> Tensor+linalg_solve_triangular _self _B _upper _left _unitriangular = unsafePerformIO $ (cast5 ATen.linalg_solve_triangular_ttbbb) _self _B _upper _left _unitriangular++linalg_vander+  :: Tensor -- ^ x+  -> Int -- ^ N+  -> Tensor+linalg_vander _x _N = unsafePerformIO $ (cast2 ATen.linalg_vander_tl) _x _N++svd+  :: Tensor -- ^ self+  -> Bool -- ^ some+  -> Bool -- ^ compute_uv+  -> (Tensor,Tensor,Tensor)+svd _self _some _compute_uv = unsafePerformIO $ (cast3 ATen.svd_tbb) _self _some _compute_uv++swapaxes+  :: Tensor -- ^ self+  -> Int -- ^ axis0+  -> Int -- ^ axis1+  -> Tensor+swapaxes _self _axis0 _axis1 = unsafePerformIO $ (cast3 ATen.swapaxes_tll) _self _axis0 _axis1++swapdims+  :: Tensor -- ^ self+  -> Int -- ^ dim0+  -> Int -- ^ dim1+  -> Tensor+swapdims _self _dim0 _dim1 = unsafePerformIO $ (cast3 ATen.swapdims_tll) _self _dim0 _dim1++cholesky+  :: Tensor -- ^ self+  -> Bool -- ^ upper+  -> Tensor+cholesky _self _upper = unsafePerformIO $ (cast2 ATen.cholesky_tb) _self _upper++cholesky_solve+  :: Tensor -- ^ self+  -> Tensor -- ^ input2+  -> Bool -- ^ upper+  -> Tensor+cholesky_solve _self _input2 _upper = unsafePerformIO $ (cast3 ATen.cholesky_solve_ttb) _self _input2 _upper++cholesky_inverse+  :: Tensor -- ^ self+  -> Bool -- ^ upper+  -> Tensor+cholesky_inverse _self _upper = unsafePerformIO $ (cast2 ATen.cholesky_inverse_tb) _self _upper++qr+  :: Tensor -- ^ self+  -> Bool -- ^ some+  -> (Tensor,Tensor)+qr _self _some = unsafePerformIO $ (cast2 ATen.qr_tb) _self _some++geqrf+  :: Tensor -- ^ self+  -> (Tensor,Tensor)+geqrf _self = unsafePerformIO $ (cast1 ATen.geqrf_t) _self++orgqr+  :: Tensor -- ^ self+  -> Tensor -- ^ input2+  -> Tensor+orgqr _self _input2 = unsafePerformIO $ (cast2 ATen.orgqr_tt) _self _input2++ormqr+  :: Tensor -- ^ self+  -> Tensor -- ^ input2+  -> Tensor -- ^ input3+  -> Bool -- ^ left+  -> Bool -- ^ transpose+  -> Tensor+ormqr _self _input2 _input3 _left _transpose = unsafePerformIO $ (cast5 ATen.ormqr_tttbb) _self _input2 _input3 _left _transpose++lu_solve+  :: Tensor -- ^ self+  -> Tensor -- ^ LU_data+  -> Tensor -- ^ LU_pivots+  -> Tensor+lu_solve _self _LU_data _LU_pivots = unsafePerformIO $ (cast3 ATen.lu_solve_ttt) _self _LU_data _LU_pivots++lu_unpack+  :: Tensor -- ^ LU_data+  -> Tensor -- ^ LU_pivots+  -> Bool -- ^ unpack_data+  -> Bool -- ^ unpack_pivots+  -> (Tensor,Tensor,Tensor)+lu_unpack _LU_data _LU_pivots _unpack_data _unpack_pivots = unsafePerformIO $ (cast4 ATen.lu_unpack_ttbb) _LU_data _LU_pivots _unpack_data _unpack_pivots++lgamma+  :: Tensor -- ^ self+  -> Tensor+lgamma _self = unsafePerformIO $ (cast1 ATen.lgamma_t) _self++digamma+  :: Tensor -- ^ self+  -> Tensor+digamma _self = unsafePerformIO $ (cast1 ATen.digamma_t) _self++polygamma+  :: Int -- ^ n+  -> Tensor -- ^ self+  -> Tensor+polygamma _n _self = unsafePerformIO $ (cast2 ATen.polygamma_lt) _n _self++erfinv+  :: Tensor -- ^ self+  -> Tensor+erfinv _self = unsafePerformIO $ (cast1 ATen.erfinv_t) _self++i0+  :: Tensor -- ^ self+  -> Tensor+i0 _self = unsafePerformIO $ (cast1 ATen.i0_t) _self++sign+  :: Tensor -- ^ self+  -> Tensor+sign _self = unsafePerformIO $ (cast1 ATen.sign_t) _self++signbit+  :: Tensor -- ^ self+  -> Tensor+signbit _self = unsafePerformIO $ (cast1 ATen.signbit_t) _self++dist+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Float -- ^ p+  -> Tensor+dist _self _other _p = unsafePerformIO $ (cast3 ATen.dist_tts) _self _other _p++atan2+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+atan2 _self _other = unsafePerformIO $ (cast2 ATen.atan2_tt) _self _other++arctan2+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+arctan2 _self _other = unsafePerformIO $ (cast2 ATen.arctan2_tt) _self _other++lerpScalar+  :: Tensor -- ^ self+  -> Tensor -- ^ end+  -> Float -- ^ weight+  -> Tensor+lerpScalar _self _end _weight = unsafePerformIO $ (cast3 ATen.lerp_tts) _self _end _weight++lerp+  :: Tensor -- ^ self+  -> Tensor -- ^ end+  -> Tensor -- ^ weight+  -> Tensor+lerp _self _end _weight = unsafePerformIO $ (cast3 ATen.lerp_ttt) _self _end _weight++histc+  :: Tensor -- ^ self+  -> Int -- ^ bins+  -> Float -- ^ min+  -> Float -- ^ max+  -> Tensor+histc _self _bins _min _max = unsafePerformIO $ (cast4 ATen.histc_tlss) _self _bins _min _max++histogram_tttb+  :: Tensor -- ^ self+  -> Tensor -- ^ bins+  -> Tensor -- ^ weight+  -> Bool -- ^ density+  -> (Tensor,Tensor)+histogram_tttb _self _bins _weight _density = unsafePerformIO $ (cast4 ATen.histogram_tttb) _self _bins _weight _density++histogram_tlatb+  :: Tensor -- ^ self+  -> Int -- ^ bins+  -> ([Double]) -- ^ range+  -> Tensor -- ^ weight+  -> Bool -- ^ density+  -> (Tensor,Tensor)+histogram_tlatb _self _bins _range _weight _density = unsafePerformIO $ (cast5 ATen.histogram_tlatb) _self _bins _range _weight _density++-- histogramdd_tlatb+--   :: Tensor -- ^ self+--   -> [Int] -- ^ bins+--   -> ([Double]) -- ^ range+--   -> Tensor -- ^ weight+--   -> Bool -- ^ density+--   -> (Tensor,[Tensor])+-- histogramdd_tlatb _self _bins _range _weight _density = unsafePerformIO $ (cast5 ATen.histogramdd_tlatb) _self _bins _range _weight _density++histogramdd_tlatb+  :: Tensor -- ^ self+  -> Int -- ^ bins+  -> ([Double]) -- ^ range+  -> Tensor -- ^ weight+  -> Bool -- ^ density+  -> (Tensor,[Tensor])+histogramdd_tlatb _self _bins _range _weight _density = unsafePerformIO $ (cast5 ATen.histogramdd_tlatb) _self _bins _range _weight _density++-- histogramdd_tlatb+--   :: Tensor -- ^ self+--   -> [Tensor] -- ^ bins+--   -> ([Double]) -- ^ range+--   -> Tensor -- ^ weight+--   -> Bool -- ^ density+--   -> (Tensor,[Tensor])+-- histogramdd_tlatb _self _bins _range _weight _density = unsafePerformIO $ (cast5 ATen.histogramdd_tlatb) _self _bins _range _weight _density++fmodScalar+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> Tensor+fmodScalar _self _other = unsafePerformIO $ (cast2 ATen.fmod_ts) _self _other++fmod+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+fmod _self _other = unsafePerformIO $ (cast2 ATen.fmod_tt) _self _other++hypot+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+hypot _self _other = unsafePerformIO $ (cast2 ATen.hypot_tt) _self _other++igamma+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+igamma _self _other = unsafePerformIO $ (cast2 ATen.igamma_tt) _self _other++igammac+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+igammac _self _other = unsafePerformIO $ (cast2 ATen.igammac_tt) _self _other++nextafter+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+nextafter _self _other = unsafePerformIO $ (cast2 ATen.nextafter_tt) _self _other++remainderScalar+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> Tensor+remainderScalar _self _other = unsafePerformIO $ (cast2 ATen.remainder_ts) _self _other++remainder+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+remainder _self _other = unsafePerformIO $ (cast2 ATen.remainder_tt) _self _other++remainder_st+  :: Float -- ^ self+  -> Tensor -- ^ other+  -> Tensor+remainder_st _self _other = unsafePerformIO $ (cast2 ATen.remainder_st) _self _other++minAll+  :: Tensor -- ^ self+  -> Tensor+minAll _self = unsafePerformIO $ (cast1 ATen.min_t) _self++fmin+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+fmin _self _other = unsafePerformIO $ (cast2 ATen.fmin_tt) _self _other++maxAll+  :: Tensor -- ^ self+  -> Tensor+maxAll _self = unsafePerformIO $ (cast1 ATen.max_t) _self++fmax+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+fmax _self _other = unsafePerformIO $ (cast2 ATen.fmax_tt) _self _other++maximum+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+maximum _self _other = unsafePerformIO $ (cast2 ATen.maximum_tt) _self _other++max+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+max _self _other = unsafePerformIO $ (cast2 ATen.max_tt) _self _other++minimum+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+minimum _self _other = unsafePerformIO $ (cast2 ATen.minimum_tt) _self _other++min+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+min _self _other = unsafePerformIO $ (cast2 ATen.min_tt) _self _other++quantile_ttlbs+  :: Tensor -- ^ self+  -> Tensor -- ^ q+  -> Int -- ^ dim+  -> Bool -- ^ keepdim+  -> String -- ^ interpolation+  -> Tensor+quantile_ttlbs _self _q _dim _keepdim _interpolation = unsafePerformIO $ (cast5 ATen.quantile_ttlbs) _self _q _dim _keepdim _interpolation++quantile_tdlbs+  :: Tensor -- ^ self+  -> Double -- ^ q+  -> Int -- ^ dim+  -> Bool -- ^ keepdim+  -> String -- ^ interpolation+  -> Tensor+quantile_tdlbs _self _q _dim _keepdim _interpolation = unsafePerformIO $ (cast5 ATen.quantile_tdlbs) _self _q _dim _keepdim _interpolation++nanquantile_ttlbs+  :: Tensor -- ^ self+  -> Tensor -- ^ q+  -> Int -- ^ dim+  -> Bool -- ^ keepdim+  -> String -- ^ interpolation+  -> Tensor+nanquantile_ttlbs _self _q _dim _keepdim _interpolation = unsafePerformIO $ (cast5 ATen.nanquantile_ttlbs) _self _q _dim _keepdim _interpolation++nanquantile_tdlbs+  :: Tensor -- ^ self+  -> Double -- ^ q+  -> Int -- ^ dim+  -> Bool -- ^ keepdim+  -> String -- ^ interpolation+  -> Tensor+nanquantile_tdlbs _self _q _dim _keepdim _interpolation = unsafePerformIO $ (cast5 ATen.nanquantile_tdlbs) _self _q _dim _keepdim _interpolation++sort+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Bool -- ^ descending+  -> (Tensor,Tensor)+sort _self _dim _descending = unsafePerformIO $ (cast3 ATen.sort_tlb) _self _dim _descending++sort_tblb+  :: Tensor -- ^ self+  -> Bool -- ^ stable+  -> Int -- ^ dim+  -> Bool -- ^ descending+  -> (Tensor,Tensor)+sort_tblb _self _stable _dim _descending = unsafePerformIO $ (cast4 ATen.sort_tblb) _self _stable _dim _descending++sortWithDimname+  :: Tensor -- ^ self+  -> Dimname -- ^ dim+  -> Bool -- ^ descending+  -> (Tensor,Tensor)+sortWithDimname _self _dim _descending = unsafePerformIO $ (cast3 ATen.sort_tnb) _self _dim _descending++sort_tbnb+  :: Tensor -- ^ self+  -> Bool -- ^ stable+  -> Dimname -- ^ dim+  -> Bool -- ^ descending+  -> (Tensor,Tensor)+sort_tbnb _self _stable _dim _descending = unsafePerformIO $ (cast4 ATen.sort_tbnb) _self _stable _dim _descending++msort+  :: Tensor -- ^ self+  -> Tensor+msort _self = unsafePerformIO $ (cast1 ATen.msort_t) _self++argsort+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Bool -- ^ descending+  -> Tensor+argsort _self _dim _descending = unsafePerformIO $ (cast3 ATen.argsort_tlb) _self _dim _descending++argsort_tblb+  :: Tensor -- ^ self+  -> Bool -- ^ stable+  -> Int -- ^ dim+  -> Bool -- ^ descending+  -> Tensor+argsort_tblb _self _stable _dim _descending = unsafePerformIO $ (cast4 ATen.argsort_tblb) _self _stable _dim _descending++argsortWithDimname+  :: Tensor -- ^ self+  -> Dimname -- ^ dim+  -> Bool -- ^ descending+  -> Tensor+argsortWithDimname _self _dim _descending = unsafePerformIO $ (cast3 ATen.argsort_tnb) _self _dim _descending++topk+  :: Tensor -- ^ self+  -> Int -- ^ k+  -> Int -- ^ dim+  -> Bool -- ^ largest+  -> Bool -- ^ sorted+  -> (Tensor,Tensor)+topk _self _k _dim _largest _sorted = unsafePerformIO $ (cast5 ATen.topk_tllbb) _self _k _dim _largest _sorted++all+  :: Tensor -- ^ self+  -> Tensor+all _self = unsafePerformIO $ (cast1 ATen.all_t) _self++any+  :: Tensor -- ^ self+  -> Tensor+any _self = unsafePerformIO $ (cast1 ATen.any_t) _self++renorm+  :: Tensor -- ^ self+  -> Float -- ^ p+  -> Int -- ^ dim+  -> Float -- ^ maxnorm+  -> Tensor+renorm _self _p _dim _maxnorm = unsafePerformIO $ (cast4 ATen.renorm_tsls) _self _p _dim _maxnorm++equal+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Bool+equal _self _other = unsafePerformIO $ (cast2 ATen.equal_tt) _self _other++pow+  :: Tensor -- ^ self+  -> Tensor -- ^ exponent+  -> Tensor+pow _self _exponent = unsafePerformIO $ (cast2 ATen.pow_tt) _self _exponent++powScalar'+  :: Float -- ^ self+  -> Tensor -- ^ exponent+  -> Tensor+powScalar' _self _exponent = unsafePerformIO $ (cast2 ATen.pow_st) _self _exponent++powScalar+  :: Tensor -- ^ self+  -> Float -- ^ exponent+  -> Tensor+powScalar _self _exponent = unsafePerformIO $ (cast2 ATen.pow_ts) _self _exponent++float_power_tt+  :: Tensor -- ^ self+  -> Tensor -- ^ exponent+  -> Tensor+float_power_tt _self _exponent = unsafePerformIO $ (cast2 ATen.float_power_tt) _self _exponent++float_power_st+  :: Float -- ^ self+  -> Tensor -- ^ exponent+  -> Tensor+float_power_st _self _exponent = unsafePerformIO $ (cast2 ATen.float_power_st) _self _exponent++float_power_ts+  :: Tensor -- ^ self+  -> Float -- ^ exponent+  -> Tensor+float_power_ts _self _exponent = unsafePerformIO $ (cast2 ATen.float_power_ts) _self _exponent++alias+  :: Tensor -- ^ self+  -> Tensor+alias _self = unsafePerformIO $ (cast1 ATen.alias_t) _self++bucketize_ttbb+  :: Tensor -- ^ self+  -> Tensor -- ^ boundaries+  -> Bool -- ^ out_int32+  -> Bool -- ^ right+  -> Tensor+bucketize_ttbb _self _boundaries _out_int32 _right = unsafePerformIO $ (cast4 ATen.bucketize_ttbb) _self _boundaries _out_int32 _right++bucketize_stbb+  :: Float -- ^ self+  -> Tensor -- ^ boundaries+  -> Bool -- ^ out_int32+  -> Bool -- ^ right+  -> Tensor+bucketize_stbb _self _boundaries _out_int32 _right = unsafePerformIO $ (cast4 ATen.bucketize_stbb) _self _boundaries _out_int32 _right++searchsorted_ttbbst+  :: Tensor -- ^ sorted_sequence+  -> Tensor -- ^ self+  -> Bool -- ^ out_int32+  -> Bool -- ^ right+  -> String -- ^ side+  -> Tensor -- ^ sorter+  -> Tensor+searchsorted_ttbbst _sorted_sequence _self _out_int32 _right _side _sorter = unsafePerformIO $ (cast6 ATen.searchsorted_ttbbst) _sorted_sequence _self _out_int32 _right _side _sorter++searchsorted_tsbbst+  :: Tensor -- ^ sorted_sequence+  -> Float -- ^ self+  -> Bool -- ^ out_int32+  -> Bool -- ^ right+  -> String -- ^ side+  -> Tensor -- ^ sorter+  -> Tensor+searchsorted_tsbbst _sorted_sequence _self _out_int32 _right _side _sorter = unsafePerformIO $ (cast6 ATen.searchsorted_tsbbst) _sorted_sequence _self _out_int32 _right _side _sorter++mse_loss+  :: Tensor -- ^ self+  -> Tensor -- ^ target+  -> Int -- ^ reduction+  -> Tensor+mse_loss _self _target _reduction = unsafePerformIO $ (cast3 ATen.mse_loss_ttl) _self _target _reduction++l1_loss+  :: Tensor -- ^ self+  -> Tensor -- ^ target+  -> Int -- ^ reduction+  -> Tensor+l1_loss _self _target _reduction = unsafePerformIO $ (cast3 ATen.l1_loss_ttl) _self _target _reduction++multi_margin_loss+  :: Tensor -- ^ self+  -> Tensor -- ^ target+  -> Float -- ^ p+  -> Float -- ^ margin+  -> Tensor -- ^ weight+  -> Int -- ^ reduction+  -> Tensor+multi_margin_loss _self _target _p _margin _weight _reduction = unsafePerformIO $ (cast6 ATen.multi_margin_loss_ttsstl) _self _target _p _margin _weight _reduction++multilabel_margin_loss+  :: Tensor -- ^ self+  -> Tensor -- ^ target+  -> Int -- ^ reduction+  -> Tensor+multilabel_margin_loss _self _target _reduction = unsafePerformIO $ (cast3 ATen.multilabel_margin_loss_ttl) _self _target _reduction++multilabel_margin_loss_forward+  :: Tensor -- ^ self+  -> Tensor -- ^ target+  -> Int -- ^ reduction+  -> (Tensor,Tensor)+multilabel_margin_loss_forward _self _target _reduction = unsafePerformIO $ (cast3 ATen.multilabel_margin_loss_forward_ttl) _self _target _reduction++nll_loss_nd+  :: Tensor -- ^ self+  -> Tensor -- ^ target+  -> Tensor -- ^ weight+  -> Int -- ^ reduction+  -> Int -- ^ ignore_index+  -> Tensor+nll_loss_nd _self _target _weight _reduction _ignore_index = unsafePerformIO $ (cast5 ATen.nll_loss_nd_tttll) _self _target _weight _reduction _ignore_index++nll_loss+  :: Tensor -- ^ self+  -> Tensor -- ^ target+  -> Tensor -- ^ weight+  -> Int -- ^ reduction+  -> Int -- ^ ignore_index+  -> Tensor+nll_loss _self _target _weight _reduction _ignore_index = unsafePerformIO $ (cast5 ATen.nll_loss_tttll) _self _target _weight _reduction _ignore_index++nll_loss_forward+  :: Tensor -- ^ self+  -> Tensor -- ^ target+  -> Tensor -- ^ weight+  -> Int -- ^ reduction+  -> Int -- ^ ignore_index+  -> (Tensor,Tensor)+nll_loss_forward _self _target _weight _reduction _ignore_index = unsafePerformIO $ (cast5 ATen.nll_loss_forward_tttll) _self _target _weight _reduction _ignore_index++nll_loss2d+  :: Tensor -- ^ self+  -> Tensor -- ^ target+  -> Tensor -- ^ weight+  -> Int -- ^ reduction+  -> Int -- ^ ignore_index+  -> Tensor+nll_loss2d _self _target _weight _reduction _ignore_index = unsafePerformIO $ (cast5 ATen.nll_loss2d_tttll) _self _target _weight _reduction _ignore_index++nll_loss2d_forward+  :: Tensor -- ^ self+  -> Tensor -- ^ target+  -> Tensor -- ^ weight+  -> Int -- ^ reduction+  -> Int -- ^ ignore_index+  -> (Tensor,Tensor)+nll_loss2d_forward _self _target _weight _reduction _ignore_index = unsafePerformIO $ (cast5 ATen.nll_loss2d_forward_tttll) _self _target _weight _reduction _ignore_index++smooth_l1_loss+  :: Tensor -- ^ self+  -> Tensor -- ^ target+  -> Int -- ^ reduction+  -> Double -- ^ beta+  -> Tensor+smooth_l1_loss _self _target _reduction _beta = unsafePerformIO $ (cast4 ATen.smooth_l1_loss_ttld) _self _target _reduction _beta++huber_loss+  :: Tensor -- ^ self+  -> Tensor -- ^ target+  -> Int -- ^ reduction+  -> Double -- ^ delta+  -> Tensor+huber_loss _self _target _reduction _delta = unsafePerformIO $ (cast4 ATen.huber_loss_ttld) _self _target _reduction _delta++soft_margin_loss+  :: Tensor -- ^ self+  -> Tensor -- ^ target+  -> Int -- ^ reduction+  -> Tensor+soft_margin_loss _self _target _reduction = unsafePerformIO $ (cast3 ATen.soft_margin_loss_ttl) _self _target _reduction++elu+  :: Tensor -- ^ self+  -> Float -- ^ alpha+  -> Float -- ^ scale+  -> Float -- ^ input_scale+  -> Tensor+elu _self _alpha _scale _input_scale = unsafePerformIO $ (cast4 ATen.elu_tsss) _self _alpha _scale _input_scale++glu+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Tensor+glu _self _dim = unsafePerformIO $ (cast2 ATen.glu_tl) _self _dim++glu_jvp+  :: Tensor -- ^ glu+  -> Tensor -- ^ x+  -> Tensor -- ^ dx+  -> Int -- ^ dim+  -> Tensor+glu_jvp _glu _x _dx _dim = unsafePerformIO $ (cast4 ATen.glu_jvp_tttl) _glu _x _dx _dim++glu_backward_jvp+  :: Tensor -- ^ grad_x+  -> Tensor -- ^ grad_glu+  -> Tensor -- ^ x+  -> Tensor -- ^ dgrad_glu+  -> Tensor -- ^ dx+  -> Int -- ^ dim+  -> Tensor+glu_backward_jvp _grad_x _grad_glu _x _dgrad_glu _dx _dim = unsafePerformIO $ (cast6 ATen.glu_backward_jvp_tttttl) _grad_x _grad_glu _x _dgrad_glu _dx _dim++hardsigmoid+  :: Tensor -- ^ self+  -> Tensor+hardsigmoid _self = unsafePerformIO $ (cast1 ATen.hardsigmoid_t) _self++hardtanh+  :: Tensor -- ^ self+  -> Float -- ^ min_val+  -> Float -- ^ max_val+  -> Tensor+hardtanh _self _min_val _max_val = unsafePerformIO $ (cast3 ATen.hardtanh_tss) _self _min_val _max_val++hardswish+  :: Tensor -- ^ self+  -> Tensor+hardswish _self = unsafePerformIO $ (cast1 ATen.hardswish_t) _self++leaky_relu+  :: Tensor -- ^ self+  -> Float -- ^ negative_slope+  -> Tensor+leaky_relu _self _negative_slope = unsafePerformIO $ (cast2 ATen.leaky_relu_ts) _self _negative_slope++log_sigmoid+  :: Tensor -- ^ self+  -> Tensor+log_sigmoid _self = unsafePerformIO $ (cast1 ATen.log_sigmoid_t) _self++log_sigmoid_forward+  :: Tensor -- ^ self+  -> (Tensor,Tensor)+log_sigmoid_forward _self = unsafePerformIO $ (cast1 ATen.log_sigmoid_forward_t) _self++softplus+  :: Tensor -- ^ self+  -> Float -- ^ beta+  -> Float -- ^ threshold+  -> Tensor+softplus _self _beta _threshold = unsafePerformIO $ (cast3 ATen.softplus_tss) _self _beta _threshold++softshrink+  :: Tensor -- ^ self+  -> Float -- ^ lambd+  -> Tensor+softshrink _self _lambd = unsafePerformIO $ (cast2 ATen.softshrink_ts) _self _lambd++adaptive_avg_pool2d+  :: Tensor -- ^ self+  -> (Int,Int) -- ^ output_size+  -> Tensor+adaptive_avg_pool2d _self _output_size = unsafePerformIO $ (cast2 ATen.adaptive_avg_pool2d_tl) _self _output_size++mkldnn_adaptive_avg_pool2d+  :: Tensor -- ^ self+  -> (Int,Int) -- ^ output_size+  -> Tensor+mkldnn_adaptive_avg_pool2d _self _output_size = unsafePerformIO $ (cast2 ATen.mkldnn_adaptive_avg_pool2d_tl) _self _output_size++adaptive_avg_pool3d+  :: Tensor -- ^ self+  -> (Int,Int,Int) -- ^ output_size+  -> Tensor+adaptive_avg_pool3d _self _output_size = unsafePerformIO $ (cast2 ATen.adaptive_avg_pool3d_tl) _self _output_size++adaptive_max_pool2d+  :: Tensor -- ^ self+  -> (Int,Int) -- ^ output_size+  -> (Tensor,Tensor)+adaptive_max_pool2d _self _output_size = unsafePerformIO $ (cast2 ATen.adaptive_max_pool2d_tl) _self _output_size++adaptive_max_pool3d+  :: Tensor -- ^ self+  -> (Int,Int,Int) -- ^ output_size+  -> (Tensor,Tensor)+adaptive_max_pool3d _self _output_size = unsafePerformIO $ (cast2 ATen.adaptive_max_pool3d_tl) _self _output_size++avg_pool2d+  :: Tensor -- ^ self+  -> (Int,Int) -- ^ kernel_size+  -> (Int,Int) -- ^ stride+  -> (Int,Int) -- ^ padding+  -> Bool -- ^ ceil_mode+  -> Bool -- ^ count_include_pad+  -> Int -- ^ divisor_override+  -> Tensor+avg_pool2d _self _kernel_size _stride _padding _ceil_mode _count_include_pad _divisor_override = unsafePerformIO $ (cast7 ATen.avg_pool2d_tlllbbl) _self _kernel_size _stride _padding _ceil_mode _count_include_pad _divisor_override++avg_pool3d+  :: Tensor -- ^ self+  -> (Int,Int,Int) -- ^ kernel_size+  -> (Int,Int,Int) -- ^ stride+  -> (Int,Int,Int) -- ^ padding+  -> Bool -- ^ ceil_mode+  -> Bool -- ^ count_include_pad+  -> Int -- ^ divisor_override+  -> Tensor+avg_pool3d _self _kernel_size _stride _padding _ceil_mode _count_include_pad _divisor_override = unsafePerformIO $ (cast7 ATen.avg_pool3d_tlllbbl) _self _kernel_size _stride _padding _ceil_mode _count_include_pad _divisor_override++fractional_max_pool2d+  :: Tensor -- ^ self+  -> (Int,Int) -- ^ kernel_size+  -> (Int,Int) -- ^ output_size+  -> Tensor -- ^ random_samples+  -> (Tensor,Tensor)+fractional_max_pool2d _self _kernel_size _output_size _random_samples = unsafePerformIO $ (cast4 ATen.fractional_max_pool2d_tllt) _self _kernel_size _output_size _random_samples++fractional_max_pool3d+  :: Tensor -- ^ self+  -> (Int,Int,Int) -- ^ kernel_size+  -> (Int,Int,Int) -- ^ output_size+  -> Tensor -- ^ random_samples+  -> (Tensor,Tensor)+fractional_max_pool3d _self _kernel_size _output_size _random_samples = unsafePerformIO $ (cast4 ATen.fractional_max_pool3d_tllt) _self _kernel_size _output_size _random_samples++max_pool2d_with_indices+  :: Tensor -- ^ self+  -> (Int,Int) -- ^ kernel_size+  -> (Int,Int) -- ^ stride+  -> (Int,Int) -- ^ padding+  -> (Int,Int) -- ^ dilation+  -> Bool -- ^ ceil_mode+  -> (Tensor,Tensor)+max_pool2d_with_indices _self _kernel_size _stride _padding _dilation _ceil_mode = unsafePerformIO $ (cast6 ATen.max_pool2d_with_indices_tllllb) _self _kernel_size _stride _padding _dilation _ceil_mode++max_pool3d_with_indices+  :: Tensor -- ^ self+  -> (Int,Int,Int) -- ^ kernel_size+  -> (Int,Int,Int) -- ^ stride+  -> (Int,Int,Int) -- ^ padding+  -> (Int,Int,Int) -- ^ dilation+  -> Bool -- ^ ceil_mode+  -> (Tensor,Tensor)+max_pool3d_with_indices _self _kernel_size _stride _padding _dilation _ceil_mode = unsafePerformIO $ (cast6 ATen.max_pool3d_with_indices_tllllb) _self _kernel_size _stride _padding _dilation _ceil_mode++max_unpool2d+  :: Tensor -- ^ self+  -> Tensor -- ^ indices+  -> (Int,Int) -- ^ output_size+  -> Tensor+max_unpool2d _self _indices _output_size = unsafePerformIO $ (cast3 ATen.max_unpool2d_ttl) _self _indices _output_size++max_unpool3d+  :: Tensor -- ^ self+  -> Tensor -- ^ indices+  -> (Int,Int,Int) -- ^ output_size+  -> (Int,Int,Int) -- ^ stride+  -> (Int,Int,Int) -- ^ padding+  -> Tensor+max_unpool3d _self _indices _output_size _stride _padding = unsafePerformIO $ (cast5 ATen.max_unpool3d_ttlll) _self _indices _output_size _stride _padding++reflection_pad1d+  :: Tensor -- ^ self+  -> (Int,Int) -- ^ padding+  -> Tensor+reflection_pad1d _self _padding = unsafePerformIO $ (cast2 ATen.reflection_pad1d_tl) _self _padding++reflection_pad2d+  :: Tensor -- ^ self+  -> (Int,Int,Int,Int) -- ^ padding+  -> Tensor+reflection_pad2d _self _padding = unsafePerformIO $ (cast2 ATen.reflection_pad2d_tl) _self _padding++reflection_pad3d+  :: Tensor -- ^ self+  -> (Int,Int,Int,Int,Int,Int) -- ^ padding+  -> Tensor+reflection_pad3d _self _padding = unsafePerformIO $ (cast2 ATen.reflection_pad3d_tl) _self _padding++replication_pad1d+  :: Tensor -- ^ self+  -> (Int,Int) -- ^ padding+  -> Tensor+replication_pad1d _self _padding = unsafePerformIO $ (cast2 ATen.replication_pad1d_tl) _self _padding++replication_pad2d+  :: Tensor -- ^ self+  -> (Int,Int,Int,Int) -- ^ padding+  -> Tensor+replication_pad2d _self _padding = unsafePerformIO $ (cast2 ATen.replication_pad2d_tl) _self _padding++replication_pad3d+  :: Tensor -- ^ self+  -> (Int,Int,Int,Int,Int,Int) -- ^ padding+  -> Tensor+replication_pad3d _self _padding = unsafePerformIO $ (cast2 ATen.replication_pad3d_tl) _self _padding++pad+  :: Tensor -- ^ self+  -> [Int] -- ^ pad+  -> String -- ^ mode+  -> Double -- ^ value+  -> Tensor+pad _self _pad _mode _value = unsafePerformIO $ (cast4 ATen.pad_tlsd) _self _pad _mode _value++upsample_linear1d_tlba+  :: Tensor -- ^ input+  -> [Int] -- ^ output_size+  -> Bool -- ^ align_corners+  -> ([Double]) -- ^ scale_factors+  -> Tensor+upsample_linear1d_tlba _input _output_size _align_corners _scale_factors = unsafePerformIO $ (cast4 ATen.upsample_linear1d_tlba) _input _output_size _align_corners _scale_factors++upsample_bilinear2d_tlba+  :: Tensor -- ^ input+  -> [Int] -- ^ output_size+  -> Bool -- ^ align_corners+  -> ([Double]) -- ^ scale_factors+  -> Tensor+upsample_bilinear2d_tlba _input _output_size _align_corners _scale_factors = unsafePerformIO $ (cast4 ATen.upsample_bilinear2d_tlba) _input _output_size _align_corners _scale_factors++upsample_trilinear3d_tlba+  :: Tensor -- ^ input+  -> [Int] -- ^ output_size+  -> Bool -- ^ align_corners+  -> ([Double]) -- ^ scale_factors+  -> Tensor+upsample_trilinear3d_tlba _input _output_size _align_corners _scale_factors = unsafePerformIO $ (cast4 ATen.upsample_trilinear3d_tlba) _input _output_size _align_corners _scale_factors++upsample_bicubic2d_tlba+  :: Tensor -- ^ input+  -> [Int] -- ^ output_size+  -> Bool -- ^ align_corners+  -> ([Double]) -- ^ scale_factors+  -> Tensor+upsample_bicubic2d_tlba _input _output_size _align_corners _scale_factors = unsafePerformIO $ (cast4 ATen.upsample_bicubic2d_tlba) _input _output_size _align_corners _scale_factors++upsample_nearest1d_tla+  :: Tensor -- ^ input+  -> [Int] -- ^ output_size+  -> ([Double]) -- ^ scale_factors+  -> Tensor+upsample_nearest1d_tla _input _output_size _scale_factors = unsafePerformIO $ (cast3 ATen.upsample_nearest1d_tla) _input _output_size _scale_factors++upsample_nearest2d_tla+  :: Tensor -- ^ input+  -> [Int] -- ^ output_size+  -> ([Double]) -- ^ scale_factors+  -> Tensor+upsample_nearest2d_tla _input _output_size _scale_factors = unsafePerformIO $ (cast3 ATen.upsample_nearest2d_tla) _input _output_size _scale_factors++upsample_nearest3d_tla+  :: Tensor -- ^ input+  -> [Int] -- ^ output_size+  -> ([Double]) -- ^ scale_factors+  -> Tensor+upsample_nearest3d_tla _input _output_size _scale_factors = unsafePerformIO $ (cast3 ATen.upsample_nearest3d_tla) _input _output_size _scale_factors++-- upsample_linear1d_tlbd+--   :: Tensor -- ^ self+--   -> Int -- ^ output_size+--   -> Bool -- ^ align_corners+--   -> Double -- ^ scales+--   -> Tensor+-- upsample_linear1d_tlbd _self _output_size _align_corners _scales = unsafePerformIO $ (cast4 ATen.upsample_linear1d_tlbd) _self _output_size _align_corners _scales++upsample_bilinear2d_tlbdd+  :: Tensor -- ^ self+  -> (Int,Int) -- ^ output_size+  -> Bool -- ^ align_corners+  -> Double -- ^ scales_h+  -> Double -- ^ scales_w+  -> Tensor+upsample_bilinear2d_tlbdd _self _output_size _align_corners _scales_h _scales_w = unsafePerformIO $ (cast5 ATen.upsample_bilinear2d_tlbdd) _self _output_size _align_corners _scales_h _scales_w++upsample_bicubic2d_tlbdd+  :: Tensor -- ^ self+  -> (Int,Int) -- ^ output_size+  -> Bool -- ^ align_corners+  -> Double -- ^ scales_h+  -> Double -- ^ scales_w+  -> Tensor+upsample_bicubic2d_tlbdd _self _output_size _align_corners _scales_h _scales_w = unsafePerformIO $ (cast5 ATen.upsample_bicubic2d_tlbdd) _self _output_size _align_corners _scales_h _scales_w++upsample_trilinear3d_tlbddd+  :: Tensor -- ^ self+  -> (Int,Int,Int) -- ^ output_size+  -> Bool -- ^ align_corners+  -> Double -- ^ scales_d+  -> Double -- ^ scales_h+  -> Double -- ^ scales_w+  -> Tensor+upsample_trilinear3d_tlbddd _self _output_size _align_corners _scales_d _scales_h _scales_w = unsafePerformIO $ (cast6 ATen.upsample_trilinear3d_tlbddd) _self _output_size _align_corners _scales_d _scales_h _scales_w++-- upsample_nearest1d_tld+--   :: Tensor -- ^ self+--   -> Int -- ^ output_size+--   -> Double -- ^ scales+--   -> Tensor+-- upsample_nearest1d_tld _self _output_size _scales = unsafePerformIO $ (cast3 ATen.upsample_nearest1d_tld) _self _output_size _scales++upsample_nearest2d_tldd+  :: Tensor -- ^ self+  -> (Int,Int) -- ^ output_size+  -> Double -- ^ scales_h+  -> Double -- ^ scales_w+  -> Tensor+upsample_nearest2d_tldd _self _output_size _scales_h _scales_w = unsafePerformIO $ (cast4 ATen.upsample_nearest2d_tldd) _self _output_size _scales_h _scales_w++upsample_nearest3d_tlddd+  :: Tensor -- ^ self+  -> (Int,Int,Int) -- ^ output_size+  -> Double -- ^ scales_d+  -> Double -- ^ scales_h+  -> Double -- ^ scales_w+  -> Tensor+upsample_nearest3d_tlddd _self _output_size _scales_d _scales_h _scales_w = unsafePerformIO $ (cast5 ATen.upsample_nearest3d_tlddd) _self _output_size _scales_d _scales_h _scales_w++slow_conv_transpose2d+  :: Tensor -- ^ self+  -> Tensor -- ^ weight+  -> (Int,Int) -- ^ kernel_size+  -> Tensor -- ^ bias+  -> (Int,Int) -- ^ stride+  -> (Int,Int) -- ^ padding+  -> (Int,Int) -- ^ output_padding+  -> (Int,Int) -- ^ dilation+  -> Tensor+slow_conv_transpose2d _self _weight _kernel_size _bias _stride _padding _output_padding _dilation = unsafePerformIO $ (cast8 ATen.slow_conv_transpose2d_ttltllll) _self _weight _kernel_size _bias _stride _padding _output_padding _dilation++slow_conv_transpose3d+  :: Tensor -- ^ self+  -> Tensor -- ^ weight+  -> (Int,Int,Int) -- ^ kernel_size+  -> Tensor -- ^ bias+  -> (Int,Int,Int) -- ^ stride+  -> (Int,Int,Int) -- ^ padding+  -> (Int,Int,Int) -- ^ output_padding+  -> (Int,Int,Int) -- ^ dilation+  -> Tensor+slow_conv_transpose3d _self _weight _kernel_size _bias _stride _padding _output_padding _dilation = unsafePerformIO $ (cast8 ATen.slow_conv_transpose3d_ttltllll) _self _weight _kernel_size _bias _stride _padding _output_padding _dilation++thnn_conv2d+  :: Tensor -- ^ self+  -> Tensor -- ^ weight+  -> (Int,Int) -- ^ kernel_size+  -> Tensor -- ^ bias+  -> (Int,Int) -- ^ stride+  -> (Int,Int) -- ^ padding+  -> Tensor+thnn_conv2d _self _weight _kernel_size _bias _stride _padding = unsafePerformIO $ (cast6 ATen.thnn_conv2d_ttltll) _self _weight _kernel_size _bias _stride _padding++conv_depthwise3d+  :: Tensor -- ^ self+  -> Tensor -- ^ weight+  -> (Int,Int,Int) -- ^ kernel_size+  -> Tensor -- ^ bias+  -> (Int,Int,Int) -- ^ stride+  -> (Int,Int,Int) -- ^ padding+  -> (Int,Int,Int) -- ^ dilation+  -> Tensor+conv_depthwise3d _self _weight _kernel_size _bias _stride _padding _dilation = unsafePerformIO $ (cast7 ATen.conv_depthwise3d_ttltlll) _self _weight _kernel_size _bias _stride _padding _dilation++slow_conv3d+  :: Tensor -- ^ self+  -> Tensor -- ^ weight+  -> (Int,Int,Int) -- ^ kernel_size+  -> Tensor -- ^ bias+  -> (Int,Int,Int) -- ^ stride+  -> (Int,Int,Int) -- ^ padding+  -> Tensor+slow_conv3d _self _weight _kernel_size _bias _stride _padding = unsafePerformIO $ (cast6 ATen.slow_conv3d_ttltll) _self _weight _kernel_size _bias _stride _padding++slow_conv3d_forward+  :: Tensor -- ^ self+  -> Tensor -- ^ weight+  -> (Int,Int,Int) -- ^ kernel_size+  -> Tensor -- ^ bias+  -> (Int,Int,Int) -- ^ stride+  -> (Int,Int,Int) -- ^ padding+  -> Tensor+slow_conv3d_forward _self _weight _kernel_size _bias _stride _padding = unsafePerformIO $ (cast6 ATen.slow_conv3d_forward_ttltll) _self _weight _kernel_size _bias _stride _padding++slow_conv_dilated2d+  :: Tensor -- ^ self+  -> Tensor -- ^ weight+  -> (Int,Int) -- ^ kernel_size+  -> Tensor -- ^ bias+  -> (Int,Int) -- ^ stride+  -> (Int,Int) -- ^ padding+  -> (Int,Int) -- ^ dilation+  -> Tensor+slow_conv_dilated2d _self _weight _kernel_size _bias _stride _padding _dilation = unsafePerformIO $ (cast7 ATen.slow_conv_dilated2d_ttltlll) _self _weight _kernel_size _bias _stride _padding _dilation++slow_conv_dilated3d+  :: Tensor -- ^ self+  -> Tensor -- ^ weight+  -> (Int,Int,Int) -- ^ kernel_size+  -> Tensor -- ^ bias+  -> (Int,Int,Int) -- ^ stride+  -> (Int,Int,Int) -- ^ padding+  -> (Int,Int,Int) -- ^ dilation+  -> Tensor+slow_conv_dilated3d _self _weight _kernel_size _bias _stride _padding _dilation = unsafePerformIO $ (cast7 ATen.slow_conv_dilated3d_ttltlll) _self _weight _kernel_size _bias _stride _padding _dilation++col2im+  :: Tensor -- ^ self+  -> (Int,Int) -- ^ output_size+  -> (Int,Int) -- ^ kernel_size+  -> (Int,Int) -- ^ dilation+  -> (Int,Int) -- ^ padding+  -> (Int,Int) -- ^ stride+  -> Tensor+col2im _self _output_size _kernel_size _dilation _padding _stride = unsafePerformIO $ (cast6 ATen.col2im_tlllll) _self _output_size _kernel_size _dilation _padding _stride++column_stack+  :: [Tensor] -- ^ tensors+  -> Tensor+column_stack _tensors = unsafePerformIO $ (cast1 ATen.column_stack_l) _tensors++im2col+  :: Tensor -- ^ self+  -> (Int,Int) -- ^ kernel_size+  -> (Int,Int) -- ^ dilation+  -> (Int,Int) -- ^ padding+  -> (Int,Int) -- ^ stride+  -> Tensor+im2col _self _kernel_size _dilation _padding _stride = unsafePerformIO $ (cast5 ATen.im2col_tllll) _self _kernel_size _dilation _padding _stride++isfinite+  :: Tensor -- ^ self+  -> Tensor+isfinite _self = unsafePerformIO $ (cast1 ATen.isfinite_t) _self++isinf+  :: Tensor -- ^ self+  -> Tensor+isinf _self = unsafePerformIO $ (cast1 ATen.isinf_t) _self++isposinf+  :: Tensor -- ^ self+  -> Tensor+isposinf _self = unsafePerformIO $ (cast1 ATen.isposinf_t) _self++isneginf+  :: Tensor -- ^ self+  -> Tensor+isneginf _self = unsafePerformIO $ (cast1 ATen.isneginf_t) _self++special_entr+  :: Tensor -- ^ self+  -> Tensor+special_entr _self = unsafePerformIO $ (cast1 ATen.special_entr_t) _self++special_ndtri+  :: Tensor -- ^ self+  -> Tensor+special_ndtri _self = unsafePerformIO $ (cast1 ATen.special_ndtri_t) _self++special_log_ndtr+  :: Tensor -- ^ self+  -> Tensor+special_log_ndtr _self = unsafePerformIO $ (cast1 ATen.special_log_ndtr_t) _self++special_expm1+  :: Tensor -- ^ self+  -> Tensor+special_expm1 _self = unsafePerformIO $ (cast1 ATen.special_expm1_t) _self++special_exp2+  :: Tensor -- ^ self+  -> Tensor+special_exp2 _self = unsafePerformIO $ (cast1 ATen.special_exp2_t) _self++special_psi+  :: Tensor -- ^ self+  -> Tensor+special_psi _self = unsafePerformIO $ (cast1 ATen.special_psi_t) _self++special_digamma+  :: Tensor -- ^ self+  -> Tensor+special_digamma _self = unsafePerformIO $ (cast1 ATen.special_digamma_t) _self++special_gammaln+  :: Tensor -- ^ self+  -> Tensor+special_gammaln _self = unsafePerformIO $ (cast1 ATen.special_gammaln_t) _self++special_erf+  :: Tensor -- ^ self+  -> Tensor+special_erf _self = unsafePerformIO $ (cast1 ATen.special_erf_t) _self++special_erfc+  :: Tensor -- ^ self+  -> Tensor+special_erfc _self = unsafePerformIO $ (cast1 ATen.special_erfc_t) _self++special_erfcx+  :: Tensor -- ^ self+  -> Tensor+special_erfcx _self = unsafePerformIO $ (cast1 ATen.special_erfcx_t) _self++special_erfinv+  :: Tensor -- ^ self+  -> Tensor+special_erfinv _self = unsafePerformIO $ (cast1 ATen.special_erfinv_t) _self++special_ndtr+  :: Tensor -- ^ self+  -> Tensor+special_ndtr _self = unsafePerformIO $ (cast1 ATen.special_ndtr_t) _self++special_xlog1py_tt+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+special_xlog1py_tt _self _other = unsafePerformIO $ (cast2 ATen.special_xlog1py_tt) _self _other++special_xlog1py_st+  :: Float -- ^ self+  -> Tensor -- ^ other+  -> Tensor+special_xlog1py_st _self _other = unsafePerformIO $ (cast2 ATen.special_xlog1py_st) _self _other++special_xlog1py_ts+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> Tensor+special_xlog1py_ts _self _other = unsafePerformIO $ (cast2 ATen.special_xlog1py_ts) _self _other++special_xlogy_tt+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+special_xlogy_tt _self _other = unsafePerformIO $ (cast2 ATen.special_xlogy_tt) _self _other++special_xlogy_st+  :: Float -- ^ self+  -> Tensor -- ^ other+  -> Tensor+special_xlogy_st _self _other = unsafePerformIO $ (cast2 ATen.special_xlogy_st) _self _other++special_xlogy_ts+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> Tensor+special_xlogy_ts _self _other = unsafePerformIO $ (cast2 ATen.special_xlogy_ts) _self _other++special_zeta_tt+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+special_zeta_tt _self _other = unsafePerformIO $ (cast2 ATen.special_zeta_tt) _self _other++special_zeta_st+  :: Float -- ^ self+  -> Tensor -- ^ other+  -> Tensor+special_zeta_st _self _other = unsafePerformIO $ (cast2 ATen.special_zeta_st) _self _other++special_zeta_ts+  :: Tensor -- ^ self+  -> Float -- ^ other+  -> Tensor+special_zeta_ts _self _other = unsafePerformIO $ (cast2 ATen.special_zeta_ts) _self _other++special_i0+  :: Tensor -- ^ self+  -> Tensor+special_i0 _self = unsafePerformIO $ (cast1 ATen.special_i0_t) _self++special_i0e+  :: Tensor -- ^ self+  -> Tensor+special_i0e _self = unsafePerformIO $ (cast1 ATen.special_i0e_t) _self++special_i1+  :: Tensor -- ^ self+  -> Tensor+special_i1 _self = unsafePerformIO $ (cast1 ATen.special_i1_t) _self++special_i1e+  :: Tensor -- ^ self+  -> Tensor+special_i1e _self = unsafePerformIO $ (cast1 ATen.special_i1e_t) _self++special_logit+  :: Tensor -- ^ self+  -> Double -- ^ eps+  -> Tensor+special_logit _self _eps = unsafePerformIO $ (cast2 ATen.special_logit_td) _self _eps++special_polygamma+  :: Int -- ^ n+  -> Tensor -- ^ self+  -> Tensor+special_polygamma _n _self = unsafePerformIO $ (cast2 ATen.special_polygamma_lt) _n _self++special_logsumexp+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Bool -- ^ keepdim+  -> Tensor+special_logsumexp _self _dim _keepdim = unsafePerformIO $ (cast3 ATen.special_logsumexp_tlb) _self _dim _keepdim++special_expit+  :: Tensor -- ^ self+  -> Tensor+special_expit _self = unsafePerformIO $ (cast1 ATen.special_expit_t) _self++special_sinc+  :: Tensor -- ^ self+  -> Tensor+special_sinc _self = unsafePerformIO $ (cast1 ATen.special_sinc_t) _self++special_round+  :: Tensor -- ^ self+  -> Int -- ^ decimals+  -> Tensor+special_round _self _decimals = unsafePerformIO $ (cast2 ATen.special_round_tl) _self _decimals++special_log1p+  :: Tensor -- ^ self+  -> Tensor+special_log1p _self = unsafePerformIO $ (cast1 ATen.special_log1p_t) _self++special_log_softmax+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> DType -- ^ dtype+  -> Tensor+special_log_softmax _self _dim _dtype = unsafePerformIO $ (cast3 ATen.special_log_softmax_tls) _self _dim _dtype++special_gammainc+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+special_gammainc _self _other = unsafePerformIO $ (cast2 ATen.special_gammainc_tt) _self _other++special_gammaincc+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+special_gammaincc _self _other = unsafePerformIO $ (cast2 ATen.special_gammaincc_tt) _self _other++special_multigammaln+  :: Tensor -- ^ self+  -> Int -- ^ p+  -> Tensor+special_multigammaln _self _p = unsafePerformIO $ (cast2 ATen.special_multigammaln_tl) _self _p++special_softmax+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> DType -- ^ dtype+  -> Tensor+special_softmax _self _dim _dtype = unsafePerformIO $ (cast3 ATen.special_softmax_tls) _self _dim _dtype++fft_fft+  :: Tensor -- ^ self+  -> Int -- ^ n+  -> Int -- ^ dim+  -> String -- ^ norm+  -> Tensor+fft_fft _self _n _dim _norm = unsafePerformIO $ (cast4 ATen.fft_fft_tlls) _self _n _dim _norm++fft_ifft+  :: Tensor -- ^ self+  -> Int -- ^ n+  -> Int -- ^ dim+  -> String -- ^ norm+  -> Tensor+fft_ifft _self _n _dim _norm = unsafePerformIO $ (cast4 ATen.fft_ifft_tlls) _self _n _dim _norm++fft_rfft+  :: Tensor -- ^ self+  -> Int -- ^ n+  -> Int -- ^ dim+  -> String -- ^ norm+  -> Tensor+fft_rfft _self _n _dim _norm = unsafePerformIO $ (cast4 ATen.fft_rfft_tlls) _self _n _dim _norm++fft_irfft+  :: Tensor -- ^ self+  -> Int -- ^ n+  -> Int -- ^ dim+  -> String -- ^ norm+  -> Tensor+fft_irfft _self _n _dim _norm = unsafePerformIO $ (cast4 ATen.fft_irfft_tlls) _self _n _dim _norm++fft_hfft+  :: Tensor -- ^ self+  -> Int -- ^ n+  -> Int -- ^ dim+  -> String -- ^ norm+  -> Tensor+fft_hfft _self _n _dim _norm = unsafePerformIO $ (cast4 ATen.fft_hfft_tlls) _self _n _dim _norm++fft_ihfft+  :: Tensor -- ^ self+  -> Int -- ^ n+  -> Int -- ^ dim+  -> String -- ^ norm+  -> Tensor+fft_ihfft _self _n _dim _norm = unsafePerformIO $ (cast4 ATen.fft_ihfft_tlls) _self _n _dim _norm++fft_fft2+  :: Tensor -- ^ self+  -> Int -- ^ s+  -> Int -- ^ dim+  -> String -- ^ norm+  -> Tensor+fft_fft2 _self _s _dim _norm = unsafePerformIO $ (cast4 ATen.fft_fft2_tlls) _self _s _dim _norm++fft_ifft2+  :: Tensor -- ^ self+  -> Int -- ^ s+  -> Int -- ^ dim+  -> String -- ^ norm+  -> Tensor+fft_ifft2 _self _s _dim _norm = unsafePerformIO $ (cast4 ATen.fft_ifft2_tlls) _self _s _dim _norm++fft_rfft2+  :: Tensor -- ^ self+  -> Int -- ^ s+  -> Int -- ^ dim+  -> String -- ^ norm+  -> Tensor+fft_rfft2 _self _s _dim _norm = unsafePerformIO $ (cast4 ATen.fft_rfft2_tlls) _self _s _dim _norm++fft_irfft2+  :: Tensor -- ^ self+  -> Int -- ^ s+  -> Int -- ^ dim+  -> String -- ^ norm+  -> Tensor+fft_irfft2 _self _s _dim _norm = unsafePerformIO $ (cast4 ATen.fft_irfft2_tlls) _self _s _dim _norm++fft_hfft2+  :: Tensor -- ^ self+  -> Int -- ^ s+  -> Int -- ^ dim+  -> String -- ^ norm+  -> Tensor+fft_hfft2 _self _s _dim _norm = unsafePerformIO $ (cast4 ATen.fft_hfft2_tlls) _self _s _dim _norm++fft_ihfft2+  :: Tensor -- ^ self+  -> Int -- ^ s+  -> Int -- ^ dim+  -> String -- ^ norm+  -> Tensor+fft_ihfft2 _self _s _dim _norm = unsafePerformIO $ (cast4 ATen.fft_ihfft2_tlls) _self _s _dim _norm++fft_fftn+  :: Tensor -- ^ self+  -> Int -- ^ s+  -> Int -- ^ dim+  -> String -- ^ norm+  -> Tensor+fft_fftn _self _s _dim _norm = unsafePerformIO $ (cast4 ATen.fft_fftn_tlls) _self _s _dim _norm++fft_ifftn+  :: Tensor -- ^ self+  -> Int -- ^ s+  -> Int -- ^ dim+  -> String -- ^ norm+  -> Tensor+fft_ifftn _self _s _dim _norm = unsafePerformIO $ (cast4 ATen.fft_ifftn_tlls) _self _s _dim _norm++fft_rfftn+  :: Tensor -- ^ self+  -> Int -- ^ s+  -> Int -- ^ dim+  -> String -- ^ norm+  -> Tensor+fft_rfftn _self _s _dim _norm = unsafePerformIO $ (cast4 ATen.fft_rfftn_tlls) _self _s _dim _norm++fft_irfftn+  :: Tensor -- ^ self+  -> Int -- ^ s+  -> Int -- ^ dim+  -> String -- ^ norm+  -> Tensor+fft_irfftn _self _s _dim _norm = unsafePerformIO $ (cast4 ATen.fft_irfftn_tlls) _self _s _dim _norm++fft_hfftn+  :: Tensor -- ^ self+  -> Int -- ^ s+  -> Int -- ^ dim+  -> String -- ^ norm+  -> Tensor+fft_hfftn _self _s _dim _norm = unsafePerformIO $ (cast4 ATen.fft_hfftn_tlls) _self _s _dim _norm++fft_ihfftn+  :: Tensor -- ^ self+  -> Int -- ^ s+  -> Int -- ^ dim+  -> String -- ^ norm+  -> Tensor+fft_ihfftn _self _s _dim _norm = unsafePerformIO $ (cast4 ATen.fft_ihfftn_tlls) _self _s _dim _norm++fft_fftshift+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Tensor+fft_fftshift _self _dim = unsafePerformIO $ (cast2 ATen.fft_fftshift_tl) _self _dim++fft_ifftshift+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Tensor+fft_ifftshift _self _dim = unsafePerformIO $ (cast2 ATen.fft_ifftshift_tl) _self _dim++linalg_cholesky_ex+  :: Tensor -- ^ self+  -> Bool -- ^ upper+  -> Bool -- ^ check_errors+  -> (Tensor,Tensor)+linalg_cholesky_ex _self _upper _check_errors = unsafePerformIO $ (cast3 ATen.linalg_cholesky_ex_tbb) _self _upper _check_errors++linalg_cholesky+  :: Tensor -- ^ self+  -> Bool -- ^ upper+  -> Tensor+linalg_cholesky _self _upper = unsafePerformIO $ (cast2 ATen.linalg_cholesky_tb) _self _upper++linalg_cross+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Int -- ^ dim+  -> Tensor+linalg_cross _self _other _dim = unsafePerformIO $ (cast3 ATen.linalg_cross_ttl) _self _other _dim++linalg_lu_factor+  :: Tensor -- ^ A+  -> Bool -- ^ pivot+  -> (Tensor,Tensor)+linalg_lu_factor _A _pivot = unsafePerformIO $ (cast2 ATen.linalg_lu_factor_tb) _A _pivot++linalg_lu_factor_ex+  :: Tensor -- ^ A+  -> Bool -- ^ pivot+  -> Bool -- ^ check_errors+  -> (Tensor,Tensor,Tensor)+linalg_lu_factor_ex _A _pivot _check_errors = unsafePerformIO $ (cast3 ATen.linalg_lu_factor_ex_tbb) _A _pivot _check_errors++linalg_lu+  :: Tensor -- ^ A+  -> Bool -- ^ pivot+  -> (Tensor,Tensor,Tensor)+linalg_lu _A _pivot = unsafePerformIO $ (cast2 ATen.linalg_lu_tb) _A _pivot++linalg_lu_solve+  :: Tensor -- ^ LU+  -> Tensor -- ^ pivots+  -> Tensor -- ^ B+  -> Bool -- ^ left+  -> Bool -- ^ adjoint+  -> Tensor+linalg_lu_solve _LU _pivots _B _left _adjoint = unsafePerformIO $ (cast5 ATen.linalg_lu_solve_tttbb) _LU _pivots _B _left _adjoint++linalg_det+  :: Tensor -- ^ A+  -> Tensor+linalg_det _A = unsafePerformIO $ (cast1 ATen.linalg_det_t) _A++det+  :: Tensor -- ^ self+  -> Tensor+det _self = unsafePerformIO $ (cast1 ATen.det_t) _self++linalg_ldl_factor_ex+  :: Tensor -- ^ self+  -> Bool -- ^ hermitian+  -> Bool -- ^ check_errors+  -> (Tensor,Tensor,Tensor)+linalg_ldl_factor_ex _self _hermitian _check_errors = unsafePerformIO $ (cast3 ATen.linalg_ldl_factor_ex_tbb) _self _hermitian _check_errors++linalg_ldl_factor+  :: Tensor -- ^ self+  -> Bool -- ^ hermitian+  -> (Tensor,Tensor)+linalg_ldl_factor _self _hermitian = unsafePerformIO $ (cast2 ATen.linalg_ldl_factor_tb) _self _hermitian++linalg_ldl_solve+  :: Tensor -- ^ LD+  -> Tensor -- ^ pivots+  -> Tensor -- ^ B+  -> Bool -- ^ hermitian+  -> Tensor+linalg_ldl_solve _LD _pivots _B _hermitian = unsafePerformIO $ (cast4 ATen.linalg_ldl_solve_tttb) _LD _pivots _B _hermitian++linalg_lstsq+  :: Tensor -- ^ a+  -> Tensor -- ^ b+  -> Double -- ^ rcond+  -> String -- ^ driver+  -> (Tensor,Tensor,Tensor,Tensor)+linalg_lstsq _a _b _rcond _driver = unsafePerformIO $ (cast4 ATen.linalg_lstsq_ttds) _a _b _rcond _driver++lstsq+  :: Tensor -- ^ b+  -> Tensor -- ^ a+  -> Tensor+lstsq _b _a =+  let (t0,_,_,_) = unsafePerformIO $ (cast2 ATen.linalg_lstsq_tt) _a _b :: (Tensor,Tensor,Tensor,Tensor)+  in t0++linalg_matmul+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+linalg_matmul _self _other = unsafePerformIO $ (cast2 ATen.linalg_matmul_tt) _self _other++linalg_vecdot+  :: Tensor -- ^ x+  -> Tensor -- ^ y+  -> Int -- ^ dim+  -> Tensor+linalg_vecdot _x _y _dim = unsafePerformIO $ (cast3 ATen.linalg_vecdot_ttl) _x _y _dim++linalg_matrix_exp+  :: Tensor -- ^ self+  -> Tensor+linalg_matrix_exp _self = unsafePerformIO $ (cast1 ATen.linalg_matrix_exp_t) _self++linalg_slogdet+  :: Tensor -- ^ A+  -> (Tensor,Tensor)+linalg_slogdet _A = unsafePerformIO $ (cast1 ATen.linalg_slogdet_t) _A++slogdet+  :: Tensor -- ^ self+  -> (Tensor,Tensor)+slogdet _self = unsafePerformIO $ (cast1 ATen.slogdet_t) _self++logdet+  :: Tensor -- ^ self+  -> Tensor+logdet _self = unsafePerformIO $ (cast1 ATen.logdet_t) _self++linalg_eig+  :: Tensor -- ^ self+  -> (Tensor,Tensor)+linalg_eig _self = unsafePerformIO $ (cast1 ATen.linalg_eig_t) _self++linalg_eigvals+  :: Tensor -- ^ self+  -> Tensor+linalg_eigvals _self = unsafePerformIO $ (cast1 ATen.linalg_eigvals_t) _self++linalg_eigh+  :: Tensor -- ^ self+  -> String -- ^ UPLO+  -> (Tensor,Tensor)+linalg_eigh _self _UPLO = unsafePerformIO $ (cast2 ATen.linalg_eigh_ts) _self _UPLO++linalg_eigvalsh+  :: Tensor -- ^ self+  -> String -- ^ UPLO+  -> Tensor+linalg_eigvalsh _self _UPLO = unsafePerformIO $ (cast2 ATen.linalg_eigvalsh_ts) _self _UPLO++linalg_householder_product+  :: Tensor -- ^ input+  -> Tensor -- ^ tau+  -> Tensor+linalg_householder_product _input _tau = unsafePerformIO $ (cast2 ATen.linalg_householder_product_tt) _input _tau++linalg_inv_ex+  :: Tensor -- ^ A+  -> Bool -- ^ check_errors+  -> (Tensor,Tensor)+linalg_inv_ex _A _check_errors = unsafePerformIO $ (cast2 ATen.linalg_inv_ex_tb) _A _check_errors++linalg_inv+  :: Tensor -- ^ A+  -> Tensor+linalg_inv _A = unsafePerformIO $ (cast1 ATen.linalg_inv_t) _A++inverse+  :: Tensor -- ^ self+  -> Tensor+inverse _self = unsafePerformIO $ (cast1 ATen.inverse_t) _self++inner+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> Tensor+inner _self _other = unsafePerformIO $ (cast2 ATen.inner_tt) _self _other++outer+  :: Tensor -- ^ self+  -> Tensor -- ^ vec2+  -> Tensor+outer _self _vec2 = unsafePerformIO $ (cast2 ATen.outer_tt) _self _vec2++ger+  :: Tensor -- ^ self+  -> Tensor -- ^ vec2+  -> Tensor+ger _self _vec2 = unsafePerformIO $ (cast2 ATen.ger_tt) _self _vec2++linalg_norm_tslbs+  :: Tensor -- ^ self+  -> Float -- ^ ord+  -> Int -- ^ dim+  -> Bool -- ^ keepdim+  -> DType -- ^ dtype+  -> Tensor+linalg_norm_tslbs _self _ord _dim _keepdim _dtype = unsafePerformIO $ (cast5 ATen.linalg_norm_tslbs) _self _ord _dim _keepdim _dtype++-- linalg_norm_tslbs+--   :: Tensor -- ^ self+--   -> String -- ^ ord+--   -> Int -- ^ dim+--   -> Bool -- ^ keepdim+--   -> DType -- ^ dtype+--   -> Tensor+-- linalg_norm_tslbs _self _ord _dim _keepdim _dtype = unsafePerformIO $ (cast5 ATen.linalg_norm_tslbs) _self _ord _dim _keepdim _dtype++linalg_vector_norm+  :: Tensor -- ^ self+  -> Float -- ^ ord+  -> Int -- ^ dim+  -> Bool -- ^ keepdim+  -> DType -- ^ dtype+  -> Tensor+linalg_vector_norm _self _ord _dim _keepdim _dtype = unsafePerformIO $ (cast5 ATen.linalg_vector_norm_tslbs) _self _ord _dim _keepdim _dtype++linalg_matrix_norm_tslbs+  :: Tensor -- ^ self+  -> Float -- ^ ord+  -> [Int] -- ^ dim+  -> Bool -- ^ keepdim+  -> DType -- ^ dtype+  -> Tensor+linalg_matrix_norm_tslbs _self _ord _dim _keepdim _dtype = unsafePerformIO $ (cast5 ATen.linalg_matrix_norm_tslbs) _self _ord _dim _keepdim _dtype++-- linalg_matrix_norm_tslbs+--   :: Tensor -- ^ self+--   -> String -- ^ ord+--   -> [Int] -- ^ dim+--   -> Bool -- ^ keepdim+--   -> DType -- ^ dtype+--   -> Tensor+-- linalg_matrix_norm_tslbs _self _ord _dim _keepdim _dtype = unsafePerformIO $ (cast5 ATen.linalg_matrix_norm_tslbs) _self _ord _dim _keepdim _dtype++linalg_svd+  :: Tensor -- ^ A+  -> Bool -- ^ full_matrices+  -> String -- ^ driver+  -> (Tensor,Tensor,Tensor)+linalg_svd _A _full_matrices _driver = unsafePerformIO $ (cast3 ATen.linalg_svd_tbs) _A _full_matrices _driver++linalg_svdvals+  :: Tensor -- ^ A+  -> String -- ^ driver+  -> Tensor+linalg_svdvals _A _driver = unsafePerformIO $ (cast2 ATen.linalg_svdvals_ts) _A _driver++linalg_cond_ts+  :: Tensor -- ^ self+  -> Float -- ^ p+  -> Tensor+linalg_cond_ts _self _p = unsafePerformIO $ (cast2 ATen.linalg_cond_ts) _self _p++-- linalg_cond_ts+--   :: Tensor -- ^ self+--   -> String -- ^ p+--   -> Tensor+-- linalg_cond_ts _self _p = unsafePerformIO $ (cast2 ATen.linalg_cond_ts) _self _p++linalg_pinv_tttb+  :: Tensor -- ^ self+  -> Tensor -- ^ atol+  -> Tensor -- ^ rtol+  -> Bool -- ^ hermitian+  -> Tensor+linalg_pinv_tttb _self _atol _rtol _hermitian = unsafePerformIO $ (cast4 ATen.linalg_pinv_tttb) _self _atol _rtol _hermitian++linalg_pinv_tddb+  :: Tensor -- ^ self+  -> Double -- ^ atol+  -> Double -- ^ rtol+  -> Bool -- ^ hermitian+  -> Tensor+linalg_pinv_tddb _self _atol _rtol _hermitian = unsafePerformIO $ (cast4 ATen.linalg_pinv_tddb) _self _atol _rtol _hermitian++linalg_pinv_tdb+  :: Tensor -- ^ self+  -> Double -- ^ rcond+  -> Bool -- ^ hermitian+  -> Tensor+linalg_pinv_tdb _self _rcond _hermitian = unsafePerformIO $ (cast3 ATen.linalg_pinv_tdb) _self _rcond _hermitian++linalg_pinv_ttb+  :: Tensor -- ^ self+  -> Tensor -- ^ rcond+  -> Bool -- ^ hermitian+  -> Tensor+linalg_pinv_ttb _self _rcond _hermitian = unsafePerformIO $ (cast3 ATen.linalg_pinv_ttb) _self _rcond _hermitian++linalg_solve_ex+  :: Tensor -- ^ A+  -> Tensor -- ^ B+  -> Bool -- ^ left+  -> Bool -- ^ check_errors+  -> (Tensor,Tensor)+linalg_solve_ex _A _B _left _check_errors = unsafePerformIO $ (cast4 ATen.linalg_solve_ex_ttbb) _A _B _left _check_errors++linalg_solve+  :: Tensor -- ^ A+  -> Tensor -- ^ B+  -> Bool -- ^ left+  -> Tensor+linalg_solve _A _B _left = unsafePerformIO $ (cast3 ATen.linalg_solve_ttb) _A _B _left++linalg_tensorinv+  :: Tensor -- ^ self+  -> Int -- ^ ind+  -> Tensor+linalg_tensorinv _self _ind = unsafePerformIO $ (cast2 ATen.linalg_tensorinv_tl) _self _ind++linalg_tensorsolve+  :: Tensor -- ^ self+  -> Tensor -- ^ other+  -> [Int] -- ^ dims+  -> Tensor+linalg_tensorsolve _self _other _dims = unsafePerformIO $ (cast3 ATen.linalg_tensorsolve_ttl) _self _other _dims++linalg_qr+  :: Tensor -- ^ A+  -> String -- ^ mode+  -> (Tensor,Tensor)+linalg_qr _A _mode = unsafePerformIO $ (cast2 ATen.linalg_qr_ts) _A _mode++linalg_matrix_power+  :: Tensor -- ^ self+  -> Int -- ^ n+  -> Tensor+linalg_matrix_power _self _n = unsafePerformIO $ (cast2 ATen.linalg_matrix_power_tl) _self _n++linalg_matrix_rank_tttb+  :: Tensor -- ^ input+  -> Tensor -- ^ atol+  -> Tensor -- ^ rtol+  -> Bool -- ^ hermitian+  -> Tensor+linalg_matrix_rank_tttb _input _atol _rtol _hermitian = unsafePerformIO $ (cast4 ATen.linalg_matrix_rank_tttb) _input _atol _rtol _hermitian++linalg_matrix_rank_tddb+  :: Tensor -- ^ self+  -> Double -- ^ atol+  -> Double -- ^ rtol+  -> Bool -- ^ hermitian+  -> Tensor+linalg_matrix_rank_tddb _self _atol _rtol _hermitian = unsafePerformIO $ (cast4 ATen.linalg_matrix_rank_tddb) _self _atol _rtol _hermitian++linalg_matrix_rank_tdb+  :: Tensor -- ^ self+  -> Double -- ^ tol+  -> Bool -- ^ hermitian+  -> Tensor+linalg_matrix_rank_tdb _self _tol _hermitian = unsafePerformIO $ (cast3 ATen.linalg_matrix_rank_tdb) _self _tol _hermitian++linalg_matrix_rank_ttb+  :: Tensor -- ^ input+  -> Tensor -- ^ tol+  -> Bool -- ^ hermitian+  -> Tensor+linalg_matrix_rank_ttb _input _tol _hermitian = unsafePerformIO $ (cast3 ATen.linalg_matrix_rank_ttb) _input _tol _hermitian++linalg_multi_dot+  :: [Tensor] -- ^ tensors+  -> Tensor+linalg_multi_dot _tensors = unsafePerformIO $ (cast1 ATen.linalg_multi_dot_l) _tensors++nested_to_padded_tensor+  :: Tensor -- ^ self+  -> Double -- ^ padding+  -> [Int] -- ^ output_size+  -> Tensor+nested_to_padded_tensor _self _padding _output_size = unsafePerformIO $ (cast3 ATen.nested_to_padded_tensor_tdl) _self _padding _output_size++segment_reduce+  :: Tensor -- ^ data+  -> String -- ^ reduce+  -> Tensor -- ^ lengths+  -> Tensor -- ^ indices+  -> Tensor -- ^ offsets+  -> Int -- ^ axis+  -> Bool -- ^ unsafe+  -> Float -- ^ initial+  -> Tensor+segment_reduce _data _reduce _lengths _indices _offsets _axis _unsafe _initial = unsafePerformIO $ (cast8 ATen.segment_reduce_tstttlbs) _data _reduce _lengths _indices _offsets _axis _unsafe _initial++pad_sequence+  :: [Tensor] -- ^ sequences+  -> Bool -- ^ batch_first+  -> Double -- ^ padding_value+  -> Tensor+pad_sequence _sequences _batch_first _padding_value = unsafePerformIO $ (cast3 ATen.pad_sequence_lbd) _sequences _batch_first _padding_value++flatten_dense_tensors+  :: [Tensor] -- ^ tensors+  -> Tensor+flatten_dense_tensors _tensors = unsafePerformIO $ (cast1 ATen.flatten_dense_tensors_l) _tensors++unflatten_dense_tensors+  :: Tensor -- ^ flat+  -> [Tensor] -- ^ tensors+  -> [Tensor]+unflatten_dense_tensors _flat _tensors = unsafePerformIO $ (cast2 ATen.unflatten_dense_tensors_tl) _flat _tensors++view_as_real_copy+  :: Tensor -- ^ self+  -> Tensor+view_as_real_copy _self = unsafePerformIO $ (cast1 ATen.view_as_real_copy_t) _self++view_as_complex_copy+  :: Tensor -- ^ self+  -> Tensor+view_as_complex_copy _self = unsafePerformIO $ (cast1 ATen.view_as_complex_copy_t) _self++as_strided_copy+  :: Tensor -- ^ self+  -> [Int] -- ^ size+  -> [Int] -- ^ stride+  -> Int -- ^ storage_offset+  -> Tensor+as_strided_copy _self _size _stride _storage_offset = unsafePerformIO $ (cast4 ATen.as_strided_copy_tlll) _self _size _stride _storage_offset++diagonal_copy+  :: Tensor -- ^ self+  -> Int -- ^ offset+  -> Int -- ^ dim1+  -> Int -- ^ dim2+  -> Tensor+diagonal_copy _self _offset _dim1 _dim2 = unsafePerformIO $ (cast4 ATen.diagonal_copy_tlll) _self _offset _dim1 _dim2++expand_copy+  :: Tensor -- ^ self+  -> [Int] -- ^ size+  -> Bool -- ^ implicit+  -> Tensor+expand_copy _self _size _implicit = unsafePerformIO $ (cast3 ATen.expand_copy_tlb) _self _size _implicit++permute_copy+  :: Tensor -- ^ self+  -> [Int] -- ^ dims+  -> Tensor+permute_copy _self _dims = unsafePerformIO $ (cast2 ATen.permute_copy_tl) _self _dims++select_copy+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Int -- ^ index+  -> Tensor+select_copy _self _dim _index = unsafePerformIO $ (cast3 ATen.select_copy_tll) _self _dim _index++detach_copy+  :: Tensor -- ^ self+  -> Tensor+detach_copy _self = unsafePerformIO $ (cast1 ATen.detach_copy_t) _self++slice_copy+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Int -- ^ start+  -> Int -- ^ end+  -> Int -- ^ step+  -> Tensor+slice_copy _self _dim _start _end _step = unsafePerformIO $ (cast5 ATen.slice_copy_tllll) _self _dim _start _end _step++split_copy+  :: Tensor -- ^ self+  -> Int -- ^ split_size+  -> Int -- ^ dim+  -> [Tensor]+split_copy _self _split_size _dim = unsafePerformIO $ (cast3 ATen.split_copy_tll) _self _split_size _dim++split_with_sizes_copy+  :: Tensor -- ^ self+  -> [Int] -- ^ split_sizes+  -> Int -- ^ dim+  -> [Tensor]+split_with_sizes_copy _self _split_sizes _dim = unsafePerformIO $ (cast3 ATen.split_with_sizes_copy_tll) _self _split_sizes _dim++squeeze_copy_t+  :: Tensor -- ^ self+  -> Tensor+squeeze_copy_t _self = unsafePerformIO $ (cast1 ATen.squeeze_copy_t) _self++squeeze_copy_tl+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Tensor+squeeze_copy_tl _self _dim = unsafePerformIO $ (cast2 ATen.squeeze_copy_tl) _self _dim++-- squeeze_copy_tl+--   :: Tensor -- ^ self+--   -> [Int] -- ^ dim+--   -> Tensor+-- squeeze_copy_tl _self _dim = unsafePerformIO $ (cast2 ATen.squeeze_copy_tl) _self _dim++t_copy+  :: Tensor -- ^ self+  -> Tensor+t_copy _self = unsafePerformIO $ (cast1 ATen.t_copy_t) _self++transpose_copy+  :: Tensor -- ^ self+  -> Int -- ^ dim0+  -> Int -- ^ dim1+  -> Tensor+transpose_copy _self _dim0 _dim1 = unsafePerformIO $ (cast3 ATen.transpose_copy_tll) _self _dim0 _dim1++unsqueeze_copy+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> Tensor+unsqueeze_copy _self _dim = unsafePerformIO $ (cast2 ATen.unsqueeze_copy_tl) _self _dim++indices_copy+  :: Tensor -- ^ self+  -> Tensor+indices_copy _self = unsafePerformIO $ (cast1 ATen.indices_copy_t) _self++values_copy+  :: Tensor -- ^ self+  -> Tensor+values_copy _self = unsafePerformIO $ (cast1 ATen.values_copy_t) _self++crow_indices_copy+  :: Tensor -- ^ self+  -> Tensor+crow_indices_copy _self = unsafePerformIO $ (cast1 ATen.crow_indices_copy_t) _self++col_indices_copy+  :: Tensor -- ^ self+  -> Tensor+col_indices_copy _self = unsafePerformIO $ (cast1 ATen.col_indices_copy_t) _self++ccol_indices_copy+  :: Tensor -- ^ self+  -> Tensor+ccol_indices_copy _self = unsafePerformIO $ (cast1 ATen.ccol_indices_copy_t) _self++row_indices_copy+  :: Tensor -- ^ self+  -> Tensor+row_indices_copy _self = unsafePerformIO $ (cast1 ATen.row_indices_copy_t) _self++unbind_copy+  :: Tensor -- ^ self+  -> Int -- ^ dim+  -> [Tensor]+unbind_copy _self _dim = unsafePerformIO $ (cast2 ATen.unbind_copy_tl) _self _dim++view_copy_tl+  :: Tensor -- ^ self+  -> [Int] -- ^ size+  -> Tensor+view_copy_tl _self _size = unsafePerformIO $ (cast2 ATen.view_copy_tl) _self _size++view_copy_ts+  :: Tensor -- ^ self+  -> DType -- ^ dtype+  -> Tensor+view_copy_ts _self _dtype = unsafePerformIO $ (cast2 ATen.view_copy_ts) _self _dtype++unfold_copy+  :: Tensor -- ^ self+  -> Int -- ^ dimension+  -> Int -- ^ size+  -> Int -- ^ step+  -> Tensor+unfold_copy _self _dimension _size _step = unsafePerformIO $ (cast4 ATen.unfold_copy_tlll) _self _dimension _size _step++alias_copy+  :: Tensor -- ^ self+  -> Tensor+alias_copy _self = unsafePerformIO $ (cast1 ATen.alias_copy_t) _self++scaled_dot_product_attention+  :: Tensor -- ^ query+  -> Tensor -- ^ key+  -> Tensor -- ^ value+  -> Maybe Tensor -- ^ attn_mask+  -> Double -- ^ dropout_p+  -> Bool -- ^ is_causal+  -> Double -- ^ scale+  -> Bool -- ^ enable_gqa+  -> Tensor+scaled_dot_product_attention _query _key _value _attn_mask _dropout_p _is_causal _scale _enable_gqa = unsafePerformIO $ (cast8 ATen.scaled_dot_product_attention_tttqdbdb) _query _key _value _attn_mask _dropout_p _is_causal _scale _enable_gqa++special_airy_ai+  :: Tensor -- ^ x+  -> Tensor+special_airy_ai _x = unsafePerformIO $ (cast1 ATen.special_airy_ai_t) _x++special_bessel_j0+  :: Tensor -- ^ self+  -> Tensor+special_bessel_j0 _self = unsafePerformIO $ (cast1 ATen.special_bessel_j0_t) _self++special_bessel_j1+  :: Tensor -- ^ self+  -> Tensor+special_bessel_j1 _self = unsafePerformIO $ (cast1 ATen.special_bessel_j1_t) _self++special_bessel_y0+  :: Tensor -- ^ self+  -> Tensor+special_bessel_y0 _self = unsafePerformIO $ (cast1 ATen.special_bessel_y0_t) _self++special_bessel_y1+  :: Tensor -- ^ self+  -> Tensor+special_bessel_y1 _self = unsafePerformIO $ (cast1 ATen.special_bessel_y1_t) _self++special_chebyshev_polynomial_t_tt+  :: Tensor -- ^ x+  -> Tensor -- ^ n+  -> Tensor+special_chebyshev_polynomial_t_tt _x _n = unsafePerformIO $ (cast2 ATen.special_chebyshev_polynomial_t_tt) _x _n++special_chebyshev_polynomial_t_st+  :: Float -- ^ x+  -> Tensor -- ^ n+  -> Tensor+special_chebyshev_polynomial_t_st _x _n = unsafePerformIO $ (cast2 ATen.special_chebyshev_polynomial_t_st) _x _n++special_chebyshev_polynomial_t_ts+  :: Tensor -- ^ x+  -> Float -- ^ n+  -> Tensor+special_chebyshev_polynomial_t_ts _x _n = unsafePerformIO $ (cast2 ATen.special_chebyshev_polynomial_t_ts) _x _n++special_chebyshev_polynomial_u_tt+  :: Tensor -- ^ x+  -> Tensor -- ^ n+  -> Tensor+special_chebyshev_polynomial_u_tt _x _n = unsafePerformIO $ (cast2 ATen.special_chebyshev_polynomial_u_tt) _x _n++special_chebyshev_polynomial_u_st+  :: Float -- ^ x+  -> Tensor -- ^ n+  -> Tensor+special_chebyshev_polynomial_u_st _x _n = unsafePerformIO $ (cast2 ATen.special_chebyshev_polynomial_u_st) _x _n++special_chebyshev_polynomial_u_ts+  :: Tensor -- ^ x+  -> Float -- ^ n+  -> Tensor+special_chebyshev_polynomial_u_ts _x _n = unsafePerformIO $ (cast2 ATen.special_chebyshev_polynomial_u_ts) _x _n++special_chebyshev_polynomial_v_tt+  :: Tensor -- ^ x+  -> Tensor -- ^ n+  -> Tensor+special_chebyshev_polynomial_v_tt _x _n = unsafePerformIO $ (cast2 ATen.special_chebyshev_polynomial_v_tt) _x _n++special_chebyshev_polynomial_v_st+  :: Float -- ^ x+  -> Tensor -- ^ n+  -> Tensor+special_chebyshev_polynomial_v_st _x _n = unsafePerformIO $ (cast2 ATen.special_chebyshev_polynomial_v_st) _x _n++special_chebyshev_polynomial_v_ts+  :: Tensor -- ^ x+  -> Float -- ^ n+  -> Tensor+special_chebyshev_polynomial_v_ts _x _n = unsafePerformIO $ (cast2 ATen.special_chebyshev_polynomial_v_ts) _x _n++special_chebyshev_polynomial_w_tt+  :: Tensor -- ^ x+  -> Tensor -- ^ n+  -> Tensor+special_chebyshev_polynomial_w_tt _x _n = unsafePerformIO $ (cast2 ATen.special_chebyshev_polynomial_w_tt) _x _n++special_chebyshev_polynomial_w_st+  :: Float -- ^ x+  -> Tensor -- ^ n+  -> Tensor+special_chebyshev_polynomial_w_st _x _n = unsafePerformIO $ (cast2 ATen.special_chebyshev_polynomial_w_st) _x _n++special_chebyshev_polynomial_w_ts+  :: Tensor -- ^ x+  -> Float -- ^ n+  -> Tensor+special_chebyshev_polynomial_w_ts _x _n = unsafePerformIO $ (cast2 ATen.special_chebyshev_polynomial_w_ts) _x _n++special_hermite_polynomial_h_tt+  :: Tensor -- ^ x+  -> Tensor -- ^ n+  -> Tensor+special_hermite_polynomial_h_tt _x _n = unsafePerformIO $ (cast2 ATen.special_hermite_polynomial_h_tt) _x _n++special_hermite_polynomial_h_st+  :: Float -- ^ x+  -> Tensor -- ^ n+  -> Tensor+special_hermite_polynomial_h_st _x _n = unsafePerformIO $ (cast2 ATen.special_hermite_polynomial_h_st) _x _n++special_hermite_polynomial_h_ts+  :: Tensor -- ^ x+  -> Float -- ^ n+  -> Tensor+special_hermite_polynomial_h_ts _x _n = unsafePerformIO $ (cast2 ATen.special_hermite_polynomial_h_ts) _x _n++special_hermite_polynomial_he_tt+  :: Tensor -- ^ x+  -> Tensor -- ^ n+  -> Tensor+special_hermite_polynomial_he_tt _x _n = unsafePerformIO $ (cast2 ATen.special_hermite_polynomial_he_tt) _x _n++special_hermite_polynomial_he_st+  :: Float -- ^ x+  -> Tensor -- ^ n+  -> Tensor+special_hermite_polynomial_he_st _x _n = unsafePerformIO $ (cast2 ATen.special_hermite_polynomial_he_st) _x _n++special_hermite_polynomial_he_ts+  :: Tensor -- ^ x+  -> Float -- ^ n+  -> Tensor+special_hermite_polynomial_he_ts _x _n = unsafePerformIO $ (cast2 ATen.special_hermite_polynomial_he_ts) _x _n++special_laguerre_polynomial_l_tt+  :: Tensor -- ^ x+  -> Tensor -- ^ n+  -> Tensor+special_laguerre_polynomial_l_tt _x _n = unsafePerformIO $ (cast2 ATen.special_laguerre_polynomial_l_tt) _x _n++special_laguerre_polynomial_l_st+  :: Float -- ^ x+  -> Tensor -- ^ n+  -> Tensor+special_laguerre_polynomial_l_st _x _n = unsafePerformIO $ (cast2 ATen.special_laguerre_polynomial_l_st) _x _n++special_laguerre_polynomial_l_ts+  :: Tensor -- ^ x+  -> Float -- ^ n+  -> Tensor+special_laguerre_polynomial_l_ts _x _n = unsafePerformIO $ (cast2 ATen.special_laguerre_polynomial_l_ts) _x _n++special_legendre_polynomial_p_tt+  :: Tensor -- ^ x+  -> Tensor -- ^ n+  -> Tensor+special_legendre_polynomial_p_tt _x _n = unsafePerformIO $ (cast2 ATen.special_legendre_polynomial_p_tt) _x _n++special_legendre_polynomial_p_st+  :: Float -- ^ x+  -> Tensor -- ^ n+  -> Tensor+special_legendre_polynomial_p_st _x _n = unsafePerformIO $ (cast2 ATen.special_legendre_polynomial_p_st) _x _n++special_legendre_polynomial_p_ts+  :: Tensor -- ^ x+  -> Float -- ^ n+  -> Tensor+special_legendre_polynomial_p_ts _x _n = unsafePerformIO $ (cast2 ATen.special_legendre_polynomial_p_ts) _x _n++special_modified_bessel_i0+  :: Tensor -- ^ self+  -> Tensor+special_modified_bessel_i0 _self = unsafePerformIO $ (cast1 ATen.special_modified_bessel_i0_t) _self++special_modified_bessel_i1+  :: Tensor -- ^ self+  -> Tensor+special_modified_bessel_i1 _self = unsafePerformIO $ (cast1 ATen.special_modified_bessel_i1_t) _self++special_modified_bessel_k0+  :: Tensor -- ^ self+  -> Tensor+special_modified_bessel_k0 _self = unsafePerformIO $ (cast1 ATen.special_modified_bessel_k0_t) _self++special_modified_bessel_k1+  :: Tensor -- ^ self+  -> Tensor+special_modified_bessel_k1 _self = unsafePerformIO $ (cast1 ATen.special_modified_bessel_k1_t) _self++special_scaled_modified_bessel_k0+  :: Tensor -- ^ x+  -> Tensor+special_scaled_modified_bessel_k0 _x = unsafePerformIO $ (cast1 ATen.special_scaled_modified_bessel_k0_t) _x++special_scaled_modified_bessel_k1+  :: Tensor -- ^ x+  -> Tensor+special_scaled_modified_bessel_k1 _x = unsafePerformIO $ (cast1 ATen.special_scaled_modified_bessel_k1_t) _x++special_shifted_chebyshev_polynomial_t_tt+  :: Tensor -- ^ x+  -> Tensor -- ^ n+  -> Tensor+special_shifted_chebyshev_polynomial_t_tt _x _n = unsafePerformIO $ (cast2 ATen.special_shifted_chebyshev_polynomial_t_tt) _x _n++special_shifted_chebyshev_polynomial_t_st+  :: Float -- ^ x+  -> Tensor -- ^ n+  -> Tensor+special_shifted_chebyshev_polynomial_t_st _x _n = unsafePerformIO $ (cast2 ATen.special_shifted_chebyshev_polynomial_t_st) _x _n++special_shifted_chebyshev_polynomial_t_ts+  :: Tensor -- ^ x+  -> Float -- ^ n+  -> Tensor+special_shifted_chebyshev_polynomial_t_ts _x _n = unsafePerformIO $ (cast2 ATen.special_shifted_chebyshev_polynomial_t_ts) _x _n++special_shifted_chebyshev_polynomial_u_tt+  :: Tensor -- ^ x+  -> Tensor -- ^ n+  -> Tensor+special_shifted_chebyshev_polynomial_u_tt _x _n = unsafePerformIO $ (cast2 ATen.special_shifted_chebyshev_polynomial_u_tt) _x _n++special_shifted_chebyshev_polynomial_u_st+  :: Float -- ^ x+  -> Tensor -- ^ n+  -> Tensor+special_shifted_chebyshev_polynomial_u_st _x _n = unsafePerformIO $ (cast2 ATen.special_shifted_chebyshev_polynomial_u_st) _x _n++special_shifted_chebyshev_polynomial_u_ts+  :: Tensor -- ^ x+  -> Float -- ^ n+  -> Tensor+special_shifted_chebyshev_polynomial_u_ts _x _n = unsafePerformIO $ (cast2 ATen.special_shifted_chebyshev_polynomial_u_ts) _x _n++special_shifted_chebyshev_polynomial_v_tt+  :: Tensor -- ^ x+  -> Tensor -- ^ n+  -> Tensor+special_shifted_chebyshev_polynomial_v_tt _x _n = unsafePerformIO $ (cast2 ATen.special_shifted_chebyshev_polynomial_v_tt) _x _n++special_shifted_chebyshev_polynomial_v_st+  :: Float -- ^ x+  -> Tensor -- ^ n+  -> Tensor+special_shifted_chebyshev_polynomial_v_st _x _n = unsafePerformIO $ (cast2 ATen.special_shifted_chebyshev_polynomial_v_st) _x _n++special_shifted_chebyshev_polynomial_v_ts+  :: Tensor -- ^ x+  -> Float -- ^ n+  -> Tensor+special_shifted_chebyshev_polynomial_v_ts _x _n = unsafePerformIO $ (cast2 ATen.special_shifted_chebyshev_polynomial_v_ts) _x _n++special_shifted_chebyshev_polynomial_w_tt+  :: Tensor -- ^ x+  -> Tensor -- ^ n+  -> Tensor+special_shifted_chebyshev_polynomial_w_tt _x _n = unsafePerformIO $ (cast2 ATen.special_shifted_chebyshev_polynomial_w_tt) _x _n++special_shifted_chebyshev_polynomial_w_st+  :: Float -- ^ x+  -> Tensor -- ^ n+  -> Tensor+special_shifted_chebyshev_polynomial_w_st _x _n = unsafePerformIO $ (cast2 ATen.special_shifted_chebyshev_polynomial_w_st) _x _n++special_shifted_chebyshev_polynomial_w_ts+  :: Tensor -- ^ x+  -> Float -- ^ n+  -> Tensor+special_shifted_chebyshev_polynomial_w_ts _x _n = unsafePerformIO $ (cast2 ATen.special_shifted_chebyshev_polynomial_w_ts) _x _n++special_spherical_bessel_j0+  :: Tensor -- ^ x+  -> Tensor+special_spherical_bessel_j0 _x = unsafePerformIO $ (cast1 ATen.special_spherical_bessel_j0_t) _x++embedding_renorm+  :: Tensor -- ^ self+  -> Tensor -- ^ indices+  -> Double -- ^ max_norm+  -> Double -- ^ norm_type+  -> Tensor+embedding_renorm _self _indices _max_norm _norm_type = unsafePerformIO $ (cast4 ATen.embedding_renorm_ttdd) _self _indices _max_norm _norm_type++resize+  :: Tensor -- ^ self+  -> [Int] -- ^ size+  -> ATen.MemoryFormat -- ^ memory_format+  -> Tensor+resize _self _size _memory_format = unsafePerformIO $ (cast3 ATen.resize_tlM) _self _size _memory_format++resize_as+  :: Tensor -- ^ self+  -> Tensor -- ^ the_template+  -> ATen.MemoryFormat -- ^ memory_format+  -> Tensor+resize_as _self _the_template _memory_format = unsafePerformIO $ (cast3 ATen.resize_as_ttM) _self _the_template _memory_format++resize_as_sparse+  :: Tensor -- ^ self+  -> Tensor -- ^ the_template+  -> Tensor+resize_as_sparse _self _the_template = unsafePerformIO $ (cast2 ATen.resize_as_sparse_tt) _self _the_template++zero+  :: Tensor -- ^ self+  -> Tensor+zero _self = unsafePerformIO $ (cast1 ATen.zero_t) _self++sparse_resize+  :: Tensor -- ^ self+  -> [Int] -- ^ size+  -> Int -- ^ sparse_dim+  -> Int -- ^ dense_dim+  -> Tensor+sparse_resize _self _size _sparse_dim _dense_dim = unsafePerformIO $ (cast4 ATen.sparse_resize_tlll) _self _size _sparse_dim _dense_dim++sparse_resize_and_clear+  :: Tensor -- ^ self+  -> [Int] -- ^ size+  -> Int -- ^ sparse_dim+  -> Int -- ^ dense_dim+  -> Tensor+sparse_resize_and_clear _self _size _sparse_dim _dense_dim = unsafePerformIO $ (cast4 ATen.sparse_resize_and_clear_tlll) _self _size _sparse_dim _dense_dim++copy_sparse_to_sparse+  :: Tensor -- ^ self+  -> Tensor -- ^ src+  -> Bool -- ^ non_blocking+  -> Tensor+copy_sparse_to_sparse _self _src _non_blocking = unsafePerformIO $ (cast3 ATen.copy_sparse_to_sparse_ttb) _self _src _non_blocking++-- set_tS+--   :: Tensor -- ^ self+--   -> Storage -- ^ source+--   -> Tensor+-- set_tS _self _source = unsafePerformIO $ (cast2 ATen.set_tS) _self _source++-- set_tSlll+--   :: Tensor -- ^ self+--   -> Storage -- ^ source+--   -> Int -- ^ storage_offset+--   -> [Int] -- ^ size+--   -> [Int] -- ^ stride+--   -> Tensor+-- set_tSlll _self _source _storage_offset _size _stride = unsafePerformIO $ (cast5 ATen.set_tSlll) _self _source _storage_offset _size _stride++set_tt+  :: Tensor -- ^ self+  -> Tensor -- ^ source+  -> Tensor+set_tt _self _source = unsafePerformIO $ (cast2 ATen.set_tt) _self _source++set_t+  :: Tensor -- ^ self+  -> Tensor+set_t _self = unsafePerformIO $ (cast1 ATen.set_t) _self+
+ src/Torch/HList.hs view
@@ -0,0 +1,511 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE UndecidableSuperClasses #-}+{-# LANGUAGE NoStarIsType #-}++module Torch.HList where++import Control.Applicative (Applicative (liftA2))+import Data.Kind+  ( Type,+  )+import GHC.Exts (IsList (..))+import GHC.TypeLits (Nat, type (+), type (-), type (<=))+import Prelude hiding (id, (.))++type family ListLength (xs :: [k]) :: Nat where+  ListLength '[] = 0+  ListLength (_h ': t) = 1 + ListLength t++data family HList (xs :: [k])++data instance HList '[] = HNil++newtype instance HList ((x :: Type) ': xs) = HCons (x, HList xs)++pattern (:.) :: forall x (xs :: [Type]). x -> HList xs -> HList (x : xs)+pattern (:.) x xs = HCons (x, xs)++infixr 2 :.++instance Show (HList '[]) where+  show _ = "H[]"++instance (Show e, Show (HList l)) => Show (HList (e ': l)) where+  show (x :. l) =+    let 'H' : '[' : s = show l+     in "H[" ++ show x ++ (if s == "]" then s else "," ++ s)++instance Eq (HList '[]) where+  HNil == HNil = True++instance (Eq x, Eq (HList xs)) => Eq (HList (x ': xs)) where+  (x :. xs) == (y :. ys) = x == y && xs == ys++instance Semigroup (HList '[]) where+  _ <> _ = HNil++instance (Semigroup a, Semigroup (HList as)) => Semigroup (HList (a ': as)) where+  (x :. xs) <> (y :. ys) = (x <> y) :. (xs <> ys)++instance Monoid (HList '[]) where+  mempty = HNil++instance (Monoid a, Monoid (HList as)) => Monoid (HList (a ': as)) where+  mempty = mempty :. mempty+++{- HLINT ignore "Redundant bracket" -}+instance IsList (Maybe (HList '[(a :: Type)])) where+  type Item (Maybe (HList '[(a :: Type)])) = a+  fromList [x] = liftA2 (:.) (Just x) (Just HNil)+  fromList _ = Nothing+  toList Nothing = []+  toList (Just (x :. HNil)) = [x]++instance+  ( IsList (Maybe (HList (a ': as))),+    a ~ Item (Maybe (HList (a ': as)))+  ) =>+  IsList (Maybe (HList ((a :: Type) ': a ': as)))+  where+  type Item (Maybe (HList (a ': a ': as))) = a+  fromList (x : xs) = liftA2 (:.) (Just x) (fromList xs)+  fromList _ = Nothing+  toList Nothing = []+  toList (Just (x :. xs)) = x : toList (Just xs)++class Apply f a b where+  apply :: f -> a -> b++-- | Stronger version of `Apply` that allows for better inference of the return type+class Apply' f a b | f a -> b where+  apply' :: f -> a -> b++data AFst = AFst++instance Apply' AFst (a, b) a where+  apply' _ (a, _) = a++data ASnd = ASnd++instance Apply' ASnd (a, b) b where+  apply' _ (_, b) = b++class HMap f (xs :: [k]) (ys :: [k]) where+  hmap :: f -> HList xs -> HList ys++instance HMap f '[] '[] where+  hmap _ _ = HNil++instance (Apply f x y, HMap f xs ys) => HMap f (x ': xs) (y ': ys) where+  hmap f (x :. xs) = apply f x :. hmap f xs++-- | Alternative version of `HMap` with better type inference based on `Apply'`+class HMap' f (xs :: [k]) (ys :: [k]) | f xs -> ys where+  hmap' :: f -> HList xs -> HList ys++instance HMap' f '[] '[] where+  hmap' _ _ = HNil++instance (Apply' f x y, HMap' f xs ys) => HMap' f (x ': xs) (y ': ys) where+  hmap' f (x :. xs) = apply' f x :. hmap' f xs++class HMapM m f (xs :: [k]) (ys :: [k]) where+  hmapM :: f -> HList xs -> m (HList ys)++instance (Monad m) => HMapM m f '[] '[] where+  hmapM _ _ = pure HNil++instance+  ( Monad m,+    Apply f x (m y),+    HMapM m f xs ys+  ) =>+  HMapM m f (x ': xs) (y ': ys)+  where+  hmapM f (x :. xs) = (:.) <$> apply f x <*> hmapM f xs++class HMapM' m f (xs :: [k]) (ys :: [k]) | f xs -> ys where+  hmapM' :: f -> HList xs -> m (HList ys)++instance (Applicative m) => HMapM' m f '[] '[] where+  hmapM' _ _ = pure HNil++instance+  ( Applicative m,+    Apply' f x (m y),+    HMapM' m f xs ys+  ) =>+  HMapM' m f (x ': xs) (y ': ys)+  where+  hmapM' f (x :. xs) = (:.) <$> apply' f x <*> hmapM' f xs++class+  Applicative f =>+  HSequence f (xs :: [k]) (ys :: [k])+    | xs -> ys,+      ys f -> xs+  where+  hsequence :: HList xs -> f (HList ys)++instance Applicative f => HSequence f '[] '[] where+  hsequence = pure++instance+  ( Applicative g,+    HSequence f xs ys,+    y ~ x,+    f ~ g+  ) =>+  HSequence g (f x ': xs) (y ': ys)+  where+  hsequence (fx :. fxs) = (:.) <$> fx <*> hsequence fxs++class HFoldr f acc xs res | f acc xs -> res where+  hfoldr :: f -> acc -> HList xs -> res++instance (acc ~ res) => HFoldr f acc '[] res where+  hfoldr _ acc _ = acc++instance+  ( Apply' f (x, res) res',+    HFoldr f acc xs res+  ) =>+  HFoldr f acc (x ': xs) res'+  where+  hfoldr f acc (x :. xs) = apply' f (x, hfoldr f acc xs)++class HFoldrM m f acc xs res | m f acc xs -> res where+  hfoldrM :: f -> acc -> HList xs -> m res++instance+  ( Monad m,+    acc ~ res+  ) =>+  HFoldrM m f acc '[] res+  where+  hfoldrM _ acc _ = pure acc++instance+  ( Monad m,+    Apply' f (x, m res) (m res'),+    HFoldrM m f acc xs res+  ) =>+  HFoldrM m f acc (x ': xs) res'+  where+  hfoldrM f acc (x :. xs) = apply' f (x, hfoldrM f acc xs :: (m res))++data HNothing = HNothing++newtype HJust x = HJust x++class HUnfold f res xs where+  hunfoldr' :: f -> res -> HList xs++type family HUnfoldRes s xs where+  HUnfoldRes _ '[] = HNothing+  HUnfoldRes s (x ': _) = HJust (x, s)++instance HUnfold f HNothing '[] where+  hunfoldr' _ _ = HNil++instance+  ( Apply f s res,+    HUnfold f res xs,+    res ~ HUnfoldRes s xs+  ) =>+  HUnfold f (HJust (x, s)) (x ': xs)+  where+  hunfoldr' f (HJust (x, s)) = x :. hunfoldr' f (apply f s :: res)++hunfoldr ::+  forall f res (xs :: [Type]) a.+  (Apply f a res, HUnfold f res xs, res ~ HUnfoldRes a xs) =>+  f ->+  a ->+  HList xs+hunfoldr f s = hunfoldr' f (apply f s :: res)++class HUnfoldM m f res xs where+  hunfoldrM' :: f -> res -> m (HList xs)++type family HUnfoldMRes m s xs where+  HUnfoldMRes m _ '[] = m HNothing+  HUnfoldMRes m s (x ': _) = m (HJust (x, s))++instance (Monad m) => HUnfoldM m f (m HNothing) '[] where+  hunfoldrM' _ _ = pure HNil++instance+  ( Monad m,+    HUnfoldM m f res xs,+    Apply f s res,+    res ~ HUnfoldMRes m s xs+  ) =>+  HUnfoldM m f (m (HJust (x, s))) (x ': xs)+  where+  hunfoldrM' f just = do+    HJust (x, s) <- just+    xs <- hunfoldrM' f (apply f s :: res)+    return (x :. xs)++hunfoldrM ::+  forall (m :: Type -> Type) f res (xs :: [Type]) a.+  (HUnfoldM m f res xs, Apply f a res, res ~ HUnfoldMRes m a xs) =>+  f ->+  a ->+  m (HList xs)+hunfoldrM f s = hunfoldrM' f (apply f s :: res)++type HReplicate n e = HReplicateFD n e (HReplicateR n e)++hreplicate :: forall n e. HReplicate n e => e -> HList (HReplicateR n e)+hreplicate = hreplicateFD @n++class+  HReplicateFD+    (n :: Nat)+    (e :: Type)+    (es :: [Type])+    | n e -> es+  where+  hreplicateFD :: e -> HList es++instance {-# OVERLAPS #-} HReplicateFD 0 e '[] where+  hreplicateFD _ = HNil++instance+  {-# OVERLAPPABLE #-}+  ( HReplicateFD (n - 1) e es,+    es' ~ (e ': es),+    1 <= n+  ) =>+  HReplicateFD n e es'+  where+  hreplicateFD e = e :. hreplicateFD @(n - 1) e++type family HReplicateR (n :: Nat) (e :: a) :: [a] where+  HReplicateR 0 _ = '[]+  HReplicateR n e = e ': HReplicateR (n - 1) e++type HConcat xs = HConcatFD xs (HConcatR xs)++hconcat :: HConcat xs => HList xs -> HList (HConcatR xs)+hconcat = hconcatFD++type family HConcatR (a :: [Type]) :: [Type]++type instance HConcatR '[] = '[]++type instance HConcatR (x ': xs) = UnHList x ++ HConcatR xs++type family UnHList a :: [Type]++type instance UnHList (HList a) = a++class HConcatFD (xxs :: [k]) (xs :: [k]) | xxs -> xs where+  hconcatFD :: HList xxs -> HList xs++instance HConcatFD '[] '[] where+  hconcatFD _ = HNil++instance (HConcatFD as bs, HAppendFD a bs cs) => HConcatFD (HList a ': as) cs where+  hconcatFD (x :. xs) = x `happendFD` hconcatFD xs++type HAppend as bs = HAppendFD as bs (as ++ bs)++happend :: HAppend as bs => HList as -> HList bs -> HList (as ++ bs)+happend = happendFD++hunappend ::+  ( cs ~ (as ++ bs),+    HAppend as bs+  ) =>+  HList cs ->+  (HList as, HList bs)+hunappend = hunappendFD++class HAppendFD (a :: [k]) (b :: [k]) (ab :: [k]) | a b -> ab, a ab -> b where+  happendFD :: HList a -> HList b -> HList ab+  hunappendFD :: HList ab -> (HList a, HList b)++type family (as :: [k]) ++ (bs :: [k]) :: [k] where+  '[] ++ bs = bs+  (a ': as) ++ bs = a ': as ++ bs++instance HAppendFD '[] b b where+  happendFD _ b = b+  hunappendFD b = (HNil, b)++instance+  ( HAppendFD as bs cs+  ) =>+  HAppendFD (a ': as :: [Type]) bs (a ': cs :: [Type])+  where+  happendFD (a :. as) bs = a :. happendFD as bs+  hunappendFD (a :. cs) = let (as, bs) = hunappendFD cs in (a :. as, bs)++class HZip (xs :: [k]) (ys :: [k]) (zs :: [k]) | xs ys -> zs, zs -> xs ys where+  hzip :: HList xs -> HList ys -> HList zs+  hunzip :: HList zs -> (HList xs, HList ys)++instance HZip '[] '[] '[] where+  hzip _ _ = HNil+  hunzip _ = (HNil, HNil)++instance ((x, y) ~ z, HZip xs ys zs) => HZip (x ': xs) (y ': ys) (z ': zs) where+  hzip (x :. xs) (y :. ys) = (x, y) :. hzip xs ys+  hunzip (~(x, y) :. zs) = let ~(xs, ys) = hunzip zs in (x :. xs, y :. ys)++class HZip' (xs :: [k]) (ys :: [k]) (zs :: [k]) | xs ys -> zs where+  hzip' :: HList xs -> HList ys -> HList zs++instance HZip' '[] '[] '[] where+  hzip' _ _ = HNil++instance+  ( HList (x ': y) ~ z,+    HZip' xs ys zs+  ) =>+  HZip' (x ': xs) (HList y ': ys) (z ': zs)+  where+  hzip' (x :. xs) (y :. ys) = (x :. y) :. hzip' xs ys++data HZipF = HZipF++instance+  ( HZip' a b c,+    x ~ (HList a, HList b),+    y ~ HList c+  ) =>+  Apply' HZipF x y+  where+  apply' _ (x, y) = hzip' x y++htranspose ::+  forall (acc :: [Type]) (xs :: [Type]) (xxs :: [Type]) (res :: Type).+  ( HReplicateFD (ListLength xs) (HList ('[] :: [Type])) acc,+    HFoldr HZipF (HList acc) (HList xs : xxs) res+  ) =>+  HList (HList xs : xxs) ->+  res+htranspose (xs :. xxs) =+  hfoldr+    HZipF+    (hreplicateFD @(ListLength xs) (HNil :: HList ('[] :: [Type])))+    (xs :. xxs)++class HZipWith f (xs :: [k]) (ys :: [k]) (zs :: [k]) | f xs ys -> zs where+  hzipWith :: f -> HList xs -> HList ys -> HList zs++instance HZipWith f '[] '[] '[] where+  hzipWith _ _ _ = HNil++instance+  ( Apply' f (x, y) z,+    HZipWith f xs ys zs+  ) =>+  HZipWith f (x ': xs) (y ': ys) (z ': zs)+  where+  hzipWith f (x :. xs) (y :. ys) = apply' f (x, y) :. hzipWith f xs ys++class HZipWithM m f (xs :: [k]) (ys :: [k]) (zs :: [k]) | f xs ys -> zs where+  hzipWithM :: f -> HList xs -> HList ys -> m (HList zs)++instance (Applicative m) => HZipWithM m f '[] '[] '[] where+  hzipWithM _ _ _ = pure HNil++instance+  ( Applicative m,+    Apply' f (x, y) (m z),+    HZipWithM m f xs ys zs+  ) =>+  HZipWithM m f (x ': xs) (y ': ys) (z ': zs)+  where+  hzipWithM f (x :. xs) (y :. ys) = (:.) <$> apply' f (x, y) <*> hzipWithM f xs ys++class+  HZip3+    (as :: [k])+    (bs :: [k])+    (cs :: [k])+    (ds :: [k])+    | as bs cs -> ds,+      ds -> as bs cs+  where+  hzip3 :: HList as -> HList bs -> HList cs -> HList ds+  hunzip3 :: HList ds -> (HList as, HList bs, HList cs)++instance HZip3 '[] '[] '[] '[] where+  hzip3 _ _ _ = HNil+  hunzip3 _ = (HNil, HNil, HNil)++instance+  ( (a, b, c) ~ d,+    HZip3 as bs cs ds+  ) =>+  HZip3 (a ': as) (b ': bs) (c ': cs) (d ': ds)+  where+  hzip3 (a :. as) (b :. bs) (c :. cs) = (a, b, c) :. hzip3 as bs cs+  hunzip3 (~(a, b, c) :. ds) =+    let ~(as, bs, cs) = hunzip3 ds in (a :. as, b :. bs, c :. cs)++class+  HZipWith3+    f+    (as :: [k])+    (bs :: [k])+    (cs :: [k])+    (ds :: [k])+    | f as bs cs -> ds+  where+  hzipWith3 :: f -> HList as -> HList bs -> HList cs -> HList ds++instance HZipWith3 f '[] '[] '[] '[] where+  hzipWith3 _ _ _ _ = HNil++instance+  ( Apply' f (a, b, c) d,+    HZipWith3 f as bs cs ds+  ) =>+  HZipWith3 f (a ': as) (b ': bs) (c ': cs) (d ': ds)+  where+  hzipWith3 f (a :. as) (b :. bs) (c :. cs) = apply' f (a, b, c) :. hzipWith3 f as bs cs++class HCartesianProduct (xs :: [k]) (ys :: [k]) (zs :: [k]) | xs ys -> zs where+  hproduct :: HList xs -> HList ys -> HList zs++instance HCartesianProduct '[] ys '[] where+  hproduct _ _ = HNil++class HAttach x (ys :: [k]) (zs :: [k]) | x ys -> zs where+  hattach :: x -> HList ys -> HList zs++instance HAttach x '[] '[] where+  hattach _ _ = HNil++instance (HAttach x ys xys) => HAttach x (y ': ys) ((x, y) ': xys) where+  hattach x (y :. ys) = (x, y) :. hattach x ys++instance+  ( HCartesianProduct xs ys zs,+    HAttach x ys xys,+    HAppendFD xys zs zs'+  ) =>+  HCartesianProduct (x ': xs) ys zs'+  where+  hproduct (x :. xs) ys = hattach x ys `happendFD` hproduct xs ys
+ src/Torch/Index.hs view
@@ -0,0 +1,183 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TemplateHaskell #-}++module Torch.Index+  ( slice,+    lslice,+  )+where++import Control.Monad ((>=>))+import Data.Void+import Language.Haskell.TH.Lib+import Language.Haskell.TH.Quote (QuasiQuoter (..))+import Language.Haskell.TH.Syntax hiding (Unsafe)+import Text.Megaparsec as M+import Text.Megaparsec.Char hiding (space)+import Text.Megaparsec.Char.Lexer+import Torch.Tensor++type Parser = Parsec Void String++sc :: Parser ()+sc = space space1 empty empty++lexm :: Parser a -> Parser a+lexm = lexeme sc++parseSlice :: String -> Q [Exp]+parseSlice str =+  case M.runParser parse' "slice" str of+    Left e -> fail $ show e+    Right v -> return v+  where+    parse' :: Parser [Exp]+    parse' = (sc >> (try slice <|> try bool <|> try other <|> number)) `sepBy` char ','+    other :: Parser Exp+    other =+      ( do+          _ <- lexm $ string ("None" :: Tokens String)+          pure $ ConE 'None+      )+        <|> ( do+                _ <- lexm $ string ("Ellipsis" :: Tokens String)+                pure $ ConE 'Ellipsis+            )+        <|> ( do+                _ <- lexm $ string ("..." :: Tokens String)+                pure $ ConE 'Ellipsis+            )+    bool :: Parser Exp+    bool =+      ( do+          _ <- lexm $ string "True"+          pure $ ConE 'True+      )+        <|> ( do+                _ <- lexm $ string "False"+                pure $ ConE 'False+            )+    number :: Parser Exp+    number =+      ( do+          v <- lexm decimal+          pure $ LitE (IntegerL v)+      )+        <|> ( do+                _ <- lexm $ string "-"+                v <- lexm decimal+                pure $ LitE (IntegerL (- v))+            )+        <|> ( do+                v <- lexm $ between (char '{') (char '}') (some alphaNumChar)+                pure $ VarE (mkName v)+            )+    slice =+      try+        ( do+            a <- number+            lexm $ string ":"+            b <- number+            lexm $ string ":"+            c <- number+            pure $ AppE (ConE 'Slice) (TupE [Just a, Just b, Just c])+        )+        <|> try+          ( do+              lexm $ string ":"+              b <- number+              lexm $ string ":"+              c <- number+              pure $ AppE (ConE 'Slice) (TupE [Just (ConE 'None), Just b, Just c])+          )+        <|> try+          ( do+              a <- number+              lexm $ string "::"+              c <- number+              pure $ AppE (ConE 'Slice) (TupE [Just a, Just (ConE 'None), Just c])+          )+        <|> try+          ( do+              a <- number+              lexm $ string ":"+              b <- number+              pure $ AppE (ConE 'Slice) (TupE [Just a, Just b])+          )+        <|> try+          ( do+              lexm $ string "::"+              c <- number+              pure $ AppE (ConE 'Slice) (TupE [Just (ConE 'None), Just (ConE 'None), Just c])+          )+        <|> try+          ( do+              lexm $ string ":"+              b <- number+              lexm $ string ":"+              pure $ AppE (ConE 'Slice) (TupE [Just (ConE 'None), Just b])+          )+        <|> try+          ( do+              lexm $ string ":"+              b <- number+              pure $ AppE (ConE 'Slice) (TupE [Just (ConE 'None), Just b])+          )+        <|> try+          ( do+              a <- number+              lexm $ string "::"+              pure $ AppE (ConE 'Slice) (TupE [Just a, Just (ConE 'None)])+          )+        <|> try+          ( do+              a <- number+              lexm $ string ":"+              pure $ AppE (ConE 'Slice) (TupE [Just a, Just (ConE 'None)])+          )+        <|> try+          ( do+              _ <- lexm $ string "::"+              pure $ AppE (ConE 'Slice) (ConE '())+          )+        <|> ( do+                _ <- lexm $ string ":"+                pure $ AppE (ConE 'Slice) (ConE '())+            )++-- | Generate a slice from a [python compatible expression](https://pytorch.org/cppdocs/notes/tensor_indexing.html).+-- When you take the odd-numbered element of tensor with `tensor[1::2]` in python,+-- you can write `tensor ! [slice|1::2|]` in hasktorch.+slice :: QuasiQuoter+slice =+  QuasiQuoter+    { quoteExp = parseSlice >=> qconcat,+      quotePat = error "quotePat is not implemented for slice.",+      quoteDec = error "quoteDec is not implemented for slice.",+      quoteType = error "quoteType is not implemented for slice."+    }+  where+    qconcat :: [Exp] -> Q Exp+    qconcat [exp] = pure exp+    qconcat exps = pure $ TupE $ map Just exps++-- | Generate a lens from a [python compatible expression](https://pytorch.org/cppdocs/notes/tensor_indexing.html).+-- When you take the odd-numbered elements of tensor with `tensor[1::2]` in python,+-- you can write `tensor ^. [lslice|1::2|]` in hasktorch.+-- When you put 2 in the odd numbered elements of the tensor,+-- you can write `tensor & [lslice|1::2|] ~. 2`.+lslice :: QuasiQuoter+lslice =+  QuasiQuoter+    { quoteExp = parseSlice >=> qconcat,+      quotePat = error "quotePat is not implemented for slice.",+      quoteDec = error "quoteDec is not implemented for slice.",+      quoteType = error "quoteType is not implemented for slice."+    }+  where+    qconcat :: [Exp] -> Q Exp+    qconcat [exp] = pure $ AppE (VarE 'toLens) exp+    qconcat exps = pure $ AppE (VarE 'toLens) $ TupE $ map Just exps
+ src/Torch/Initializers.hs view
@@ -0,0 +1,100 @@+module Torch.Initializers where++import Torch.Functional hiding (sqrt)+import Torch.Tensor+import Torch.TensorFactories++-- Note: Identity = linear w/o activation+data NonLinearity = Identity | Sigmoid | Tanh | Relu | LeakyRelu Float++data FanMode = FanIn | FanOut++newtype Shape = Shape [Int]++-- | Gain scaling value for He initialization+calculateGain :: NonLinearity -> Float+calculateGain Identity = 1.0+calculateGain Sigmoid = 1.0+calculateGain Tanh = 5.0 / 3+calculateGain Relu = sqrt 2.0+calculateGain (LeakyRelu param) = sqrt (2.0 / (1.0 + param ^^ 2))++-- | Fan-in / Fan-out scaling calculation+calculateFan :: [Int] -> (Int, Int)+calculateFan shape+  | dimT < 2 = error "Fan in and fan out can not be computed for tensor with fewer than 2 dimensions"+  | dimT == 2 = (shape !! 1, head shape)+  | otherwise = (numInputFmaps * receptiveFieldSize, numOutputFmaps * receptiveFieldSize)+  where+    dimT = length shape+    numInputFmaps = shape !! 1 -- size t 1+    numOutputFmaps = head shape -- size t 0+    receptiveFieldSize = product $ tail shape++-- | Xavier Initialization - Uniform+xavierUniform :: Float -> [Int] -> IO Tensor+xavierUniform gain shape = do+  init <- randIO' shape+  pure $ subScalar bound $ mulScalar (bound * 2.0) init+  where+    (fanIn, fanOut) = calculateFan shape+    std = gain * sqrt (2.0 / (fromIntegral fanIn + fromIntegral fanOut))+    bound = sqrt 3.0 * std++-- | Xavier Initialization - Normal+xavierNormal :: Float -> [Int] -> IO Tensor+xavierNormal gain shape = do+  init <- randnIO' shape+  pure $ mulScalar std init+  where+    (fanIn, fanOut) = calculateFan shape+    std = gain * sqrt (2.0 / (fromIntegral fanIn + fromIntegral fanOut))++-- | Get fan in or fan out value depending on selected fan mode, used by Kaiming+getter :: FanMode -> ((Int, Int) -> Int)+getter FanIn = fst+getter FanOut = snd++-- | Kaiming Initialization - Uniform+kaimingUniform :: FanMode -> NonLinearity -> [Int] -> IO Tensor+kaimingUniform mode nonlinearity shape = do+  init <- randIO' shape+  pure $ subScalar bound $ mulScalar (bound * 2.0) init+  where+    fanValue = fromIntegral $ getter mode (calculateFan shape)+    std = calculateGain nonlinearity / sqrt fanValue+    bound = sqrt 3.0 * std++-- | Kaiming Initialization - Normal+kaimingNormal :: FanMode -> NonLinearity -> [Int] -> IO Tensor+kaimingNormal mode nonlinearity shape = mulScalar std <$> randnIO' shape+  where+    fanValue = fromIntegral $ getter mode (calculateFan shape)+    std = calculateGain nonlinearity / sqrt fanValue++-- | Handle weights + bias+-- based on https://github.com/pytorch/pytorch/blob/master/torch/nn/modules/linear.py#L79+kaimingFC :: [Int] -> IO (Tensor, Tensor)+kaimingFC weightShape = do+  weight <- kaimingUniform' weightShape+  biasInit <- randIO' biasShape+  let bias = subScalar bound $ mulScalar (bound * 2.0) biasInit+  pure (weight, bias)+  where+    (fanIn, _) = calculateFan weightShape+    bound = 1.0 / (sqrt . fromIntegral $ fanIn) :: Float+    biasShape = [head weightShape]++{- PyTorch defaults -}++kaimingUniform' :: [Int] -> IO Tensor+kaimingUniform' = kaimingUniform FanIn (LeakyRelu 0.0)++kaimingNormal' :: [Int] -> IO Tensor+kaimingNormal' = kaimingNormal FanIn (LeakyRelu 0.0)++xavierUniform' :: [Int] -> IO Tensor+xavierUniform' = xavierUniform 1.0++xavierNormal' :: [Int] -> IO Tensor+xavierNormal' = xavierNormal 1.0
− src/Torch/Int.hs
@@ -1,29 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Int--- Copyright :  (c) Sam Stites 2017--- License   :  BSD3--- Maintainer:  sam@stites.io--- Stability :  experimental--- Portability: non-portable---------------------------------------------------------------------------------module Torch.Int (module X) where--import Torch.Int.Index as X-import Torch.Indef.Int.Tensor as X-import Torch.Indef.Int.Tensor.Copy as X-import Torch.Indef.Int.Tensor.Index as X-import Torch.Indef.Int.Tensor.Masked as X-import Torch.Indef.Int.Tensor.Math as X-import Torch.Indef.Int.Tensor.Math.Compare as X-import Torch.Indef.Int.Tensor.Math.CompareT as X-import Torch.Indef.Int.Tensor.Math.Pairwise as X-import Torch.Indef.Int.Tensor.Math.Pointwise as X-import Torch.Indef.Int.Tensor.Math.Reduce as X-import Torch.Indef.Int.Tensor.Math.Scan as X-import Torch.Indef.Int.Tensor.Mode as X-import Torch.Indef.Int.Tensor.ScatterGather as X-import Torch.Indef.Int.Tensor.Sort as X-import Torch.Indef.Int.Tensor.TopK as X--import Torch.Indef.Int.Tensor.Math.Pointwise.Signed as X
− src/Torch/Int/Dynamic.hs
@@ -1,28 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Int.Dynamic--- Copyright :  (c) Sam Stites 2017--- License   :  BSD3--- Maintainer:  sam@stites.io--- Stability :  experimental--- Portability: non-portable---------------------------------------------------------------------------------module Torch.Int.Dynamic (module X) where--import Torch.Indef.Int.Dynamic.Tensor as X-import Torch.Indef.Int.Dynamic.Tensor.Copy as X-import Torch.Indef.Int.Dynamic.Tensor.Index as X-import Torch.Indef.Int.Dynamic.Tensor.Masked as X-import Torch.Indef.Int.Dynamic.Tensor.Math as X-import Torch.Indef.Int.Dynamic.Tensor.Math.Compare as X-import Torch.Indef.Int.Dynamic.Tensor.Math.CompareT as X-import Torch.Indef.Int.Dynamic.Tensor.Math.Pairwise as X-import Torch.Indef.Int.Dynamic.Tensor.Math.Pointwise as X-import Torch.Indef.Int.Dynamic.Tensor.Math.Reduce as X-import Torch.Indef.Int.Dynamic.Tensor.Math.Scan as X-import Torch.Indef.Int.Dynamic.Tensor.Mode as X-import Torch.Indef.Int.Dynamic.Tensor.ScatterGather as X-import Torch.Indef.Int.Dynamic.Tensor.Sort as X-import Torch.Indef.Int.Dynamic.Tensor.TopK as X--import Torch.Indef.Int.Dynamic.Tensor.Math.Pointwise.Signed as X
− src/Torch/Int/Storage.hs
@@ -1,13 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Int.Storage--- Copyright :  (c) Sam Stites 2017--- License   :  BSD3--- Maintainer:  sam@stites.io--- Stability :  experimental--- Portability: non-portable---------------------------------------------------------------------------------module Torch.Int.Storage (module X) where--import Torch.Indef.Int.Storage      as X-import Torch.Indef.Int.Storage.Copy as X
+ src/Torch/Jit.hs view
@@ -0,0 +1,40 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-}++module Torch.Jit where++import Torch.Script+import Torch.Tensor+import Torch.NN+import Control.Concurrent.STM.TVar+import Control.Concurrent.STM (atomically)+import System.IO.Unsafe (unsafePerformIO)++newtype ScriptCache = ScriptCache { unScriptCache :: TVar (Maybe ScriptModule) }++newScriptCache :: IO ScriptCache+newScriptCache = ScriptCache <$> newTVarIO Nothing++jitIO :: ScriptCache -> ([Tensor] -> IO [Tensor]) -> [Tensor] -> IO [Tensor]+jitIO (ScriptCache cache) func input = do+  v <- readTVarIO cache+  script <- case v of+    Just script' -> return script'+    Nothing -> do+      m <- trace "MyModule" "forward" func input+      script' <- toScriptModule m+      atomically $ writeTVar cache (Just script')+      return script'+  IVTensor r0 <- forwardStoch script (map IVTensor input)+  return [r0]++jit :: ScriptCache -> ([Tensor] -> [Tensor]) -> [Tensor] -> [Tensor]+jit cache func input = unsafePerformIO $ jitIO cache (return . func) input
+ src/Torch/Layout.hs view
@@ -0,0 +1,21 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}++module Torch.Layout where++import Torch.Internal.Class (Castable (..))+import qualified Torch.Internal.Const as ATen+import qualified Torch.Internal.Type as ATen++data Layout = Strided | Sparse | Mkldnn+  deriving (Eq, Show)++instance Castable Layout ATen.Layout where+  cast Strided f = f ATen.kStrided+  cast Sparse f = f ATen.kSparse+  cast Mkldnn f = f ATen.kMkldnn++  uncast x f+    | x == ATen.kStrided = f Strided+    | x == ATen.kSparse = f Sparse+    | x == ATen.kMkldnn = f Mkldnn
+ src/Torch/Lens.hs view
@@ -0,0 +1,97 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}++module Torch.Lens where++import Control.Monad.Identity+import Control.Monad.State.Strict+import GHC.Generics++-- | Type synonym for lens+type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t++type Lens' s a = Lens s s a a++type Traversal s t a b = forall f. Applicative f => (a -> f b) -> s -> f t++type Traversal' s a = Traversal s s a a++class HasTypes s a where+  types_ :: Traversal' s a+  default types_ :: (Generic s, GHasTypes (Rep s) a) => Traversal' s a+  types_ func s = to <$> gtypes func (from s)+  {-# INLINE types_ #-}++instance {-# OVERLAPS #-} (Generic s, GHasTypes (Rep s) a) => HasTypes s a++over :: Traversal' s a -> (a -> a) -> s -> s+over l f = runIdentity . l (Identity . f)++flattenValues :: forall a s. Traversal' s a -> s -> [a]+flattenValues func orgData = reverse . snd $ runState (func push orgData) []+  where+    push :: a -> State [a] a+    push v = do+      d <- get+      put $ v : d+      return v++replaceValues :: forall a s. Traversal' s a -> s -> [a] -> s+replaceValues func orgData newValues = fst $ runState (func pop orgData) newValues+  where+    pop :: a -> State [a] a+    pop _ = do+      d <- get+      case d of+        [] -> error "Not enough values supplied to replaceValues"+        x : xs -> do+          put xs+          return x++types :: forall a s. HasTypes s a => Traversal' s a+types = types_ @s @a++class GHasTypes s a where+  gtypes :: forall b. Traversal' (s b) a++instance GHasTypes U1 a where+  gtypes _ = pure+  {-# INLINE gtypes #-}++instance (GHasTypes f a, GHasTypes g a) => GHasTypes (f :+: g) a where+  gtypes func (L1 x) = L1 <$> gtypes func x+  gtypes func (R1 x) = R1 <$> gtypes func x++instance (GHasTypes f a, GHasTypes g a) => GHasTypes (f :*: g) a where+  gtypes func (x :*: y) = (:*:) <$> gtypes func x <*> gtypes func y+  {-# INLINE gtypes #-}++instance (HasTypes s a) => GHasTypes (K1 i s) a where+  gtypes func (K1 x) = K1 <$> types func x+  {-# INLINE gtypes #-}++instance GHasTypes s a => GHasTypes (M1 i t s) a where+  gtypes func (M1 x) = M1 <$> gtypes func x+  {-# INLINE gtypes #-}++instance {-# OVERLAPS #-} (HasTypes s a) => HasTypes [s] a where+  types_ func [] = pure []+  types_ func (x : xs) = (:) <$> types_ func x <*> types_ func xs+  {-# INLINE types_ #-}++instance {-# OVERLAPS #-} (HasTypes s0 a, HasTypes s1 a) => HasTypes (s0, s1) a where+  types_ func (s0, s1) = (,) <$> types_ func s0 <*> types_ func s1+  {-# INLINE types_ #-}++instance {-# OVERLAPS #-} (HasTypes s0 a, HasTypes s1 a, HasTypes s2 a) => HasTypes (s0, s1, s2) a where+  types_ func (s0, s1, s2) = (,,) <$> types_ func s0 <*> types_ func s1 <*> types_ func s2+  {-# INLINE types_ #-}
− src/Torch/Long.hs
@@ -1,35 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Long--- Copyright :  (c) Sam Stites 2017--- License   :  BSD3--- Maintainer:  sam@stites.io--- Stability :  experimental--- Portability: non-portable---------------------------------------------------------------------------------module Torch.Long (module X) where--import Numeric.Dimensions as X-import Torch.Types.TH as X--import Torch.Long.Types as X hiding (storage)-import Torch.Long.Index as X hiding (withDynamicState)-import Torch.Long.Mask as X--import Torch.Indef.Long.Tensor as X-import Torch.Indef.Long.Tensor.Copy as X-import Torch.Indef.Long.Tensor.Index as X-import Torch.Indef.Long.Tensor.Masked as X-import Torch.Indef.Long.Tensor.Math as X-import Torch.Indef.Long.Tensor.Math.Compare as X-import Torch.Indef.Long.Tensor.Math.CompareT as X-import Torch.Indef.Long.Tensor.Math.Pairwise as X-import Torch.Indef.Long.Tensor.Math.Pointwise as X-import Torch.Indef.Long.Tensor.Math.Reduce as X-import Torch.Indef.Long.Tensor.Math.Scan as X-import Torch.Indef.Long.Tensor.Mode as X-import Torch.Indef.Long.Tensor.ScatterGather as X-import Torch.Indef.Long.Tensor.Sort as X-import Torch.Indef.Long.Tensor.TopK as X--import Torch.Indef.Long.Tensor.Math.Pointwise.Signed as X
− src/Torch/Long/Dynamic.hs
@@ -1,28 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Long.Dynamic--- Copyright :  (c) Sam Stites 2017--- License   :  BSD3--- Maintainer:  sam@stites.io--- Stability :  experimental--- Portability: non-portable---------------------------------------------------------------------------------module Torch.Long.Dynamic (module X) where--import Torch.Indef.Long.Dynamic.Tensor as X-import Torch.Indef.Long.Dynamic.Tensor.Copy as X-import Torch.Indef.Long.Dynamic.Tensor.Index as X-import Torch.Indef.Long.Dynamic.Tensor.Masked as X-import Torch.Indef.Long.Dynamic.Tensor.Math as X-import Torch.Indef.Long.Dynamic.Tensor.Math.Compare as X-import Torch.Indef.Long.Dynamic.Tensor.Math.CompareT as X-import Torch.Indef.Long.Dynamic.Tensor.Math.Pairwise as X-import Torch.Indef.Long.Dynamic.Tensor.Math.Pointwise as X-import Torch.Indef.Long.Dynamic.Tensor.Math.Reduce as X-import Torch.Indef.Long.Dynamic.Tensor.Math.Scan as X-import Torch.Indef.Long.Dynamic.Tensor.Mode as X-import Torch.Indef.Long.Dynamic.Tensor.ScatterGather as X-import Torch.Indef.Long.Dynamic.Tensor.Sort as X-import Torch.Indef.Long.Dynamic.Tensor.TopK as X--import Torch.Indef.Long.Dynamic.Tensor.Math.Pointwise.Signed as X
− src/Torch/Long/Storage.hs
@@ -1,13 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Long.Storage--- Copyright :  (c) Sam Stites 2017--- License   :  BSD3--- Maintainer:  sam@stites.io--- Stability :  experimental--- Portability: non-portable---------------------------------------------------------------------------------module Torch.Long.Storage (module X) where--import Torch.Indef.Long.Storage      as X-import Torch.Indef.Long.Storage.Copy as X
+ src/Torch/NN.hs view
@@ -0,0 +1,762 @@+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE OverloadedRecordDot #-}+{-# LANGUAGE DuplicateRecordFields #-}++module Torch.NN where++import Control.Applicative (Applicative (liftA2))+import Control.Monad.State.Strict+import Data.Foldable (toList)+import Data.Kind+import GHC.Generics+import System.IO.Unsafe (unsafePerformIO)+import Torch.Autograd+import Torch.Device+import Torch.Functional+import Torch.Initializers+import Torch.Internal.Cast (cast3)+import qualified Torch.Internal.Managed.Native as ATen+import qualified Torch.Internal.Managed.Type.Tensor as ATen+import Torch.Scalar+import Torch.Tensor+import Torch.TensorFactories (ones', randIO', randnIO', zeros')++type Parameter = IndependentTensor++type ParamStream a = State [Parameter] a++nextParameter :: ParamStream Parameter+nextParameter = do+  params <- get+  case params of+    [] -> error "Not enough parameters supplied to replaceParameters"+    (p : t) -> do put t; return p++class HasForward f a b | f a -> b where+  forward :: f -> a -> b+  default forward ::+    ( Generic f,+      Generic a,+      Generic b,+      GHasForward (Rep f) (Rep a) (Rep b)+    ) =>+    f ->+    a ->+    b+  forward f a = to $ gForward (from f) (from a)+  forwardStoch :: f -> a -> IO b+  default forwardStoch ::+    ( Generic f,+      Generic a,+      Generic b,+      GHasForward (Rep f) (Rep a) (Rep b)+    ) =>+    f ->+    a ->+    IO b+  forwardStoch f a = to <$> gForwardStoch (from f) (from a)++class GHasForward (f :: Type -> Type) (a :: Type -> Type) (b :: Type -> Type) | f a -> b where+  gForward :: forall c c' c''. f c -> a c' -> b c''+  gForwardStoch :: forall c c' c''. f c -> a c' -> IO (b c)++instance GHasForward U1 U1 U1 where+  gForward U1 U1 = U1+  gForwardStoch U1 U1 = return U1++instance+  ( GHasForward f a b,+    GHasForward g a' b',+    b'' ~ (b :+: b')+  ) =>+  GHasForward (f :+: g) (a :+: a') b''+  where+  gForward (L1 f) (L1 a) = L1 $ gForward f a+  gForward (R1 g) (R1 a') = R1 $ gForward g a'+  gForwardStoch (L1 f) (L1 a) = L1 <$> gForwardStoch f a+  gForwardStoch (R1 g) (R1 a') = R1 <$> gForwardStoch g a'++instance+  ( GHasForward f a b,+    GHasForward g a' b',+    b'' ~ (b :*: b')+  ) =>+  GHasForward (f :*: g) (a :*: a') b''+  where+  gForward (f :*: g) (a :*: a') = gForward f a :*: gForward g a'+  gForwardStoch (f :*: g) (a :*: a') = liftA2 (:*:) (gForwardStoch f a) (gForwardStoch g a')++instance+  (HasForward f a b) =>+  GHasForward (K1 i f) (K1 i a) (K1 i b)+  where+  gForward (K1 f) (K1 a) = K1 $ forward f a+  gForwardStoch (K1 f) (K1 a) = K1 <$> forwardStoch f a++instance+  (GHasForward f a b) =>+  GHasForward (M1 i t f) (M1 i t' a) (M1 i t' b)+  where+  gForward (M1 f) (M1 a) = M1 $ gForward f a+  gForwardStoch (M1 f) (M1 a) = M1 <$> gForwardStoch f a++class Parameterized f where+  flattenParameters :: f -> [Parameter]+  default flattenParameters :: (Generic f, GParameterized (Rep f)) => f -> [Parameter]+  flattenParameters f = gFlattenParameters (from f)++  _replaceParameters :: f -> ParamStream f+  default _replaceParameters :: (Generic f, GParameterized (Rep f)) => f -> ParamStream f+  _replaceParameters f = to <$> _gReplaceParameters (from f)++replaceParameters :: Parameterized f => f -> [Parameter] -> f+replaceParameters f params =+  let (f', remaining) = runState (_replaceParameters f) params+   in if null remaining+        then f'+        else error "Some parameters in a call to replaceParameters haven't been consumed!"++instance Parameterized Tensor where+  flattenParameters _ = []+  _replaceParameters = return++instance Parameterized Parameter where+  flattenParameters = pure+  _replaceParameters _ = nextParameter++instance {-# OVERLAPS #-} (Scalar a) => Parameterized a where+  flattenParameters _ = []+  _replaceParameters = return++instance {-# OVERLAPS #-} (Parameterized a, Parameterized b) => Parameterized (a, b) where+  flattenParameters (a, b) = flattenParameters a ++ flattenParameters b+  _replaceParameters (a, b) = do+    a' <- _replaceParameters a+    b' <- _replaceParameters b+    return (a', b')++instance {-# OVERLAPS #-} (Parameterized a, Parameterized b, Parameterized c) => Parameterized (a, b, c) where+  flattenParameters (a, b, c) = flattenParameters a ++ flattenParameters b ++ flattenParameters c+  _replaceParameters (a, b, c) = do+    a' <- _replaceParameters a+    b' <- _replaceParameters b+    c' <- _replaceParameters c+    return (a', b', c')++instance {-# OVERLAPS #-} (Foldable t, Traversable t, Parameterized a) => Parameterized (t a) where+  flattenParameters = (=<<) flattenParameters . toList+  _replaceParameters = mapM _replaceParameters++instance Parameterized (a -> a) where+  flattenParameters _ = []+  _replaceParameters = return++class GParameterized f where+  gFlattenParameters :: forall a. f a -> [Parameter]+  _gReplaceParameters :: forall a. f a -> ParamStream (f a)++instance GParameterized U1 where+  gFlattenParameters U1 = []+  _gReplaceParameters U1 = return U1++instance (GParameterized f, GParameterized g) => GParameterized (f :+: g) where+  gFlattenParameters (L1 x) = gFlattenParameters x+  gFlattenParameters (R1 x) = gFlattenParameters x+  _gReplaceParameters (L1 x) = do+    x' <- _gReplaceParameters x+    return $ L1 x'+  _gReplaceParameters (R1 x) = do+    x' <- _gReplaceParameters x+    return $ R1 x'++instance (GParameterized f, GParameterized g) => GParameterized (f :*: g) where+  gFlattenParameters (x :*: y) = gFlattenParameters x ++ gFlattenParameters y+  _gReplaceParameters (x :*: y) = do+    x' <- _gReplaceParameters x+    y' <- _gReplaceParameters y+    return $ x' :*: y'++instance (Parameterized c) => GParameterized (K1 i c) where+  gFlattenParameters (K1 x) = flattenParameters x+  _gReplaceParameters (K1 x) = do+    x' <- _replaceParameters x+    return $ K1 x'++instance (GParameterized f) => GParameterized (M1 i t f) where+  gFlattenParameters (M1 x) = gFlattenParameters x+  _gReplaceParameters (M1 x) = do+    x' <- _gReplaceParameters x+    return $ M1 x'++class Randomizable spec f | spec -> f where+  sample :: spec -> IO f++--+-- Linear FC Layer+--++data LinearSpec = LinearSpec+  { in_features :: Int,+    out_features :: Int+  }+  deriving (Show, Eq)++data Linear = Linear+  { weight :: Parameter,+    bias :: Parameter+  }+  deriving (Show, Generic, Parameterized)++linear :: Linear -> Tensor -> Tensor+linear layer input = linear' input w b+  where+    linear' input weight bias = unsafePerformIO $ cast3 ATen.linear_ttt input weight bias+    w = toDependent (layer.weight)+    b = toDependent (layer.bias)++linearForward :: Linear -> Tensor -> Tensor+linearForward = linear -- temporary alias until dependencies are updated++instance HasForward Linear Tensor Tensor where+  forward = linearForward+  forwardStoch m x = pure $ linearForward m x++instance Randomizable LinearSpec Linear where+  sample LinearSpec {..} = do+    w <-+      makeIndependent+        =<< kaimingUniform+          FanIn+          (LeakyRelu $ Prelude.sqrt (5.0 :: Float))+          [out_features, in_features]+    init <- randIO' [out_features]+    let bound =+          (1 :: Float)+            / Prelude.sqrt+              ( fromIntegral+                  ( getter FanIn $+                      calculateFan+                        [ out_features,+                          in_features+                        ]+                  ) ::+                  Float+              )+    b <-+      makeIndependent+        =<< pure+          ( subScalar bound $ mulScalar (bound * 2.0) init+          )+    return $ Linear w b++--+-- Conv1d+--+data Conv1dSpec = Conv1dSpec+  { inputChannelSize1d :: Int,+    outputChannelSize1d :: Int,+    kernelSize :: Int+  }+  deriving (Show, Eq)++data Conv1d = Conv1d+  { weight :: Parameter,+    bias :: Parameter+  }+  deriving (Show, Generic, Parameterized)++conv1dForward ::+  -- | layer+  Conv1d ->+  -- | stride+  Int ->+  -- | padding+  Int ->+  -- | input+  Tensor ->+  -- | output+  Tensor+conv1dForward layer = Torch.Functional.conv1d' w b+  where+    w = toDependent (layer.weight)+    b = toDependent (layer.bias)++instance Randomizable Conv1dSpec Conv1d where+  sample Conv1dSpec {..} = do+    w <-+      makeIndependent+        =<< kaimingUniform+          FanIn+          (LeakyRelu $ Prelude.sqrt (5.0 :: Float))+          [ outputChannelSize1d,+            inputChannelSize1d,+            kernelSize+          ]+    init <- randIO' [outputChannelSize1d]+    let bound =+          (1 :: Float)+            / Prelude.sqrt+              ( fromIntegral+                  ( getter FanIn $+                      calculateFan+                        [ outputChannelSize1d,+                          inputChannelSize1d,+                          kernelSize+                        ]+                  ) ::+                  Float+              )+    b <-+      makeIndependent+        =<< pure+          ( subScalar bound $ mulScalar (bound * 2.0) init+          )+    return $ Conv1d w b++--+-- Conv2d+--++data Conv2dSpec = Conv2dSpec+  { inputChannelSize2d :: Int,+    outputChannelSize2d :: Int,+    kernelHeight2d :: Int,+    kernelWidth2d :: Int+  }+  deriving (Show, Eq)++data Conv2d = Conv2d+  { weight :: Parameter,+    bias :: Parameter+  }+  deriving (Show, Generic, Parameterized)++conv2dForward ::+  -- | layer+  Conv2d ->+  -- | stride+  (Int, Int) ->+  -- | padding+  (Int, Int) ->+  -- | input+  Tensor ->+  -- | output+  Tensor+conv2dForward layer = Torch.Functional.conv2d' w b+  where+    w = toDependent (layer.weight)+    b = toDependent (layer.bias)++instance Randomizable Conv2dSpec Conv2d where+  sample Conv2dSpec {..} = do+    w <-+      makeIndependent+        =<< kaimingUniform+          FanIn+          (LeakyRelu $ Prelude.sqrt (5.0 :: Float))+          [ outputChannelSize2d,+            inputChannelSize2d,+            kernelHeight2d,+            kernelWidth2d+          ]+    init <- randIO' [outputChannelSize2d]+    let bound =+          (1 :: Float)+            / Prelude.sqrt+              ( fromIntegral+                  ( getter FanIn $+                      calculateFan+                        [ outputChannelSize2d,+                          inputChannelSize2d,+                          kernelHeight2d,+                          kernelWidth2d+                        ]+                  ) ::+                  Float+              )+    b <-+      makeIndependent+        =<< pure+          ( subScalar bound $ mulScalar (bound * 2.0) init+          )+    return $ Conv2d w b++--+-- Conv3d+--++data Conv3dSpec = Conv3dSpec+  { inputChannelSize3d :: Int,+    outputChannelSize3d :: Int,+    kernelHeight3d :: Int,+    kernelWidth3d :: Int,+    kernelDepth3d :: Int+  }+  deriving (Show, Eq)++data Conv3d = Conv3d+  { weight :: Parameter,+    bias :: Parameter+  }+  deriving (Show, Generic, Parameterized)++conv3dForward ::+  -- | layer+  Conv3d ->+  -- | stride+  (Int, Int, Int) ->+  -- | padding+  (Int, Int, Int) ->+  -- | input+  Tensor ->+  -- | output+  Tensor+conv3dForward layer = Torch.Functional.conv3d' w b+  where+    w = toDependent (layer.weight)+    b = toDependent (layer.bias)++instance Randomizable Conv3dSpec Conv3d where+  sample Conv3dSpec {..} = do+    w <-+      makeIndependent+        =<< kaimingUniform+          FanIn+          (LeakyRelu $ Prelude.sqrt (5.0 :: Float))+          [ outputChannelSize3d,+            inputChannelSize3d,+            kernelHeight3d,+            kernelWidth3d,+            kernelDepth3d+          ]+    init <- randIO' [outputChannelSize3d]+    let bound =+          (1 :: Float)+            / Prelude.sqrt+              ( fromIntegral+                  ( getter FanIn $+                      calculateFan+                        [ outputChannelSize3d,+                          inputChannelSize3d,+                          kernelHeight3d,+                          kernelWidth3d,+                          kernelDepth3d+                        ]+                  ) ::+                  Float+              )+    b <-+      makeIndependent+        =<< pure+          ( subScalar bound $ mulScalar (bound * 2.0) init+          )+    return $ Conv3d w b++--+-- ConvTranspose1d+--++data ConvTranspose1dSpec = ConvTranspose1dSpec+  { trInputChannelSize1d :: Int,+    trOutputChannelSize1d :: Int,+    trKernelSize :: Int+  }+  deriving (Show, Eq)++data ConvTranspose1d = ConvTranspose1d+  { weight :: Parameter,+    bias :: Parameter+  }+  deriving (Show, Generic, Parameterized)++convTranspose1dForward ::+  -- | layer+  ConvTranspose1d ->+  -- | stride+  Int ->+  -- | padding+  Int ->+  -- | input+  Tensor ->+  -- | output+  Tensor+convTranspose1dForward layer = convTranspose1d' w b+  where+    w = toDependent (layer.weight)+    b = toDependent (layer.bias)++instance Randomizable ConvTranspose1dSpec ConvTranspose1d where+  sample ConvTranspose1dSpec {..} = do+    w <-+      makeIndependent+        =<< kaimingUniform+          FanIn+          (LeakyRelu $ Prelude.sqrt (5.0 :: Float))+          [ trInputChannelSize1d,+            trOutputChannelSize1d,+            trKernelSize+          ]+    init <- randIO' [trOutputChannelSize1d]+    let bound =+          (1 :: Float)+            / Prelude.sqrt+              ( fromIntegral+                  ( getter FanIn $+                      calculateFan+                        [ trInputChannelSize1d,+                          trOutputChannelSize1d,+                          trKernelSize+                        ]+                  ) ::+                  Float+              )+    b <-+      makeIndependent+        =<< pure+          ( subScalar bound $ mulScalar (bound * 2.0) init+          )+    return $ ConvTranspose1d w b++--+-- ConvTranspose2d+--++data ConvTranspose2dSpec = ConvTranspose2dSpec+  { trInputChannelSize2d :: Int,+    trOutputChannelSize2d :: Int,+    trKernelHeight2d :: Int,+    trKernelWidth2d :: Int+  }+  deriving (Show, Eq)++data ConvTranspose2d = ConvTranspose2d+  { weight :: Parameter,+    bias :: Parameter+  }+  deriving (Show, Generic, Parameterized)++convTranspose2dForward ::+  -- | layer+  ConvTranspose2d ->+  -- | stride+  (Int, Int) ->+  -- | padding+  (Int, Int) ->+  -- | input+  Tensor ->+  -- | output+  Tensor+convTranspose2dForward layer = convTranspose2d' w b+  where+    w = toDependent (layer.weight)+    b = toDependent (layer.bias)++instance Randomizable ConvTranspose2dSpec ConvTranspose2d where+  sample ConvTranspose2dSpec {..} = do+    w <-+      makeIndependent+        =<< kaimingUniform+          FanIn+          (LeakyRelu $ Prelude.sqrt (5.0 :: Float))+          [ trInputChannelSize2d,+            trOutputChannelSize2d,+            trKernelHeight2d,+            trKernelWidth2d+          ]+    init <- randIO' [trOutputChannelSize2d]+    let bound =+          (1 :: Float)+            / Prelude.sqrt+              ( fromIntegral+                  ( getter FanIn $+                      calculateFan+                        [ trInputChannelSize2d,+                          trOutputChannelSize2d,+                          trKernelHeight2d,+                          trKernelWidth2d+                        ]+                  ) ::+                  Float+              )+    b <-+      makeIndependent+        =<< pure+          ( subScalar bound $ mulScalar (bound * 2.0) init+          )+    return $ ConvTranspose2d w b++--+-- ConvTranspose2d+--++data ConvTranspose3dSpec = ConvTranspose3dSpec+  { trInputChannelSize3d :: Int,+    trOutputChannelSize3d :: Int,+    trKernelHeight3d :: Int,+    trKernelWidth3d :: Int,+    trKernelDepth3d :: Int+  }+  deriving (Show, Eq)++data ConvTranspose3d = ConvTranspose3d+  { weight :: Parameter,+    bias :: Parameter+  }+  deriving (Show, Generic, Parameterized)++convTranspose3dForward ::+  -- | layer+  ConvTranspose3d ->+  -- | stride+  (Int, Int, Int) ->+  -- | padding+  (Int, Int, Int) ->+  -- | input+  Tensor ->+  -- | output+  Tensor+convTranspose3dForward layer = convTranspose3d' w b+  where+    w = toDependent (layer.weight)+    b = toDependent (layer.bias)++instance Randomizable ConvTranspose3dSpec ConvTranspose3d where+  sample ConvTranspose3dSpec {..} = do+    w <-+      makeIndependent+        =<< kaimingUniform+          FanIn+          (LeakyRelu $ Prelude.sqrt (5.0 :: Float))+          [ trInputChannelSize3d,+            trOutputChannelSize3d,+            trKernelHeight3d,+            trKernelWidth3d,+            trKernelDepth3d+          ]+    init <- randIO' [trOutputChannelSize3d]+    let bound =+          (1 :: Float)+            / Prelude.sqrt+              ( fromIntegral+                  ( getter FanIn $+                      calculateFan+                        [ trInputChannelSize3d,+                          trOutputChannelSize3d,+                          trKernelHeight3d,+                          trKernelWidth3d,+                          trKernelDepth3d+                        ]+                  ) ::+                  Float+              )+    b <-+      makeIndependent+        =<< pure+          ( subScalar bound $ mulScalar (bound * 2.0) init+          )+    return $ ConvTranspose3d w b++data BatchNormSpec = BatchNormSpec+  { numFeatures :: Int+  }+  deriving (Show, Eq)++data BatchNorm = BatchNorm+  { weight :: Parameter,+    bias :: Parameter,+    runningMean :: MutableTensor,+    runningVar :: MutableTensor+  }+  deriving (Show, Generic)++batchNormForwardIO :: BatchNorm -> Bool -> Double -> Double -> Tensor -> IO Tensor+batchNormForwardIO params train momentum eps input =+  Torch.Functional.batchNormIO+    (toDependent params.weight)+    (toDependent params.bias)+    params.runningMean+    params.runningVar+    train+    momentum+    eps+    input++instance Randomizable BatchNormSpec BatchNorm where+  sample BatchNormSpec {..} = do+    w <- makeIndependent (ones' [numFeatures])+    b <- makeIndependent (zeros' [numFeatures])+    mean <- MutableTensor <$> toDependent <$> makeIndependentWithRequiresGrad (zeros' [numFeatures]) False+    var <- MutableTensor <$> toDependent <$> makeIndependentWithRequiresGrad (ones' [numFeatures]) False+    return $ BatchNorm w b mean var++data InstanceNormSpec = InstanceNormSpec+  { numFeatures :: Int+  }+  deriving (Show, Eq)++data InstanceNorm = InstanceNorm+  { weight :: Parameter,+    bias :: Parameter,+    runningMean :: MutableTensor,+    runningVar :: MutableTensor+  }+  deriving (Show, Generic)++instanceNormForwardIO :: InstanceNorm -> Bool -> Double -> Double -> Tensor -> IO Tensor+instanceNormForwardIO params train momentum eps input =+  Torch.Functional.instanceNormIO+    (toDependent params.weight)+    (toDependent params.bias)+    params.runningMean+    params.runningVar+    train+    momentum+    eps+    input++instance Randomizable InstanceNormSpec InstanceNorm where+  sample InstanceNormSpec {..} = do+    w <- makeIndependent (ones' [numFeatures])+    b <- makeIndependent (zeros' [numFeatures])+    mean <- MutableTensor <$> toDependent <$> makeIndependentWithRequiresGrad (zeros' [numFeatures]) False+    var <- MutableTensor <$> toDependent <$> makeIndependentWithRequiresGrad (ones' [numFeatures]) False+    return $ InstanceNorm w b mean var++data UpSampleSpec = UpSampleSpec+  { upsampleInputFilters :: Int,+    upsampleStride :: Int+  }+  deriving (Show, Eq)++instance Parameterized UpSampleSpec where+  flattenParameters _ = []+  _replaceParameters = return++data UpSample = UpSample+  { upsampleSpec :: UpSampleSpec+  }+  deriving (Show, Generic, Parameterized)++instance Randomizable UpSampleSpec UpSample where+  sample s = do+    UpSample+      <$> pure s++instance HasForward UpSample Tensor Tensor where+  forward (UpSample (UpSampleSpec {..})) input =+    upsampleNearest2d (outputWidth * upsampleStride, outputHeight * upsampleStride) (fromIntegral upsampleStride) (fromIntegral upsampleStride) input+    where+      outputWidth : outputHeight : _ = reverse $ shape input+  forwardStoch m x = pure $ forward m x
+ src/Torch/NN/Recurrent/Cell/Elman.hs view
@@ -0,0 +1,51 @@+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}++module Torch.NN.Recurrent.Cell.Elman where++import GHC.Generics+import Torch++data ElmanSpec = ElmanSpec+  { inputSize :: Int,+    hiddenSize :: Int+  }+  deriving (Eq, Show)++data ElmanCell = ElmanCell+  { weightsIH :: Parameter,+    weightsHH :: Parameter,+    biasIH :: Parameter,+    biasHH :: Parameter+  }+  deriving (Generic, Show)++elmanCellForward ::+  -- | cell parameters+  ElmanCell ->+  -- | input+  Tensor ->+  -- | hidden+  Tensor ->+  -- | output+  Tensor+elmanCellForward ElmanCell {..} input hidden =+  rnnReluCell weightsIH' weightsHH' biasIH' biasHH' hidden input+  where+    weightsIH' = toDependent weightsIH+    weightsHH' = toDependent weightsHH+    biasIH' = toDependent biasIH+    biasHH' = toDependent biasIH++instance Parameterized ElmanCell++instance Randomizable ElmanSpec ElmanCell where+  sample ElmanSpec {..} = do+    weightsIH <- makeIndependent =<< randnIO' [hiddenSize, inputSize]+    weightsHH <- makeIndependent =<< randnIO' [hiddenSize, hiddenSize]+    biasIH <- makeIndependent =<< randnIO' [hiddenSize]+    biasHH <- makeIndependent =<< randnIO' [hiddenSize]+    return $ ElmanCell weightsIH weightsHH biasIH biasHH
+ src/Torch/NN/Recurrent/Cell/GRU.hs view
@@ -0,0 +1,61 @@+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}++module Torch.NN.Recurrent.Cell.GRU where++import GHC.Generics+import Torch++data GRUSpec = GRUSpec+  { inputSize :: Int,+    hiddenSize :: Int+  }+  deriving (Eq, Show)++data GRUCell = GRUCell+  { weightsIH :: Parameter,+    weightsHH :: Parameter,+    biasIH :: Parameter,+    biasHH :: Parameter+  }+  deriving (Generic, Show)++gruCellForward ::+  -- | cell parameters+  GRUCell ->+  -- | input+  Tensor ->+  -- | hidden+  Tensor ->+  -- | output+  Tensor+gruCellForward GRUCell {..} input hidden =+  gruCell weightsIH' weightsHH' biasIH' biasHH' hidden input+  where+    weightsIH' = toDependent weightsIH+    weightsHH' = toDependent weightsHH+    biasIH' = toDependent biasIH+    biasHH' = toDependent biasHH++instance Parameterized GRUCell++instance Randomizable GRUSpec GRUCell where+  sample GRUSpec {..} = do+    -- https://pytorch.org/docs/stable/generated/torch.nn.GRUCell.html+    weightsIH' <- makeIndependent =<< initScale <$> randIO' [3 * hiddenSize, inputSize]+    weightsHH' <- makeIndependent =<< initScale <$> randIO' [3 * hiddenSize, hiddenSize]+    biasIH' <- makeIndependent =<< initScale <$> randIO' [3 * hiddenSize]+    biasHH' <- makeIndependent =<< initScale <$> randIO' [3 * hiddenSize]+    pure $+      GRUCell+        { weightsIH = weightsIH',+          weightsHH = weightsHH',+          biasIH = biasIH',+          biasHH = biasHH'+        }+    where+      scale = Prelude.sqrt $ 1.0 / fromIntegral hiddenSize :: Float+      initScale = subScalar scale . mulScalar scale . mulScalar (2.0 :: Float)
+ src/Torch/NN/Recurrent/Cell/LSTM.hs view
@@ -0,0 +1,61 @@+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}++module Torch.NN.Recurrent.Cell.LSTM where++import GHC.Generics+import Torch++data LSTMSpec = LSTMSpec+  { inputSize :: Int,+    hiddenSize :: Int+  }+  deriving (Eq, Show)++data LSTMCell = LSTMCell+  { weightsIH :: Parameter,+    weightsHH :: Parameter,+    biasIH :: Parameter,+    biasHH :: Parameter+  }+  deriving (Generic, Show)++lstmCellForward ::+  -- | cell parameters+  LSTMCell ->+  -- | (hidden, cell)+  (Tensor, Tensor) ->+  -- | input+  Tensor ->+  -- | output (hidden, cell)+  (Tensor, Tensor)+lstmCellForward LSTMCell {..} hidden input =+  lstmCell weightsIH' weightsHH' biasIH' biasHH' hidden input+  where+    weightsIH' = toDependent weightsIH+    weightsHH' = toDependent weightsHH+    biasIH' = toDependent biasIH+    biasHH' = toDependent biasHH++instance Parameterized LSTMCell++instance Randomizable LSTMSpec LSTMCell where+  sample LSTMSpec {..} = do+    -- x4 dimension calculations - see https://pytorch.org/docs/master/generated/torch.nn.LSTMCell.html+    weightsIH' <- makeIndependent =<< initScale <$> randIO' [4 * hiddenSize, inputSize]+    weightsHH' <- makeIndependent =<< initScale <$> randIO' [4 * hiddenSize, hiddenSize]+    biasIH' <- makeIndependent =<< initScale <$> randIO' [4 * hiddenSize]+    biasHH' <- makeIndependent =<< initScale <$> randIO' [4 * hiddenSize]+    pure $+      LSTMCell+        { weightsIH = weightsIH',+          weightsHH = weightsHH',+          biasIH = biasIH',+          biasHH = biasHH'+        }+    where+      scale = Prelude.sqrt $ 1.0 / fromIntegral hiddenSize :: Float+      initScale = subScalar scale . mulScalar scale . mulScalar (2.0 :: Float)
+ src/Torch/Optim.hs view
@@ -0,0 +1,269 @@+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE DeriveGeneric #-}++module Torch.Optim where++import Control.Monad.State+import Control.Monad (foldM)+import System.Mem (performGC)+import Torch.Autograd+import Torch.Functional+import Torch.Internal.GC (mallocTrim)+import Torch.NN+import Torch.Tensor+import Torch.TensorFactories+import Prelude hiding (sqrt)+import GHC.Generics (Generic)+import Control.DeepSeq (NFData, force)++type LearningRate = Tensor++type Loss = Tensor++newtype Gradients = Gradients [Tensor] deriving (Show)++newtype OptimizerState option = OptimizerState option++grad' :: Loss -> [Parameter] -> Gradients+grad' t p = Gradients (grad t p)++class Optimizer optimizer where+  step :: LearningRate -> Gradients -> [Tensor] -> optimizer -> ([Tensor], optimizer)++  -- | run a single iteration of an optimizer, returning new parameters and updated optimizer state+  runStep :: (Parameterized model) => model -> optimizer -> Loss -> LearningRate -> IO (model, optimizer)+  runStep paramState optState lossValue = runStep' paramState optState (grad' lossValue $ flattenParameters paramState)++  -- | run a single iteration of an optimizer, returning new parameters and updated optimizer state+  runStep' :: (Parameterized model) => model -> optimizer -> Gradients -> LearningRate -> IO (model, optimizer)+  runStep' paramState optState gradients lr = do+    performGC+    mallocTrim 0+    let (flatParameters', optState') = step lr gradients depParameters optState+    newFlatParam <- mapM makeIndependent flatParameters'+    pure (replaceParameters paramState newFlatParam, optState')+    where+      flatParameters = flattenParameters paramState+      depParameters = fmap toDependent flatParameters++--+-- Gradient Descent+--++data GD = GD deriving (Show)++-- | Stateless gradient descent step+gd :: LearningRate -> Gradients -> [Tensor] -> [Tensor]+gd lr (Gradients gradients) parameters = zipWith step parameters gradients+  where+    step p dp = p - (lr * dp)++-- | Gradient descent step with a dummy state variable+gd' :: LearningRate -> Gradients -> [Tensor] -> GD -> ([Tensor], GD)+gd' lr gradients depParameters dummy = (gd lr gradients depParameters, dummy)++instance Optimizer GD where+  step = gd'++sgd :: LearningRate -> [Parameter] -> [Tensor] -> [Tensor]+sgd lr parameters = zipWith step depParameters+  where+    step p dp = p - (lr * dp)+    depParameters = map toDependent parameters++--+-- Gradient Descent with Momentum+--++data GDM = GDM {beta :: Float, momentum :: [Tensor]} deriving (Show)++-- gradient descent with momentum step+gdm ::+  -- | learning rate+  LearningRate ->+  -- | model parameter gradients+  Gradients ->+  -- | model parameters+  [Tensor] ->+  -- | beta & momentum+  GDM ->+  -- | returns new parameters + updated momentum+  ([Tensor], GDM)+gdm lr (Gradients gradients) parameters (GDM beta momentum) =+  (fmap fst runStep, GDM beta (fmap snd runStep))+  where+    step p dp z = let z' = mulScalar beta z + dp in (p - lr * z', z')+    runStep = zipWith3 step parameters gradients momentum++instance Optimizer GDM where+  step = gdm++--+-- Adam+--++-- | State representation for Adam Optimizer+data Adam = Adam+  { beta1 :: Float, -- 1st moment forgetting factor+    beta2 :: Float, -- 2nd moment forgetting factor+    m1 :: [Tensor], -- 1st moment+    m2 :: [Tensor], -- 2nd moment+    iter :: Int -- iteration+  }+  deriving (Show, Generic)++instance NFData Adam++mkAdam ::+  Int ->+  Float ->+  Float ->+  [Parameter] ->+  Adam+mkAdam iter beta1 beta2 parameters =+  Adam+    beta1+    beta2+    (initZeros <$> parameters)+    (initZeros <$> parameters)+    iter+  where+    initZeros = zerosLike . toDependent++-- | Adam step+adam ::+  -- | learning rate+  LearningRate ->+  -- | model parameter gradients+  Gradients ->+  -- | model parameters+  [Tensor] ->+  -- | adam parameters - beta1, beta2, moments, iteration+  Adam ->+  -- | returns new parameters + updated adam parameters+  ([Tensor], Adam)+adam lr (Gradients gradients) parameters Adam {..} = (parameters', Adam beta1 beta2 m1' m2' (iter + 1))+  where+    -- decaying averages of 1st & 2nd moments+    f1 m1 dp = mulScalar beta1 m1 + mulScalar (1 - beta1) dp+    f2 m2 dp = mulScalar beta2 m2 + mulScalar (1 - beta2) (dp * dp)+    -- force to prevent spine laziness. See https://github.com/hasktorch/hasktorch/pull/728+    m1' = force $ zipWith f1 m1 gradients+    m2' = force $ zipWith f2 m2 gradients+    -- bias adjustment+    a beta = divScalar (1 - beta ^ (iter + 1))+    a1 = fmap (a beta1) m1'+    a2 = fmap (a beta2) m2'+    -- parameter update+    eps = 1e-37+    update prevParam a1' a2' = prevParam - lr * a1' / (sqrt a2' + eps)+    parameters' = zipWith3 update parameters a1 a2++instance Optimizer Adam where+  step = adam++--+-- AdamW+--++-- | State representation for AdamW Optimizer+data AdamW = AdamW+  { beta1W :: Float, -- 1st moment forgetting factor+    beta2W :: Float, -- 2nd moment forgetting factor+    m1W :: [Tensor], -- 1st moment+    m2W :: [Tensor], -- 2nd moment+    iterW :: Int, -- iteration+    weightDecayW :: Float -- weight decay+  }+  deriving (Show, Generic)++instance NFData AdamW++mkAdamW ::+  Int ->+  Float ->+  Float ->+  Float ->+  [Parameter] ->+  AdamW+mkAdamW iter beta1 beta2 weightDecay parameters =+  AdamW+    beta1+    beta2+    (initZeros <$> parameters)+    (initZeros <$> parameters)+    iter+    weightDecay+  where+    initZeros = zerosLike . toDependent++-- | AdamW step+adamw ::+  -- | learning rate+  LearningRate ->+  -- | model parameter gradients+  Gradients ->+  -- | model parameters+  [Tensor] ->+  -- | adamw parameters+  AdamW ->+  -- | returns new parameters + updated adamw parameters+  ([Tensor], AdamW)+adamw lr (Gradients gradients) parameters AdamW {..} =+    (parameters', AdamW beta1W beta2W m1' m2' (iterW + 1) weightDecayW)+  where+    -- decaying averages of 1st & 2nd moments+    f1 m1 dp = mulScalar beta1W m1 + mulScalar (1 - beta1W) dp+    f2 m2 dp = mulScalar beta2W m2 + mulScalar (1 - beta2W) (dp * dp)+    -- force to prevent spine laziness. See https://github.com/hasktorch/hasktorch/pull/728+    m1' = force $ zipWith f1 m1W gradients+    m2' = force $ zipWith f2 m2W gradients+    -- bias adjustment+    a beta = divScalar (1 - beta ^ (iterW + 1))+    a1 = fmap (a beta1W) m1'+    a2 = fmap (a beta2W) m2'+    -- parameter update+    eps = 1e-8+    update prevParam a1' a2' = prevParam - lr * (a1' / (sqrt a2' + eps) + mulScalar weightDecayW prevParam)+    parameters' = zipWith3 update parameters a1 a2++instance Optimizer AdamW where+  step = adamw++--+-- Adagrad+--++-- | State representation for Adagrad Optimizer+data Adagrad = Adagrad {gsum :: [Tensor]} -- sum of squared gradients+  deriving (Show)++-- | Adagrad step+adagrad ::+  -- | learning rate+  LearningRate ->+  -- | model parameter gradients+  Gradients ->+  -- | model parameters+  [Tensor] ->+  -- | adagrad parameters - gsum, iteration+  Adagrad ->+  -- | returns new parameters + updated adam parameters+  ([Tensor], Adagrad)+adagrad lr (Gradients gradients) parameters Adagrad {..} = (parameters', Adagrad gsum')+  where+    -- add gradient squared to running total+    f gsum dp = gsum + dp * dp+    gsum' = zipWith f gsum gradients++    -- parameter update+    eps = 1e-37+    update prevParam a1' a2' = prevParam - lr * a1' / (sqrt (a2' + eps))+    parameters' = zipWith3 update parameters gradients gsum'++instance Optimizer Adagrad where+  step = adagrad++-- | syntactic sugar for looping with foldM+foldLoop :: a -> Int -> (a -> Int -> IO a) -> IO a+foldLoop x count block = foldM block x [1 .. count]
+ src/Torch/Optim/CppOptim.hs view
@@ -0,0 +1,282 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-}++module Torch.Optim.CppOptim where++import Data.Default.Class+import Foreign.ForeignPtr+import System.Mem (performGC)+import Torch.Autograd+import Torch.Internal.Cast+import Torch.Internal.Class (Castable (..), CppObject (..), CppTuple2 (..), CppTuple3 (..), CppTuple4 (..))+import Torch.Internal.GC (mallocTrim)+import qualified Torch.Internal.Managed.Optim as LibTorch+import qualified Torch.Internal.Type as ATen+import Torch.NN+import qualified Torch.Optim as Optim+import Torch.Tensor++type CppOptimizerRef = ForeignPtr ATen.Optimizer++data CppOptimizerState option = CppOptimizerState option CppOptimizerRef++-- class Optimizer option where+--   initOptimizer :: Parameterized model => option -> model -> IO (OptimizerState option model)+--   step :: Parameterized model => OptimizerState option model -> (model -> IO Tensor) -> IO Tensor+--   -- Returned d depends on the state of optimizer.+--   -- Do not call step function after this function is called.+--   getParams :: Parameterized model => OptimizerState option model -> IO model+--   step (OptimizerState _ optimizer initParams) loss = cast0 (LibTorch.step optimizer trans)+--     where+--       trans :: ForeignPtr ATen.TensorList -> IO (ForeignPtr ATen.Tensor)+--       trans inputs =+--         uncast inputs $ \inputs' -> do+--           (Unsafe ret) <- loss $ replaceParameters initParams $  map (IndependentTensor . Unsafe) inputs'+--           cast ret return+--   getParams (OptimizerState _ optimizer initParams) = fmap (replaceParameters initParams . map (IndependentTensor . Unsafe)) $ cast0 (LibTorch.getParams optimizer)++stepWithGenerator ::+  CppOptimizerState option ->+  ForeignPtr ATen.Generator ->+  ([Tensor] -> ForeignPtr ATen.Generator -> IO (Tensor, ForeignPtr ATen.Generator)) ->+  IO (Tensor, ForeignPtr ATen.Generator)+stepWithGenerator o@(CppOptimizerState _ ref) generator loss = do+  (v, nextGenerator) <- cast3 LibTorch.stepWithGenerator ref generator loss'+  return (v, nextGenerator)+  where+    loss' :: ForeignPtr ATen.TensorList -> ForeignPtr ATen.Generator -> IO (ForeignPtr (ATen.StdTuple '(ATen.Tensor, ATen.Generator)))+    loss' params gen = do+      (v :: Tensor, gen') <- uncast params $ \params' -> loss params' gen+      v' <- cast v pure :: IO (ForeignPtr ATen.Tensor)+      cast (v', gen') pure++class CppOptimizer option where+  initOptimizer :: Parameterized model => option -> model -> IO (CppOptimizerState option)+  unsafeStep :: Parameterized model => model -> CppOptimizerState option -> Tensor -> IO (model, CppOptimizerState option)+  unsafeStep model o@(CppOptimizerState _ optimizer) loss = do+    v <- cast2 LibTorch.unsafeStep optimizer loss+    let newModel = replaceParameters model $ map (IndependentTensor . Unsafe) v+    return (newModel, o)++instance {-# OVERLAPS #-} CppOptimizer option => Optim.Optimizer (CppOptimizerState option) where+  step = error "step is not implemented for CppOptimizer."+  runStep paramState optState lossValue lr = do+    performGC+    mallocTrim 0+    unsafeStep paramState optState lossValue++  runStep' = error "runStep' is not implemented for CppOptimizer."++data AdagradOptions = AdagradOptions+  { adagradLr :: Double,+    adagradLrDecay :: Double,+    adagradWeightDecay :: Double,+    adagradInitialAccumulatorValue :: Double,+    adagradEps :: Double+  }+  deriving (Show, Eq)++instance Default AdagradOptions where+  def =+    AdagradOptions+      { adagradLr = 1e-2,+        adagradLrDecay = 0,+        adagradWeightDecay = 0,+        adagradInitialAccumulatorValue = 0,+        adagradEps = 1e-10+      }++instance CppOptimizer AdagradOptions where+  initOptimizer opt@AdagradOptions {..} initParams = do+    v <- cast6 LibTorch.adagrad adagradLr adagradLrDecay adagradWeightDecay adagradInitialAccumulatorValue adagradEps initParams'+    return $ CppOptimizerState opt v+    where+      initParams' = map toDependent $ flattenParameters initParams++data AdamOptions = AdamOptions+  { adamLr :: Double,+    adamBetas :: (Double, Double),+    adamEps :: Double,+    adamWeightDecay :: Double,+    adamAmsgrad :: Bool+  }+  deriving (Show, Eq)++instance Default AdamOptions where+  def =+    AdamOptions+      { adamLr = 1e-3,+        adamBetas = (0.9, 0.999),+        adamEps = 1e-8,+        adamWeightDecay = 0,+        adamAmsgrad = False+      }++instance CppOptimizer AdamOptions where+  initOptimizer opt@AdamOptions {..} initParams = do+    v <- cast7 LibTorch.adam adamLr (fst adamBetas) (snd adamBetas) adamEps adamWeightDecay adamAmsgrad initParams'+    return $ CppOptimizerState opt v+    where+      initParams' = map toDependent $ flattenParameters initParams++data AdamwOptions = AdamwOptions+  { adamwLr :: Double,+    adamwBetas :: (Double, Double),+    adamwEps :: Double,+    adamwWeightDecay :: Double,+    adamwAmsgrad :: Bool+  }+  deriving (Show, Eq)++instance Default AdamwOptions where+  def =+    AdamwOptions+      { adamwLr = 1e-3,+        adamwBetas = (0.9, 0.999),+        adamwEps = 1e-8,+        adamwWeightDecay = 1e-2,+        adamwAmsgrad = False+      }++instance CppOptimizer AdamwOptions where+  initOptimizer opt@AdamwOptions {..} initParams = do+    v <- cast7 LibTorch.adamw adamwLr (fst adamwBetas) (snd adamwBetas) adamwEps adamwWeightDecay adamwAmsgrad initParams'+    return $ CppOptimizerState opt v+    where+      initParams' = map toDependent $ flattenParameters initParams++data LbfgsOptions = LbfgsOptions+  { lbfgsLr :: Double,+    lbfgsMaxIter :: Int,+    lbfgsMaxEval :: Int,+    lbfgsToleranceGrad :: Double,+    lbfgsToleranceChange :: Double,+    lbfgsHistorySize :: Int,+    lbfgsLineSearchFn :: Maybe String+  }+  deriving (Show, Eq)++instance Default LbfgsOptions where+  def =+    LbfgsOptions+      { lbfgsLr = 1,+        lbfgsMaxIter = 20,+        lbfgsMaxEval = (20 * 5) `div` 4,+        lbfgsToleranceGrad = 1e-7,+        lbfgsToleranceChange = 1e-9,+        lbfgsHistorySize = 100,+        lbfgsLineSearchFn = Nothing+      }++instance CppOptimizer LbfgsOptions where+  initOptimizer opt@LbfgsOptions {..} initParams = do+    v <- cast8 LibTorch.lbfgs lbfgsLr lbfgsMaxIter lbfgsMaxEval lbfgsToleranceGrad lbfgsToleranceChange lbfgsHistorySize lbfgsLineSearchFn initParams'+    return $ CppOptimizerState opt v+    where+      initParams' = map toDependent $ flattenParameters initParams++data RmspropOptions = RmspropOptions+  { rmspropLr :: Double,+    rmspropAlpha :: Double,+    rmspropEps :: Double,+    rmspropWeightDecay :: Double,+    rmspropMomentum :: Double,+    rmspropCentered :: Bool+  }+  deriving (Show, Eq)++instance Default RmspropOptions where+  def =+    RmspropOptions+      { rmspropLr = 1e-2,+        rmspropAlpha = 0.99,+        rmspropEps = 1e-8,+        rmspropWeightDecay = 0,+        rmspropMomentum = 0,+        rmspropCentered = False+      }++instance CppOptimizer RmspropOptions where+  initOptimizer opt@RmspropOptions {..} initParams = do+    v <- cast7 LibTorch.rmsprop rmspropLr rmspropAlpha rmspropEps rmspropWeightDecay rmspropMomentum rmspropCentered initParams'+    return $ CppOptimizerState opt v+    where+      initParams' = map toDependent $ flattenParameters initParams++data SGDOptions = SGDOptions+  { sgdLr :: Double,+    sgdMomentum :: Double,+    sgdDampening :: Double,+    sgdWeightDecay :: Double,+    sgdNesterov :: Bool+  }+  deriving (Show, Eq)++instance Default SGDOptions where+  def =+    SGDOptions+      { sgdLr = 1e-3,+        sgdMomentum = 0,+        sgdDampening = 0,+        sgdWeightDecay = 0,+        sgdNesterov = False+      }++instance CppOptimizer SGDOptions where+  initOptimizer opt@SGDOptions {..} initParams = do+    v <- cast6 LibTorch.sgd sgdLr sgdMomentum sgdDampening sgdWeightDecay sgdNesterov initParams'+    return $ CppOptimizerState opt v+    where+      initParams' = map toDependent $ flattenParameters initParams++saveState :: CppOptimizerState option -> FilePath -> IO ()+saveState (CppOptimizerState _ optimizer) file = cast2 LibTorch.save optimizer file++loadState :: CppOptimizerState option -> FilePath -> IO ()+loadState (CppOptimizerState _ optimizer) file = cast2 LibTorch.load optimizer file++data AdamwParamGroupOptions = AdamwParamGroupOptions+  { adamwPgLr :: Double,+    adamwPgBetas :: (Double, Double),+    adamwPgEps :: Double,+    adamwPgWeightDecay :: Double,+    adamwPgAmsgrad :: Bool+  }+  deriving (Show, Eq)++instance Default AdamwParamGroupOptions where+  def =+    AdamwParamGroupOptions+      { adamwPgLr = 1e-3,+        adamwPgBetas = (0.9, 0.999),+        adamwPgEps = 1e-8,+        adamwPgWeightDecay = 1e-2,+        adamwPgAmsgrad = False+      }++initAdamwWithGroups :: AdamwParamGroupOptions -> [Tensor] -> [Tensor] -> IO (CppOptimizerState AdamwParamGroupOptions)+initAdamwWithGroups opt@AdamwParamGroupOptions {..} decayParams noDecayParams = do+  v <- cast8 LibTorch.adamwWithParamGroups adamwPgLr (fst adamwPgBetas) (snd adamwPgBetas) adamwPgEps adamwPgWeightDecay adamwPgAmsgrad decayParams noDecayParams+  return $ CppOptimizerState opt v++cppOptimizerStepOnly :: CppOptimizerState option -> IO ()+cppOptimizerStepOnly (CppOptimizerState _ optimizer) = cast1 LibTorch.stepOnly optimizer++cppOptimizerZeroGrad :: CppOptimizerState option -> IO ()+cppOptimizerZeroGrad (CppOptimizerState _ optimizer) = cast1 LibTorch.zeroGrad optimizer++cppOptimizerSetGrads :: CppOptimizerState option -> [Tensor] -> IO ()+cppOptimizerSetGrads (CppOptimizerState _ optimizer) grads = cast2 LibTorch.setParamGrads optimizer grads++cppOptimizerGetAllParams :: CppOptimizerState option -> IO [Tensor]+cppOptimizerGetAllParams (CppOptimizerState _ optimizer) = cast1 LibTorch.getAllParams optimizer++cppOptimizerSetLr :: CppOptimizerState option -> Double -> IO ()+cppOptimizerSetLr (CppOptimizerState _ optimizer) lr = cast2 LibTorch.setLr optimizer lr
+ src/Torch/Random.hs view
@@ -0,0 +1,208 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RecordWildCards #-}++module Torch.Random+  ( mkGenerator,+    Generator,+    randn,+    randn',+    rand,+    rand',+    randint,+    randint',+    normal,+    normal',+  )+where++import Control.Concurrent+import Control.Concurrent.STM+import Control.Monad.IO.Class+import Control.Monad.STM+import Data.Int+import Data.Word+import Foreign.ForeignPtr+import System.IO.Unsafe+import Torch.Device+import Torch.Internal.Cast+import Torch.Internal.Class (Castable (..))+import qualified Torch.Internal.Const as ATen+import qualified Torch.Internal.Managed.TensorFactories as LibTorch+import qualified Torch.Internal.Managed.Type.Generator as ATen+import qualified Torch.Internal.Type as ATen+import Torch.Tensor+import Torch.TensorOptions++instance Show (TVar (Either (Word64, Device) (ForeignPtr ATen.Generator))) where+  show _ = "_"++newtype Generator = UnsafeGenerator+  { unGenerator :: TVar (Either (Word64, Device) (ForeignPtr ATen.Generator))+  }+  deriving (Eq, Show)++mkGenerator :: Device -> Word64 -> IO Generator+mkGenerator device seed =+  case device of+    Device CPU _ -> do+      genPtr <- ATen.newCPUGenerator seed+      genenerator <- newTVarIO (Right genPtr)+      return $ UnsafeGenerator genenerator+    Device CUDA idx -> do+      genPtr <- ATen.newCUDAGenerator (fromIntegral idx)+      ATen.generator_set_current_seed genPtr seed+      genenerator <- newTVarIO (Right genPtr)+      return $ UnsafeGenerator genenerator+    Device MPS _ -> do+      genPtr <- ATen.newMPSGenerator+      ATen.generator_set_current_seed genPtr seed+      genenerator <- newTVarIO (Right genPtr)+      return $ UnsafeGenerator genenerator++type RandomGenFunc = ForeignPtr ATen.IntArray -> ForeignPtr ATen.Generator -> ForeignPtr ATen.TensorOptions -> IO (ForeignPtr ATen.Tensor)++generatorFactory :: RandomGenFunc -> [Int] -> TensorOptions -> Generator -> (Tensor, Generator)+generatorFactory func size options (UnsafeGenerator generator) =+  unsafePerformIO $ do+    mGenerator <- atomically $ do+      v <- readTVar generator+      case v of+        Right v' -> do+          let device =+                if generatorIsCuda v'+                  then Device {deviceType = CUDA, deviceIndex = fromIntegral $ generatorDevice v'}+                  else+                    if generatorIsMps v'+                    then Device {deviceType = MPS, deviceIndex = 0}+                    else Device {deviceType = CPU, deviceIndex = 0}+              seed = generatorSeed v'+          writeTVar generator $ seed `seq` deviceType device `seq` deviceIndex device `seq` Left (seed, device)+          return $ Right v'+        Left v -> return (Left v)+    genPtr <- case mGenerator of+      Right gen -> return gen+      Left (seed, device) -> case device of+        Device CPU _ -> ATen.newCPUGenerator seed+        Device CUDA idx -> do+          gen <- ATen.newCUDAGenerator (fromIntegral idx)+          ATen.generator_set_current_seed gen seed+          return gen+        Device MPS _ -> do+          gen <- ATen.newMPSGenerator+          ATen.generator_set_current_seed gen seed+          return gen+    tensor <- cast3 func size genPtr options+    nextGenenerator <- newTVarIO (Right genPtr)+    return (tensor, UnsafeGenerator nextGenenerator)+  where+    generatorIsCpu :: ForeignPtr ATen.Generator -> Bool+    generatorIsCpu gen = unsafePerformIO $ cast1 ATen.generator_is_cpu gen++    generatorIsCuda :: ForeignPtr ATen.Generator -> Bool+    generatorIsCuda gen = unsafePerformIO $ cast1 ATen.generator_is_cuda gen++    generatorIsMps :: ForeignPtr ATen.Generator -> Bool+    generatorIsMps gen = unsafePerformIO $ cast1 ATen.generator_is_mps gen++    generatorDevice :: ForeignPtr ATen.Generator -> Int+    generatorDevice gen = unsafePerformIO $ cast1 ATen.generator_get_device gen++    generatorSeed :: ForeignPtr ATen.Generator -> Word64+    generatorSeed gen = unsafePerformIO $ cast1 ATen.generator_current_seed gen++randn ::+  -- | size+  [Int] ->+  -- | options+  TensorOptions ->+  -- | generator+  Generator ->+  -- | output+  (Tensor, Generator)+randn = generatorFactory LibTorch.randn_lGo++randn' ::+  -- | size+  [Int] ->+  -- | generator+  Generator ->+  -- | output+  (Tensor, Generator)+randn' size = randn size defaultOpts++rand ::+  -- | size+  [Int] ->+  -- | options+  TensorOptions ->+  -- | generator+  Generator ->+  -- | output+  (Tensor, Generator)+rand = generatorFactory LibTorch.rand_lGo++rand' ::+  -- | size+  [Int] ->+  -- | generator+  Generator ->+  -- | output+  (Tensor, Generator)+rand' size = rand size defaultOpts++randint ::+  -- | low+  Int ->+  -- | high+  Int ->+  -- | size+  [Int] ->+  -- | options+  TensorOptions ->+  -- | generator+  Generator ->+  -- | output+  (Tensor, Generator)+randint low high = generatorFactory (LibTorch.randint_lllGo (fromIntegral low) (fromIntegral high))++randint' ::+  -- | low+  Int ->+  -- | high+  Int ->+  -- | size+  [Int] ->+  -- | generator+  Generator ->+  -- | output+  (Tensor, Generator)+randint' low high size = randint low high size defaultOpts++normal ::+  -- | mean+  Double ->+  -- | std+  Double ->+  -- | size+  [Int] ->+  -- | options+  TensorOptions ->+  -- | generator+  Generator ->+  -- | output+  (Tensor, Generator)+normal mean std = generatorFactory (LibTorch.normal_ddlGo (realToFrac mean) (realToFrac std))++normal' ::+  -- | mean+  Double ->+  -- | std+  Double ->+  -- | size+  [Int] ->+  -- | generator+  Generator ->+  -- | output+  (Tensor, Generator)+normal' mean std size = normal mean std size defaultOpts
+ src/Torch/Scalar.hs view
@@ -0,0 +1,39 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}++module Torch.Scalar where++import Foreign.ForeignPtr+import Torch.Internal.Cast+import Torch.Internal.Class (Castable (..))+import qualified Torch.Internal.Const as ATen+import Torch.Internal.Managed.Cast+import qualified Torch.Internal.Managed.Type.Scalar as ATen+import qualified Torch.Internal.Type as ATen++instance Castable Float (ForeignPtr ATen.Scalar) where+  cast x f = ATen.newScalar_f (realToFrac x) >>= f+  uncast x f = undefined++instance Castable Double (ForeignPtr ATen.Scalar) where+  cast x f = ATen.newScalar_d (realToFrac x) >>= f+  uncast x f = undefined++instance Castable Int (ForeignPtr ATen.Scalar) where+  cast x f = ATen.newScalar_i (fromIntegral x) >>= f+  uncast x f = undefined++instance Castable Bool (ForeignPtr ATen.Scalar) where+  cast x f = ATen.newScalar_b (if x then 1 else 0) >>= f+  uncast x f = undefined++class (Castable a (ForeignPtr ATen.Scalar)) => Scalar a++instance Scalar Float++instance Scalar Double++instance Scalar Int++instance Scalar Bool
+ src/Torch/Script.hs view
@@ -0,0 +1,578 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-}++module Torch.Script where++import Control.Exception.Safe (throwIO)+import Control.Monad (forM, forM_, replicateM)+import Data.Int (Int16, Int64)+import Data.List (intercalate)+import Data.Proxy+import Data.Reflection+import Data.Word (Word8)+import Foreign.C.Types+import Foreign.ForeignPtr+import Foreign.Ptr+import Foreign.Storable+import Numeric+import System.IO.Unsafe+import Torch.Autograd+import Torch.DType+import Torch.Device+import Torch.Internal.Cast+import Torch.Internal.Class (Castable (..), CppObject (..), CppTuple2 (..), CppTuple3 (..), CppTuple4 (..))+import qualified Torch.Internal.Const as ATen+import qualified Torch.Internal.Managed.Cast as ATen+import qualified Torch.Internal.Managed.Native as ATen+import qualified Torch.Internal.Managed.Type.Context as ATen+import Torch.Internal.Managed.Type.IValue+import qualified Torch.Internal.Managed.Type.Module as LibTorch+import qualified Torch.Internal.Managed.Type.StdArray as ATen+import qualified Torch.Internal.Managed.Type.StdString as ATen+import qualified Torch.Internal.Managed.Type.Tensor as ATen+import qualified Torch.Internal.Managed.Type.TensorOptions as ATen+import Torch.Internal.Type (TensorList)+import qualified Torch.Internal.Type as ATen+import Torch.Internal.Unmanaged.Type.C10Dict+import Torch.Internal.Unmanaged.Type.IValue (IValueLike (..))+import qualified Torch.Internal.Unmanaged.Type.Module as Unmanaged+import Torch.NN+import Torch.Tensor (Tensor (..), toDevice)+import Torch.TensorOptions++newtype ScriptModule = UnsafeScriptModule (ForeignPtr ATen.Module)++newtype RawModule = UnsafeRawModule (ForeignPtr ATen.Module)++instance Show ScriptModule where+  show obj = unsafePerformIO $ dumpToStr' obj++type RawIValue = ForeignPtr ATen.IValue++newtype Blob = UnsafeBlob (ForeignPtr (ATen.C10Ptr ATen.Blob))++newtype Object = UnsafeObject (ForeignPtr (ATen.C10Ptr ATen.IVObject))++newtype Future = UnsafeFuture (ForeignPtr (ATen.C10Ptr ATen.IVFuture))++newtype Capsule = UnsafeCapsule (ForeignPtr (ATen.C10Ptr ATen.Capsule))++-- | See https://github.com/pytorch/pytorch/wiki/PyTorch-IR+newtype Graph = UnsafeGraph (ForeignPtr (ATen.SharedPtr ATen.JitGraph))++data JitGraph = JitGraph+  { graphInputs :: [JitValue],+    graphOutputs :: [JitValue],+    graphNodes :: [JitNode]+  }+  deriving (Show, Eq)++data JitNode = JitNode+  { nodeInputs :: [JitValue],+    nodeOutputs :: [JitValue],+    nodeKind :: String+  }+  deriving (Show, Eq)++data JitValue = JitValue+  { valueId :: Int,+    valueType :: String+  }+  deriving (Show, Eq)++instance Show Blob where+  show _ = "Blob"++instance Show Future where+  show _ = "Future"++instance Show Object where+  show _ = "Object"++instance Show Capsule where+  show _ = "Capsule"++data IValue+  = IVNone+  | IVTensor Tensor+  | IVDouble Double+  | IVInt Int64+  | IVBool Bool+  | IVTuple [IValue]+  | IVIntList [Int64]+  | IVDoubleList [Double]+  | IVBoolList [Bool]+  | IVString String+  | IVTensorList [Tensor]+  | IVBlob -- Blob+  | IVGenericList [IValue]+  | IVGenericDict [(IValue, IValue)]+  | IVFuture -- Future+  | IVDevice -- Device+  | IVObject -- Object+  | IVUninitialized+  | IVCapsule -- Capsule+  deriving (Show)++instance Castable ScriptModule (ForeignPtr ATen.Module) where+  cast (UnsafeScriptModule obj) f = f obj+  uncast obj f = f $ UnsafeScriptModule obj++instance Castable RawModule (ForeignPtr ATen.Module) where+  cast (UnsafeRawModule obj) f = f obj+  uncast obj f = f $ UnsafeRawModule obj++instance Castable Graph (ForeignPtr (ATen.SharedPtr ATen.JitGraph)) where+  cast (UnsafeGraph obj) f = f obj+  uncast obj f = f $ UnsafeGraph obj++newModule :: String -> IO RawModule+newModule = cast1 LibTorch.newModule++saveScript :: ScriptModule -> FilePath -> IO ()+saveScript = cast2 LibTorch.save++saveScript' :: RawModule -> FilePath -> IO ()+saveScript' = cast2 LibTorch.save++data LoadMode+  = WithoutRequiredGrad+  | WithRequiredGrad+  deriving (Show, Eq)++-- | Load a torchscript file+loadScript :: LoadMode -> FilePath -> IO ScriptModule+loadScript WithoutRequiredGrad file = cast1 LibTorch.load file+loadScript WithRequiredGrad file = do+  module'@(UnsafeRawModule rmodule) <- cast1 LibTorch.load file+  params <- getParametersIO module'+  paramsWithRequiredGrad <- forM params makeIndependent+  setParameters module' (map toDependent paramsWithRequiredGrad)+  return (UnsafeScriptModule rmodule)++loadScript' :: FilePath -> IO RawModule+loadScript' = cast1 LibTorch.load++instance HasForward ScriptModule [IValue] IValue where+  forward module' = unsafePerformIO . forwardStoch module'+  forwardStoch = cast2 forward'+    where+      forward' :: ScriptModule -> [RawIValue] -> IO RawIValue+      forward' = cast2 LibTorch.forward++registerParameter :: RawModule -> String -> Tensor -> Bool -> IO ()+registerParameter = cast4 LibTorch.registerParameter++registerModule :: RawModule -> String -> RawModule -> IO ()+registerModule = cast3 LibTorch.registerModule++getParameters ::+  -- | module+  ScriptModule ->+  -- | output+  [Tensor]+getParameters = unsafePerformIO . cast1 LibTorch.getParameters++getParametersIO ::+  -- | module+  RawModule ->+  -- | output+  IO [Tensor]+getParametersIO = cast1 LibTorch.getParameters++setParameters :: RawModule -> [Tensor] -> IO ()+setParameters = cast2 LibTorch.setParameters++updateParameters :: LoadMode -> ScriptModule -> [Tensor] -> ScriptModule+updateParameters mode module' inputs = unsafePerformIO $+  case mode of+    WithoutRequiredGrad -> cast1 LibTorch.clone module'+    WithRequiredGrad -> do+      r <- cast1 LibTorch.clone module'+      paramsWithRequiredGrad <- forM inputs makeIndependent+      setParameters' r (map toDependent paramsWithRequiredGrad)+      return r+  where+    setParameters' :: ScriptModule -> [Tensor] -> IO ()+    setParameters' = cast2 LibTorch.setParameters++getNamedParameters ::+  -- | module+  ScriptModule ->+  -- | output+  [(String, Tensor)]+getNamedParameters (UnsafeScriptModule m) = unsafePerformIO $ do+  dat <- LibTorch.getNamedParameters m+  forM dat $ \(key, value) ->+    (,) <$> uncast key return <*> uncast value return++getNamedBuffers ::+  -- | module+  ScriptModule ->+  -- | output+  [(String, Tensor)]+getNamedBuffers (UnsafeScriptModule m) = unsafePerformIO $ do+  dat <- LibTorch.getNamedBuffers m+  forM dat $ \(key, value) ->+    (,) <$> uncast key return <*> uncast value return++-- | Load all attributes including training flags+-- This function returns IVObject type as Tensor type.+-- To get Tensor type, use get getNamedParameters and getNamedBuffers.+getNamedAttributes ::+  -- | module+  ScriptModule ->+  -- | output+  [(String, IValue)]+getNamedAttributes (UnsafeScriptModule m) = unsafePerformIO $ do+  dat <- LibTorch.getNamedAttributes m+  forM dat $ \(key, value) ->+    (,) <$> uncast key return <*> uncast value return++getNamedModules ::+  -- | module+  ScriptModule ->+  -- | output+  [(String, ScriptModule)]+getNamedModules (UnsafeScriptModule m) = unsafePerformIO $ do+  dat <- LibTorch.getNamedModules m+  forM dat $ \(key, value) ->+    (,) <$> uncast key return <*> uncast value return++getNamedChildren ::+  -- | module+  ScriptModule ->+  -- | output+  [(String, ScriptModule)]+getNamedChildren (UnsafeScriptModule m) = unsafePerformIO $ do+  dat <- LibTorch.getNamedChildren m+  forM dat $ \(key, value) ->+    (,) <$> uncast key return <*> uncast value return++toScriptModule :: RawModule -> IO ScriptModule+toScriptModule rawModule = do+  (UnsafeRawModule r) <- cloneRawModule rawModule+  return $ UnsafeScriptModule r++toRawModule :: ScriptModule -> IO RawModule+toRawModule scriptModule = do+  (UnsafeScriptModule r) <- clone' scriptModule+  return $ UnsafeRawModule r+  where+    clone' = cast1 LibTorch.clone++cloneRawModule :: RawModule -> IO RawModule+cloneRawModule = cast1 LibTorch.clone++data RuntimeMode = Eval | Train deriving (Show, Eq)++setRuntimeMode :: RawModule -> RuntimeMode -> IO ()+setRuntimeMode rmod mode = cast2 LibTorch.train rmod (mode == Train)++define :: RawModule -> String -> IO ()+define = cast2 LibTorch.define++dumpToStr ::+  -- | module+  ScriptModule ->+  -- | print_method_bodies+  Bool ->+  -- | print_attr_values+  Bool ->+  -- | print_param_values+  Bool ->+  -- | ouput+  IO String+dumpToStr = cast4 LibTorch.dumpToStr++dumpToStr' :: ScriptModule -> IO String+dumpToStr' obj = dumpToStr obj True True True++runMethod ::+  -- | module+  ScriptModule ->+  -- | func+  String ->+  -- | inputs+  [IValue] ->+  -- | output+  IValue+runMethod module' func = unsafePerformIO . cast3 runMethod' module' func+  where+    runMethod' :: ScriptModule -> String -> [RawIValue] -> IO RawIValue+    runMethod' = cast3 LibTorch.runMethod++runMethod1 ::+  -- | module+  ScriptModule ->+  -- | func+  String ->+  -- | inputs+  IValue ->+  -- | output+  IValue+runMethod1 module' func = unsafePerformIO . cast3 runMethod1' module' func+  where+    runMethod1' :: ScriptModule -> String -> RawIValue -> IO RawIValue+    runMethod1' = cast3 LibTorch.runMethod1++instance Parameterized ScriptModule where+  flattenParameters module' = map IndependentTensor $ getParameters module'+  _replaceParameters module' = do+    let len = length (getParameters module')+    ps' <- replicateM len nextParameter+    return $ updateParameters WithRequiredGrad module' (map toDependent ps')++trace ::+  -- | moduleName+  String ->+  -- | functionName+  String ->+  -- | function+  ([Tensor] -> IO [Tensor]) ->+  -- | inputs+  [Tensor] ->+  -- | output+  IO RawModule+trace moduleName functionName func = cast3 (\m f inps -> LibTorch.trace m f (trans func) inps) moduleName functionName+  where+    trans :: ([Tensor] -> IO [Tensor]) -> ForeignPtr TensorList -> IO (ForeignPtr TensorList)+    trans func inputs =+      uncast inputs $ \inputs' -> do+        ret <- func inputs'+        cast ret return++-- | This function generates torchscript-module from Parameterized-instance of hasktorch.+-- Usage is below.+-- -- >> let example_inputs = asTensor (4::Float)+-- -- >> init_parameters <- sample MonoSpec+-- -- >> mutableTorchscript <- traceWithParameters "MyModule"+-- --                            (\parameters [example_inputs'] -> return [(traced_function parameters example_inputs')])+-- --                            init_parameters+-- --                            [example_inputs]+-- -- >> immutableTorchscript <- toScriptModule mutableTorchscript+-- -- >> save immutableTorchscript "<your torchscript file>"+traceWithParameters ::+  Parameterized f =>+  -- | module name+  String ->+  -- | traced function+  (f -> [Tensor] -> IO [Tensor]) ->+  -- | initial parameters+  f ->+  -- | example inputs+  [Tensor] ->+  -- | torchscript module+  IO RawModule+traceWithParameters moduleName func parameterized_parameters inputs = do+  let parameters = map toDependent (flattenParameters parameterized_parameters)+      fromParams params = replaceParameters parameterized_parameters (map IndependentTensor params)+      plen = length parameters+      ilen = length inputs+  r <-+    trace+      moduleName+      "forwardWithParameters"+      ( \parametersAndInputs ->+          func+            (fromParams (take plen parametersAndInputs))+            (drop plen parametersAndInputs)+      )+      (parameters ++ inputs)+  forM_ (zip [0 ..] parameters) $ \(i, p) ->+    registerParameter r ("p" ++ show i) p False+  let args = intercalate ", " $ map (\i -> "i" ++ show i) [0 .. (ilen -1)]+      params = intercalate ", " $ map (\i -> "self.p" ++ show i) [0 .. (plen -1)]+  define r $+    "def forward(self, " ++ args ++ "):\n" ++ "    return self.forwardWithParameters(" ++ params ++ ", " ++ args ++ " )\n"+  return r++traceAsGraph ::+  -- | function+  ([Tensor] -> IO [Tensor]) ->+  -- | inputs+  [Tensor] ->+  -- | output+  IO Graph+traceAsGraph func = cast1 (LibTorch.traceAsGraph (trans func))+  where+    trans :: ([Tensor] -> IO [Tensor]) -> ForeignPtr TensorList -> IO (ForeignPtr TensorList)+    trans func inputs =+      uncast inputs $ \inputs' -> do+        ret <- func inputs'+        cast ret return++printGraph :: Graph -> IO String+printGraph = cast1 LibTorch.printGraph++-- | Output onnx file from graph. (really experimental implementation)+-- printOnnx uses export_onnx function of libtorch.+-- It outputs following error, because prim::Constant symbol using torchscript does not exist.+-- -- Exception: ONNX export failed: Couldn't export operator prim::Constant+-- -- Defined at:+-- --   Graph we tried to export:+-- --   graph(%0 : Float(),+-- --               %1 : Float()):+-- --     %2 : int = prim::Constant[value=1]()+-- --   %3 : Float() = aten::add(%0, %1, %2)+-- --   return (%3)+-- -- ; type: std::runtime_error+-- On the other hand, torch.onnx.export of python works.+-- onnx's symbol map is in python code.+-- https://github.com/pytorch/pytorch/blob/master/torch/onnx/symbolic_opset9.py+--+-- If you need onnx-file, at first make torchscript by trace , then convert torchscript into onnx by python-code.+printOnnx :: Graph -> IO String+printOnnx = cast1 LibTorch.printOnnx++graphToJitGraph :: Graph -> IO JitGraph+graphToJitGraph (UnsafeGraph graph) =+  withForeignPtr graph $ \g0 -> Unmanaged.withJitGraph g0 $ \g -> do+    graphInputs <- toJitValue =<< Unmanaged.graphInputs g+    graphOutputs <- toJitValue =<< Unmanaged.graphOutputs g+    graphNodes <- toJitNode =<< Unmanaged.graphNodes g+    pure JitGraph {..}+  where+    toJitValue inputs =+      forM inputs $ \i -> do+        valueId <- cast1 Unmanaged.valueId i+        valueType <- cast0 (cast1 Unmanaged.valueType i :: IO (ForeignPtr ATen.StdString))+        pure JitValue {..}+    toJitNode nodes =+      forM nodes $ \n -> do+        nodeInputs <- toJitValue =<< Unmanaged.nodeInputs n+        nodeOutputs <- toJitValue =<< Unmanaged.nodeOutputs n+        nodeKind <- cast0 (cast1 Unmanaged.nodeKind n :: IO (ForeignPtr ATen.StdString))+        pure JitNode {..}++instance Castable [IValue] [RawIValue] where+  cast a f = forM a (`cast` return) >>= f+  uncast a f = forM a (`uncast` return) >>= f++instance Castable IValue RawIValue where+  cast IVNone f = newIValue >>= f+  cast (IVTensor (Unsafe v)) f = toIValue v >>= f+  cast (IVDouble v) f = toIValue v >>= f+  cast (IVInt v) f = toIValue v >>= f+  cast (IVBool v) f = toIValue v >>= f+  cast (IVTuple v) f = do+    rawIValues <- cast v return :: IO [RawIValue]+    c10tuple <- cast rawIValues return :: IO (ForeignPtr (ATen.C10Ptr ATen.IVTuple))+    f =<< toIValue c10tuple+  cast (IVIntList v) f = do+    v' <- cast v return :: IO (ForeignPtr (ATen.C10List Int64))+    f =<< toIValue v'+  cast (IVDoubleList v) f = do+    cdoubles <- forM v (`cast` return) :: IO [CDouble]+    c10list <- cast cdoubles return :: IO (ForeignPtr (ATen.C10List CDouble))+    f =<< toIValue c10list+  cast (IVBoolList v) f = do+    cbools <- forM v (`cast` return) :: IO [CBool]+    c10list <- cast cbools return :: IO (ForeignPtr (ATen.C10List CBool))+    f =<< toIValue c10list+  cast (IVString v) f = do+    v' <- cast v return :: IO (ForeignPtr ATen.StdString)+    f =<< toIValue v'+  cast (IVTensorList v) f = do+    v' <- cast v return :: IO (ForeignPtr (ATen.C10List ATen.Tensor))+    f =<< toIValue v'+  cast (IVGenericList v) f = do+    rawIValues <- cast v return :: IO [RawIValue]+    c10list <- cast rawIValues return :: IO (ForeignPtr (ATen.C10List ATen.IValue))+    f =<< toIValue c10list+  cast (IVGenericDict v) f = do+    keys <- cast (map fst v) return :: IO [RawIValue]+    values <- cast (map snd v) return :: IO [RawIValue]+    let rawIValues = zip keys values+    c10list <- cast rawIValues return :: IO (ForeignPtr (ATen.C10Dict '(ATen.IValue, ATen.IValue)))+    f =<< toIValue c10list+  --  cast (IVBlob (UnsafeBlob v)) f = toIValue v >>= f+  --  cast (IVFuture (UnsafeFuture v)) f = toIValue v >>= f+  --  cast (IVDevice v) f = toIValue v >>= f+  --  cast (IVObject (UnsafeObject v)) f = toIValue v >>= f+  --  cast (IVUninitialized) f = f (toIValue v)+  --  cast (IVCapsule v) f = toIValue v >>= f+  cast a f = throwIO $ userError $ "Unsupported data-type:" ++ show a+  uncast obj f =+    select+      [ (iValue_isNone obj, f IVNone),+        (iValue_isTensor obj, fromIValue obj >>= f . IVTensor . Unsafe),+        (iValue_isDouble obj, fromIValue obj >>= f . IVDouble),+        (iValue_isInt obj, fromIValue obj >>= f . IVInt),+        (iValue_isBool obj, fromIValue obj >>= f . IVBool),+        ( iValue_isString obj,+          do+            v <- fromIValue obj :: IO (ForeignPtr ATen.StdString)+            str <- uncast v return :: IO String+            f (IVString str)+        ),+        ( iValue_isTensorList obj,+          do+            v' <- fromIValue obj :: IO (ForeignPtr (ATen.C10List ATen.Tensor))+            ts <- uncast v' return :: IO [Tensor]+            f (IVTensorList ts)+        ),+        ( iValue_isDoubleList obj,+          do+            v' <- fromIValue obj :: IO (ForeignPtr (ATen.C10List CDouble))+            cdoubles <- uncast v' return :: IO [CDouble]+            doubles <- forM cdoubles (`uncast` return) :: IO [Double]+            f (IVDoubleList doubles)+        ),+        ( iValue_isIntList obj,+          do+            v' <- fromIValue obj :: IO (ForeignPtr (ATen.C10List Int64))+            ts <- uncast v' return :: IO [Int64]+            f (IVIntList ts)+        ),+        ( iValue_isBoolList obj,+          do+            v' <- fromIValue obj :: IO (ForeignPtr (ATen.C10List CBool))+            cbools <- uncast v' return :: IO [CBool]+            bools <- forM cbools (`uncast` return) :: IO [Bool]+            f (IVBoolList bools)+        ),+        ( iValue_isTuple obj,+          do+            c10tuple <- fromIValue obj :: IO (ForeignPtr (ATen.C10Ptr ATen.IVTuple))+            rawIValues <- uncast c10tuple return :: IO [RawIValue]+            ts <- uncast rawIValues return :: IO [IValue]+            f (IVTuple ts)+        ),+        ( iValue_isList obj,+          do+            c10list <- fromIValue obj :: IO (ForeignPtr (ATen.C10List ATen.IValue))+            rawIValues <- uncast c10list return :: IO [RawIValue]+            ts <- uncast rawIValues return :: IO [IValue]+            f (IVGenericList ts)+        ),+        ( iValue_isGenericDict obj,+          do+            c10list <- fromIValue obj :: IO (ForeignPtr (ATen.C10Dict '(ATen.IValue, ATen.IValue)))+            rawIValues <- uncast c10list return :: IO [(RawIValue, RawIValue)]+            ts <- forM rawIValues $ \(a, b) -> do+              a' <- uncast a return+              b' <- uncast b return+              return (a', b')+            f (IVGenericDict ts)+        ),+        (iValue_isBlob obj, f IVBlob),+        (iValue_isFuture obj, f IVFuture),+        (iValue_isDevice obj, f IVDevice),+        (iValue_isObject obj, f IVObject),+        (iValue_isCapsule obj, f IVCapsule)+      ]+    where+      select [] = throwIO $ userError "Unsupported IValue"+      select ((cond, body) : xs) =+        cond >>= \case+          1 -> body+          _ -> select xs
+ src/Torch/Serialize.hs view
@@ -0,0 +1,107 @@+module Torch.Serialize where++import Control.Exception.Safe+  ( SomeException (..),+    throwIO,+    try,+  )+import Control.Monad (when)+import qualified Data.ByteString as BS+import qualified Data.ByteString.Internal as BSI+import Foreign.Marshal.Utils (copyBytes)+import qualified Foreign.ForeignPtr as F+import qualified Foreign.Ptr as F+import System.IO+import Torch.Autograd+import Torch.DType+import Torch.Functional+import Torch.Internal.Cast+import qualified Torch.Internal.Managed.Serialize as S+import Torch.NN+import Torch.Script hiding (clone, load, save)+import Torch.Tensor++save ::+  -- | inputs+  [Tensor] ->+  -- | file+  FilePath ->+  -- | output+  IO ()+save = cast2 S.save++load ::+  -- | file+  FilePath ->+  -- | output+  IO [Tensor]+load = cast1 S.load++-- | Save state_dict+pickleSave ::+  -- | inputs+  IValue ->+  -- | file+  FilePath ->+  -- | output+  IO ()+pickleSave = cast2 S.pickleSave++-- | Load a state_dict file+-- You should use a dict function of pytorch to save a state_dict file as follows.+--+-- > torch.save(dict(model.state_dict()), "state_dict.pth")+pickleLoad ::+  -- | file+  FilePath ->+  -- | output+  IO IValue+pickleLoad = cast1 S.pickleLoad++saveParams ::+  Parameterized f =>+  -- | model+  f ->+  -- | filepath+  FilePath ->+  -- | output+  IO ()+saveParams model filePath = do+  let params = map toDependent $ flattenParameters model+  save params filePath++loadParams ::+  Parameterized b =>+  -- | model+  b ->+  -- | filepath+  FilePath ->+  -- | output+  IO b+loadParams model filePath = do+  tensors <- load filePath+  let params = map IndependentTensor tensors+  pure $ replaceParameters model params++class RawFile a where+  loadBinary :: Handle -> a -> IO a+  saveBinary :: Handle -> a -> IO ()++instance RawFile Tensor where+  loadBinary handle tensor = do+    let len = (byteLength (dtype tensor)) * product (shape tensor)+    v <- BS.hGet handle len+    t <- clone tensor+    withTensor t $ \ptr1 -> do+      let (BSI.PS fptr _ len') = v+      when (len' < len) $ do+        throwIO $ userError $ "Read data's size is less than input tensor's one(" <> show len <> ")."+      F.withForeignPtr fptr $ \ptr2 -> do+        copyBytes (F.castPtr ptr1) (F.castPtr ptr2) (Prelude.min len len')+        return t++  saveBinary handle tensor = do+    let len = (byteLength (dtype tensor)) * product (shape tensor)+    t <- clone tensor+    withTensor tensor $ \ptr1 -> do+      hPutBuf handle (F.castPtr ptr1) len
− src/Torch/Short.hs
@@ -1,29 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Short--- Copyright :  (c) Sam Stites 2017--- License   :  BSD3--- Maintainer:  sam@stites.io--- Stability :  experimental--- Portability: non-portable---------------------------------------------------------------------------------module Torch.Short (module X) where--import Torch.Short.Index as X-import Torch.Indef.Short.Tensor as X-import Torch.Indef.Short.Tensor.Copy as X-import Torch.Indef.Short.Tensor.Index as X-import Torch.Indef.Short.Tensor.Masked as X-import Torch.Indef.Short.Tensor.Math as X-import Torch.Indef.Short.Tensor.Math.Compare as X-import Torch.Indef.Short.Tensor.Math.CompareT as X-import Torch.Indef.Short.Tensor.Math.Pairwise as X-import Torch.Indef.Short.Tensor.Math.Pointwise as X-import Torch.Indef.Short.Tensor.Math.Reduce as X-import Torch.Indef.Short.Tensor.Math.Scan as X-import Torch.Indef.Short.Tensor.Mode as X-import Torch.Indef.Short.Tensor.ScatterGather as X-import Torch.Indef.Short.Tensor.Sort as X-import Torch.Indef.Short.Tensor.TopK as X--import Torch.Indef.Short.Tensor.Math.Pointwise.Signed as X
− src/Torch/Short/Dynamic.hs
@@ -1,28 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Short.Dynamic--- Copyright :  (c) Sam Stites 2017--- License   :  BSD3--- Maintainer:  sam@stites.io--- Stability :  experimental--- Portability: non-portable---------------------------------------------------------------------------------module Torch.Short.Dynamic (module X) where--import Torch.Indef.Short.Dynamic.Tensor as X-import Torch.Indef.Short.Dynamic.Tensor.Copy as X-import Torch.Indef.Short.Dynamic.Tensor.Index as X-import Torch.Indef.Short.Dynamic.Tensor.Masked as X-import Torch.Indef.Short.Dynamic.Tensor.Math as X-import Torch.Indef.Short.Dynamic.Tensor.Math.Compare as X-import Torch.Indef.Short.Dynamic.Tensor.Math.CompareT as X-import Torch.Indef.Short.Dynamic.Tensor.Math.Pairwise as X-import Torch.Indef.Short.Dynamic.Tensor.Math.Pointwise as X-import Torch.Indef.Short.Dynamic.Tensor.Math.Reduce as X-import Torch.Indef.Short.Dynamic.Tensor.Math.Scan as X-import Torch.Indef.Short.Dynamic.Tensor.Mode as X-import Torch.Indef.Short.Dynamic.Tensor.ScatterGather as X-import Torch.Indef.Short.Dynamic.Tensor.Sort as X-import Torch.Indef.Short.Dynamic.Tensor.TopK as X--import Torch.Indef.Short.Dynamic.Tensor.Math.Pointwise.Signed as X
− src/Torch/Short/Storage.hs
@@ -1,13 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Short.Storage--- Copyright :  (c) Sam Stites 2017--- License   :  BSD3--- Maintainer:  sam@stites.io--- Stability :  experimental--- Portability: non-portable---------------------------------------------------------------------------------module Torch.Short.Storage (module X) where--import Torch.Indef.Short.Storage      as X-import Torch.Indef.Short.Storage.Copy as X
+ src/Torch/Tensor.hs view
@@ -0,0 +1,928 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE UndecidableInstances #-}++module Torch.Tensor where++import Control.Exception.Safe (throwIO)+import Control.Monad (forM, forM_)+import Numeric.Half+import Data.Complex+import Data.Int (Int16, Int64)+import Data.List (intercalate)+import Data.Proxy+import Data.Reflection+import qualified Data.Vector as V+import qualified Data.Vector.Storable as VS+import qualified Data.Vector.Unboxed as VU+import qualified Data.Vector.Generic as VG+import Data.Word (Word8)+import Foreign.C.Types+import Foreign.ForeignPtr+import Foreign.Marshal.Utils (copyBytes)+import Foreign.Ptr+import Foreign.Storable+import GHC.Generics+import GHC.ForeignPtr(mallocPlainForeignPtrBytes)+import Numeric+import System.IO.Unsafe+import Torch.DType+import Torch.Device+import Torch.Internal.Cast+import Torch.Internal.Class (Castable (..), CppTuple2 (..), CppTuple3 (..), CppTuple4 (..))+import qualified Torch.Internal.Const as ATen+import qualified Torch.Internal.Managed.Cast as ATen+import qualified Torch.Internal.Managed.Native as ATen+import qualified Torch.Internal.Managed.TensorFactories as LibTorch+import qualified Torch.Internal.Managed.Type.Context as ATen+import qualified Torch.Internal.Managed.Type.StdArray as ATen+import qualified Torch.Internal.Managed.Type.StdString as ATen+import qualified Torch.Internal.Managed.Type.Tensor as ATen+import qualified Torch.Internal.Managed.Type.StdOptional as ATen+import qualified Torch.Internal.Managed.Type.TensorIndex as ATen+import qualified Torch.Internal.Managed.Type.TensorOptions as ATen+import qualified Torch.Internal.Managed.Type.Extra as ATen+import qualified Torch.Internal.Type as ATen+import qualified Torch.Internal.Unmanaged.Type.Tensor as Unmanaged (tensor_data_ptr)+import Torch.Lens+import Torch.TensorOptions+import Control.DeepSeq (NFData, rnf)++type ATenTensor = ForeignPtr ATen.Tensor++-- do not use the constructor+newtype Tensor = Unsafe ATenTensor++instance NFData Tensor where+  rnf (Unsafe _) = ()++instance Castable Tensor ATenTensor where+  cast (Unsafe aten_tensor) f = f aten_tensor+  uncast aten_tensor f = f $ Unsafe aten_tensor++newtype MutableTensor = MutableTensor Tensor deriving Show++newMutableTensor :: Tensor -> IO MutableTensor+newMutableTensor tensor = MutableTensor <$> cast1 ATen.detach_t tensor++toImmutable :: MutableTensor -> IO Tensor+toImmutable (MutableTensor tensor) = cast1 ATen.detach_t tensor++type ATenOptionalTensor = ForeignPtr (ATen.StdOptional ATen.Tensor)++-- do not use the constructor+newtype OptionalTensor = UnsafeOptional ATenOptionalTensor++instance Castable OptionalTensor ATenOptionalTensor where+  cast (UnsafeOptional aten_optional_tensor) f = f aten_optional_tensor+  uncast aten_optional_tensor f = f $ UnsafeOptional aten_optional_tensor++instance Castable (Maybe Tensor) OptionalTensor where+  cast Nothing f = do+    ptr <- ATen.stdOptionalTensor_empty+    f (UnsafeOptional ptr)+  cast (Just tensor) f = do+    cast tensor $ \atenTensor -> do+      ptr <- ATen.stdOptionalTensor_create atenTensor+      f (UnsafeOptional ptr)+  uncast (UnsafeOptional ptr) f = do+    hasValue <- ATen.stdOptionalTensor_has_value ptr+    if hasValue /= 0+      then do+        atenTensor <- ATen.stdOptionalTensor_value ptr+        uncast atenTensor $ \tensor -> f (Just tensor)+      else f Nothing++instance Castable (Maybe Tensor) ATenOptionalTensor where+  cast maybeTensor f = do+    cast maybeTensor $ \(optTensor :: OptionalTensor) -> do+      cast optTensor f+  uncast ptr f = do+    uncast ptr $ \(optTensor :: OptionalTensor) -> do+      uncast optTensor f++--------------------------------------------------------------------------------+-- Basic tensor properties+--------------------------------------------------------------------------------++-- | Returns the total number of elements in the input tensor.+numel ::+  -- | input+  Tensor ->+  -- | number of elements in tensor+  Int+numel t = unsafePerformIO $ cast1 ATen.tensor_numel $ t++-- | Returns the size of a given dimension of the input tensor.+size ::+  -- | dimension+  Int ->+  -- | input+  Tensor ->+  Int+size dim t = unsafePerformIO $ (cast2 ATen.tensor_size_l) t dim++-- | Returns the shape of the tensor+shape ::+  -- | input+  Tensor ->+  -- | list of integers representing the shape of the tensor+  [Int]+shape t = unsafePerformIO $ (cast1 ATen.tensor_sizes) t++-- | Returns the dimensions of the input tensor+dim ::+  -- | input+  Tensor ->+  -- | output+  Int+dim t = unsafePerformIO $ (cast1 ATen.tensor_dim) t++-- | Returns the dimensions of the input tensor+dimUnsafe ::+  -- | input+  Tensor ->+  -- | output+  Int+dimUnsafe t = unsafePerformIO $ (cast1 ATen.tensor_dim_unsafe) t++-- | Returns the dimensions of the input tensor+dimCUnsafe ::+  -- | input+  Tensor ->+  -- | output+  Int+dimCUnsafe t = unsafePerformIO $ (cast1 ATen.tensor_dim_c_unsafe) t++-- | Returns the device on which the tensor is currently allocated+device ::+  -- | input+  Tensor ->+  -- | object representing the device+  Device+device t = unsafePerformIO $ do+  hasCUDA <- cast0 ATen.hasCUDA :: IO Bool+  if hasCUDA+    then do+      isCUDA <- cast1 ATen.tensor_is_cuda t :: IO Bool+      if isCUDA then cuda <$> cast1 ATen.tensor_get_device t else pure cpu+    else do+      hasMPS <- cast0 ATen.hasMPS :: IO Bool+      if hasMPS+        then do+        isMPS <- cast1 ATen.tensor_is_mps t :: IO Bool+        if isMPS then pure mps else pure cpu+      else+        pure cpu+  where+    cpu = Device {deviceType = CPU, deviceIndex = 0}+    cuda :: Int -> Device+    cuda di = Device {deviceType = CUDA, deviceIndex = fromIntegral di}+    mps = Device {deviceType = MPS, deviceIndex = 0}++-- | Returns the data type of the input tensor+dtype ::+  -- | input+  Tensor ->+  -- | data type of the input tensor+  DType+dtype t = unsafePerformIO $ cast1 ATen.tensor_scalar_type t++toComplex :: Tensor -> Complex Double+toComplex t = unsafePerformIO $+    case dtype t of+      ComplexHalf -> do+        r :+ i  <- withTensor t $ \ptr -> peekElemOff (castPtr ptr) 0 :: IO (Complex Half)+        return (realToFrac r :+ realToFrac i)+      ComplexFloat -> do+        r :+ i  <- withTensor t $ \ptr -> peekElemOff (castPtr ptr) 0 :: IO (Complex Float)+        return (realToFrac r :+ realToFrac i)+      ComplexDouble -> withTensor t $ \ptr -> peekElemOff (castPtr ptr) 0 :: IO (Complex Double)+      _ -> (:+ 0) <$> cast1 ATen.tensor_item_double t++toDouble :: Tensor -> Double+toDouble t = unsafePerformIO $ cast1 ATen.tensor_item_double t++toInt :: Tensor -> Int+toInt t = unsafePerformIO $ cast1 ATen.tensor_item_int64_t t++-- | Casts the input tensor to the given data type+_toType ::+  -- | data type to cast input to+  DType ->+  -- | input+  Tensor ->+  -- | output+  Tensor+_toType dtype t = unsafePerformIO $ cast2 ATen.tensor_toType_s t dtype++instance HasTypes Tensor Tensor where+  types_ = id++instance HasTypes (a -> a) Tensor where+  types_ _ = pure++instance HasTypes Int Tensor where+  types_ _ = pure++instance HasTypes Double Tensor where+  types_ _ = pure++instance HasTypes Float Tensor where+  types_ _ = pure++instance HasTypes Bool Tensor where+  types_ _ = pure++instance HasTypes Int Int where+  types_ = id++instance HasTypes Float Float where+  types_ = id++instance HasTypes Double Double where+  types_ = id++instance HasTypes Bool Bool where+  types_ = id++toType :: forall a. HasTypes a Tensor => DType -> a -> a+toType dtype t = over (types @Tensor @a) (_toType dtype) t++toDevice :: forall a. HasTypes a Tensor => Device -> a -> a+toDevice device' t = over (types @Tensor @a) (_toDevice device') t++-- | Casts the input tensor to given device+_toDevice ::+  -- | device to cast input to+  Device ->+  -- | input+  Tensor ->+  -- | output+  Tensor+_toDevice device' t = unsafePerformIO $ do+  hasDevice <- case deviceType device' of+    CPU -> pure True+    CUDA -> cast0 ATen.hasCUDA+    MPS -> cast0 ATen.hasMPS+  let device = Torch.Tensor.device t+  t' <-+    toDevice'+      (deviceType device)+      (deviceType device')+      (deviceIndex device)+      (deviceIndex device')+      hasDevice+  check+    (deviceType device')+    (deviceType $ Torch.Tensor.device t')+    (deviceIndex device')+    (deviceIndex $ Torch.Tensor.device t')+  pure t'+  where+    toDevice' dt dt' di di' _ | dt == dt' && di == di' = pure t -- do nothing+    toDevice' CUDA CUDA di di' True | di /= di' = getOpts t >>= withDeviceIndex di' >>= to t -- copy from di to di'+    toDevice' CPU CUDA 0 di' True | di' >= 0 = getOpts t >>= withDeviceIndex di' >>= to t -- copy from cpu:0 to cuda:di'+    toDevice' CUDA CPU di 0 True | di >= 0 = getOpts t >>= withDeviceType CPU >>= to t -- copy from cuda:di to cpu:0+    toDevice' CPU MPS 0 0 True = getOpts t >>= withDeviceType MPS >>= to t -- copy from cpu:0 to mps:0'+    toDevice' MPS CPU 0 0 True = getOpts t >>= withDeviceType CPU >>= to t -- copy from mps:0 to cpu:0+    toDevice' dt dt' di di' _ =+      error $+        "cannot move tensor from \""+          <> show dt+          <> ":"+          <> show di+          <> "\" to \""+          <> show dt'+          <> ":"+          <> show di'+          <> "\""+    getOpts :: Tensor -> IO TensorOptions+    getOpts = cast1 ATen.tensor_options+    withDeviceType :: DeviceType -> TensorOptions -> IO TensorOptions+    withDeviceType dt opts = cast2 ATen.tensorOptions_device_D opts dt+    withDeviceIndex :: Int16 -> TensorOptions -> IO TensorOptions+    withDeviceIndex di opts = cast2 ATen.tensorOptions_device_index_s opts di -- careful, setting the device index implies setting the device type to CUDA!+    to :: Tensor -> TensorOptions -> IO Tensor+    to t opts = cast4 ATen.tensor_to_obb t opts nonBlocking copy+      where+        nonBlocking = False+        copy = False+    check dt dt' di di' | dt == dt' && di == di' = pure ()+    check dt dt' di di' =+      error $+        "moving of tensor failed: device should have been \""+          <> show dt+          <> ":"+          <> show di+          <> "\" but is \""+          <> show dt'+          <> ":"+          <> show di'+          <> "\""++-- | Non-blocking variant of _toDevice for async H2D transfers.+-- IMPORTANT: Caller must synchronize before using the tensor (e.g., via+-- cudaStreamSynchronize or a synchronizing CUDA operation).+_toDeviceNonBlocking ::+  -- | device to cast input to+  Device ->+  -- | input+  Tensor ->+  -- | output (may still be transferring)+  Tensor+_toDeviceNonBlocking device' t = unsafePerformIO $ do+  hasDevice <- case deviceType device' of+    CPU -> pure True+    CUDA -> cast0 ATen.hasCUDA+    MPS -> cast0 ATen.hasMPS+  let device = Torch.Tensor.device t+  toDevice'+    (deviceType device)+    (deviceType device')+    (deviceIndex device)+    (deviceIndex device')+    hasDevice+  where+    toDevice' dt dt' di di' _ | dt == dt' && di == di' = pure t+    toDevice' CUDA CUDA di di' True | di /= di' = getOpts t >>= withDeviceIndex di' >>= toNonBlocking t+    toDevice' CPU CUDA 0 di' True | di' >= 0 = getOpts t >>= withDeviceIndex di' >>= toNonBlocking t+    toDevice' CUDA CPU di 0 True | di >= 0 = getOpts t >>= withDeviceType CPU >>= toNonBlocking t+    toDevice' CPU MPS 0 0 True = getOpts t >>= withDeviceType MPS >>= toNonBlocking t+    toDevice' MPS CPU 0 0 True = getOpts t >>= withDeviceType CPU >>= toNonBlocking t+    toDevice' dt dt' di di' _ =+      error $+        "cannot move tensor from \""+          <> show dt+          <> ":"+          <> show di+          <> "\" to \""+          <> show dt'+          <> ":"+          <> show di'+          <> "\""+    getOpts :: Tensor -> IO TensorOptions+    getOpts = cast1 ATen.tensor_options+    withDeviceType :: DeviceType -> TensorOptions -> IO TensorOptions+    withDeviceType dt opts = cast2 ATen.tensorOptions_device_D opts dt+    withDeviceIndex :: Int16 -> TensorOptions -> IO TensorOptions+    withDeviceIndex di opts = cast2 ATen.tensorOptions_device_index_s opts di+    toNonBlocking :: Tensor -> TensorOptions -> IO Tensor+    toNonBlocking t opts = cast4 ATen.tensor_to_obb t opts nonBlocking copy+      where+        nonBlocking = True+        copy = False++toDeviceWithTensor :: Tensor -> Tensor -> Tensor+toDeviceWithTensor reference input = unsafePerformIO $ cast2 ATen.tensor_to_device reference input++-- | Slices the input tensor along the selected dimension at the given index.+select ::+  -- | dimension to slice along+  Int ->+  -- | index in the given dimension+  Int ->+  -- | input+  Tensor ->+  -- | output+  Tensor+select dim idx t = unsafePerformIO $ cast3 ATen.tensor_select_ll t dim idx++-- | Returns a new tensor which indexes the input tensor along dimension dim using the entries in index which is a LongTensor.+indexSelect ::+  -- | dim+  Int ->+  -- | indexTensor+  Tensor ->+  -- | input+  Tensor ->+  -- | output+  Tensor+indexSelect dim indexTensor t = unsafePerformIO $ (cast3 ATen.index_select_tlt) t dim indexTensor++indexSelect' ::+  -- | dim+  Int ->+  -- | indexList+  [Int] ->+  -- | input+  Tensor ->+  -- | output+  Tensor+indexSelect' dim indexList t = unsafePerformIO $ (cast3 ATen.index_select_tlt) t dim (_toDevice (device t) (asTensor indexList))++-- | Slices the input tensor along the selected dimension at the given range.+sliceDim ::+  -- | dim+  Int ->+  -- | start+  Int ->+  -- | end+  Int ->+  -- | step+  Int ->+  -- | input+  Tensor ->+  Tensor+sliceDim _dim _start _end _step _self = unsafePerformIO $ (cast5 ATen.slice_tllll) _self _dim _start _end _step++isContiguous ::+  Tensor ->+  Bool+isContiguous t = unsafePerformIO $ (cast1 ATen.tensor_is_contiguous) t++contiguous ::+  Tensor ->+  Tensor+contiguous t = unsafePerformIO $ (cast1 ATen.tensor_contiguous) t++-- | Returns a tensor with the same data and number of elements as input, but with the specified shape.+reshape ::+  [Int] ->+  Tensor ->+  Tensor+reshape shape t = unsafePerformIO $ cast2 ATen.reshape_tl t shape++--------------------------------------------------------------------------------+-- Move backend+--------------------------------------------------------------------------------++toSparse :: Tensor -> Tensor+toSparse t = unsafePerformIO $ (cast2 ATen.tensor_to_sparse_l) t (dimCUnsafe t)++toDense :: Tensor -> Tensor+toDense t = unsafePerformIO $ (cast1 ATen.tensor_to_dense) t++toMKLDNN :: Tensor -> Tensor+toMKLDNN t = unsafePerformIO $ (cast1 ATen.tensor_to_mkldnn) t++toCPU :: Tensor -> Tensor+toCPU t = unsafePerformIO $ (cast1 ATen.tensor_cpu) t++toCUDA :: Tensor -> Tensor+toCUDA t = unsafePerformIO $ (cast1 ATen.tensor_cuda) t++toMPS :: Tensor -> Tensor+toMPS t = unsafePerformIO $ (cast1 ATen.tensor_mps) t++--------------------------------------------------------------------------------+-- Indexing support+--------------------------------------------------------------------------------++-- TensorIndex is the same as slice of pytorch.+--+-- There is one-to-one correspondence between Pytorch and Hasktorch tensor index types:+-- Pytorch                 | Hasktorch+-- -----------------------------------------------------+-- `None`                  | `None`+-- `Ellipsis`              | `Ellipsis`+-- `...`                   | `Ellipsis`+-- `123`                   | `123`+-- `True` / `False`        | `True` / `False`+-- `:`                     | `Slice ()`+-- `::`                    | `Slice ()`+-- `1:`                    | `Slice (1, None)`+-- `1::`                   | `Slice (1, None)`+-- `:3`                    | `Slice (None, 3)`+-- `:3:`                   | `Slice (None, 3)`+-- `::2`                   | `Slice (None, None, 2)`+-- `1:3`                   | `Slice (1, 3)`+-- `1::2`                  | `Slice (1, None, 2)`+-- `:3:2`                  | `Slice (None, 3, 2)`+-- `1:3:2`                 | `Slice (1, 3, 2)`+-- `torch.tensor([1, 2])`) | `asTensor([1, 2 ::Int])`++newtype RawTensorIndexList = RawTensorIndexList (ForeignPtr (ATen.StdVector ATen.TensorIndex))++newtype RawTensorIndex = RawTensorIndex (ForeignPtr ATen.TensorIndex)++(!) :: TensorIndex a => Tensor -> a -> Tensor+(Unsafe t) ! idx = unsafePerformIO $ do+  let idxs = pushIndex [] idx+  vec <- ATen.newTensorIndexList+  forM_ idxs $ \(RawTensorIndex i) -> do+    ATen.tensorIndexList_push_back vec i+  ATen.index t vec >>= (return . Unsafe)++maskedFill :: (TensorIndex a, TensorLike t) => Tensor -> a -> t -> Tensor+maskedFill (Unsafe t') idx v' = unsafePerformIO $ do+  let idxs = pushIndex [] idx+      (Unsafe v) = asTensor v'+  t <- ATen.clone_t t'+  vec <- ATen.newTensorIndexList+  forM_ idxs $ \(RawTensorIndex i) -> do+    ATen.tensorIndexList_push_back vec i+  ATen.index_put_ t vec v+  return $ Unsafe t++data None = None+  deriving (Show, Eq)++data Ellipsis = Ellipsis+  deriving (Show, Eq)++newtype Slice a = Slice a+  deriving (Show, Eq)++instance Castable RawTensorIndex (ForeignPtr ATen.TensorIndex) where+  cast (RawTensorIndex obj) f = f obj+  uncast obj f = f $ RawTensorIndex obj++class TensorIndex a where+  pushIndex :: [RawTensorIndex] -> a -> [RawTensorIndex]+  toLens :: TensorLike b => a -> Lens' Tensor b+  default toLens :: TensorLike b => a -> Lens' Tensor b+  toLens idx func s = maskedFill s idx <$> (asTensor <$> func (asValue (s ! idx)))++instance {-# OVERLAPS #-} TensorIndex None where+  pushIndex vec _ = unsafePerformIO $ do+    idx <- ATen.newTensorIndexWithNone+    return ((RawTensorIndex idx) : vec)++instance {-# OVERLAPS #-} TensorIndex Ellipsis where+  pushIndex vec _ = unsafePerformIO $ do+    idx <- ATen.newTensorIndexWithEllipsis+    return ((RawTensorIndex idx) : vec)++instance {-# OVERLAPS #-} TensorIndex Bool where+  pushIndex vec b = unsafePerformIO $ do+    idx <- ATen.newTensorIndexWithBool (if b then 1 else 0)+    return ((RawTensorIndex idx) : vec)++instance {-# OVERLAPS #-} (Integral a) => TensorIndex (Slice (a, a)) where+  pushIndex vec (Slice (start, end)) = unsafePerformIO $ do+    idx <- ATen.newTensorIndexWithSlice (fromIntegral start :: CInt) (fromIntegral end :: CInt) 1+    return ((RawTensorIndex idx) : vec)++instance {-# OVERLAPS #-} (Integral a) => TensorIndex (Slice (a, a, a)) where+  pushIndex vec (Slice (start, end, step)) = unsafePerformIO $ do+    idx <- ATen.newTensorIndexWithSlice (fromIntegral start :: CInt) (fromIntegral end :: CInt) (fromIntegral step :: CInt)+    return ((RawTensorIndex idx) : vec)++instance {-# OVERLAPS #-} (Integral a) => TensorIndex (Slice (None, None, a)) where+  pushIndex vec (Slice (_, _, step)) = unsafePerformIO $ do+    idx <- ATen.newTensorIndexWithSlice 0 (maxBound :: CInt) (fromIntegral step :: CInt)+    return ((RawTensorIndex idx) : vec)++instance {-# OVERLAPS #-} (Integral a) => TensorIndex (Slice a) where+  pushIndex vec (Slice start) = unsafePerformIO $ do+    idx <- ATen.newTensorIndexWithSlice (fromIntegral start :: CInt) (maxBound :: CInt) 1+    return ((RawTensorIndex idx) : vec)++instance {-# OVERLAPS #-} (Integral a) => TensorIndex (Slice (a, None)) where+  pushIndex vec (Slice (start, _)) = unsafePerformIO $ do+    idx <- ATen.newTensorIndexWithSlice (fromIntegral start :: CInt) (maxBound :: CInt) 1+    return ((RawTensorIndex idx) : vec)++instance {-# OVERLAPS #-} (Integral a) => TensorIndex (Slice (a, None, a)) where+  pushIndex vec (Slice (start, _, step)) = unsafePerformIO $ do+    idx <- ATen.newTensorIndexWithSlice (fromIntegral start :: CInt) (maxBound :: CInt) (fromIntegral step :: CInt)+    return ((RawTensorIndex idx) : vec)++instance {-# OVERLAPS #-} (Integral a) => TensorIndex (Slice (None, a, a)) where+  pushIndex vec (Slice (_, end, step)) = unsafePerformIO $ do+    idx <- ATen.newTensorIndexWithSlice 0 (fromIntegral end :: CInt) (fromIntegral step :: CInt)+    return ((RawTensorIndex idx) : vec)++instance {-# OVERLAPS #-} (Integral a) => TensorIndex (Slice (None, a)) where+  pushIndex vec (Slice (_, end)) = unsafePerformIO $ do+    idx <- ATen.newTensorIndexWithSlice 0 (fromIntegral end :: CInt) 1+    return ((RawTensorIndex idx) : vec)++instance {-# OVERLAPS #-} TensorIndex (Slice ()) where+  pushIndex vec (Slice ()) = unsafePerformIO $ do+    idx <- ATen.newTensorIndexWithSlice 0 (maxBound :: CInt) 1+    return ((RawTensorIndex idx) : vec)++instance TensorIndex Int where+  pushIndex vec v = unsafePerformIO $ do+    idx <- ATen.newTensorIndexWithInt (fromIntegral v :: CInt)+    return ((RawTensorIndex idx) : vec)++instance TensorIndex Integer where+  pushIndex vec v = unsafePerformIO $ do+    idx <- ATen.newTensorIndexWithInt (fromIntegral v :: CInt)+    return ((RawTensorIndex idx) : vec)++instance TensorIndex Tensor where+  pushIndex vec v = unsafePerformIO $ do+    idx <- cast1 ATen.newTensorIndexWithTensor v+    return (idx : vec)++instance TensorIndex () where+  pushIndex vec _ = unsafePerformIO $ do+    idx <- ATen.newTensorIndexWithSlice 0 (maxBound :: CInt) 1+    return ((RawTensorIndex idx) : vec)++instance (TensorIndex a, TensorIndex b) => TensorIndex (a, b) where+  pushIndex vec (a, b) = (flip pushIndex a) . (flip pushIndex b) $ vec++instance (TensorIndex a, TensorIndex b, TensorIndex c) => TensorIndex (a, b, c) where+  pushIndex vec (a, b, c) = (flip pushIndex a) . (flip pushIndex b) . (flip pushIndex c) $ vec++instance (TensorIndex a, TensorIndex b, TensorIndex c, TensorIndex d) => TensorIndex (a, b, c, d) where+  pushIndex vec (a, b, c, d) = (flip pushIndex a) . (flip pushIndex b) . (flip pushIndex c) . (flip pushIndex d) $ vec++instance (TensorIndex a, TensorIndex b, TensorIndex c, TensorIndex d, TensorIndex e) => TensorIndex (a, b, c, d, e) where+  pushIndex vec (a, b, c, d, e) = (flip pushIndex a) . (flip pushIndex b) . (flip pushIndex c) . (flip pushIndex d) . (flip pushIndex e) $ vec++--------------------------------------------------------------------------------+-- Scalar <-> Tensor promotion+--------------------------------------------------------------------------------++asValue :: TensorLike a => Tensor -> a+asValue t =+  let cpuTensor = if device t == Device CPU 0 then t else toCPU t+      contTensor = if isContiguous cpuTensor then cpuTensor else contiguous cpuTensor+   in _asValue contTensor++class TensorOptionLike a where+  withTensorOptions :: Tensor -> a -> Tensor++instance  TensorOptionLike TensorOptions where+  withTensorOptions t opts = unsafePerformIO $ cast4 ATen.tensor_to_obb t opts nonBlocking copy+    where+      nonBlocking = False+      copy = False++instance  TensorOptionLike Tensor where+  withTensorOptions t opts = unsafePerformIO $ cast4 ATen.tensor_to_tbb t opts nonBlocking copy+    where+      nonBlocking = False+      copy = False++class TensorLike a where+  asTensor' :: TensorOptionLike opt => a -> opt -> Tensor+  asTensor' v opts = withTensorOptions (asTensor v) opts+  asTensor :: a -> Tensor+  _asValue :: Tensor -> a++  -- Internal functions(like "_xxx") are below. Do not use them directly.+  _dtype :: DType+  _dims :: a -> [Int]+  _deepDims :: a -> Maybe [Int]+  _peekElemOff :: Ptr () -> Int -> [Int] -> IO a+  _pokeElemOff :: Ptr () -> Int -> a -> IO ()++bool_opts = withDType Bool defaultOpts++uint8_opts = withDType UInt8 defaultOpts++int64_opts = withDType Int64 defaultOpts++float_opts = withDType Float defaultOpts++double_opts = withDType Double defaultOpts++withTensor :: Tensor -> (Ptr () -> IO a) -> IO a+withTensor t fn =+  let tensor = if isContiguous t then t else contiguous t+   in cast tensor $ \t' -> withForeignPtr t' $ \tensor_ptr -> Unmanaged.tensor_data_ptr tensor_ptr >>= fn++-- | The internal function of withTensor. It does not check contiguous memory-layout.+_withTensor :: Tensor -> (Ptr () -> IO a) -> IO a+_withTensor t fn =+  cast t $ \t' -> withForeignPtr t' $ \tensor_ptr -> Unmanaged.tensor_data_ptr tensor_ptr >>= fn++instance {-# OVERLAPPING #-} (Reifies a DType, Storable a) => TensorLike a where+  asTensor v = unsafePerformIO $ do+    t <- ((cast2 ATen.new_empty_tensor) :: [Int] -> TensorOptions -> IO Tensor) [] $ withDType (_dtype @a) defaultOpts+    _withTensor t $ \ptr -> do+      _pokeElemOff ptr 0 v+    return t++  _asValue t = unsafePerformIO $ do+    if _dtype @a == dtype t+      then do+        withTensor t $ \ptr -> do+          _peekElemOff ptr 0 []+      else throwIO $ userError $ "The infered DType of asValue is " ++ show (_dtype @a) ++ ", but the DType of tensor on memory is " ++ show (dtype t) ++ "."++  _dtype = reflect (Proxy :: Proxy a)+  _dims _ = []+  _deepDims _ = Just []+  _peekElemOff ptr offset _ = peekElemOff (castPtr ptr) offset+  _pokeElemOff ptr offset v = pokeElemOff (castPtr ptr) offset v++instance {-# OVERLAPPING #-} TensorLike Bool where+  asTensor v = unsafePerformIO $ do+    t <- ((cast2 ATen.new_empty_tensor) :: [Int] -> TensorOptions -> IO Tensor) [] $ withDType (_dtype @Bool) defaultOpts+    _withTensor t $ \ptr -> do+      _pokeElemOff ptr 0 v+    return t++  _asValue t = unsafePerformIO $ do+    if _dtype @Bool == dtype t+      then do+        withTensor t $ \ptr -> do+          _peekElemOff ptr 0 []+      else throwIO $ userError $ "The infered DType of asValue is " ++ show (_dtype @Bool) ++ ", but the DType of tensor on memory is " ++ show (dtype t) ++ "."++  _dtype = reflect (Proxy :: Proxy Bool)+  _dims _ = []+  _deepDims _ = Just []+  _peekElemOff ptr offset _ = (/= 0) <$> (peekElemOff (castPtr ptr) offset :: IO Word8)+  _pokeElemOff ptr offset v = pokeElemOff (castPtr ptr) offset ((if v then 1 else 0) :: Word8)++instance {-# OVERLAPPING #-} TensorLike Tensor where+  asTensor' v opts = withTensorOptions v opts+  asTensor = id+  _asValue = id+  _dtype = error "Not implemented for Tensor-type"+  _dims v = error "Not implemented for Tensor-type"+  _deepDims v = error "Not implemented for Tensor-type"+  _peekElemOff = error "Not implemented for Tensor-type"+  _pokeElemOff = error "Not implemented for Tensor-type"++instance {-# OVERLAPPING #-} TensorLike a => TensorLike (a, a) where+  asTensor (a, b) = asTensor [a, b]+  _asValue v =+    let [a, b] = _asValue v+     in (a, b)+  _dtype = error "Not implemented for tuple-type"+  _dims v = error "Not implemented for tuple-type"+  _deepDims v = error "Not implemented for tuple-type"+  _peekElemOff = error "Not implemented for tuple-type"+  _pokeElemOff = error "Not implemented for tuple-type"++instance {-# OVERLAPPING #-} TensorLike a => TensorLike [a] where+  asTensor v = unsafePerformIO $ do+    t <- ((cast2 ATen.new_empty_tensor) :: [Int] -> TensorOptions -> IO Tensor) (_dims v) $ withDType (_dtype @a) defaultOpts+    _withTensor t $ \ptr -> do+      _pokeElemOff ptr 0 v+    return t++  _asValue t = unsafePerformIO $ do+    if _dtype @a == dtype t+      then do+        withTensor t $ \ptr -> do+          _peekElemOff ptr 0 (shape t)+      else throwIO $ userError $ "The infered DType of asValue is " ++ show (_dtype @a) ++ ", but the DType of tensor on memory is " ++ show (dtype t) ++ "."++  _dtype = _dtype @a++  _dims [] = [0]+  _dims v@(x : _) = (length v) : (_dims x)++  _deepDims [] = Just [0]+  _deepDims v@(x : xs) = do+    deepDimsX <- _deepDims x+    deepDimsXs <- traverse _deepDims xs+    if and $ fmap (deepDimsX ==) deepDimsXs+      then return $ length v : deepDimsX+      else Nothing++  _peekElemOff ptr offset [] = return []+  _peekElemOff ptr offset (d : dims) =+    let width = product dims+     in forM [0 .. (d -1)] $ \i ->+          _peekElemOff ptr (offset + i * width) dims++  _pokeElemOff ptr offset [] = return ()+  _pokeElemOff ptr offset v@(x : _) =+    let width = product (_dims x)+     in forM_ (zip [0 ..] v) $ \(i, d) ->+          if product (_dims d) == width -- This validation may be slow.+            then (_pokeElemOff @a) ptr (offset + i * width) d+            else throwIO $ userError $ "There are lists having different length."++instance {-# OVERLAPPING #-} (Reifies a DType, Storable a) => TensorLike (VS.Vector a) where+  asTensor v = unsafePerformIO $ do+    t <- ((cast2 ATen.new_empty_tensor) :: [Int] -> TensorOptions -> IO Tensor) [VS.length v] $ withDType (_dtype @a) defaultOpts+    _withTensor t $ \ptr -> do+      VS.unsafeWith v $ \vptr -> do+        copyBytes+          (castPtr ptr)+          (castPtr vptr)+          (VS.length v * (sizeOf (undefined :: a)))+    return t++  _asValue t = unsafePerformIO $+    let len = head (shape t)+    in+      withTensor t $ \ptr -> do+        fp <- mallocPlainForeignPtrBytes (len * (sizeOf (undefined :: a)))+        withForeignPtr fp $ \vptr -> do+          copyBytes+            (castPtr vptr)+            (castPtr ptr)+            (len * (sizeOf (undefined :: a)))+        return $ VS.unsafeFromForeignPtr fp 0 len++  _dtype = reflect (Proxy :: Proxy a)+  _dims v = [VS.length v]+  _deepDims v = Just [VS.length v]+  _peekElemOff = error "Not implemented for storable vector"+  _pokeElemOff = error "Not implemented for storable vector"++instance {-# OVERLAPPING #-} (Reifies a DType, Storable a, VG.Vector VU.Vector a) => TensorLike (VU.Vector a) where+  asTensor v = asTensor (VG.convert v :: VS.Vector a)+  _asValue t = VG.convert (_asValue t :: VS.Vector a)++  _dtype = reflect (Proxy :: Proxy a)+  _dims v = [VG.length v]+  _deepDims v = Just [VG.length v]+  _peekElemOff = error "Not implemented for unboxed vector"+  _pokeElemOff = error "Not implemented for unboxed vector"++class AsTensors as where+  toTensors :: as -> V.Vector Tensor+  default toTensors :: (Generic as, GAsTensors (Rep as)) => as -> V.Vector Tensor+  toTensors a = gToTensors $ from a++instance TensorLike a => AsTensors a where+  toTensors = pure . asTensor++class GAsTensors record where+  gToTensors :: record as -> V.Vector Tensor++instance (GAsTensors ls, GAsTensors rs) => GAsTensors (ls :*: rs) where+  gToTensors (g :*: d) = gToTensors g V.++ gToTensors d++instance (GAsTensors ls, GAsTensors rs) => GAsTensors (ls :+: rs) where+  gToTensors (L1 g) = gToTensors g+  gToTensors (R1 g) = gToTensors g++instance (GAsTensors ls) => GAsTensors (M1 i c ls) where+  gToTensors (M1 g) = gToTensors g++instance (TensorLike ls) => GAsTensors (K1 i ls) where+  gToTensors (K1 g) = pure $ asTensor g++--------------------------------------------------------------------------------+-- Show+--------------------------------------------------------------------------------++instance Show Tensor where+  show t' =+    case (dim t) of+      0 -> details ++ show0d t+      1 -> details ++ show1d t+      n -> details ++ shownd n 0 t+    where+      t = if device t' == Device CPU 0 then t' else toCPU t'+      -- TODO: this is obviously not the right way to do it,+      -- and will be terribly slow, so please fix it.+      showElems elemShow sep t = "[" ++ (intercalate sep $ map elemShow [t ! i | i <- [0 .. ((size 0 t) - 1)]]) ++ "]"+      padPositive x s = if x >= 0 then " " ++ s else s+      -- TODO: this assumes that scientific notation only uses one-digit exponents, which is not+      --       true in general+      padLarge x s = if (abs x) >= 0.1 then s ++ "   " else s+      show0d x =+        if isIntegral (dtype t)+          then padPositive (toInt x) $ show $ toInt x+          else+            if isComplex (dtype t)+               then+                 let r :+ i = toComplex x+                 in (padLarge r $ padPositive r $ showGFloat (Just 4) r "") ++ " + i" +++                    (padLarge i $ padPositive i $ showGFloat (Just 4) i "")+               else padLarge (toDouble x) $ padPositive (toDouble x) $ showGFloat (Just 4) (toDouble x) ""+      show1d = showElems show0d ", "+      shownd n offset =+        case n of+          2 -> showElems show1d (",\n " ++ padding ++ replicate offset ' ')+          _ -> showElems (shownd (n -1) (offset + 1)) (",\n " ++ padding ++ replicate offset ' ')+      details = "Tensor " ++ (show $ dtype t) ++ " " ++ (show $ shape t) ++ " "+      padding = map (const ' ') details++--------------------------------------------------------------------------------++-- Castable instances+--------------------------------------------------------------------------------++-- NB: ATen only defines Castable [ForeignPtr ATen.Tensor] (ForeignPtr ATen.TensorList)+instance Castable [Tensor] (ForeignPtr ATen.TensorList) where+  cast xs f = do+    ptr_list <- mapM (\x -> (cast x return :: IO (ForeignPtr ATen.Tensor))) xs+    cast ptr_list f+  uncast xs f = uncast xs $ \ptr_list -> do+    tensor_list <- mapM (\(x :: ForeignPtr ATen.Tensor) -> uncast x return) ptr_list+    f tensor_list++instance Castable [Tensor] (ForeignPtr (ATen.C10List ATen.Tensor)) where+  cast xs f = do+    ptr_list <- mapM (\x -> (cast x return :: IO (ForeignPtr ATen.Tensor))) xs+    cast ptr_list f+  uncast xs f = uncast xs $ \ptr_list -> do+    tensor_list <- mapM (\(x :: ForeignPtr ATen.Tensor) -> uncast x return) ptr_list+    f tensor_list++instance Castable [Tensor] (ForeignPtr (ATen.C10List (ATen.C10Optional ATen.Tensor))) where+  cast xs f = do+    ptr_list <- mapM (\x -> (cast x return :: IO (ForeignPtr ATen.Tensor))) xs+    cast ptr_list f+  uncast xs f = uncast xs $ \ptr_list -> do+    tensor_list <- mapM (\(x :: ForeignPtr ATen.Tensor) -> uncast x return) ptr_list+    f tensor_list
+ src/Torch/TensorFactories.hs view
@@ -0,0 +1,508 @@+{-# LANGUAGE FlexibleContexts #-}++module Torch.TensorFactories where++import Foreign.ForeignPtr+import System.IO.Unsafe+import Torch.Dimname+import Torch.Internal.Cast+import Torch.Internal.Class (Castable (..))+import qualified Torch.Internal.Const as ATen+import qualified Torch.Internal.Managed.Autograd as LibTorch+import Torch.Internal.Managed.Cast+import qualified Torch.Internal.Managed.Native as ATen+import qualified Torch.Internal.Managed.TensorFactories as LibTorch+import qualified Torch.Internal.Managed.Type.Tensor as ATen+import qualified Torch.Internal.Managed.Type.TensorOptions as ATen+import qualified Torch.Internal.Type as ATen+import Torch.Scalar+import Torch.Tensor+import Torch.TensorOptions++-- XXX: We use the torch:: constructors, not at:: constructures, because+--      otherwise we cannot use libtorch's AD.++type FactoryType =+  ForeignPtr ATen.IntArray ->+  ForeignPtr ATen.TensorOptions ->+  IO (ForeignPtr ATen.Tensor)++type FactoryTypeWithDimnames =+  ForeignPtr ATen.IntArray ->+  ForeignPtr ATen.DimnameList ->+  ForeignPtr ATen.TensorOptions ->+  IO (ForeignPtr ATen.Tensor)++mkFactory ::+  -- | aten_impl+  FactoryType ->+  -- | shape+  [Int] ->+  -- | opts+  TensorOptions ->+  -- | output+  IO Tensor+mkFactory = cast2++mkFactoryUnsafe :: FactoryType -> [Int] -> TensorOptions -> Tensor+mkFactoryUnsafe f shape opts = unsafePerformIO $ mkFactory f shape opts++mkFactoryWithDimnames :: FactoryTypeWithDimnames -> [(Int, Dimname)] -> TensorOptions -> IO Tensor+mkFactoryWithDimnames aten_impl shape = cast3 aten_impl (map fst shape) (map snd shape)++mkFactoryUnsafeWithDimnames :: FactoryTypeWithDimnames -> [(Int, Dimname)] -> TensorOptions -> Tensor+mkFactoryUnsafeWithDimnames f shape opts = unsafePerformIO $ mkFactoryWithDimnames f shape opts++mkDefaultFactory :: ([Int] -> TensorOptions -> a) -> [Int] -> a+mkDefaultFactory non_default shape = non_default shape defaultOpts++mkDefaultFactoryWithDimnames :: ([(Int, Dimname)] -> TensorOptions -> a) -> [(Int, Dimname)] -> a+mkDefaultFactoryWithDimnames non_default shape = non_default shape defaultOpts++-------------------- Factories --------------------++-- | Returns a tensor filled with the scalar value 1, with the shape defined by the variable argument size.+ones ::+  -- | sequence of integers defining the shape of the output tensor.+  [Int] ->+  -- | configures the data type, device, layout and other properties of the resulting tensor.+  TensorOptions ->+  -- | output+  Tensor+ones = mkFactoryUnsafe LibTorch.ones_lo++-- TODO - ones_like from Native.hs is redundant with this++-- | Returns a tensor filled with the scalar value 1, with the same size as input tensor+onesLike ::+  -- | input+  Tensor ->+  -- | output+  Tensor+onesLike self = unsafePerformIO $ cast1 ATen.ones_like_t self++-- | Returns a tensor filled with the scalar value 0, with the shape defined by the variable argument size.+zeros ::+  -- | sequence of integers defining the shape of the output tensor.+  [Int] ->+  -- | configures the data type, device, layout and other properties of the resulting tensor.+  TensorOptions ->+  -- | output+  Tensor+zeros = mkFactoryUnsafe LibTorch.zeros_lo++-- | Returns a tensor filled with the scalar value 0, with the same size as input tensor+zerosLike ::+  -- | input+  Tensor ->+  -- | output+  Tensor+zerosLike self = unsafePerformIO $ cast1 ATen.zeros_like_t self++-- | Returns a tensor filled with random numbers from a uniform distribution on the interval [0,1)+randIO ::+  -- | sequence of integers defining the shape of the output tensor.+  [Int] ->+  -- | configures the data type, device, layout and other properties of the resulting tensor.+  TensorOptions ->+  -- | output+  IO Tensor+randIO = mkFactory LibTorch.rand_lo++-- | Returns a tensor filled with random numbers from a standard normal distribution.+randnIO ::+  -- | sequence of integers defining the shape of the output tensor.+  [Int] ->+  -- | configures the data type, device, layout and other properties of the resulting tensor.+  TensorOptions ->+  -- | output+  IO Tensor+randnIO = mkFactory LibTorch.randn_lo++-- | Returns a tensor filled with random integers generated uniformly between low (inclusive) and high (exclusive).+randintIO ::+  -- | lowest integer to be drawn from the distribution. Default: 0.+  Int ->+  -- | one above the highest integer to be drawn from the distribution.+  Int ->+  -- | the shape of the output tensor.+  [Int] ->+  -- | configures the data type, device, layout and other properties of the resulting tensor.+  TensorOptions ->+  -- | output+  IO Tensor+randintIO low high = mkFactory (LibTorch.randint_lllo (fromIntegral low) (fromIntegral high))++-- | Returns a tensor with the same size as input that is filled with random numbers from standard normal distribution.+randnLikeIO ::+  -- | input+  Tensor ->+  -- | output+  IO Tensor+randnLikeIO = cast1 ATen.randn_like_t++-- | Returns a tensor with the same size as input that is filled with random numbers from a uniform distribution on the interval [0,1).+randLikeIO ::+  -- | input+  Tensor ->+  -- | configures the data type, device, layout and other properties of the resulting tensor.+  TensorOptions ->+  -- | output+  IO Tensor+randLikeIO = cast2 LibTorch.rand_like_to++fullLike ::+  -- | input+  Tensor ->+  -- | _fill_value+  Float ->+  -- | opt+  TensorOptions ->+  -- | output+  IO Tensor+fullLike = cast3 LibTorch.full_like_tso++onesWithDimnames :: [(Int, Dimname)] -> TensorOptions -> Tensor+onesWithDimnames = mkFactoryUnsafeWithDimnames LibTorch.ones_lNo++zerosWithDimnames :: [(Int, Dimname)] -> TensorOptions -> Tensor+zerosWithDimnames = mkFactoryUnsafeWithDimnames LibTorch.zeros_lNo++randWithDimnames :: [(Int, Dimname)] -> TensorOptions -> IO Tensor+randWithDimnames = mkFactoryWithDimnames LibTorch.rand_lNo++randnWithDimnames :: [(Int, Dimname)] -> TensorOptions -> IO Tensor+randnWithDimnames = mkFactoryWithDimnames LibTorch.randn_lNo++-- | Returns a one-dimensional tensor of steps equally spaced points between start and end.+linspace ::+  (Scalar a, Scalar b) =>+  -- | @start@+  a ->+  -- | @end@+  b ->+  -- | @steps@+  Int ->+  -- | configures the data type, device, layout and other properties of the resulting tensor.+  TensorOptions ->+  -- | output+  Tensor+linspace start end steps opts = unsafePerformIO $ cast4 LibTorch.linspace_sslo start end steps opts++logspace :: (Scalar a, Scalar b) => a -> b -> Int -> Double -> TensorOptions -> Tensor+logspace start end steps base opts = unsafePerformIO $ cast5 LibTorch.logspace_ssldo start end steps base opts++-- https://github.com/hasktorch/ffi-experimental/pull/57#discussion_r301062033+-- empty :: [Int] -> TensorOptions -> Tensor+-- empty = mkFactoryUnsafe LibTorch.empty_lo++eyeSquare ::+  -- | dim+  Int ->+  -- | opts+  TensorOptions ->+  -- | output+  Tensor+eyeSquare dim = unsafePerformIO . cast2 LibTorch.eye_lo dim++-- | Returns a 2-D tensor with ones on the diagonal and zeros elsewhere.+eye ::+  -- | the number of rows+  Int ->+  -- | the number of columns+  Int ->+  -- | configures the data type, device, layout and other properties of the resulting tensor.+  TensorOptions ->+  -- | output+  Tensor+eye nrows ncols opts = unsafePerformIO $ cast3 LibTorch.eye_llo nrows ncols opts++-- | Returns a tensor of given size filled with fill_value.+full ::+  Scalar a =>+  -- | the shape of the output tensor.+  [Int] ->+  -- | the number to fill the output tensor with+  a ->+  -- | configures the data type, device, layout and other properties of the resulting tensor.+  TensorOptions ->+  -- | output+  Tensor+full shape value opts = unsafePerformIO $ cast3 LibTorch.full_lso shape value opts++-- | Constructs a sparse tensors in COO(rdinate) format with non-zero elements at the given indices with the given values.+sparseCooTensor ::+  -- | The indices are the coordinates of the non-zero values in the matrix+  Tensor ->+  -- | Initial values for the tensor.+  Tensor ->+  -- | the shape of the output tensor.+  [Int] ->+  -- |+  TensorOptions ->+  -- | output+  Tensor+sparseCooTensor indices values size opts = unsafePerformIO $ cast4 sparse_coo_tensor_ttlo indices values size opts+  where+    sparse_coo_tensor_ttlo indices' values' size' opts' = do+      i' <- LibTorch.dropVariable indices'+      v' <- LibTorch.dropVariable values'+      LibTorch.sparse_coo_tensor_ttlo i' v' size' opts'++-------------------- Factories with default type --------------------++ones' :: [Int] -> Tensor+ones' = mkDefaultFactory ones++zeros' :: [Int] -> Tensor+zeros' = mkDefaultFactory zeros++randIO' :: [Int] -> IO Tensor+randIO' = mkDefaultFactory randIO++randnIO' :: [Int] -> IO Tensor+randnIO' = mkDefaultFactory randnIO++randintIO' :: Int -> Int -> [Int] -> IO Tensor+randintIO' low high = mkDefaultFactory (randintIO low high)++randLikeIO' :: Tensor -> IO Tensor+randLikeIO' t = randLikeIO t defaultOpts++bernoulliIO' ::+  -- | t+  Tensor ->+  -- | output+  IO Tensor+bernoulliIO' = cast1 ATen.bernoulli_t++bernoulliIO ::+  -- | t+  Tensor ->+  -- | p+  Double ->+  -- | output+  IO Tensor+bernoulliIO = cast2 ATen.bernoulli_td++poissonIO ::+  -- | t+  Tensor ->+  -- | output+  IO Tensor+poissonIO = cast1 ATen.poisson_t++multinomialIO' ::+  -- | t+  Tensor ->+  -- | num_samples+  Int ->+  -- | output+  IO Tensor+multinomialIO' = cast2 ATen.multinomial_tl++multinomialIO ::+  -- | t+  Tensor ->+  -- | num_samples+  Int ->+  -- | replacement+  Bool ->+  -- | output+  IO Tensor+multinomialIO = cast3 ATen.multinomial_tlb++normalIO' ::+  -- | _mean+  Tensor ->+  -- | output+  IO Tensor+normalIO' = cast1 ATen.normal_t++normalIO ::+  -- | _mean+  Tensor ->+  -- | _std+  Tensor ->+  -- | output+  IO Tensor+normalIO = cast2 ATen.normal_tt++normalScalarIO ::+  -- | _mean+  Tensor ->+  -- | _std+  Double ->+  -- | output+  IO Tensor+normalScalarIO = cast2 ATen.normal_td++normalScalarIO' ::+  -- | _mean+  Double ->+  -- | _std+  Tensor ->+  -- | output+  IO Tensor+normalScalarIO' = cast2 ATen.normal_dt++normalWithSizeIO ::+  -- | _mean+  Double ->+  -- | _std+  Double ->+  -- | _size+  Int ->+  -- | output+  IO Tensor+normalWithSizeIO = cast3 ATen.normal_ddl++rreluIO''' ::+  -- | t+  Tensor ->+  -- | output+  IO Tensor+rreluIO''' = cast1 ATen.rrelu_t++rreluIO'' ::+  Scalar a =>+  -- | t+  Tensor ->+  -- | upper+  a ->+  -- | output+  IO Tensor+rreluIO'' = cast2 ATen.rrelu_ts++rreluIO' ::+  Scalar a =>+  -- | t+  Tensor ->+  -- | lower+  a ->+  -- | upper+  a ->+  -- | output+  IO Tensor+rreluIO' = cast3 ATen.rrelu_tss++rreluIO ::+  Scalar a =>+  -- | t+  Tensor ->+  -- | lower+  a ->+  -- | upper+  a ->+  -- | training+  Bool ->+  -- | output+  IO Tensor+rreluIO = cast4 ATen.rrelu_tssb++rreluWithNoiseIO''' ::+  -- | t+  Tensor ->+  -- | noise+  Tensor ->+  -- | output+  IO Tensor+rreluWithNoiseIO''' = cast2 ATen.rrelu_with_noise_tt++rreluWithNoiseIO'' ::+  Scalar a =>+  -- | t+  Tensor ->+  -- | noise+  Tensor ->+  -- | upper+  a ->+  -- | output+  IO Tensor+rreluWithNoiseIO'' = cast3 ATen.rrelu_with_noise_tts++rreluWithNoiseIO' ::+  Scalar a =>+  -- | t+  Tensor ->+  -- | noise+  Tensor ->+  -- | lower+  a ->+  -- | upper+  a ->+  -- | output+  IO Tensor+rreluWithNoiseIO' = cast4 ATen.rrelu_with_noise_ttss++rreluWithNoiseIO ::+  Scalar a =>+  -- | t+  Tensor ->+  -- | noise+  Tensor ->+  -- | lower+  a ->+  -- | upper+  a ->+  -- | training+  Bool ->+  -- | output+  IO Tensor+rreluWithNoiseIO = cast5 ATen.rrelu_with_noise_ttssb++onesWithDimnames' :: [(Int, Dimname)] -> Tensor+onesWithDimnames' = mkDefaultFactoryWithDimnames onesWithDimnames++zerosWithDimnames' :: [(Int, Dimname)] -> Tensor+zerosWithDimnames' = mkDefaultFactoryWithDimnames zerosWithDimnames++randWithDimnames' :: [(Int, Dimname)] -> IO Tensor+randWithDimnames' = mkDefaultFactoryWithDimnames randWithDimnames++randnWithDimnames' :: [(Int, Dimname)] -> IO Tensor+randnWithDimnames' = mkDefaultFactoryWithDimnames randnWithDimnames++linspace' :: (Scalar a, Scalar b) => a -> b -> Int -> Tensor+linspace' start end steps = linspace start end steps defaultOpts++logspace' :: (Scalar a, Scalar b) => a -> b -> Int -> Double -> Tensor+logspace' start end steps base = logspace start end steps base defaultOpts++eyeSquare' :: Int -> Tensor+eyeSquare' dim = eyeSquare dim defaultOpts++eye' :: Int -> Int -> Tensor+eye' nrows ncols = eye nrows ncols defaultOpts++full' :: Scalar a => [Int] -> a -> Tensor+full' shape value = full shape value defaultOpts++sparseCooTensor' :: Tensor -> Tensor -> [Int] -> Tensor+sparseCooTensor' indices values size = sparseCooTensor indices values size defaultOpts++-- | Returns a 1-D tensor with values from the interval [start, end) taken with common difference step beginning from start.+arange ::+  -- | start+  Int ->+  -- | end+  Int ->+  -- | step+  Int ->+  -- | configures the data type, device, layout and other properties of the resulting tensor.+  TensorOptions ->+  -- | output+  Tensor+arange s e ss o = unsafePerformIO $ (cast4 ATen.arange_ssso) s e ss o++-- | Returns a 1-D tensor with values from the interval [start, end) taken with common difference step beginning from start.+arange' ::+  -- | start+  Int ->+  -- | end+  Int ->+  -- | step+  Int ->+  -- | output+  Tensor+arange' s e ss = arange s e ss defaultOpts
+ src/Torch/TensorOptions.hs view
@@ -0,0 +1,61 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RecordWildCards #-}++module Torch.TensorOptions where++import Data.Int+import Foreign.ForeignPtr+import System.IO.Unsafe+import Torch.DType+import Torch.Device+import Torch.Internal.Cast+import Torch.Internal.Class (Castable (..))+import qualified Torch.Internal.Const as ATen+import qualified Torch.Internal.Managed.Type.Context as ATen+import qualified Torch.Internal.Managed.Type.TensorOptions as ATen+import qualified Torch.Internal.Type as ATen+import Torch.Layout++type ATenTensorOptions = ForeignPtr ATen.TensorOptions++newtype TensorOptions = TensorOptions ATenTensorOptions deriving (Show)++instance Castable TensorOptions ATenTensorOptions where+  cast (TensorOptions aten_opts) f = f aten_opts+  uncast aten_opts f = f $ TensorOptions aten_opts++defaultOpts :: TensorOptions+defaultOpts =+  TensorOptions $ unsafePerformIO $ ATen.newTensorOptions_s ATen.kFloat++withDType :: DType -> TensorOptions -> TensorOptions+withDType dtype opts =+  unsafePerformIO $ cast2 ATen.tensorOptions_dtype_s opts dtype++withDevice :: Device -> TensorOptions -> TensorOptions+withDevice Device {..} opts = unsafePerformIO $ do+  case deviceType of+    CPU -> pure opts+    CUDA -> do+      hasCUDA <- cast0 ATen.hasCUDA+      withDevice' deviceType deviceIndex hasCUDA opts+    MPS -> do+      hasMPS <- cast0 ATen.hasMPS+      withDevice' deviceType deviceIndex hasMPS opts+  where+    withDeviceType :: DeviceType -> TensorOptions -> IO TensorOptions+    withDeviceType dt opts = cast2 ATen.tensorOptions_device_D opts dt+    withDeviceIndex :: Int16 -> TensorOptions -> IO TensorOptions+    withDeviceIndex di opts = cast2 ATen.tensorOptions_device_index_s opts di -- careful, this somehow implies deviceType = CUDA+    withDevice' ::+      DeviceType -> Int16 -> Bool -> TensorOptions -> IO TensorOptions+    withDevice' CPU 0 _ opts = pure opts >>= withDeviceType CPU+    withDevice' CUDA di True opts | di >= 0 = pure opts >>= withDeviceIndex di+    withDevice' MPS 0 True opts = pure opts >>= withDeviceType MPS+    withDevice' dt di _ _ =+      error $ "cannot move tensor to \"" <> show dt <> ":" <> show di <> "\""++withLayout :: Layout -> TensorOptions -> TensorOptions+withLayout layout opts =+  unsafePerformIO $ cast2 ATen.tensorOptions_layout_L opts layout
+ src/Torch/Tutorial.hs view
@@ -0,0 +1,644 @@+{-# OPTIONS_GHC -fno-warn-unused-imports #-}++-- | Hasktorch is a library for scientific computing and differentiable+-- programming.+module Torch.Tutorial+  ( -- $tutorial+  )+where++import Torch.Internal.Managed.Type.Context (manual_seed_L)++-- $setup+-- >>> manual_seed_L 123+-- >>> :set -XNoOverloadedLists++-- $tutorial+-- = What is Hasktorch?+-- #introduction#+--+-- Hasktorch is a Haskell library for scientific computing and+-- differentiable programming.  It leverages @libtorch@ (the backend+-- library powering PyTorch) for efficient tensor manipulation and+-- automatic differentiation, while bringing to bear Haskell's expressive+-- type system and first-class support for for the functional programming+-- paradigm.+--+-- == Goal of this tutorial+--+-- The sequence of topics and examples here is loosely based on the+-- PyTorch tutorial [Deep Learning with PyTorch: A 60 Minute+-- Blitz](https://pytorch.org/tutorials/beginner/deep_learning_60min_blitz.html)+-- by Soumith Chintala.+--+-- In this tutorial we will implement a simple machine learning+-- model. Along the way, you will learn to+--+-- - create and manipulate tensors+--+-- - build computation graphs from tensors and compute gradients+--+-- - optimize parameters with respect to an objective function+--+-- = Usage+-- #usage#+--+-- The reader is encouraged to follow along with the examples in a GHCi session.+--+-- To start, import 'Torch':+--+-- >>> import Torch+--+-- == Tensors+-- #tensors#+--+-- A `Tensor` in Hasktorch is multidimensional array with a fixed shape+-- and element type.+--+-- For example, we can initialize a tensor with shape @[3, 4]@ and filled+-- with zeros using+--+-- >>> Torch.zeros' [3, 4]+-- Tensor Float [3,4] [[ 0.0000,  0.0000,  0.0000,  0.0000],+--                     [ 0.0000,  0.0000,  0.0000,  0.0000],+--                     [ 0.0000,  0.0000,  0.0000,  0.0000]]+--+-- We can also initialize a tensor from a Haskell list using+-- 'Torch.Tensor.asTensor':+--+-- >>> asTensor ([[4, 3], [2, 1]] :: [[Float]])+-- Tensor Float [2,2] [[ 4.0000   ,  3.0000   ],+--                     [ 2.0000   ,  1.0000   ]]+--+-- Note that the numerical type of the tensor is inferred from the types of+-- the values in the list.+--+-- Scalar values are represented in Hasktorch as tensors with shape @[]@:+--+-- >>> asTensor 3.5+-- Tensor Double []  3.5000+--+-- We can get the scalar value back out using 'Torch.Tensor.asValue':+--+-- >>> asValue (asTensor 3.5)+-- 3.5+--+-- === Specifying Tensor parameters+--+-- In the previous section we initialized a tensor filled with zeros+-- using @zeros'@ (note the prime suffix). Hasktorch functions use a+-- convention where default versions of functions use a prime suffix. The+-- unprimed versions of these functions expect an additional parameter+-- specifying tensor parameters. For example:+--+-- @+--   zeros :: [Int] -> 'Torch.TensorOptions' -> Tensor+-- @+--+-- @TensorOptions@ are typically specified by starting with+-- 'Torch.TensorOptions.defaultOpts' and modifying using one or more of+-- the following:+--+-- - 'Torch.TensorOptions.withDType' configures the data type of the elements+-- - 'Torch.TensorOptions.withDevice' configures on which device the tensor is to be used+-- - others (see 'Torch.TensorOptions')+--+-- For example, to construct a matrix filled with zeros of dtype @Int64@:+--+-- >>> zeros [4, 4] (withDType Int64 defaultOpts)+-- Tensor Int64 [4,4] [[ 0,  0,  0,  0],+--                     [ 0,  0,  0,  0],+--                     [ 0,  0,  0,  0],+--                     [ 0,  0,  0,  0]]+--+-- === Tensor factories+--+-- Hasktorch comes with many "factory" functions similar to @zeros@ and+-- @zeros'@ useful for initializing common kinds of tensors. For example,+-- 'Torch.TensorFactories.ones',+-- 'Torch.TensorFactories.full',+-- 'Torch.TensorFactories.eye',+-- and the primed versions of these. See 'Torch.TensorFactories' for a+-- complete list.+--+-- One useful class of factory functions are those suffixed with "-like"+-- (e.g. 'Torch.TensorFactories.onesLike'), which initialize a tensor+-- with the same dimensions as their argument. For example:+--+-- >>> let x = zeros' [3, 2]+-- >>> onesLike x+-- Tensor Float [3,2] [[ 1.0000   ,  1.0000   ],+--                     [ 1.0000   ,  1.0000   ],+--                     [ 1.0000   ,  1.0000   ]]+--+-- == Operations+-- #operations#+--+-- Most operations are pure functions, similar to Haskell standard library+-- math operations.+--+-- Tensors implement the @Num@ typeclass:+--+-- >>> let x = ones' [4]+-- >>> x + x+-- Tensor Float [4] [ 2.0000   ,  2.0000   ,  2.0000   ,  2.0000   ]+--+-- Some operations transform a tensor:+--+-- >>> Torch.relu (asTensor ([-1.0, -0.5, 0.5, 1] :: [Float]))+-- Tensor Float [4] [ 0.0000,  0.0000,  0.5000   ,  1.0000   ]+--+-- 'Torch.Tensor.selectDim' slices out a selection by specifying a dimension and index:+--+-- >>> let x = asTensor [[[1, 2, 3]], [[4, 5, 6]], [[7, 8, 9]], [[10, 11, 12]]]+-- >>> shape x+-- [4,1,3]+--+-- >>> select 2 1 x+-- Tensor Double [4,1] [[ 2.0000   ],+--                      [ 5.0000   ],+--                      [ 8.0000   ],+--                      [ 11.0000   ]]+--+-- >>> let y = asTensor [1, 2, 3]+-- >>> Torch.select 0 1 y+-- Tensor Double []  2.0000+--+-- Values can be extracted from a tensor using @asValue@ so long as the+-- dtype matches the Haskell type:+--+-- >>> let x = asTensor ([2] :: [Int])+-- >>> let y = asValue x :: Int+-- >>> y+-- 2+--+-- == Randomness+--+-- Create a randomly initialized matrix:+--+-- >>> x <-randIO' [2, 2]+-- >>> x+-- Tensor Float [2,2] [[ 0.2961   ,  0.5166   ],+--                     [ 0.2517   ,  0.6886   ]]+--+-- Note that since random initialization returns a different result each+-- time, unlike other tensor constructors, is monadic reflecting the+-- context of an underlying random number generator (RNG) changing state.+--+-- Hasktorch includes variations of random tensor initializers in which the+-- RNG object is threaded explicitly rather than implicitly. See the+-- @Torch.Random@ module functions for details and variations. Samplers for+-- which the RNG is not explicit such as @randIO\'@ example above use the+-- @-IO@ suffix.+--+--+-- == Automatic Differentiation+-- #automatic-differentiation#+--+-- Automatic differentiation is achieved through the use of two primary+-- functions in the 'Torch.Autograd' module,+-- 'Torch.Autograd.makeIndependent' and 'Torch.Autograd.grad'.+--+-- === Independent Tensors+-- #independent-tensors#+--+-- @makeIndependent@ is used to instantiate an independent tensor variable+-- from which a compute graph is constructed for differentiation, while+-- @grad@ uses compute graph to compute gradients.+--+-- @makeIndependent@ takes a tensor as input and returns an IO action+-- which produces an 'Torch.Autograd.IndependentTensor':+--+-- >  makeIndependent :: Tensor -> IO IndependentTensor+--+-- What is the definition of the @IndependentTensor@ type produced by the+-- @makeIndependent@ action? It’s defined in the Hasktorch library as:+--+-- >  newtype IndependentTensor = IndependentTensor { toDependent :: Tensor }+-- >  deriving (Show)+--+-- Thus @IndependentTensor@ is simply a wrapper around the underlying+-- Tensor that is passed in as the argument to @makeIndependent@. Building+-- up computations using ops applied to the @toDependent@ tensor of an+-- @IndependentTensor@ will implicitly construct a compute graph to which+-- @grad@ can be applied.+--+-- All tensors have an underlying property that can be retrieved using+-- the 'Torch.Autograd.requiresGrad' function which indicates whether+-- they are a differentiable value in a compute graph. <#notes [1]>+--+-- >>> let x = asTensor [1, 2, 3]+-- >>> y <- makeIndependent (asTensor [4, 5, 6])+-- >>> let y' = toDependent y+-- >>> let z = x + y'+-- >>> requiresGrad x+-- False+--+-- >>> requiresGrad y'+-- True+--+-- >>> requiresGrad z+-- True+--+-- In summary, tensors that are computations of values derived from tensor+-- constructors (e.g. @ones@, @zeros@, @fill@, @randIO@ etc.) outside the+-- context of a @IndependentTensor@ are not differentiable. Tensors that+-- are derived from computations on the @toDependent@ value of an+-- @IndependentTensor@ are differentiable, as the above example+-- illustrates.+--+-- === Gradients+-- #gradients#+--+-- Once a computation graph is constructed by applying ops and computing+-- derived quantities stemming from a @toDependent@ value of an+-- @IndependentTensor@, a gradient can be taken by using the @grad@+-- function specifying in the first argument tensor corresponding to+-- function value of interest and a list of @Independent@ tensor variables+-- that the the derivative is taken with respect to:+--+-- >  grad :: Tensor -> [IndependentTensor] -> [Tensor]+--+-- Let’s demonstrate this with a concrete example. We create a tensor and+-- derive an @IndependentTensor@ from it:+--+-- >>> x <- makeIndependent (ones' [2, 2])+-- >>> let x' = toDependent x+-- >>> x'+-- Tensor Float [2,2] [[ 1.0000   ,  1.0000   ],+--                     [ 1.0000   ,  1.0000   ]]+--+-- Now do some computations on the dependent tensor:+--+-- >>> let y = x' + 2+-- >>> y+-- Tensor Float [2,2] [[ 3.0000   ,  3.0000   ],+--                     [ 3.0000   ,  3.0000   ]]+--+-- Since y is dependent on the x independent tensor, it is differentiable:+--+-- >>> requiresGrad y+-- True+--+-- Applying more operations:+--+-- >>> let z = y * y * 3+-- >>> let out = mean z+-- >>> z+-- Tensor Float [2,2] [[ 27.0000   ,  27.0000   ],+--                     [ 27.0000   ,  27.0000   ]]+--+-- Now retrieve the gradient:+--+-- >>> grad out [x]+-- [Tensor Float [2,2] [[ 4.5000   ,  4.5000   ],+--                     [ 4.5000   ,  4.5000   ]]]+--+-- == Differentiable Programs (Neural Networks)+-- #differentiable-programs-neural-networks#+--+-- From a functional programming perspective, a neural network is+-- represented by data and functions, much like any other functional+-- program. The only distinction that differentiates neural networks from+-- any other functional program is that it implements a small interface+-- surface to support differentiation. Thus, we can consider neural+-- networks to be \"differentiable functional programming\".+--+-- The data in neural networks are the values to be fitted that+-- parameterize the functions which carry out the inference operation and+-- are modified based on gradients of through those functions.+--+-- As with a regular Haskell program, this data is represented by an+-- algebraic data type (ADT). The ADT can take on any shape that’s needed+-- to model the domain of interest, allowing a great deal of flexibility+-- and enabling all of Haskell’s strenghts in data modeling - can use sum+-- or product types, nest types, etc. The ADT can implement various+-- typeclasses to take on other functionality.+--+-- The core interface that defines capability specific to differentiable+-- programming is the 'Torch.NN.Parameterized' typeclass:+--+-- >  class Parameterized f where+-- >    flattenParameters :: f -> [Parameter]+-- >    default flattenParameters :: (Generic f, Parameterized' (Rep f)) => f -> [Parameter]+-- >    flattenParameters f = flattenParameters' (from f)+-- >+-- >    replaceOwnParameters :: f -> ParamStream f+-- >    default replaceOwnParameters :: (Generic f, Parameterized' (Rep f)) => f -> ParamStream f+-- >    replaceOwnParameters f = to <$> replaceOwnParameters' (from f)+--+-- Note @Parameter@ is simply a type alias for @IndependentTensor@ in the+-- context of neural networks (i.e. @type Parameter = IndependentTensor@).+--+-- The role of @flattenParameters@ is to unroll any arbitrary ADT+-- representation of a neural network into a standard flattened+-- representation consisting a list of @IndependentTensor@ which is used to+-- compute gradients.+--+-- @replaceOwnParameters@ is used to update parameters. ParamStream is a+-- type alias for a State type with state represented by a @Parameter@ list+-- and a value parameter corresponding to the ADT defining the model.+--+-- >  type ParamStream a = State [Parameter] a+--+-- Note the use of generics. Generics allow the compiler to usually+-- automatically derive @flattenParameters@ and @replaceOwnParameter@+-- instances without any code if your type is built up on tensors,+-- containers of tensors, or other types that are built from tensor values+-- (for example, layer modules provided in @Torch.NN@. In many cases, as+-- you’ll see in the following examples, you will only need to add+--+-- >  instance Parameterized MyNeuralNetwork+--+-- (where @MyNeuralNetwork@ is an ADT definition for your model) and the+-- compiler will derive implementations for the @flattenParameters@ and+-- @replaceOwnParameters@.+--+-- === Linear Regression+-- #linear-regression#+--+-- Lets start with a simple example of linear regression. Here we generate+-- random data with an underlying affine relationship between the inputs+-- and outputs, then fit a linear regression to reproduce that+-- relationship.+--+-- This example is adapted from+-- <https://github.com/hasktorch/hasktorch/tree/master/examples/regression>.+--+-- In a standard supervised learning model, the neural network is+-- initialized using a randomized initialization scheme. An iterative+-- optimization is performed such that at each iteration a batch.+--+-- >  module Main where+-- >+-- >  import Control.Monad (when)+-- >  import Torch+-- >+-- >  groundTruth :: Tensor -> Tensor+-- >  groundTruth t = squeezeAll $ matmul t weight + bias+-- >    where+-- >      weight = asTensor ([42.0, 64.0, 96.0] :: [Float])+-- >      bias = full' [1] (3.14 :: Float)+-- >+-- >  model :: Linear -> Tensor -> Tensor+-- >  model state input = squeezeAll $ linear state input+-- >+-- >  main :: IO ()+-- >  main = do+-- >      init <- sample $ LinearSpec{in_features = numFeatures, out_features = 1}+-- >      randGen <- mkGenerator (Device CPU 0) 12345+-- >      (trained, _) <- foldLoop (init, randGen) 2000 $ \(state, randGen) i -> do+-- >          let (input, randGen') = randn' [batchSize, numFeatures] randGen+-- >              (y, y') = (groundTruth input, model state input)+-- >              loss = mseLoss y y'+-- >          when (i `mod` 100 == 0) $ do+-- >              putStrLn $ "Iteration: " ++ show i ++ " | Loss: " ++ show loss+-- >          (newParam, _) <- runStep state GD loss 5e-3+-- >          pure (replaceParameters state newParam, randGen')+-- >      pure ()+-- >    where+-- >      batchSize = 4+-- >      numFeatures = 3+--+-- Note the expression of the architecture in the 'Torch.NN.linear'+-- function (a single linear layer, or alternatively a neural network+-- with zero hidden layers), does not require an explicit representation+-- of the compute graph, but is simply a composition of tensor+-- ops. Because of the autodiff mechanism described in the previous+-- section, the graph is constructed automatically as pure functional ops+-- are applied, given a context of a set of independent variables.+--+-- The @init@ variable is initialized as a @Linear@ type (defined in+-- @Torch.NN@) using @sample@ which randomly initializes a @Linear@ value.+--+-- @Linear@ is a built-in ADT implementing the @Parameterized@ typeclass+-- and representing a fully connected linear layer, equivalent to linear+-- regression when no hidden layers are present.+--+-- @init@ is passed into the 'Torch.Optim.foldLoop'@<#notes [2]> as the @state@+-- variable.+--+-- A new list of @Parameter@ values is passed back from+-- 'Torch.Optim.runStep' (which calls @grad@ to retrieve gradients, given+-- a loss function, learning rate, and optimizer) and the typeclass+-- function @replaceParameters@ is used to update the model at each+-- iteration.+--+-- Initialization is discussed in more detail in the following section+--+-- === Weight Initialization+-- #weight-initialization#+--+-- Random initialization of weights is not a pure function since two+-- random initializations return different values. Initialization occurs+-- by calling the 'Torch.NN.sample' function for an ADT (@spec@)+-- implementing the 'Torch.NN.Randomizable' typeclass:+--+-- >  class Randomizable spec f | spec -> f where+-- >    sample :: spec -> IO f+--+-- In a typical (but not required) usage, @f@ is an ADT that implements the+-- @Parameterized@ typeclass, so that there’s a pair of types - a+-- specification type implementing the @spec@ input to @sample@ and a type+-- implementing @Parameterizable@ representing the model state.+--+-- For example, a linear fully connected layer is provided by the+-- @Torch.NN@ module and defined therein as:+--+-- >  data Linear = Linear { weight :: Parameter, bias :: Parameter } deriving (Show, Generic)+--+-- and is typically used with a specification type:+--+-- >  data LinearSpec = LinearSpec { in_features :: Int, out_features :: Int }+-- >    deriving (Show, Eq)+--+-- Putting this together, in untyped tensor usage, the user can implement+-- custom models or layers implementing the @Parameterizable@ typeclass+-- built up from other ADTs implementing @Parameterizable@. The shape of+-- the data required for initialization is described by a type implementing+-- @Randomizable@’s @spec@ parameter, and the @sample@ implementation+-- specifies the default weight initialization.+--+-- Note this initialization approach is specific to untyped tensors. One+-- consequence of using typed tensors is that the information in these+-- @spec@ types is reflected in the type itself and thus are not needed.+--+-- What if you want to use a custom initialization that differs from the+-- default? You can define an alternative function with the same signature+-- @spec -> IO f@ and use the alternative function instead of @sample@.+--+-- === Optimizers+-- #optimizers#+--+-- Optimization implementations are functions that take as input the+-- current parameter values of a model, parameter gradient estimates of the+-- loss function at those parameters for a single batch, and a+-- characteristic learning describing how large a perturbation to make to+-- the parameters in order to reduce the loss. Given those inputs, they+-- output a new set of parameters.+--+-- In the simple case of stochastic gradient descent, the function to+-- output a new set of parameters is to subtract from the current parameter+-- \(\theta\), the gradient of the loss \(\nabla J\) scaled by the learning+-- rate \(\eta\):+--+-- \[\theta_{i+1} = \theta_i - \eta \nabla J(\theta)\]+--+-- While stochastic gradient descent is a stateless function of the+-- parameters, loss, and gradient, some optimizers have a notion of+-- internal state that is propagated from one step to the step, for+-- example, retaining and updating momentum between steps:+--+-- \[\begin{gathered}+--     \Delta \theta_i = \alpha \Delta \theta_{i-1} - \eta \nabla J(\theta) \\+--     \theta_{i+1} = \theta_i + \Delta \theta_i+-- \end{gathered}\]+--+-- In this case, the momentum term \(\Delta \theta_i\) is carried forward+-- as internal state of the optimizer that is propagated to the next step.+-- \(\alpha\) is an optimizer parameter which determines a weighting on the+-- momentum term relative to the gradient.+--+-- Implementation of an optimizer consists of defining an ADT describing+-- the optimizer state and a @step@ function that implements a single step+-- perturbation given the learning rate, loss gradients, current+-- parameters, and optimizer state.+--+-- This function interface is described in the 'Torch.Optim.Optimizer'+-- typeclass interface:+--+-- >  class Optimizer o where+-- >      step :: LearningRate -> Gradients -> [Tensor] -> o -> ([Tensor], o)+--+-- @Gradients@ is a newtype wrapper around a list of tensors to make+-- intent explicit: @newtype Gradients = Gradients [Tensor]@.+--+-- Hasktorch provides built-in optimizer implementations in @Torch.Optim@.+-- Some illustrative example implementations follow.+--+-- Being stateless, stochastic gradient descent has an ADT that has only+-- one constructor value:+--+-- >  data GD = GD+--+-- and implements the step function as:+--+-- >  instance Optimizer GD where+-- >      step lr gradients depParameters dummy = (gd lr gradients depParameters, dummy)+-- >          where+-- >          step p dp = p - (lr * dp)+-- >          gd lr (Gradients gradients) parameters = zipWith step parameters gradients+--+-- The use of an optimizer was illustrated in the linear regression example+-- using the function @runStep@+--+-- >  (newParam, _) <- runStep state GD loss 5e-3+--+-- In this case the new optimizer state returned is ignored (as @_@) since+-- gradient descent does not have any internal state. Under the hood,+-- @runStep@ does a little bookkeeping making independent variables from a+-- model, computing gradients, and passing values to the @step@ function.+-- Usually a user can ignore the details and just pass model parameters and+-- the optimizer to runStep as an abstracted interface which takes+-- parameter values, the optimizer value, loss (a tensor), and learning+-- rate as input and returns new parameters and an updated optimizer value.+--+-- >  runStep :: (Parameterized p, Optimizer o) =>+-- >          p -> o -> Tensor -> LearningRate -> IO ([Parameter], o)+--+-- = Typed Tensors+-- #typed-tensors#+--+-- Typed tensors provide an alternative API for which tensor+-- characteristics are encoded in the type of the tensor. The Hasktorch+-- library is layered such that [ TODO ]+--+-- Using typed tensors increases the expressiveness of program invariants+-- that can be automatically checked by GHC at the cost of needing to be+-- more explicit in writing code and also requiring working with Haskell’s+-- type-level machinery. Type-level Haskell programming has arisen through+-- progressive compiler iteration leading to mechanisms that have a higher+-- degree of complexity compared to value-level Haskell code or other+-- languages such as Idris which were designed with type-level computations+-- from inception. In spite of these compromises, Haskell offers enough+-- capability to express powerful type-level representations of models that+-- is matched by few other languages used for production applications.+--+-- Things we can do in typed Hasktorch:+--+-- -   specify, check, and infer tensor shapes at compile time+--+-- -   specify, check, and infer tensor data types at compile time+--+-- -   specify, check, and infer tensor compute devices at compile time+--+-- We can encode all Hasktorch tensor shapes on the type level using+-- type-level lists and natural numbers:+--+-- >  type EmptyShape = '[]+-- >  type OneDimensionalShape (a :: Nat) = '[a]+-- >  type TwoDimensionalShape (a :: Nat) (b :: Nat) = '[a, b]+-- >  ...+--+-- Tensor data types and compute device types are lifted to the type level+-- using the @DataKinds@ language extension:+--+-- >  type BooleanCPUTensor (shape :: [Nat]) = Tensor '(CPU,  0) 'Bool  shape+-- >  type IntCUDATensor    (shape :: [Nat]) = Tensor '(CUDA, 1) 'Int64 shape+--+-- Devices are represented as tuples consisting of a @DeviceType@ (here+-- @CPU@ for the CPU and @CUDA@ for a CUDA device, respectively) and a+-- device id (here the @Nat@s @0@ and @1@, respectively).+--+-- It is a common misconception that specifying tensor properties at+-- compile time is only possible if all tensor properties are constants and+-- are statically known. If this were the case, then we could only write+-- functions over fully specified tensors, say,+--+-- >  boring :: BooleanCPUTensor '[] -> BooleanCPUTensor '[]+-- >  boring = id+--+-- Fortunately, Haskell has the ability to reason about type variables.+-- This feature is called parametric polymorphism. Consider this simple+-- example of a function:+--+-- >  tensorNoOp+-- >    :: forall (shape :: [Nat]) (dtype :: DType) (device :: (DeviceType, Nat))+-- >     . Tensor device dtype shape+-- >    -> Tensor device dtype shape+-- >  tensorNoOp = id+--+-- Here, @shape@, @dtype@, and @device@ are type variables that have been+-- constrained to be of kind shape, data type, and device, respectively.+-- The universal quantifier @forall@ implies that this function is+-- well-defined for all inhabitants of the types that are compatible with+-- the type variables and their constraints.+--+-- The @tensorNoOp@ function may seem trivial, and that is because its type+-- is very strongly constrained: Given any typed tensor, it must return a+-- tensor of the same shape and with the same data type and on the same+-- device. Besides by means of the identity, @id@, there are not many ways+-- in which this function can be implemented.+--+-- There is a connection between a type signature of a function and+-- mathematical proofs. We can say that the fact that a function exists is+-- witnessed by its implementation. The implementation, @tensorNoOp = id@,+-- is the proof of the theorem stated by @tensorNoOp@’s type signature. And+-- here we have a proof that we can run this function on any device and for+-- any data type and tensor shape.+--+-- This is the essence of typed Hasktorch. As soon as the compiler gives+-- its OK, we hold a proof that our program will run without shape or CUDA+-- errors.+--+-- #notes#+--+-- 1.  PyTorch users will be familiar with this as the @requires_grad@+--     member variable for the PyTorch tensor type. The Hasktorch mechanism+--     is distinct from PyTorch’s mechanism - by only allowing gradients to+--     be applied in the context of a set of @IndependentTensor@ variables,+--     it allows ops to be semantically pure and preserve referential+--     transparency.+--+-- 2.  @foldLoop@ is a convenience function defined in terms of @foldM@ as+--     @foldLoop x count block = foldM block x ([1 .. count] :: [a])@
+ src/Torch/Typed.hs view
@@ -0,0 +1,43 @@+module Torch.Typed+  ( module Torch.HList,+    module Torch.Typed,+    module Torch.Data,+    module Torch.Typed.Auxiliary,+    module Torch.Typed.Autograd,+    module Torch.Typed.Device,+    module Torch.Typed.DType,+    module Torch.Typed.Factories,+    module Torch.Typed.Functional,+    module Torch.Typed.NN,+    module Torch.Typed.Optim,+    module Torch.Typed.Parameter,+    module Torch.Typed.Serialize,+    module Torch.Typed.Tensor,+    module Torch.Typed.Vision,+    Torch.Device.Device (..),+    Torch.Device.DeviceType (..),+    Torch.DType.DType (..),+    Torch.Scalar.Scalar (..),+    Torch.Functional.Reduction (..),+    Torch.Functional.Tri (..),+  )+where++import Torch.DType (DType (..))+import Torch.Data+import Torch.Device (Device (..), DeviceType (..))+import Torch.Functional (Reduction (..), Tri (..))+import Torch.HList+import Torch.Scalar (Scalar (..))+import Torch.Typed.Autograd+import Torch.Typed.Auxiliary+import Torch.Typed.DType+import Torch.Typed.Device+import Torch.Typed.Factories+import Torch.Typed.Functional+import Torch.Typed.NN+import Torch.Typed.Optim+import Torch.Typed.Parameter hiding (parameterToDType, parameterToDevice)+import Torch.Typed.Serialize+import Torch.Typed.Tensor hiding (toDType, toDevice)+import Torch.Typed.Vision
+ src/Torch/Typed/Autograd.hs view
@@ -0,0 +1,94 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE NoStarIsType #-}+{-# LANGUAGE RecordWildCards #-}++module Torch.Typed.Autograd+  ( Torch.Typed.Autograd.HasGrad,+    Torch.Typed.Autograd.grad,+  )+where++import Data.Kind+import GHC.TypeLits+import System.IO.Unsafe+import qualified Torch.DType as D+import qualified Torch.Device as D+import Torch.HList+import qualified Torch.Internal.Cast as ATen+import qualified Torch.Internal.Class as ATen+import qualified Torch.Internal.Managed.Autograd as LibTorch+import qualified Torch.Tensor as D+import Torch.Typed.Parameter+import Torch.Typed.Tensor+import Torch.Autograd (GradOptions(..))+++class HasGrad a b | a -> b where+  -- | calculate gradients of a zero-dimensional tensor with respect to a list of parameters+  grad :: forall dtype device. Tensor device dtype '[] -> a -> b+  gradWithOptions :: forall dtype device. GradOptions -> Tensor device dtype '[] -> a -> b++  toDependent :: a -> b++-- instance HasGrad (Tensor device dtype shape) (Tensor device dtype shape) where+--   grad loss input = head . unsafePerformIO $ ATen.cast2+--     Torch.Managed.Autograd.grad+--     loss+--     [Torch.Typed.Autograd.toDependent input]+--   toDependent = id++instance HasGrad (Parameter device dtype shape) (Tensor device dtype shape) where+  grad loss input =+    head . unsafePerformIO $+      ATen.cast2+        LibTorch.grad+        loss+        [Torch.Typed.Autograd.toDependent input]+  gradWithOptions GradOptions{..} loss input =+    head . unsafePerformIO $+      ATen.cast5+        LibTorch.gradWithOptions+        keepGraph+        createGraph+        accumulateGrad+        loss+        [Torch.Typed.Autograd.toDependent input]+  toDependent = Torch.Typed.Parameter.toDependent++instance HasGrad (HList ('[] :: [Type])) (HList ('[] :: [Type])) where+  grad _ = id+  toDependent = id++instance+  ( HasGrad a b,+    HasGrad (HList as) (HList bs),+    ATen.Castable (HList (b ': bs)) [D.ATenTensor]+  ) =>+  HasGrad (HList (a ': as)) (HList (b ': bs))+  where+  grad loss inputs =+    unsafePerformIO $+      ATen.cast2+        LibTorch.grad+        loss+        (Torch.Typed.Autograd.toDependent inputs)+  gradWithOptions GradOptions{..} loss inputs =+    unsafePerformIO $+      ATen.cast5+        LibTorch.gradWithOptions+        keepGraph+        createGraph+        accumulateGrad+        loss+        (Torch.Typed.Autograd.toDependent inputs)+  toDependent (a :. as) =+    Torch.Typed.Autograd.toDependent a :. Torch.Typed.Autograd.toDependent as
+ src/Torch/Typed/Auxiliary.hs view
@@ -0,0 +1,402 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE RankNTypes #-}++module Torch.Typed.Auxiliary where++import qualified Data.Int as I+import Data.Kind+import Data.Proxy+import Data.Type.Equality+import GHC.TypeLits+import qualified Torch.DType as D+import qualified Torch.Device as D+import Torch.HList+import Data.Constraint+import Unsafe.Coerce (unsafeCoerce)++natValI :: forall n. KnownNat n => Int+natValI = fromIntegral $ natVal $ Proxy @n++natValInt16 :: forall n. KnownNat n => I.Int16+natValInt16 = fromIntegral $ natVal $ Proxy @n++type family Fst (t :: (a, b)) :: a where+  Torch.Typed.Auxiliary.Fst '(x, _) = x++type family Snd (t :: (a, b)) :: b where+  Torch.Typed.Auxiliary.Snd '(_, x) = x++type family Fst3 (t :: (a, b, c)) :: a where+  Fst3 '(x, _, _) = x++type family Snd3 (t :: (a, b, c)) :: b where+  Snd3 '(_, x, _) = x++type family Trd3 (t :: (a, b, c)) :: c where+  Trd3 '(_, _, x) = x++--------------------------------------------------------------------------------+-- Nice error messages for type checking failures+--------------------------------------------------------------------------------++type family DimOutOfBoundCheckImpl (shape :: [a]) (dim :: Nat) (xs :: [a]) (n :: Nat) :: Constraint where+  DimOutOfBoundCheckImpl shape dim '[] _ = DimOutOfBound shape dim+  DimOutOfBoundCheckImpl _ _ _ 0 = ()+  DimOutOfBoundCheckImpl shape dim (_ ': xs) n = DimOutOfBoundCheckImpl shape dim xs (n - 1)++type DimOutOfBoundCheck shape dim = DimOutOfBoundCheckImpl shape dim shape dim++type family DimOutOfBound (shape :: [a]) (dim :: Nat) where+  DimOutOfBound shape dim =+    TypeError+      ( Text "Out of bound dimension: "+          :<>: ShowType dim+          :<>: Text " (the tensor is only "+          :<>: ShowType (ListLength shape)+          :<>: Text "D)"+      )++type family IndexOutOfBound (shape :: [a]) (dim :: Nat) (idx :: Nat) where+  IndexOutOfBound shape dim idx =+    TypeError+      ( Text "Out of bound index "+          :<>: ShowType idx+          :<>: Text " for dimension "+          :<>: ShowType dim+          :<>: Text " (the tensor shape is "+          :<>: ShowType shape+          :<>: Text ")"+      )++--------------------------------------------------------------------------------+-- Type-level helpers for working with dimension lists+--------------------------------------------------------------------------------++type family AppendToMaybe (h :: a) (mt :: Maybe [a]) :: Maybe [a] where+  AppendToMaybe h Nothing = Nothing+  AppendToMaybe h (Just t) = Just (h : t)++type family AppendToMaybe' (h :: Maybe a) (mt :: Maybe [a]) :: Maybe [a] where+  AppendToMaybe' Nothing _ = Nothing+  AppendToMaybe' _ Nothing = Nothing+  AppendToMaybe' (Just h) (Just t) = Just (h : t)++type family MaybePrepend (mh :: Maybe a) (t :: [a]) :: [a] where+  MaybePrepend Nothing t = t+  MaybePrepend (Just h) t = h : t++----------------------------------------++type family LastDim (l :: [a]) :: Nat where+  LastDim (_ ': '[]) = 0+  LastDim (_ ': t) = 1 + LastDim t++type family Product (xs :: [Nat]) :: Nat where+  Product '[] = 1+  Product (x ': xs) = x GHC.TypeLits.* Product xs++type family BackwardsImpl (last :: Nat) (n :: Nat) :: Nat where+  BackwardsImpl last n = last - n++type Backwards l n = BackwardsImpl (LastDim l) n++-- | Evaluate a type-level constraint for whether or not the former shape is a suffix of the latter shape+--+-- >>> :kind! IsSuffixOf '[1] '[1]+-- IsSuffixOf '[1] '[1] :: Constraint+-- = () :: Constraint+-- >>> :kind! IsSuffixOf '[1] '[2, 1]+-- IsSuffixOf '[1] '[2, 1] :: Constraint+-- = () :: Constraint+-- >>> :kind! IsSuffixOf '[2] '[2, 1]+-- IsSuffixOf '[2] '[2, 1] :: Constraint+-- = (TypeError ...)+-- >>> :kind! IsSuffixOf '[1, 1] '[2, 1]+-- IsSuffixOf '[1, 1] '[2, 1] :: Constraint+-- = (TypeError ...)+-- >>> :kind! IsSuffixOf '[2, 1] '[2, 1]+-- IsSuffixOf '[2, 1] '[2, 1] :: Constraint+-- = () :: Constraint+type IsSuffixOf xs ys = CheckIsSuffixOf xs ys (IsSuffixOfImpl xs ys (DropLengthMaybe xs ys))++type family CheckIsSuffixOf (xs :: [a]) (ys :: [a]) (result :: Bool) :: Constraint where+  CheckIsSuffixOf _ _ 'True = ()+  CheckIsSuffixOf xs ys 'False = TypeError (ShowType xs :<>: Text " is not a suffix of " :<>: ShowType ys)++type family IsSuffixOfImpl (xs :: [a]) (ys :: [a]) (mDelta :: Maybe [b]) :: Bool where+  IsSuffixOfImpl xs ys ('Just delta) = xs == DropLength delta ys+  IsSuffixOfImpl _ _ 'Nothing = 'False++type family DropLengthMaybe (xs :: [a]) (ys :: [b]) :: Maybe [b] where+  DropLengthMaybe '[] ys = 'Just ys+  DropLengthMaybe _ '[] = 'Nothing+  DropLengthMaybe (_ : xs) (_ : ys) = DropLengthMaybe xs ys++type family DropLength (xs :: [a]) (ys :: [b]) :: [b] where+  DropLength '[] ys = ys+  DropLength _ '[] = '[]+  DropLength (_ : xs) (_ : ys) = DropLength xs ys++----------------------------------------++type family Init (xs :: [a]) :: [a] where+  Init '[] = TypeError (Text "Init of empty list.")+  Init (x ': '[]) = '[]+  Init (x ': xs) = x ': Init xs++type family Last (xs :: [a]) :: a where+  Last '[] = TypeError (Text "Last of empty list.")+  Last (x ': '[]) = x+  Last (x ': xs) = Last xs++type family InsertImpl (n :: Nat) (x :: a) (l :: [a]) :: Maybe [a] where+  InsertImpl 0 x l = Just (x ': l)+  InsertImpl n x '[] = Nothing+  InsertImpl n x (h ': t) = AppendToMaybe h (InsertImpl (n - 1) x t)++type family CheckInsert (n :: Nat) (x :: a) (l :: [a]) (result :: Maybe [a]) :: [a] where+  CheckInsert _ _ _ (Just xs) = xs+  CheckInsert n x l Nothing = DimOutOfBound l n++type family Insert (n :: Nat) (x :: a) (l :: [a]) :: [a] where+  Insert n x l = CheckInsert n x l (InsertImpl n x l)++type family RemoveImpl (l :: [a]) (n :: Nat) :: Maybe [a] where+  RemoveImpl (h ': t) 0 = Just t+  RemoveImpl (h ': t) n = AppendToMaybe h (RemoveImpl t (n - 1))+  RemoveImpl _ _ = Nothing++type family CheckRemove (l :: [a]) (n :: Nat) (result :: Maybe [a]) :: [a] where+  CheckRemove l n Nothing = DimOutOfBound l n+  CheckRemove _ _ (Just result) = result++type Remove l n = CheckRemove l n (RemoveImpl l n)++----------------------------------------++type family IndexImpl (l :: [a]) (n :: Nat) :: Maybe a where+  IndexImpl (h ': t) 0 = Just h+  IndexImpl (h ': t) n = IndexImpl t (n - 1)+  IndexImpl _ _ = Nothing++type family CheckIndex (l :: [a]) (n :: Nat) (result :: Maybe a) :: a where+  CheckIndex l n Nothing = DimOutOfBound l n+  CheckIndex _ _ (Just result) = result++type Index l n = CheckIndex l n (IndexImpl l n)++----------------------------------------++type family InRangeCheck (shape :: [Nat]) (dim :: Nat) (idx :: Nat) (ok :: Ordering) :: Constraint where+  InRangeCheck _ _ _ 'LT = ()+  InRangeCheck shape dim idx _ = IndexOutOfBound shape dim idx++type InRange shape dim idx = InRangeCheck shape dim idx (CmpNat idx (Index shape dim))++----------------------------------------++type family ReverseImpl (l :: [a]) (acc :: [a]) :: [a] where+  ReverseImpl '[] acc = acc+  ReverseImpl (h ': t) acc = ReverseImpl t (h ': acc)++type Reverse l = ReverseImpl l '[]++type family ExtractDim (dim :: Nat) (shape :: [Nat]) :: Maybe Nat where+  ExtractDim 0 (h ': _) = Just h+  ExtractDim dim (_ ': t) = ExtractDim (dim - 1) t+  ExtractDim _ _ = Nothing++type family ReplaceDim (dim :: Nat) (shape :: [Nat]) (n :: Nat) :: Maybe [Nat] where+  ReplaceDim 0 (_ ': t) n = Just (n ': t)+  ReplaceDim dim (h ': t) n = AppendToMaybe h (ReplaceDim (dim - 1) t n)+  ReplaceDim _ _ _ = Nothing++type family If c t e where+  If 'True t e = t+  If 'False t e = e++type family AllDimsPositive (shape :: [Nat]) :: Constraint where+  AllDimsPositive '[] = ()+  AllDimsPositive (x ': xs) = If (1 <=? x) (AllDimsPositive xs) (TypeError (Text "Expected positive dimension but got " :<>: ShowType x :<>: Text "!"))++--------------------------------------------------------------------------------+-- Operations+--------------------------------------------------------------------------------++type family IsAtLeast (n :: Nat) (m :: Nat) (cmp :: Ordering) :: Constraint where+  IsAtLeast n m LT =+    TypeError+      ( Text "Expected a dimension of size at least "+          :<>: ShowType n+          :<>: Text " but got "+          :<>: ShowType m+          :<>: Text "!"+      )+  IsAtLeast _ _ _ = ()++-- IsAtLeast goes first, because while it doesn't help with inferring any+-- inequality constraints, it will give a _significantly_ nicer error message+-- than KnownNat.+-- TODO: This is designed for inequalities of the form <expression> >= constant, but+--       we have variables on both sides in ConvSideCheck which sometimes leads to+--       funny error messages like "expected at least 5, got 29!".+type (>=) (n :: Nat) (m :: Nat) = (IsAtLeast n m (CmpNat n m), KnownNat (n - m))++--------------------------------------------------------------------------------+-- DType Promotion+--------------------------------------------------------------------------------++type family CmpDType (dtype :: D.DType) (dtype' :: D.DType) :: Ordering where+  CmpDType dtype dtype = 'EQ+  CmpDType D.Bool D.UInt8 = 'LT+  CmpDType D.Bool D.Int8 = 'LT+  CmpDType D.Bool D.Int16 = 'LT+  CmpDType D.Bool D.Int32 = 'LT+  CmpDType D.Bool D.Int64 = 'LT+  CmpDType D.Bool D.Half = 'LT+  CmpDType D.Bool D.Float = 'LT+  CmpDType D.Bool D.Double = 'LT+  CmpDType D.UInt8 D.Int8 = 'LT+  CmpDType D.UInt8 D.Int16 = 'LT+  CmpDType D.UInt8 D.Int32 = 'LT+  CmpDType D.UInt8 D.Int64 = 'LT+  CmpDType D.UInt8 D.Half = 'LT+  CmpDType D.UInt8 D.Float = 'LT+  CmpDType D.UInt8 D.Double = 'LT+  CmpDType D.Int8 D.Int16 = 'LT+  CmpDType D.Int8 D.Int32 = 'LT+  CmpDType D.Int8 D.Int64 = 'LT+  CmpDType D.Int8 D.Half = 'LT+  CmpDType D.Int8 D.Float = 'LT+  CmpDType D.Int8 D.Double = 'LT+  CmpDType D.Int16 D.Int32 = 'LT+  CmpDType D.Int16 D.Int64 = 'LT+  CmpDType D.Int16 D.Half = 'LT+  CmpDType D.Int16 D.Float = 'LT+  CmpDType D.Int16 D.Double = 'LT+  CmpDType D.Int32 D.Int64 = 'LT+  CmpDType D.Int32 D.Half = 'LT+  CmpDType D.Int32 D.Float = 'LT+  CmpDType D.Int32 D.Double = 'LT+  CmpDType D.Int64 D.Half = 'LT+  CmpDType D.Int64 D.Float = 'LT+  CmpDType D.Int64 D.Double = 'LT+  CmpDType D.Half D.Float = 'LT+  CmpDType D.Half D.Double = 'LT+  CmpDType D.Float D.Double = 'LT+  CmpDType _ _ = 'GT++type family DTypePromotionImpl (dtype :: D.DType) (dtype' :: D.DType) (ord :: Ordering) :: D.DType where+  DTypePromotionImpl D.UInt8 D.Int8 _ = D.Int16+  DTypePromotionImpl D.Int8 D.UInt8 _ = D.Int16+  DTypePromotionImpl dtype _ EQ = dtype+  DTypePromotionImpl _ dtype LT = dtype+  DTypePromotionImpl dtype _ GT = dtype++type DTypePromotion dtype dtype' = DTypePromotionImpl dtype dtype' (CmpDType dtype dtype')++--------------------------------------------------------------------------------+-- DType Validation+--------------------------------------------------------------------------------++type family DTypeIsFloatingPoint (device :: (D.DeviceType, Nat)) (dtype :: D.DType) :: Constraint where+  DTypeIsFloatingPoint _ 'D.Half = ()+  DTypeIsFloatingPoint _ 'D.Float = ()+  DTypeIsFloatingPoint _ 'D.Double = ()+  DTypeIsFloatingPoint _ 'D.BFloat16 = ()+  DTypeIsFloatingPoint '(deviceType, _) dtype = UnsupportedDTypeForDevice deviceType dtype++type family DTypeIsIntegral (device :: (D.DeviceType, Nat)) (dtype :: D.DType) :: Constraint where+  DTypeIsIntegral _ 'D.Bool = ()+  DTypeIsIntegral _ 'D.UInt8 = ()+  DTypeIsIntegral _ 'D.Int8 = ()+  DTypeIsIntegral _ 'D.Int16 = ()+  DTypeIsIntegral _ 'D.Int32 = ()+  DTypeIsIntegral _ 'D.Int64 = ()+  DTypeIsIntegral '(deviceType, _) dtype = UnsupportedDTypeForDevice deviceType dtype++type family DTypeIsNotHalf (device :: (D.DeviceType, Nat)) (dtype :: D.DType) :: Constraint where+  DTypeIsNotHalf '(deviceType, _) D.Half = UnsupportedDTypeForDevice deviceType D.Half+  DTypeIsNotHalf _ _ = ()++type family DTypeIsNotDouble (device :: (D.DeviceType, Nat)) (dtype :: D.DType) :: Constraint where+  DTypeIsNotDouble '(deviceType, _) D.Double = UnsupportedDTypeForDevice deviceType D.Double+  DTypeIsNotDouble _ _ = ()++type family DTypeIsNotBool (device :: (D.DeviceType, Nat)) (dtype :: D.DType) :: Constraint where+  DTypeIsNotBool '(deviceType, _) D.Bool = UnsupportedDTypeForDevice deviceType D.Bool+  DTypeIsNotBool _ _ = ()++type family UnsupportedDTypeForDevice (deviceType :: D.DeviceType) (dtype :: D.DType) :: Constraint where+  UnsupportedDTypeForDevice deviceType dtype =+    TypeError+      ( Text "This operation does not support "+          :<>: ShowType dtype+          :<>: Text " tensors on devices of type "+          :<>: ShowType deviceType+          :<>: Text "."+      )++type family StandardFloatingPointDTypeValidation (device :: (D.DeviceType, Nat)) (dtype :: D.DType) :: Constraint where+  StandardFloatingPointDTypeValidation '( 'D.CPU, 0) dtype =+    ( DTypeIsFloatingPoint '( 'D.CPU, 0) dtype,+      DTypeIsNotHalf '( 'D.CPU, 0) dtype+    )+  StandardFloatingPointDTypeValidation '( 'D.CUDA, deviceIndex) dtype = DTypeIsFloatingPoint '( 'D.CUDA, deviceIndex) dtype+  StandardFloatingPointDTypeValidation '( 'D.MPS, 0) dtype =+    ( DTypeIsFloatingPoint '( 'D.MPS, 0) dtype,+      DTypeIsNotDouble '( 'D.MPS, 0) dtype+    )+  StandardFloatingPointDTypeValidation '(deviceType, _) dtype = UnsupportedDTypeForDevice deviceType dtype++type family StandardDTypeValidation (device :: (D.DeviceType, Nat)) (dtype :: D.DType) :: Constraint where+  StandardDTypeValidation '( 'D.CPU, 0) dtype =+    ( DTypeIsNotBool '( 'D.CPU, 0) dtype,+      DTypeIsNotHalf '( 'D.CPU, 0) dtype+    )+  StandardDTypeValidation '( 'D.CUDA, deviceIndex) dtype = DTypeIsNotBool '( 'D.CUDA, deviceIndex) dtype+  StandardDTypeValidation '( 'D.MPS, 0) dtype =+    ( DTypeIsNotBool '( 'D.MPS, 0) dtype,+      DTypeIsNotDouble '( 'D.MPS, 0) dtype+    )+  StandardDTypeValidation '(deviceType, _) dtype = UnsupportedDTypeForDevice deviceType dtype+++--------------------------------------------------------------------------------+-- An unsafe function to enforce a constraint.+--------------------------------------------------------------------------------++unsafeConstraint :: forall c a. (c => a) -> a+unsafeConstraint = withDict (dummyDict @c)+  where+    dummyDict :: forall b. Dict b+    dummyDict = unsafeCoerce (Dict :: Dict ())++--------------------------------------------------------------------------------+-- Helper functions to handle nat at runtime.+--------------------------------------------------------------------------------++withNat ::+  Int ->+  ( forall n.+    KnownNat n =>+    Proxy n ->+    r+  ) ->+  r+withNat i f = case someNatVal (fromIntegral i) of+  Nothing -> error "Negative Number in withNat!"+  (Just (SomeNat p)) -> f p++forEachNat :: forall n a. KnownNat n => (forall i. KnownNat i => Proxy i -> a) -> [a]+forEachNat func = map (\i -> withNat i func) [0 .. (natValI @n -1)]
+ src/Torch/Typed/DType.hs view
@@ -0,0 +1,115 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}++module Torch.Typed.DType where++import Data.Kind (Type)+import GHC.Generics+import GHC.TypeLits+import GHC.TypeLits.Extra+import System.IO.Unsafe+import qualified Torch.DType as D+import qualified Torch.Device as D+import Torch.HList+import qualified Torch.Internal.Cast as ATen+import qualified Torch.Internal.Class as ATen+import qualified Torch.Internal.Managed.Autograd as LibTorch+import qualified Torch.Tensor as D+import Torch.Typed.Parameter+import Torch.Typed.Tensor++class HasToDType dtype' dtype f g | dtype' dtype f -> g, dtype' dtype g -> f where+  -- >>> model <- A.sample (Torch.Typed.NN.LinearSpec @1 @1 @'D.Float @'( 'D.CPU, 0))+  -- >>> :type Torch.Typed.DType.toDType @'D.Double @'D.Float model+  -- Torch.Typed.DType.toDType @'D.Double @'D.Float model+  -- :: Torch.Typed.NN.Linear 1 1 'Double '( 'CPU, 0)+  toDType :: f -> g++-- In a data type `f` parameterized by zero or more data type variables, replace the given data type `dtype` with the data type `dtype'`.+--+-- >>> :kind! ReplaceDType (Torch.Typed.NN.Linear 1 1 'D.Float '( 'D.CPU, 0)) 'D.Double 'D.Float+-- ReplaceDType (Torch.Typed.NN.Linear 1 1 'D.Float '( 'D.CPU, 0)) 'D.Double 'D.Float :: *+-- = Torch.Typed.NN.Linear 1 1 'Double '( 'CPU, 0)+type family ReplaceDType (f :: k) (dtype' :: D.DType) (dtype :: D.DType) :: k where+  ReplaceDType (t dtype) dtype' dtype = t dtype'+  ReplaceDType (t a) dtype' dtype = (ReplaceDType t dtype' dtype) (ReplaceDType a dtype' dtype)+  ReplaceDType t _ _ = t++-- In a data type `f` parameterized by zero or one data type variables, replace the only occurring data type with the data type `dtype'`.+--+-- >>> :kind! ReplaceDType' (Torch.Typed.NN.Linear 1 1 'D.Float '( 'D.CPU, 0)) 'D.Double+-- ReplaceDType' (Torch.Typed.NN.Linear 1 1 'D.Float '( 'D.CPU, 0)) 'D.Double :: *+-- = Torch.Typed.NN.Linear 1 1 'Double '( 'CPU, 0)+type family ReplaceDType' (f :: k) (dtype' :: D.DType) :: k where+  ReplaceDType' (t (dtype :: D.DType)) dtype' = t dtype'+  ReplaceDType' (t a) dtype' = (ReplaceDType' t dtype') (ReplaceDType' a dtype')+  ReplaceDType' t _ = t++instance+  ( g ~ ReplaceDType f dtype' dtype,+    f ~ ReplaceDType g dtype dtype',+    Generic f,+    Generic g,+    GHasToDType dtype' dtype (Rep f) (Rep g)+  ) =>+  HasToDType dtype' dtype f g+  where+  toDType = to . gToDType @dtype' @dtype . from++class+  GHasToDType+    (dtype' :: D.DType)+    (dtype :: D.DType)+    (f :: Type -> Type)+    (g :: Type -> Type)+  where+  gToDType :: forall a. f a -> g a++instance+  ( GHasToDType dtype' dtype l l',+    GHasToDType dtype' dtype r r'+  ) =>+  GHasToDType dtype' dtype (l :*: r) (l' :*: r')+  where+  gToDType (l :*: r) =+    let l' = gToDType @dtype' @dtype l+        r' = gToDType @dtype' @dtype r+     in l' :*: r'++instance {-# OVERLAPS #-} (KnownDType dtype') => HasToDType dtype' dtype (Tensor device dtype shape) (Tensor device dtype' shape) where+  toDType = Torch.Typed.Tensor.toDType++instance {-# OVERLAPS #-} (KnownDType dtype') => HasToDType dtype' dtype (Parameter device dtype shape) (Parameter device dtype' shape) where+  toDType = Torch.Typed.Parameter.parameterToDType++instance {-# OVERLAPPABLE #-} (HasToDType dtype' dtype f g) => GHasToDType dtype' dtype (K1 i f) (K1 i g) where+  gToDType = K1 . Torch.Typed.DType.toDType @dtype' @dtype . unK1++instance (GHasToDType dtype' dtype f g) => GHasToDType dtype' dtype (M1 i t f) (M1 i t g) where+  gToDType = M1 . gToDType @dtype' @dtype . unM1++instance GHasToDType dtype' dtype U1 U1 where+  gToDType = id++-- >>> :kind! GetDType (Torch.Typed.NN.Linear 1 1 'D.Float '( 'D.CPU, 0))+-- GetDType (Torch.Typed.NN.Linear 1 1 'D.Float '( 'D.CPU, 0)) :: Maybe D.DType+-- = 'Just 'D.Float+--+-- >>> :kind! GetDType (Torch.Typed.Tensor.Tensor '( 'D.CUDA, 0) 'D.Float '[1])+-- GetDType (Torch.Typed.Tensor.Tensor '( 'D.CUDA, 0) 'D.Float '[1]) :: Maybe D.DType+-- = 'Just 'D.Float+type family GetDType (f :: k) :: Maybe D.DType where+  GetDType (t (dtype :: D.DType)) = Just dtype+  GetDType (t a) = GetDType t+  GetDType t = Nothing
+ src/Torch/Typed/Device.hs view
@@ -0,0 +1,243 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}++module Torch.Typed.Device where++import Data.Kind (Type)+import Data.Proxy (Proxy (..))+import GHC.Generics+import GHC.TypeLits+import GHC.TypeLits.Extra+import System.IO.Unsafe+import qualified Torch.DType as D+import qualified Torch.Device as D+import Torch.HList+import qualified Torch.Internal.Cast as ATen+import qualified Torch.Internal.Class as ATen+import qualified Torch.Internal.Managed.Autograd as LibTorch+import qualified Torch.Tensor as D+import Torch.Typed.Auxiliary+import Torch.Typed.Functional+import Torch.Typed.Parameter+import Torch.Typed.Tensor++class+  HasToDevice+    (device' :: (D.DeviceType, Nat))+    (device :: (D.DeviceType, Nat))+    (f :: Type)+    (g :: Type)+    | device' device f -> g,+      device' device g -> f+  where+  -- >>> model <- A.sample (Torch.Typed.NN.LinearSpec @1 @1 @'D.Float @'( 'D.CPU, 0))+  -- >>> :type Torch.Typed.Device.toDevice @'( 'D.CUDA, 0) @'( 'D.CPU, 0) model+  -- Torch.Typed.Device.toDevice @'( 'D.CUDA, 0) @'( 'D.CPU, 0) model+  -- :: Torch.Typed.NN.Linear 1 1 'Float '( 'CUDA, 0)+  toDevice :: f -> g++-- In a data type `f` parameterized by zero or more device type variables, replace the given device type `device` with the device type `device'`.+--+-- >>> :kind! ReplaceDevice (Torch.Typed.NN.Linear 1 1 'D.Float '( 'D.CPU, 0)) '( 'D.CUDA, 0) '( 'D.CPU, 0)+-- ReplaceDevice (Torch.Typed.NN.Linear 1 1 'D.Float '( 'D.CPU, 0)) '( 'D.CUDA, 0) '( 'D.CPU, 0) :: *+-- = Torch.Typed.NN.Linear 1 1 'Float '( 'CUDA, 0)+type family ReplaceDevice (f :: k) (device' :: (D.DeviceType, Nat)) (device :: (D.DeviceType, Nat)) :: k where+  ReplaceDevice (t device) device' device = t device'+  ReplaceDevice (t a) device' device = (ReplaceDevice t device' device) (ReplaceDevice a device' device)+  ReplaceDevice t _ _ = t++-- In a data type `f` parameterized by zero or one device type variables, replace the only occurring device type with the device type `device'`.+--+-- >>> :kind! ReplaceDevice' (Torch.Typed.NN.Linear 1 1 'D.Float '( 'D.CPU, 0)) '( 'D.CUDA, 0)+-- ReplaceDevice' (Torch.Typed.NN.Linear 1 1 'D.Float '( 'D.CPU, 0)) '( 'D.CUDA, 0) :: *+-- = Torch.Typed.NN.Linear 1 1 'Float '( 'CUDA, 0)+type family ReplaceDevice' (f :: k) (device' :: (D.DeviceType, Nat)) :: k where+  ReplaceDevice' (t (device :: (D.DeviceType, Nat))) device' = t device'+  ReplaceDevice' (t a) device' = (ReplaceDevice' t device') (ReplaceDevice' a device')+  ReplaceDevice' t _ = t++instance+  ( g ~ ReplaceDevice f device' device,+    f ~ ReplaceDevice g device device',+    Generic f,+    Generic g,+    GHasToDevice device' device (Rep f) (Rep g)+  ) =>+  HasToDevice device' device f g+  where+  toDevice = to . gToDevice @device' @device . from++class+  GHasToDevice+    (device' :: (D.DeviceType, Nat))+    (device :: (D.DeviceType, Nat))+    (f :: Type -> Type)+    (g :: Type -> Type)+  where+  gToDevice :: forall a. f a -> g a++instance+  ( GHasToDevice device' device l l',+    GHasToDevice device' device r r'+  ) =>+  GHasToDevice device' device (l :*: r) (l' :*: r')+  where+  gToDevice (l :*: r) =+    let l' = gToDevice @device' @device l+        r' = gToDevice @device' @device r+     in l' :*: r'++instance {-# OVERLAPS #-} HasToDevice device' device Double Double where+  toDevice = id++instance {-# OVERLAPS #-} (KnownDevice device') => HasToDevice device' device (Tensor device dtype shape) (Tensor device' dtype shape) where+  toDevice = Torch.Typed.Tensor.toDevice++instance {-# OVERLAPS #-} (KnownDevice device') => HasToDevice device' device (Parameter device dtype shape) (Parameter device' dtype shape) where+  toDevice = Torch.Typed.Parameter.parameterToDevice++instance {-# OVERLAPS #-} HasToDevice device' device (HList ('[] :: [Type])) (HList ('[] :: [Type])) where+  toDevice = id++instance {-# OVERLAPS #-} (HasToDevice device' device x x', HasToDevice device' device (HList xs) (HList xs')) => HasToDevice device' device (HList (x ': xs)) (HList (x' ': xs')) where+  toDevice (x :. xs) = Torch.Typed.Device.toDevice @device' @device x :. Torch.Typed.Device.toDevice @device' @device xs++instance {-# OVERLAPPABLE #-} (HasToDevice device' device f g) => GHasToDevice device' device (K1 i f) (K1 i g) where+  gToDevice = K1 . Torch.Typed.Device.toDevice @device' @device . unK1++instance (GHasToDevice device' device f g) => GHasToDevice device' device (M1 i t f) (M1 i t g) where+  gToDevice = M1 . gToDevice @device' @device . unM1++instance GHasToDevice device' device U1 U1 where+  gToDevice = id++class HasReplicate (devices' :: [(D.DeviceType, Nat)]) (device :: (D.DeviceType, Nat)) (f :: Type) (gs :: [Type]) | devices' device f -> gs where+  replicate :: f -> HList gs++instance HasReplicate '[] device f '[] where+  replicate _ = HNil++instance+  ( HasReplicate devices' device f gs,+    HasToDevice device' device f g+  ) =>+  HasReplicate (device' ': devices') device f (g ': gs)+  where+  replicate f = Torch.Typed.Device.toDevice @device' @device f :. Torch.Typed.Device.replicate @devices' @device @f @gs f++class+  HasToDevices+    (devices' :: [(D.DeviceType, Nat)])+    (devices :: [(D.DeviceType, Nat)])+    (fs :: [Type])+    (gs :: [Type])+    | devices' devices fs -> gs,+      devices' devices gs -> fs+  where+  toDevices :: HList fs -> HList gs++instance HasToDevices '[] '[] '[] '[] where+  toDevices HNil = HNil++instance+  ( HasToDevices devices' devices fs gs,+    HasToDevice device' device f g+  ) =>+  HasToDevices (device' ': devices') (device ': devices) (f ': fs) (g ': gs)+  where+  toDevices (f :. fs) = Torch.Typed.Device.toDevice @device' @device f :. toDevices @devices' @devices @fs @gs fs++-- >>> :kind! GetDevice (Torch.Typed.NN.Linear 1 1 'D.Float '( 'D.CPU, 0))+-- GetDevice (Torch.Typed.NN.Linear 1 1 'D.Float '( 'D.CPU, 0)) :: Maybe (D.DeviceType, Nat)+-- = 'Just '( 'D.CPU, 0)+--+-- >>> :kind! GetDevice (Torch.Typed.Tensor.Tensor '( 'D.CUDA, 0) 'D.Float '[1])+-- GetDevice (Torch.Typed.Tensor.Tensor '( 'D.CUDA, 0) 'D.Float '[1]) :: Maybe (D.DeviceType, Nat)+-- = 'Just '( 'D.CUDA, 0)+type family GetDevice (f :: k) :: Maybe (D.DeviceType, Nat) where+  GetDevice (t (device :: (D.DeviceType, Nat))) = Just device+  GetDevice (t a) = GetDevice t+  GetDevice t = Nothing++-- >>> :kind! GetDevices '[Torch.Typed.Tensor.Tensor '( 'D.CUDA, 0) 'D.Float '[1], Torch.Typed.Tensor.Tensor '( 'D.CUDA, 1) 'D.Float '[1]]+-- GetDevices '[Torch.Typed.Tensor.Tensor '( 'D.CUDA, 0) 'D.Float '[1], Torch.Typed.Tensor.Tensor '( 'D.CUDA, 1) 'D.Float '[1]] :: [(D.DeviceType, Nat)]+-- = '[ '( 'D.CUDA, 0), '( 'D.CUDA, 1)]+type family GetDevices (fs :: [k]) :: [(D.DeviceType, Nat)] where+  GetDevices '[] = '[]+  GetDevices (f ': fs) = MaybePrepend (GetDevice f) (GetDevices fs)++-- class HasChunk chunks f gs | chunks f -> gs where+--   chunk :: f -> HList gs++-- class GHasChunk+--   (chunks :: Nat)+--   (f :: Type -> Type)+--   (gs :: [Type]) | chunks f -> gs where+--   gChunk :: forall a . f a -> HList gs++-- class GZipChunks (gs :: [k]) (gs' :: [k]) (gs'' :: [k]) | gs gs' -> gs'' where+--   gZipChunks   :: HList gs -> HList gs' -> HList gs''+--   -- gUnzipChunks :: HList gs'' -> HList gs :*: HList gs'++-- instance GZipChunks '[] '[] '[] where+--   gZipChunks _ _ = HNil+--   -- gUnzipChunks _ = HNil :*: HNil++-- instance+--   ( (g :*: g') ~ g''+--   , GZipChunks gs gs' gs''+--   ) => GZipChunks (g ': gs) (g' ': gs') (g'' ': gs'') where+--   gZipChunks (g :. gs) (g' :. gs') = (g :*: g') :. gZipChunks gs gs'+-- gZipChunks x y = _undefined+-- gUnzipChunks (~(g :*: g') :. gs'') =+--   let ~(gs :*: gs') = gUnzipChunks gs''+--   in  (g :. gs') :*: (y :. ys)++-- instance+--   (++--   ) =>++-- class HasCat fs g | fs -> g where+--   cat :: HList fs -> g++class HasScatter devices' device f gs | devices' device f -> gs where+  scatter :: f -> HList gs++instance+  ( chunks ~ ListLength devices',+    tensorChunks ~ Chunk chunks 0 shape dtype device,+    ATen.Castable (HList tensorChunks) [D.ATenTensor],+    devices ~ HReplicateR chunks device,+    HasToDevices devices' devices tensorChunks gs,+    KnownNat chunks+  ) =>+  HasScatter devices' device (Tensor device dtype shape) gs+  where+  scatter = toDevices @devices' @devices . Torch.Typed.Functional.chunk @chunks @0++class HasGather device' devices fs g | device' devices fs -> g where+  gather :: HList fs -> g++instance+  ( chunks ~ ListLength fs,+    devices ~ GetDevices fs,+    devices' ~ HReplicateR chunks device',+    HasToDevices devices' devices fs tensorChunks,+    '(shape, dtype, device') ~ Cat 0 tensorChunks,+    ATen.Castable (HList tensorChunks) [D.ATenTensor]+  ) =>+  HasGather device' devices fs (Tensor device' dtype shape)+  where+  gather = Torch.Typed.Functional.cat @0 . toDevices @devices' @devices
+ src/Torch/Typed/Factories.hs view
@@ -0,0 +1,186 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE UndecidableSuperClasses #-}+{-# LANGUAGE NoStarIsType #-}++module Torch.Typed.Factories where++import Control.Arrow ((&&&))+import Data.Default.Class+import Data.Finite+import Data.Kind (Constraint)+import Data.Proxy+import Data.Reflection+import GHC.TypeLits+import System.IO.Unsafe+import qualified Torch.DType as D+import qualified Torch.Device as D+import qualified Torch.Functional as D+import Torch.Internal.Cast+import qualified Torch.Scalar as D+import qualified Torch.Tensor as D+import qualified Torch.TensorFactories as D+import qualified Torch.TensorOptions as D+import Torch.Typed.Auxiliary+import Torch.Typed.Tensor+import Prelude hiding (sin)++instance (TensorOptions shape dtype device) => Default (Tensor device dtype shape) where+  def = zeros++instance (TensorOptions shape' dtype device, shape' ~ ToNats shape) => Default (NamedTensor device dtype shape) where+  def = fromUnnamed zeros++zeros ::+  forall shape dtype device.+  (TensorOptions shape dtype device) =>+  Tensor device dtype shape+zeros =+  UnsafeMkTensor $+    D.zeros+      (optionsRuntimeShape @shape @dtype @device)+      ( D.withDevice (optionsRuntimeDevice @shape @dtype @device)+          . D.withDType (optionsRuntimeDType @shape @dtype @device)+          $ D.defaultOpts+      )++full ::+  forall shape dtype device a.+  (TensorOptions shape dtype device, D.Scalar a) =>+  a ->+  Tensor device dtype shape+full value =+  UnsafeMkTensor $+    D.full+      (optionsRuntimeShape @shape @dtype @device)+      value+      ( D.withDevice (optionsRuntimeDevice @shape @dtype @device)+          . D.withDType (optionsRuntimeDType @shape @dtype @device)+          $ D.defaultOpts+      )++ones ::+  forall shape dtype device.+  (TensorOptions shape dtype device) =>+  Tensor device dtype shape+ones =+  UnsafeMkTensor $+    D.ones+      (optionsRuntimeShape @shape @dtype @device)+      ( D.withDevice (optionsRuntimeDevice @shape @dtype @device)+          . D.withDType (optionsRuntimeDType @shape @dtype @device)+          $ D.defaultOpts+      )++type family RandDTypeIsValid (device :: (D.DeviceType, Nat)) (dtype :: D.DType) :: Constraint where+  RandDTypeIsValid '( 'D.CPU, 0) dtype =+    ( DTypeIsNotBool '( 'D.CPU, 0) dtype,+      DTypeIsNotHalf '( 'D.CPU, 0) dtype+    )+  RandDTypeIsValid '( 'D.CUDA, _) dtype = ()+  RandDTypeIsValid '( 'D.MPS, 0) dtype = ()+  RandDTypeIsValid '(deviceType, _) dtype = UnsupportedDTypeForDevice deviceType dtype++rand ::+  forall shape dtype device.+  ( TensorOptions shape dtype device,+    RandDTypeIsValid device dtype+  ) =>+  IO (Tensor device dtype shape)+rand =+  UnsafeMkTensor+    <$> D.randIO+      (optionsRuntimeShape @shape @dtype @device)+      ( D.withDevice (optionsRuntimeDevice @shape @dtype @device)+          . D.withDType (optionsRuntimeDType @shape @dtype @device)+          $ D.defaultOpts+      )++randn ::+  forall shape dtype device.+  ( TensorOptions shape dtype device,+    RandDTypeIsValid device dtype+  ) =>+  IO (Tensor device dtype shape)+randn =+  UnsafeMkTensor+    <$> D.randnIO+      (optionsRuntimeShape @shape @dtype @device)+      ( D.withDevice (optionsRuntimeDevice @shape @dtype @device)+          . D.withDType (optionsRuntimeDType @shape @dtype @device)+          $ D.defaultOpts+      )++randint ::+  forall shape dtype device.+  ( TensorOptions shape dtype device,+    RandDTypeIsValid device dtype+  ) =>+  Int ->+  Int ->+  IO (Tensor device dtype shape)+randint low high =+  UnsafeMkTensor+    <$> (D.randintIO low high)+      (optionsRuntimeShape @shape @dtype @device)+      ( D.withDevice (optionsRuntimeDevice @shape @dtype @device)+          . D.withDType (optionsRuntimeDType @shape @dtype @device)+          $ D.defaultOpts+      )++-- | linspace+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [Float]) $ linspace @7 @'( 'D.CPU, 0) 0 3+-- (Float,([7],[0.0,0.5,1.0,1.5,2.0,2.5,3.0]))+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [Float]) $ linspace @3 @'( 'D.CPU, 0) 0 2+-- (Float,([3],[0.0,1.0,2.0]))+linspace ::+  forall steps device start end.+  ( D.Scalar start,+    D.Scalar end,+    KnownNat steps,+    TensorOptions '[steps] 'D.Float device+  ) =>+  -- | start+  start ->+  -- | end+  end ->+  -- | output+  Tensor device 'D.Float '[steps]+linspace start end =+  UnsafeMkTensor $+    D.linspace+      start+      end+      (natValI @steps)+      ( D.withDevice (optionsRuntimeDevice @'[steps] @D.Float @device)+          . D.withDType (optionsRuntimeDType @'[steps] @D.Float @device)+          $ D.defaultOpts+      )++eyeSquare ::+  forall n dtype device.+  ( KnownNat n,+    TensorOptions '[n, n] dtype device+  ) =>+  -- | output+  Tensor device dtype '[n, n]+eyeSquare =+  UnsafeMkTensor $+    D.eyeSquare+      (natValI @n)+      ( D.withDevice (optionsRuntimeDevice @'[n, n] @dtype @device)+          . D.withDType (optionsRuntimeDType @'[n, n] @dtype @device)+          $ D.defaultOpts+      )
+ src/Torch/Typed/Functional.hs view
@@ -0,0 +1,6161 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE UndecidableSuperClasses #-}+{-# LANGUAGE NoStarIsType #-}++module Torch.Typed.Functional where++import Control.Arrow ((&&&))+import Data.Finite+import qualified Data.Int as I+import Data.Kind+  ( Constraint,+    Type,+  )+import Data.Maybe+import Data.Proxy+import Data.Reflection+import Data.Vector.Sized (Vector)+import qualified Data.Vector.Sized as V+import Foreign.ForeignPtr+import GHC.Generics (Generic)+import GHC.Natural (Natural)+import GHC.TypeLits+import GHC.TypeLits.Extra+import System.IO.Unsafe+import qualified Torch.DType as D+import qualified Torch.Device as D+import Torch.Functional+  ( Reduction (..),+    Tri (..),+    isUpper,+    kOne,+  )+import Torch.HList+import qualified Torch.Internal.Cast as ATen+import qualified Torch.Internal.Class as ATen+import qualified Torch.Internal.Const as ATen+import qualified Torch.Internal.Managed.Cast as ATen.Managed+import qualified Torch.Internal.Managed.Native as ATen.Managed+import qualified Torch.Internal.Managed.Type.Scalar as ATen.Managed+import qualified Torch.Internal.Managed.Type.Tensor as ATen.Managed+import qualified Torch.Internal.Managed.Type.Tuple as ATen.Managed+import qualified Torch.Internal.Type as ATen+import qualified Torch.Scalar as D+import qualified Torch.Tensor as D+import qualified Torch.TensorFactories as D+import qualified Torch.TensorOptions as D+import Torch.Typed.Auxiliary+import Torch.Typed.Factories+import Torch.Typed.Tensor+import Prelude hiding+  ( abs,+    acos,+    acosh,+    all,+    any,+    asin,+    asinh,+    atan,+    atanh,+    ceil,+    cos,+    cosh,+    exp,+    floor,+    isNaN,+    log,+    max,+    min,+    round,+    sin,+    sinh,+    tan,+    tanh,+  )++-- $setup+--+-- >>> :seti -XOverloadedLists++-- | Computes the bitwise NOT of the given input tensor.+-- The input tensor must be of integral or Boolean types.+-- For bool tensors, it computes the logical NOT.+--+-- >>> dtype &&& shape $ bitwiseNot (ones :: CPUTensor 'D.Bool [3,3])+-- (Bool,[3,3])+bitwiseNot ::+  forall device shape.+  -- | input+  Tensor device 'D.Bool shape ->+  -- | output+  Tensor device 'D.Bool shape+bitwiseNot input = unsafePerformIO $ ATen.cast1 ATen.Managed.bitwise_not_t input++-- | Computes the element-wise logical NOT of the given input tensor.+-- If not specified, the output tensor will have the bool dtype.+-- If the input tensor is not a bool tensor, zeros are treated as False and non-zeros are treated as True.+logicalNot ::+  forall device shape.+  -- | input+  Tensor device 'D.Bool shape ->+  -- | output+  Tensor device 'D.Bool shape+logicalNot input = unsafePerformIO $ ATen.cast1 ATen.Managed.logical_not_t input++logicalXor ::+  forall device shape.+  -- | self+  Tensor device 'D.Bool shape ->+  -- | other+  Tensor device 'D.Bool shape ->+  Tensor device 'D.Bool shape+logicalXor self other = unsafePerformIO $ ATen.cast2 ATen.Managed.logical_xor_tt self other++logicalAnd ::+  forall device shape.+  -- | self+  Tensor device 'D.Bool shape ->+  -- | other+  Tensor device 'D.Bool shape ->+  Tensor device 'D.Bool shape+logicalAnd self other = unsafePerformIO $ ATen.cast2 ATen.Managed.logical_and_tt self other++logicalOr ::+  forall device shape.+  -- | self+  Tensor device 'D.Bool shape ->+  -- | other+  Tensor device 'D.Bool shape ->+  Tensor device 'D.Bool shape+logicalOr self other = unsafePerformIO $ ATen.cast2 ATen.Managed.logical_or_tt self other++type family SumDType (dtype :: D.DType) :: D.DType where+  SumDType D.Bool = D.Int64+  SumDType D.UInt8 = D.Int64+  SumDType D.Int8 = D.Int64+  SumDType D.Int16 = D.Int64+  SumDType D.Int32 = D.Int64+  SumDType D.Int64 = D.Int64+  SumDType D.Half = D.Half+  SumDType D.Float = D.Float+  SumDType D.Double = D.Double++type family SumDTypeIsValid (device :: (D.DeviceType, Nat)) (dtype :: D.DType) :: Constraint where+  SumDTypeIsValid '( 'D.CPU, 0) dtype = DTypeIsNotHalf '( 'D.CPU, 0) dtype+  SumDTypeIsValid '( 'D.CUDA, _) dtype = ()+  SumDTypeIsValid '( 'D.MPS, 0) dtype = ()+  SumDTypeIsValid '(deviceType, _) dtype = UnsupportedDTypeForDevice deviceType dtype++-- | sumAll+--+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: Int) $ sumAll (ones :: CPUTensor 'D.Bool '[2, 3])+-- (Int64,([],6))+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: Int) $ sumAll (ones :: CPUTensor 'D.UInt8 '[2, 3])+-- (Int64,([],6))+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: Int) $ sumAll (ones :: CPUTensor 'D.Int8 '[2, 3])+-- (Int64,([],6))+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: Int) $ sumAll (ones :: CPUTensor 'D.Int16 '[2, 3])+-- (Int64,([],6))+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: Int) $ sumAll (ones :: CPUTensor 'D.Int32 '[2, 3])+-- (Int64,([],6))+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: Int) $ sumAll (ones :: CPUTensor 'D.Int64 '[2, 3])+-- (Int64,([],6))+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: Float) $ sumAll (ones :: CPUTensor 'D.Float '[2, 3])+-- (Float,([],6.0))+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: Double) $ sumAll (ones :: CPUTensor 'D.Double '[2, 3])+-- (Double,([],6.0))+sumAll ::+  forall shape dtype' dtype device.+  ( SumDTypeIsValid device dtype,+    dtype' ~ SumDType dtype+  ) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype' '[]+sumAll input = unsafePerformIO $ ATen.cast1 ATen.Managed.sum_t input++-- | sumDim+--+-- >>> dtype &&& shape $ sumDim @0 (ones :: CPUTensor 'D.Float '[3,4,5])+-- (Float,[4,5])+-- >>> sumDim @1 (ones :: CPUTensor 'D.Float '[2,4])+-- Tensor Float [2] [ 4.0000   ,  4.0000   ]+sumDim ::+  forall d shape shape' dtype dtype' device.+  ( KnownNat d,+    shape' ~ DropValue shape d,+    SumDTypeIsValid device dtype,+    dtype' ~ SumDType dtype+  ) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype' shape'+sumDim input = unsafePerformIO $ ATen.cast2 ATen.Managed.sum_tl input (natValI @d)++-- | abs+--+-- >>> dtype &&& shape $ abs (ones :: CPUTensor 'D.Float '[2,2])+-- (Float,[2,2])+abs ::+  forall shape dtype device.+  (StandardDTypeValidation device dtype) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+abs input = unsafePerformIO $ ATen.cast1 ATen.Managed.abs_t input++-- | ceil+--+-- >>> dtype &&& shape $ ceil (ones :: CPUTensor 'D.Float '[2,2])+-- (Float,[2,2])+ceil ::+  forall shape dtype device.+  (StandardFloatingPointDTypeValidation device dtype) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+ceil input = unsafePerformIO $ ATen.cast1 ATen.Managed.ceil_t input++-- | floor+--+-- >>> dtype &&& shape $ floor (ones :: CPUTensor 'D.Float '[2,2])+-- (Float,[2,2])+floor ::+  forall shape dtype device.+  (StandardFloatingPointDTypeValidation device dtype) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+floor input = unsafePerformIO $ ATen.cast1 ATen.Managed.floor_t input++type family MinMaxDTypeIsValid (device :: (D.DeviceType, Nat)) (dtype :: D.DType) :: Constraint where+  MinMaxDTypeIsValid '( 'D.CPU, 0) dtype = DTypeIsNotHalf '( 'D.CPU, 0) dtype+  MinMaxDTypeIsValid '( 'D.CUDA, _) dtype = ()+  MinMaxDTypeIsValid '( 'D.MPS, 0) dtype = ()+  MinMaxDTypeIsValid '(deviceType, _) dtype = UnsupportedDTypeForDevice deviceType dtype++-- | min+--+-- >>> dtype &&& shape $ min (ones :: CPUTensor 'D.Float '[2,2])+-- (Float,[])+min ::+  forall shape dtype device.+  ( MinMaxDTypeIsValid device dtype,+    AllDimsPositive shape+  ) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype '[]+min input = unsafePerformIO $ ATen.cast1 ATen.Managed.min_t input++-- | max+--+-- >>> dtype &&& shape $ max (ones :: CPUTensor 'D.Float '[2,2])+-- (Float,[])+max ::+  forall shape dtype device.+  ( MinMaxDTypeIsValid device dtype,+    AllDimsPositive shape+  ) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype '[]+max input = unsafePerformIO $ ATen.cast1 ATen.Managed.max_t input++type family MeanDTypeValidation (device :: (D.DeviceType, Nat)) (dtype :: D.DType) :: Constraint where+  MeanDTypeValidation '(deviceType, deviceIndex) dtype =+    ( DTypeIsFloatingPoint '(deviceType, deviceIndex) dtype,+      DTypeIsNotHalf '(deviceType, deviceIndex) dtype+    )++-- | Computes the mean while carrying out a full reduction of all tensor dimensions.+--+-- >>> meanAll (ones :: CPUTensor 'D.Float '[])+-- Tensor Float []  1.0000+-- >>> meanAll (zeros :: CPUTensor 'D.Float '[2,2])+-- Tensor Float []  0.0000+meanAll ::+  forall shape dtype device.+  ( MeanDTypeValidation device dtype,+    AllDimsPositive shape+  ) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype '[]+meanAll input = unsafePerformIO $ ATen.cast1 ATen.Managed.mean_t input++-- | Computes the mean while carrying out a full reduction of all tensor dimensions.+-- This version is not restricted and can return NaN.+--+-- >>> unsafeMeanAll (ones :: CPUTensor 'D.Float '[])+-- Tensor Float []  1.0000+-- >>> unsafeMeanAll (ones :: CPUTensor 'D.Float '[0])+-- Tensor Float [] NaN+-- >>> unsafeMeanAll (zeros :: CPUTensor 'D.Float '[2,2])+-- Tensor Float []  0.0000+unsafeMeanAll ::+  forall shape dtype device.+  MeanDTypeValidation device dtype =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype '[]+unsafeMeanAll+  input = unsafePerformIO $ ATen.cast1 ATen.Managed.mean_t input++-- | Computes the mean and reduces the tensor over the specified dimension.+--+-- >>> t = ones :: CPUTensor 'D.Float '[3,4,5]+-- >>> dtype &&& shape $ meanDim @0 t+-- (Float,[4,5])+-- >>> dtype &&& shape $ meanDim @1 t+-- (Float,[3,5])+-- >>> dtype &&& shape $ meanDim @2 t+-- (Float,[3,4])+meanDim ::+  forall dim shape' shape dtype device.+  ( KnownNat dim,+    shape' ~ DropValue shape dim,+    MeanDTypeValidation device dtype,+    AllDimsPositive shape+  ) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape'+meanDim input = unsafePerformIO $ ATen.cast2 ATen.Managed.mean_tl input (natValI @dim)++-- | Computes the mean and reduces the tensor over the specified dimension.+--+-- >>> import Torch.Typed.Factories+-- >>> import Data.Default.Class+-- >>> t = def :: NamedTensor '( D.CPU, 0) 'D.Float '[Vector 3, Vector 4, Vector 5]+-- >>> dtype &&& shape $ meanNamedDim @(Vector 4) t+-- (Float,[3,5])+meanNamedDim ::+  forall dim shape' shape dtype device.+  ( KnownNat (FindDim dim shape),+    shape' ~ DropNamedValue shape dim,+    MeanDTypeValidation device dtype+  ) =>+  -- | input+  NamedTensor device dtype shape ->+  -- | output+  NamedTensor device dtype shape'+meanNamedDim input = unsafePerformIO $ ATen.cast2 ATen.Managed.mean_tl input _dim+  where+    _dim = natValI @(FindDim dim shape)++-- | Computes the mean and optionally reduces the tensor over the specified dimension.+--+-- See https://pytorch.org/docs/stable/torch.html#torch.mean for more information.+--+-- >>> t = fromJust [[5, 1], [3, 2], [4, 1], [2, 7]] :: CPUTensor 'D.Float '[4, 2]+-- >>> mean @0 @KeepDim t+-- Tensor Float [1,2] [[ 3.5000   ,  2.7500   ]]+mean ::+  forall dim keepOrDropDim shape' shape dtype device.+  ( KnownNat dim,+    KnownKeepOrDropDim keepOrDropDim,+    shape' ~ ConditionalDropDimension shape dim keepOrDropDim,+    MeanDTypeValidation device dtype,+    AllDimsPositive shape+  ) =>+  Tensor device dtype shape ->+  Tensor device dtype shape'+mean input =+  unsafePerformIO $+    ATen.cast3+      ATen.Managed.mean_tlb+      input+      (natValI @dim)+      (keepOrDropDimVal @keepOrDropDim)++-- | Computes the median while carrying out a full reduction of all tensor dimensions.+--+-- >>> dtype &&& shape $ medianAll (ones :: CPUTensor 'D.Float '[2,2])+-- (Float,[])+medianAll ::+  forall shape dtype device.+  ( StandardDTypeValidation device dtype,+    AllDimsPositive shape+  ) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype '[]+medianAll input = unsafePerformIO $ ATen.cast1 ATen.Managed.median_t input++-- | Computes the median and reduces the tensor over the specified dimension.+--+-- >>> t = ones :: CPUTensor 'D.Float '[3,4,5]+-- >>> dtype &&& shape $ fst $ medianDim @0 t+-- (Float,[4,5])+-- >>> dtype &&& shape $ fst $ medianDim @1 t+-- (Float,[3,5])+-- >>> dtype &&& shape $ fst $ medianDim @2 t+-- (Float,[3,4])+medianDim ::+  forall dim shape' shape dtype device.+  ( KnownNat dim,+    shape' ~ DropValue shape dim,+    StandardDTypeValidation device dtype,+    AllDimsPositive shape+  ) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  ( Tensor device dtype shape',+    Tensor device 'D.Int64 shape'+  )+medianDim input = unsafePerformIO $ ATen.cast2 ATen.Managed.median_tl input (natValI @dim)++-- | Computes the median and optionally reduces the tensor over the specified dimension.+--+-- See https://pytorch.org/docs/stable/torch.html#torch.median for more information.+--+-- >>> t = fromJust [[5, 1], [3, 2], [4, 1], [2, 7]] :: CPUTensor 'D.Float '[4, 2]+--+-- -- libtorch 1.7.0+-- -- (Tensor Float [1,2] [[ 3.0000   ,  1.0000   ]],Tensor Int64 [1,2] [[ 1,  0]])+-- -- libtorch 1.8.0+-- >>> median @0 @KeepDim t+-- (Tensor Float [1,2] [[ 3.0000   ,  1.0000   ]],Tensor Int64 [1,2] [[ 1,  2]])+median ::+  forall dim keepOrDropDim shape' shape dtype device.+  ( KnownNat dim,+    KnownKeepOrDropDim keepOrDropDim,+    shape' ~ ConditionalDropDimension shape dim keepOrDropDim,+    StandardDTypeValidation device dtype,+    AllDimsPositive shape+  ) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  (Tensor device dtype shape', Tensor device 'D.Int64 shape')+median input =+  unsafePerformIO $+    ATen.cast3+      ATen.Managed.median_tlb+      input+      (natValI @dim)+      (keepOrDropDimVal @keepOrDropDim)++-- | Returns a tuple '(modes, indices)' where 'modes' is the mode value of each row of the 'input' tensor+-- in the given dimension 'dim', i.e. a value which appears most often in that row,+-- and 'indices' is the index location of each mode value found.+--+-- See https://pytorch.org/docs/stable/torch.html#torch.mode for more information.+--+-- >>> t = fromJust [[0, 5], [0, 2], [3, 5]] :: CPUTensor 'D.Int64 '[3, 2]+--+-- >>> (modes :: CPUTensor 'D.Int64 '[2], indices :: CPUTensor 'D.Int64 '[2]) = mode @0 @DropDim t+-- >>> (dtype modes, shape modes, D.asValue (toDynamic modes) :: [Int])+-- (Int64,[2],[0,5])+-- >>> (dtype indices, shape indices, D.asValue (toDynamic indices) :: [Int])+-- (Int64,[2],[1,2])+--+-- >>> t = fromJust [[0, 0], [0, 1], [3, 3]] :: CPUTensor 'D.Float '[3, 2]+--+-- >>> (modes :: CPUTensor 'D.Float '[3,1], indices :: CPUTensor 'D.Int64 '[3,1]) = mode @1 @KeepDim t+-- >>> (dtype modes, shape modes, D.asValue (toDynamic modes) :: [[Float]])+-- (Float,[3,1],[[0.0],[0.0],[3.0]])+-- >>> (dtype indices, shape indices, D.asValue (toDynamic indices) :: [[Int]])+-- (Int64,[3,1],[[1],[0],[1]])+mode ::+  forall dim keepOrDropDim shape' shape dtype device.+  ( KnownNat dim,+    KnownKeepOrDropDim keepOrDropDim,+    shape' ~ ConditionalDropDimension shape dim keepOrDropDim,+    StandardDTypeValidation device dtype,+    AllDimsPositive shape+  ) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  (Tensor device dtype shape', Tensor device 'D.Int64 shape')+mode input =+  unsafePerformIO $+    ATen.cast3+      ATen.Managed.mode_tlb+      input+      (natValI @dim)+      (keepOrDropDimVal @keepOrDropDim)++-- | addScalar+-- TODO: what dtypes is this defined for?+-- TODO: what scalar types is this defined for?+--+-- >>> dtype &&& shape $ addScalar 1 (ones :: CPUTensor 'D.Float '[2,2])+-- (Float,[2,2])+addScalar ::+  forall a shape dtype device.+  D.Scalar a =>+  -- | scalar input+  a ->+  -- | tensor input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+addScalar a input = unsafePerformIO $ ATen.cast2 ATen.Managed.add_ts input a++-- | subScalar+-- TODO: what dtypes is this defined for?+-- TODO: what scalar types is this defined for?+--+-- >>> dtype &&& shape $ subScalar 1 (ones :: CPUTensor 'D.Float '[2,2])+-- (Float,[2,2])+subScalar ::+  forall a shape dtype device.+  D.Scalar a =>+  -- | scalar input+  a ->+  -- | tensor input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+subScalar a input = unsafePerformIO $ ATen.cast2 ATen.Managed.sub_ts input a++-- | mulScalar+-- TODO: what dtypes is this defined for?+-- TODO: what scalar types is this defined for?+--+-- >>> dtype &&& shape $ mulScalar 2 (ones :: CPUTensor 'D.Float '[2,2])+-- (Float,[2,2])+mulScalar ::+  forall a shape dtype device.+  D.Scalar a =>+  -- | scalar input+  a ->+  -- | tensor input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+mulScalar a input = unsafePerformIO $ ATen.cast2 ATen.Managed.mul_ts input a++-- | divScalar+-- TODO: what dtypes is this defined for?+-- TODO: what scalar types is this defined for?+--+-- >>> dtype &&& shape $ divScalar 2 (ones :: CPUTensor 'D.Float '[2,2])+-- (Float,[2,2])+divScalar ::+  forall a shape dtype device.+  D.Scalar a =>+  -- | scalar input+  a ->+  -- | tensor input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+divScalar a input = unsafePerformIO $ ATen.cast2 ATen.Managed.div_ts input a++-- | divScalar'+-- TODO: what dtypes is this defined for?+-- TODO: what scalar types is this defined for?+--+-- >>> dtype &&& shape $ divScalar 2 (ones :: CPUTensor 'D.Float '[2,2])+-- (Float,[2,2])+divScalar' ::+  forall a shape dtype device.+  D.Scalar a =>+  -- | tensor input+  Tensor device dtype shape ->+  -- | scalar input+  a ->+  -- | output+  Tensor device dtype shape+divScalar' input a = a `mulScalar` reciprocal input++-- | powScalar+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> dtype &&& shape $ powScalar 2 (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+powScalar ::+  forall a shape dtype device.+  D.Scalar a =>+  -- | power+  a ->+  -- | input tensor+  Tensor device dtype shape ->+  -- | output tensor+  Tensor device dtype shape+powScalar a input = unsafePerformIO $ ATen.cast2 ATen.Managed.pow_ts input a++-- | erf+--+-- >>> dtype &&& shape $ erf (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+erf ::+  forall shape dtype device.+  (StandardFloatingPointDTypeValidation device dtype) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+erf input = unsafePerformIO $ ATen.cast1 ATen.Managed.erf_t input++-- | exp+--+-- >>> dtype &&& shape $ exp (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+exp ::+  forall shape dtype device.+  (StandardFloatingPointDTypeValidation device dtype) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+exp input = unsafePerformIO $ ATen.cast1 ATen.Managed.exp_t input++-- | log1p+--+-- >>> dtype &&& shape $ log1p (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+log1p ::+  forall shape dtype device.+  (StandardFloatingPointDTypeValidation device dtype) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+log1p input = unsafePerformIO $ ATen.cast1 ATen.Managed.log1p_t input++-- | log2+-- >>> dtype &&& shape $ log2 (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+log2 ::+  forall shape dtype device.+  (StandardFloatingPointDTypeValidation device dtype) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+log2 input = unsafePerformIO $ ATen.cast1 ATen.Managed.log2_t input++-- | log10+--+-- >>> dtype &&& shape $ log10 (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+log10 ::+  forall shape dtype device.+  (StandardFloatingPointDTypeValidation device dtype) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+log10 input = unsafePerformIO $ ATen.cast1 ATen.Managed.log10_t input++-- | pow+-- this operation supports broadcasting+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> dtype &&& shape $ pow (2 :: CPUTensor 'D.Float '[]) (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+pow ::+  forall shape'' shape shape' dtype device.+  ( BasicArithmeticDTypeIsValid device dtype,+    shape'' ~ Broadcast shape shape'+  ) =>+  -- | power+  Tensor device dtype shape ->+  -- | input tensor+  Tensor device dtype shape' ->+  -- | output tensor+  Tensor device dtype shape''+pow exponent input = unsafePerformIO $ ATen.cast2 ATen.Managed.pow_tt input exponent++-- | relu activation function+--+-- >>> dtype &&& shape $ relu (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+relu ::+  forall shape dtype device t.+  ( StandardFloatingPointDTypeValidation device dtype,+    IsUnnamed t device dtype shape+  ) =>+  -- | input+  t ->+  -- | output+  t+relu input = unWrap $ unsafePerformIO $ ATen.cast1 ATen.Managed.relu_t (Wrap input)++-- | selu+--+-- >>> dtype &&& shape $ selu (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+selu ::+  forall shape dtype device.+  (StandardFloatingPointDTypeValidation device dtype) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+selu input = unsafePerformIO $ ATen.cast1 ATen.Managed.selu_t input++-- | mish+-- `mish` is a smooth activation function, see https://arxiv.org/abs/1908.08681 for details.+--+-- >>> dtype &&& shape &&& (\t -> D.asValue (toDynamic t) :: [[Float]]) $ mish (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,([3,2],[[0.86509836,0.86509836],[0.86509836,0.86509836],[0.86509836,0.86509836]]))+mish ::+  forall shape dtype device.+  ( StandardFloatingPointDTypeValidation device dtype,+    BasicArithmeticDTypeIsValid device dtype,+    shape ~ Broadcast shape shape+  ) =>+  Tensor device dtype shape ->+  Tensor device dtype shape+mish = mul =<< tanh . softplus (1 :: Float) 20++-- | sigmoid+--+-- >>> dtype &&& shape $ sigmoid (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+sigmoid ::+  forall shape dtype device.+  (StandardFloatingPointDTypeValidation device dtype) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+sigmoid input = unsafePerformIO $ ATen.cast1 ATen.Managed.sigmoid_t input++-- | sin+--+-- >>> dtype &&& shape $ sin (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+sin ::+  forall shape dtype device t.+  ( StandardFloatingPointDTypeValidation device dtype,+    IsUnnamed t device dtype shape+  ) =>+  -- | input+  t ->+  -- | output+  t+sin input = unWrap $ unsafePerformIO $ ATen.cast1 ATen.Managed.sin_t (Wrap input)++-- | sinh+--+-- >>> dtype &&& shape $ sinh (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+sinh ::+  forall shape dtype device t.+  ( StandardFloatingPointDTypeValidation device dtype,+    IsUnnamed t device dtype shape+  ) =>+  -- | input+  t ->+  -- | output+  t+sinh input = unWrap $ unsafePerformIO $ ATen.cast1 ATen.Managed.sinh_t (Wrap input)++-- | cos+--+-- >>> dtype &&& shape $ cos (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+cos ::+  forall shape dtype device t.+  ( StandardFloatingPointDTypeValidation device dtype,+    IsUnnamed t device dtype shape+  ) =>+  -- | input+  t ->+  -- | output+  t+cos input = unWrap $ unsafePerformIO $ ATen.cast1 ATen.Managed.cos_t (Wrap input)++-- | sqrt+sqrt ::+  forall shape dtype device t.+  ( StandardFloatingPointDTypeValidation device dtype,+    IsUnnamed t device dtype shape+  ) =>+  -- | input+  t ->+  -- | output+  t+sqrt input = unWrap $ unsafePerformIO $ ATen.cast1 ATen.Managed.sqrt_t (Wrap input)++-- | tanh+tanh ::+  forall shape dtype device.+  (StandardFloatingPointDTypeValidation device dtype) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+tanh input = unsafePerformIO $ ATen.cast1 ATen.Managed.tanh_t input++-- | ConditionalReduction+--+-- >>> :kind! ConditionalReduction '[3,2] ReduceNone+-- ConditionalReduction '[3,2] ReduceNone :: [Natural]+-- = [3, 2]+-- >>> :kind! ConditionalReduction '[3,2] ReduceMean+-- ConditionalReduction '[3,2] ReduceMean :: [Natural]+-- = '[]+type family ConditionalReduction (shape :: [Nat]) (reduction :: Reduction) :: [Nat] where+  ConditionalReduction shape ReduceNone = shape+  ConditionalReduction shape _ = '[]++class KnownReduction reduction where+  reductionVal :: Int++instance KnownReduction ReduceNone where+  reductionVal = 0++instance KnownReduction ReduceMean where+  reductionVal = 1++instance KnownReduction ReduceSum where+  reductionVal = 2++-- | binary cross entropy+--+-- >>> t = ones :: CPUTensor 'D.Float '[2,2]+-- >>> dtype &&& shape $ binaryCrossEntropy @ReduceNone t t t+-- (Float,[2,2])+-- >>> dtype &&& shape $ binaryCrossEntropy @ReduceMean t t t+-- (Float,[])+-- >>> dtype &&& shape $ binaryCrossEntropy @ReduceSum t t t+-- (Float,[])+binaryCrossEntropy ::+  forall (reduction :: Reduction) shape shape' dtype device.+  ( KnownReduction reduction,+    shape' ~ ConditionalReduction shape reduction,+    StandardFloatingPointDTypeValidation device dtype+  ) =>+  -- | weight+  Tensor device dtype shape ->+  -- | prediction+  Tensor device dtype shape ->+  -- | target+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape'+binaryCrossEntropy weight prediction target =+  unsafePerformIO $+    ATen.cast4+      ATen.Managed.binary_cross_entropy_tttl+      prediction+      target+      weight+      (reductionVal @reduction)++-- | mseLoss+--+-- >>> t = ones :: CPUTensor 'D.Float '[2,2]+-- >>> dtype &&& shape $ mseLoss @ReduceNone t t+-- (Float,[2,2])+-- >>> dtype &&& shape $ mseLoss @ReduceMean t t+-- (Float,[])+-- >>> dtype &&& shape $ mseLoss @ReduceSum t t+-- (Float,[])+mseLoss ::+  forall (reduction :: Reduction) shape shape' dtype device.+  ( KnownReduction reduction,+    shape' ~ ConditionalReduction shape reduction,+    StandardFloatingPointDTypeValidation device dtype+  ) =>+  -- | prediction+  Tensor device dtype shape ->+  -- | target+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape'+mseLoss prediction target =+  unsafePerformIO $+    ATen.cast3+      ATen.Managed.mse_loss_ttl+      prediction+      target+      (reductionVal @reduction)++-- | softmax+--+-- >>> t = ones :: CPUTensor 'D.Float '[2,2]+-- >>> dtype &&& shape $ softmax @0 t+-- (Float,[2,2])+-- >>> dtype &&& shape $ softmax @1 t+-- (Float,[2,2])+softmax ::+  forall dim shape dtype device.+  ( KnownNat dim,+    DimOutOfBoundCheck shape dim,+    KnownDType dtype,+    StandardFloatingPointDTypeValidation device dtype+  ) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+softmax input =+  unsafePerformIO $+    ATen.cast3 ATen.Managed.softmax_tls input (natValI @dim) (dtypeVal @dtype)++-- | logSoftmax+--+-- >>> t = ones :: CPUTensor 'D.Float '[2,2]+-- >>> dtype &&& shape $ logSoftmax @0 t+-- (Float,[2,2])+-- >>> dtype &&& shape $ logSoftmax @1 t+-- (Float,[2,2])+logSoftmax ::+  forall dim shape dtype device.+  ( KnownNat dim,+    DimOutOfBoundCheck shape dim,+    KnownDType dtype,+    StandardFloatingPointDTypeValidation device dtype+  ) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+logSoftmax input =+  unsafePerformIO $+    ATen.cast3 ATen.Managed.log_softmax_tls input (natValI @dim) (dtypeVal @dtype)++type family Square (shape :: [Nat]) :: [Nat] where+  Square (n : n : '[]) = '[n, n]+  Square (b : n : n : '[]) = '[b, n, n]+  Square _ = TypeError (Text "This shape must be square matrix or batch + square matrix.")++type family VectorOfSquare (shape :: [Nat]) :: [Nat] where+  VectorOfSquare (n : n : '[]) = '[n]+  VectorOfSquare (b : n : n : '[]) = '[b, n]+  VectorOfSquare _ = TypeError (Text "This shape must be square matrix or batch + square matrix.")++type family FstSquareDim (shape :: [Nat]) :: Nat where+  FstSquareDim (n : m : '[]) = n+  FstSquareDim (b : n : m : '[]) = n+  FstSquareDim _ = TypeError (Text "Can not get first dimention of matrix or batch + matrix.")++type family InverseShapeIsValid (device :: (D.DeviceType, Nat)) (shape :: [Nat]) :: Constraint where+  InverseShapeIsValid '( 'D.CPU, 0) _ = ()+  InverseShapeIsValid '( 'D.CUDA, _) shape = AllDimsPositive shape+  InverseShapeIsValid '( 'D.MPS, 0) shape = AllDimsPositive shape++type family InverseDTypeIsValid (device :: (D.DeviceType, Nat)) (dtype :: D.DType) :: Constraint where+  InverseDTypeIsValid '( 'D.CPU, 0) dtype =+    ( DTypeIsFloatingPoint '( 'D.CPU, 0) dtype,+      DTypeIsNotHalf '( 'D.CPU, 0) dtype+    )+  InverseDTypeIsValid '( 'D.CUDA, deviceIndex) dtype =+    ( DTypeIsFloatingPoint '( 'D.CUDA, deviceIndex) dtype,+      DTypeIsNotHalf '( 'D.CUDA, deviceIndex) dtype+    )+  InverseDTypeIsValid '( 'D.MPS, 0) dtype =+    ( DTypeIsFloatingPoint '( 'D.MPS, 0) dtype,+      DTypeIsNotHalf '( 'D.MPS, 0) dtype+    )+  InverseDTypeIsValid '(deviceType, _) dtype = UnsupportedDTypeForDevice deviceType dtype++-- | inverse+-- TODO: if rank < n for any tensors in the batch, then this will not work. we can't decide this statically, but we should prevent runtime errors. therefore, return Maybe?+--+-- >>> t <- randn :: IO (CPUTensor 'D.Float '[3,2,2])+-- >>> dtype &&& shape $ inverse t+-- (Float,[3,2,2])+-- >>> t <- randn :: IO (CPUTensor 'D.Float '[2,2])+-- >>> dtype &&& shape $ inverse t+-- (Float,[2,2])+inverse ::+  forall shape shape' dtype device.+  ( shape' ~ Square shape,+    InverseShapeIsValid device shape,+    InverseDTypeIsValid device dtype+  ) =>+  -- | inverse+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape'+inverse input = unsafePerformIO $ ATen.cast1 ATen.Managed.inverse_t input++type family SymeigDTypeIsValid (device :: (D.DeviceType, Nat)) (dtype :: D.DType) :: Constraint where+  SymeigDTypeIsValid '( 'D.CPU, 0) dtype =+    ( DTypeIsFloatingPoint '( 'D.CPU, 0) dtype,+      DTypeIsNotHalf '( 'D.CPU, 0) dtype+    )+  SymeigDTypeIsValid '( 'D.CUDA, deviceIndex) dtype =+    ( DTypeIsFloatingPoint '( 'D.CUDA, deviceIndex) dtype,+      DTypeIsNotHalf '( 'D.CUDA, deviceIndex) dtype+    )+  SymeigDTypeIsValid '( 'D.MPS, 0) dtype =+    ( DTypeIsFloatingPoint '( 'D.MPS, 0) dtype,+      DTypeIsNotHalf '( 'D.MPS, 0) dtype+    )+  SymeigDTypeIsValid '(deviceType, _) dtype = UnsupportedDTypeForDevice deviceType dtype++-- | symeig+-- Warning:+-- torch.symeig is deprecated in favor of torch.linalg.eigh and will be removed in a future PyTorch release.+-- The default behavior has changed from using the upper triangular portion of the matrix by default to using the lower triangular portion.+-- L, _ = torch.symeig(A, upper=upper)+-- should be replaced with+-- L = torch.linalg.eigvalsh(A, UPLO='U' if upper else 'L')+-- and+-- L, V = torch.symeig(A, eigenvectors=True)+-- should be replaced with+-- L, V = torch.linalg.eigh(A, UPLO='U' if upper else 'L') (function operator())+--+-- >>> t <- rand :: IO (CPUTensor 'D.Float '[3,2,2])+-- >>> (eigenVals,eigenVecs) = symeig Upper t+-- >>> dtype &&& shape $ eigenVals -- Skip warning+-- ...+-- >>> dtype &&& shape $ eigenVals+-- (Float,[3,2])+-- >>> :t eigenVals+-- eigenVals :: Tensor '(D.CPU, 0) 'D.Float [3, 2]+-- >>> dtype &&& shape $ eigenVecs+-- (Float,[3,2,2])+-- >>> :t eigenVecs+-- eigenVecs :: Tensor '(D.CPU, 0) 'D.Float [3, 2, 2]+-- >>> (eigenVals,eigenVecs) = symeig Lower t+-- >>> dtype &&& shape $ eigenVals+-- (Float,[3,2])+-- >>> dtype &&& shape $ eigenVecs+-- (Float,[3,2,2])+symeig ::+  forall shape shape' shape'' dtype device.+  ( shape' ~ VectorOfSquare shape,+    shape'' ~ Square shape,+    SymeigDTypeIsValid device dtype+  ) =>+  -- | upper or lower triagonal+  Tri ->+  -- | input+  Tensor device dtype shape ->+  -- | eigenvalues and eigenvectors+  ( Tensor device dtype shape',+    Tensor device dtype shape''+  )+symeig upper input =+  unsafePerformIO $+    ATen.cast3 ATen.Managed._linalg_eigh_tsb input boolUpper True+  where+    boolUpper =+      case upper of+        Upper -> "U"+        Lower -> "L"++-- | symeigvalues+--+-- >>> t <- rand :: IO (CPUTensor 'D.Float '[3,2,2])+-- >>> eigenVals = symeigvalues Upper t+-- >>> dtype &&& shape $ eigenVals+-- (Float,[3,2])+-- >>> :t eigenVals+-- eigenVals :: Tensor '(D.CPU, 0) 'D.Float [3, 2]+symeigvalues ::+  forall shape shape' dtype device.+  ( shape' ~ VectorOfSquare shape,+    SymeigDTypeIsValid device dtype+  ) =>+  -- | upper or lower triagonal+  Tri ->+  -- | input+  Tensor device dtype shape ->+  Tensor device dtype shape'+symeigvalues upper input = fst symeig'+  where+    symeig' :: (Tensor device dtype shape', Tensor device dtype shape'')+    symeig' = unsafePerformIO $ ATen.cast3 ATen.Managed._linalg_eigh_tsb input boolUpper True+    boolUpper =+      case upper of+        Upper -> "U"+        Lower -> "L"++data EigenVectors = EnableEigenVectors | DisableEigenVectors++class KnownEigenVectors a where+  enableEigenVectors :: Bool++instance KnownEigenVectors EnableEigenVectors where+  enableEigenVectors = True++instance KnownEigenVectors DisableEigenVectors where+  enableEigenVectors = False++type family ConditionalEigenVectors (eigenvectors :: EigenVectors) (n :: Nat) :: [Nat] where+  ConditionalEigenVectors EnableEigenVectors n = '[n, n]+  ConditionalEigenVectors DisableEigenVectors _ = '[0]++type family EigDTypeIsValid (device :: (D.DeviceType, Nat)) (dtype :: D.DType) :: Constraint where+  EigDTypeIsValid '(D.CPU, 0) dtype =+    ( DTypeIsFloatingPoint '(D.CPU, 0) dtype,+      DTypeIsNotHalf '(D.CPU, 0) dtype+    )+  EigDTypeIsValid '( 'D.CUDA, deviceIndex) dtype =+    ( DTypeIsFloatingPoint '( 'D.CUDA, deviceIndex) dtype,+      DTypeIsNotHalf '( 'D.CUDA, deviceIndex) dtype+    )+  EigDTypeIsValid '( 'D.MPS, 0) dtype =+    ( DTypeIsFloatingPoint '( 'D.MPS, 0) dtype,+      DTypeIsNotHalf '( 'D.MPS, 0) dtype+    )+  EigDTypeIsValid '(deviceType, _) dtype = UnsupportedDTypeForDevice deviceType dtype++type family ToComplexNumber (dtype :: D.DType) :: D.DType where+  ToComplexNumber D.Half = D.ComplexHalf+  ToComplexNumber D.Float = D.ComplexFloat+  ToComplexNumber D.Double = D.ComplexDouble+  ToComplexNumber other = other++-- | eig+-- Warning:+-- torch.eig is deprecated in favor of torch.linalg.eig and will be removed in a future PyTorch release.+-- torch.linalg.eig returns complex tensors of dtype cfloat or cdouble rather than real tensors mimicking complex tensors.+-- L, _ = torch.eig(A)+-- should be replaced with+-- L_complex = torch.linalg.eigvals(A)+-- and+-- L, V = torch.eig(A, eigenvectors=True)+-- should be replaced with+-- L_complex, V_complex = torch.linalg.eig(A) (function operator())+--+-- >>> t <- rand :: IO (CPUTensor 'D.Float '[3,3])+-- >>> (eigenVals,eigenVecs) = eig @EnableEigenVectors t+-- >>> dtype &&& shape $ eigenVals+-- (ComplexFloat,[3])+-- >>> :t eigenVals+-- eigenVals :: Tensor '(D.CPU, 0) D.ComplexFloat '[3]+-- >>> dtype &&& shape $ eigenVecs+-- (ComplexFloat,[3,3])+-- >>> :t eigenVecs+ -- eigenVecs :: Tensor '(D.CPU, 0) D.ComplexFloat [3, 3]+-- >>> (eigenVals,eigenVecs) = eig @DisableEigenVectors t+-- >>> dtype &&& shape $ eigenVals+-- (ComplexFloat,[3])+-- >>> dtype &&& shape $ eigenVecs+-- (ComplexFloat,[3,3])+-- >>> :t eigenVecs+-- eigenVecs :: Tensor '(D.CPU, 0) D.ComplexFloat [3, 3]+eig ::+  forall eigenvectors n shape dtype device.+  ( KnownNat n,+    KnownEigenVectors eigenvectors,+    EigDTypeIsValid device dtype,+    KnownDType (ToComplexNumber dtype)+  ) =>+  -- | input matrix+  Tensor device dtype '[n, n] ->+  -- | eigenvalues and eigenvectors+  ( Tensor device (ToComplexNumber dtype) '[n],+    Tensor device (ToComplexNumber dtype) '[n, n]+  )+eig input =+  unsafePerformIO $ ATen.cast1 ATen.Managed.linalg_eig_t input++type family SVDShapes (shape :: [Nat]) (reduced :: ReducedSVD) :: ([Nat], [Nat], [Nat]) where+  SVDShapes '[0, n] 'ThinSVD = '( '[0, 0], '[0], '[n, n])+  SVDShapes '[m, n] 'ThinSVD = '( '[m, Min m n], '[Min m n], '[n, Min m n])+  SVDShapes '[m, n] 'FullSVD = '( '[m, m], '[Min m n], '[n, n])+  SVDShapes '[b, 0, n] 'ThinSVD = '( '[b, 0, 0], '[b, 0], '[b, n, n])+  SVDShapes '[b, m, n] 'ThinSVD = '( '[b, m, Min m n], '[b, Min m n], '[b, n, Min m n])+  SVDShapes '[b, m, n] 'FullSVD = '( '[b, m, m], '[b, Min m n], '[b, n, n])+  SVDShapes _ _ = TypeError (Text "A singular value decomposition can only be computed for 2D matrices for at most one batch dimension.")++data ReducedSVD = ThinSVD | FullSVD++class KnownReducedSVD (reduced :: ReducedSVD) where+  reducedSVD :: Bool++instance KnownReducedSVD ThinSVD where+  reducedSVD = True++instance KnownReducedSVD FullSVD where+  reducedSVD = False++type family SVDDTypeIsValid (device :: (D.DeviceType, Nat)) (dtype :: D.DType) :: Constraint where+  SVDDTypeIsValid '(D.CPU, 0) dtype =+    ( DTypeIsFloatingPoint '(D.CPU, 0) dtype,+      DTypeIsNotHalf '(D.CPU, 0) dtype+    )+  SVDDTypeIsValid '( 'D.CUDA, deviceIndex) dtype =+    ( DTypeIsFloatingPoint '( 'D.CUDA, deviceIndex) dtype,+      DTypeIsNotHalf '( 'D.CUDA, deviceIndex) dtype+    )+  SVDDTypeIsValid '(D.MPS, 0) dtype =+    ( DTypeIsFloatingPoint '(D.MPS, 0) dtype,+      DTypeIsNotHalf '(D.MPS, 0) dtype+    )+  SVDDTypeIsValid '(deviceType, _) dtype = UnsupportedDTypeForDevice deviceType dtype++-- | Singular Value Decomposition+-- TODO: When `compute_uv` is `False`, backward cannot be performed since `u` and `v` from the forward pass are required for the backward operation. There is no way to encode in the types at this point in time. Thus, only `True` is supported currently.+--+-- This function returns a tuple `(u, s, v)`+-- which is the singular value decomposition of a input real matrix+-- or batches of real matrices input such that+-- `input = U×diag(S)×V^T`.+--+-- >>> a <- randn :: IO (CPUTensor 'D.Float '[3, 5])+-- >>> (u, s, v) = svd @'ThinSVD a+-- >>> dtype &&& shape $ u+-- (Float,[3,3])+-- >>> dtype &&& shape $ s+-- (Float,[3])+-- >>> dtype &&& shape $ v+-- (Float,[5,3])+-- >>> (u, s, v) = svd @'FullSVD a+-- >>> dtype &&& shape $ u+-- (Float,[3,3])+-- >>> dtype &&& shape $ s+-- (Float,[3])+-- >>> dtype &&& shape $ v+-- (Float,[5,5])+-- >>> a <- randn :: IO (CPUTensor 'D.Float '[5, 3])+-- >>> (u, s, v) = svd @'ThinSVD a+-- >>> dtype &&& shape $ u+-- (Float,[5,3])+-- >>> dtype &&& shape $ s+-- (Float,[3])+-- >>> dtype &&& shape $ v+-- (Float,[3,3])+-- >>> (u, s, v) = svd @'FullSVD a+-- >>> dtype &&& shape $ u+-- (Float,[5,5])+-- >>> dtype &&& shape $ s+-- (Float,[3])+-- >>> dtype &&& shape $ v+-- (Float,[3,3])+svd ::+  forall reduced shape shapeU shapeS shapeV dtype device.+  ( KnownReducedSVD reduced,+    '(shapeU, shapeS, shapeV) ~ SVDShapes shape reduced,+    SVDDTypeIsValid device dtype+  ) =>+  -- | (batched) input real matrix+  Tensor device dtype shape ->+  -- | (batched) output tuple of `u`, `s`, and `v`+  ( Tensor device dtype shapeU,+    Tensor device dtype shapeS,+    Tensor device dtype shapeV+  )+svd input =+  unsafePerformIO $ ATen.cast3 ATen.Managed.svd_tbb input (reducedSVD @reduced) True++type family CholeskyDTypeIsValid (device :: (D.DeviceType, Nat)) (dtype :: D.DType) :: Constraint where+  CholeskyDTypeIsValid '(D.CPU, 0) dtype =+    ( DTypeIsFloatingPoint '(D.CPU, 0) dtype,+      DTypeIsNotHalf '(D.CPU, 0) dtype+    )+  CholeskyDTypeIsValid '( 'D.CUDA, deviceIndex) dtype =+    ( DTypeIsFloatingPoint '( 'D.CUDA, deviceIndex) dtype,+      DTypeIsNotHalf '( 'D.CUDA, deviceIndex) dtype+    )+  CholeskyDTypeIsValid '(D.MPS, 0) dtype =+    ( DTypeIsFloatingPoint '(D.MPS, 0) dtype,+      DTypeIsNotHalf '(D.MPS, 0) dtype+    )+  CholeskyDTypeIsValid '(deviceType, _) dtype = UnsupportedDTypeForDevice deviceType dtype++-- | cholesky+-- TODO: cholesky can throw if the input is not positive-definite.+-- Computes the Cholesky decomposition of a symmetric positive-definite matrix.+-- The operation supports batching.+--+-- Warning:+-- torch.cholesky is deprecated in favor of torch.linalg.cholesky and will be removed in a future PyTorch release.+-- L = torch.cholesky(A)+-- should be replaced with+-- L = torch.linalg.cholesky(A)+-- and+-- U = torch.cholesky(A, upper=True)+-- should be replaced with+-- U = torch.linalg.cholesky(A.transpose(-2, -1).conj()).transpose(-2, -1).conj() (function operator())+--+-- >>> t <- rand :: IO (CPUTensor 'D.Float '[2,2])+-- >>> u = cholesky Upper (t `matmul` transpose2D t) -- Skip warning+-- ...+-- >>> dtype &&& shape $ u+-- (Float,[2,2])+-- >>> :t u+-- u :: Tensor '(D.CPU, 0) 'D.Float [2, 2]+cholesky ::+  forall shape shape' dtype device.+  ( shape' ~ Square shape,+    CholeskyDTypeIsValid device dtype+  ) =>+  -- | indicate whether to return an upper or lower triangular matrix.+  Tri ->+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape'+cholesky upper input = unsafePerformIO $ ATen.cast2 ATen.Managed.cholesky_tb input boolUpper+  where+    boolUpper = isUpper upper++-- | choleskyInverse+-- Computes the inverse of a symmetric positive-definite matrix+-- using its Cholesky factor, returned, e.g., by `cholesky`.+-- Unlike `cholesky`, this operation does not support batching.+-- The inverse is computed using the LAPACK routine `?potri`.+--+-- >>> t <- rand :: IO (CPUTensor 'D.Float '[2,2])+-- >>> tri = Upper+-- >>> u = cholesky tri (t `matmul` transpose2D t)+-- >>> dtype &&& shape $ choleskyInverse tri u+-- (Float,[2,2])+choleskyInverse ::+  forall n dtype device.+  ( 1 <= n,+    CholeskyDTypeIsValid device dtype+  ) =>+  -- | decides whether the upper or the lower triangular part of the input tensor is used+  Tri ->+  -- | the input 2-D tensor `u`, an upper or lower triangular Cholesky factor+  Tensor device dtype '[n, n] ->+  -- | the output 2-D tensor+  Tensor device dtype '[n, n]+choleskyInverse upper input =+  unsafePerformIO $+    ATen.cast2 ATen.Managed.cholesky_inverse_tb input boolUpper+  where+    boolUpper = isUpper upper++-- | choleskySolve+-- Solves the system of linear equations represented by `a c = b`+-- using the Cholesky factor matrix `u` of `a` (returned, e.g., by `cholesky`),+-- where `a` is a positive semidefinite matrix.+-- The operation supports batching.+--+-- >>> t <- rand :: IO (CPUTensor 'D.Float '[3,3])+-- >>> a = t `matmul` transpose2D t+-- >>> b <- rand :: IO (CPUTensor 'D.Float '[3,2])+-- >>> tri = Upper+-- >>> u = cholesky tri a+-- >>> dtype &&& shape $ choleskySolve tri b u+-- (Float,[3,2])+choleskySolve ::+  forall m_k m_m dtype device.+  ( Square m_m ~ m_m,+    FstSquareDim m_m ~ FstSquareDim m_k,+    1 <= FstSquareDim m_m,+    CholeskyDTypeIsValid device dtype+  ) =>+  -- | decides whether the upper or the lower triangular part of the input tensor `u` is used+  Tri ->+  -- | the (batched) RHS tensor `b`+  Tensor device dtype m_k ->+  -- | the (batched) input 2-D tensor `u`, an upper or lower triangular Cholesky factor+  Tensor device dtype m_m ->+  -- | the (batched) output 2-D tensor+  Tensor device dtype m_k+choleskySolve upper b u =+  unsafePerformIO $+    ATen.cast3 ATen.Managed.cholesky_solve_ttb b u boolUpper+  where+    boolUpper = isUpper upper++type family SolveDTypeIsValid (device :: (D.DeviceType, Nat)) (dtype :: D.DType) :: Constraint where+  SolveDTypeIsValid '(D.CPU, 0) dtype =+    ( DTypeIsFloatingPoint '(D.CPU, 0) dtype,+      DTypeIsNotHalf '(D.CPU, 0) dtype+    )+  SolveDTypeIsValid '( 'D.CUDA, deviceIndex) dtype =+    ( DTypeIsFloatingPoint '( 'D.CUDA, deviceIndex) dtype,+      DTypeIsNotHalf '( 'D.CUDA, deviceIndex) dtype+    )+  SolveDTypeIsValid '( 'D.MPS, 0) dtype =+    ( DTypeIsFloatingPoint '( 'D.MPS, 0) dtype,+      DTypeIsNotHalf '( 'D.MPS, 0) dtype+    )+  SolveDTypeIsValid '(deviceType, _) dtype = UnsupportedDTypeForDevice deviceType dtype++-- | solve+-- Solves the system of linear equations represented by `a c = b` and also returns the LU decomposition of `a`.+-- `a` has to be a positive semidefinite matrix.+-- The operation supports batching.+--+-- Warning:+-- torch.solve is deprecated in favor of torch.linalg.solveand will be removed in a future PyTorch release.+-- torch.linalg.solve has its arguments reversed and does not return the LU factorization.+-- To get the LU factorization see torch.lu, which can be used with torch.lu_solve or torch.lu_unpack.+-- X = torch.solve(B, A).solution+-- should be replaced with+-- X = torch.linalg.solve(A, B) (function operator())+--+-- >>> t <- rand :: IO (CPUTensor 'D.Float '[10,10])+-- >>> a = t `matmul` transpose2D t+-- >>> b <- rand :: IO (CPUTensor 'D.Float '[10,3])+-- >>> c = solve b a+-- >>> dtype &&& shape $ c+-- (Float,[10,3])+-- >>> :t c+-- c :: Tensor '(D.CPU, 0) 'D.Float [10, 3]+solve ::+  forall m_k m_m dtype device.+  ( Square m_m ~ m_m,+    FstSquareDim m_m ~ FstSquareDim m_k,+    1 <= FstSquareDim m_m,+    SolveDTypeIsValid device dtype+  ) =>+  -- | the (batched) RHS tensor `b`+  Tensor device dtype m_k ->+  -- | the (batched) positive semidefinite matrix `a`+  Tensor device dtype m_m ->+  -- | the (batched) outputs c+  Tensor device dtype m_k+solve b a =+  let (v::Tensor device dtype m_k, _ :: Tensor device dtype m_k) = unsafePerformIO $ ATen.cast2 ATen.Managed.linalg_solve_ex_tt a b+  in v++-- | geqrf+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+-- `geqrf` computes a QR decomposition of the given `input` matrix,+-- but without constructing `Q` and `R` as explicit separate matrices.+-- Rather, this function directly calls the underlying LAPACK function `?geqrf`+-- which produces a tuple `(a, tau)` of intermediate results as defined in+-- the LAPACK documentation for `?geqrf`.+--+-- You can use `orgqr` on `(a, tau)` to compute the real orthogonal matrix `Q`,+-- but in general you may just want to use `qr` instead.+--+-- See the LAPACK documentation for `?geqrf` for further details,+-- https://software.intel.com/en-us/node/521004.+--+-- >>> (a, tau) = geqrf (ones :: CPUTensor 'D.Float '[3,4])+-- >>> dtype &&& shape $ a+-- (Float,[3,4])+-- >>> dtype &&& shape $ tau+-- (Float,[3])+-- >>> (a, tau) = geqrf (ones :: CPUTensor 'D.Float '[4,3])+-- >>> dtype &&& shape $ a+-- (Float,[4,3])+-- >>> dtype &&& shape $ tau+-- (Float,[3])+geqrf ::+  forall m n dtype device.+  -- | input matrix+  Tensor device dtype '[m, n] ->+  -- | tuple `(a, tau)` of output matrices+  ( Tensor device dtype '[m, n],+    Tensor device dtype '[Min m n]+  )+geqrf input = unsafePerformIO $ ATen.cast1 ATen.Managed.geqrf_t input++-- | orgqr+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+-- Computes the orthogonal matrix `Q` of a QR factorization+-- from the `(a, tau)` tuple returned by `geqrf`.+--+-- This directly calls the underlying LAPACK function `?orgqr`.+-- See the LAPACK documentation for `?orgqr` for further details,+-- https://software.intel.com/en-us/mkl-developer-reference-c-orgqr.+--+-- When libtorch-1.7, this function behavior is changed.+-- First dimention should be greater than second dimention.+--+-- >>> dtype &&& shape $ orgqr (ones :: CPUTensor 'D.Float '[4,3]) (ones :: CPUTensor 'D.Float '[3])+-- (Float,[4,3])+orgqr ::+  forall m n dtype device.+  ( KnownNat n,+    KnownNat m,+    n <= m+  ) =>+  Tensor device dtype '[m, n] ->+  Tensor device dtype '[n] ->+  Tensor device dtype '[m, n]+orgqr a tau = unsafePerformIO $ ATen.cast2 ATen.Managed.orgqr_tt a tau++-- | sign+-- works for all dtypes+--+-- >>> dtype &&& shape $ sign (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+sign ::+  forall shape dtype device.+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+sign input = unsafePerformIO $ ATen.cast1 ATen.Managed.sign_t input++type family SetValue (shape :: [Nat]) (i :: Nat) (j :: Nat) :: [Nat] where+  SetValue '[] _ _ = '[]+  SetValue (x : xs) 0 j = j : xs+  SetValue (x : xs) i j = x : SetValue xs (i -1) j++type family GetValue (shape :: [Nat]) (i :: Nat) :: Nat where+  GetValue '[] _ = TypeError (Text "Can not find a element in the list.")+  GetValue (x : xs) 0 = x+  GetValue (x : xs) i = GetValue xs (i -1)++-- | Transpose+--+-- >>> :kind! Transpose '[3,2] 0 1+-- Transpose '[3,2] 0 1 :: [Natural]+-- = [2, 3]+-- >>> :kind! Transpose '[3,2,1] 1 2+-- Transpose '[3,2,1] 1 2 :: [Natural]+-- = [3, 1, 2]+type family Transpose (shape :: [Nat]) (dim0 :: Nat) (dim1 :: Nat) :: [Nat] where+  Transpose s d0 d1 = (SetValue (SetValue s d0 (GetValue s d1)) d1 (GetValue s d0))++-- | transpose+-- See "../../../../deps/pytorch/aten/src/ATen/native/TensorShape.cpp".+--+-- >>> dtype &&& shape $ transpose @0 @1 (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[2,3])+-- >>> dtype &&& shape $ transpose @0 @1 (ones :: CPUTensor 'D.Float '[3,2,1])+-- (Float,[2,3,1])+-- >>> dtype &&& shape $ transpose @1 @2 (ones :: CPUTensor 'D.Float '[3,2,1])+-- (Float,[3,1,2])+transpose ::+  forall n m shape shape' dtype device.+  ( KnownNat n,+    KnownNat m,+    shape' ~ Transpose shape n m+  ) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape'+transpose input =+  unsafePerformIO $ ATen.cast3 ATen.Managed.transpose_tll input (natValI @n) (natValI @m)++-- | transpose2d, special case for a 2D tensor+--+-- >>> dtype &&& shape $ transpose2D (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[2,3])+transpose2D ::+  forall (i :: Nat) (j :: Nat) dtype device.+  -- | input+  Tensor device dtype '[i, j] ->+  -- | output+  Tensor device dtype '[j, i]+transpose2D = transpose @0 @1++class KnownTri (tri :: Tri) where+  triVal :: Tri++instance KnownTri Upper where+  triVal = Upper++instance KnownTri Lower where+  triVal = Lower++type family DiagSize (tri :: Tri) (index :: Nat) (m :: Nat) (n :: Nat) :: Nat where+  DiagSize 'Upper i m n =+    If+      (i <=? n)+      (Min m (n - i))+      ( TypeError+          ( Text "For a matrix with shape "+              :<>: ShowType '[m, n]+              :<>: Text ", the maximum index for an upper diagonal is "+              :<>: ShowType n+              :<>: Text ", but asked for index "+              :<>: ShowType i+          )+      )+  DiagSize 'Lower i m n =+    If+      (i <=? m)+      (Min (m - i) n)+      ( TypeError+          ( Text "For a matrix with shape "+              :<>: ShowType '[m, n]+              :<>: Text ", the maximum index for a lower diagonal is "+              :<>: ShowType m+              :<>: Text ", but asked for index "+              :<>: ShowType i+          )+      )++type family DiagShape (tri :: Tri) (index :: Nat) (shape :: [Nat]) :: [Nat] where+  DiagShape _ i '[n] = '[n + i, n + i]+  DiagShape tri i '[m, n] = '[DiagSize tri i m n]+  DiagShape _ _ shape =+    TypeError+      ( Text "The input must be a matrix or a vector, but it has "+          :<>: ShowType (ListLength shape)+          :<>: Text " dimensions."+      )++-- | diag+--+-- >>> dtype &&& shape $ diag @'Upper @0 (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[2])+-- >>> dtype &&& shape $ diag @'Upper @1 (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[1])+-- >>> dtype &&& shape $ diag @'Lower @1 (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[2])+diag ::+  forall tri index shape shape' device dtype.+  ( KnownTri tri,+    KnownNat index,+    StandardDTypeValidation device dtype,+    shape' ~ DiagShape tri index shape+  ) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape'+diag t = unsafePerformIO $+  ATen.cast2 ATen.Managed.tensor_diag_l t $+    case triVal @tri of+      Upper -> natValI @index+      Lower -> - natValI @index++-- | all+-- See https://pytorch.org/docs/stable/tensors.html#torch.BoolTensor.all.+--+-- >>> t = all (fromJust [False, False] :: CPUTensor 'D.Bool '[2])+-- >>> toInt t == 1+-- False+--+-- >>> t = all (fromJust [False, True] :: CPUTensor 'D.Bool '[2])+-- >>> toInt t == 1+-- False+--+-- >>> t = all (fromJust [True, True] :: CPUTensor 'D.Bool '[2])+-- >>> toInt t == 1+-- True+all ::+  forall shape device.+  -- | input+  Tensor device 'D.Bool shape ->+  -- | output+  Tensor device 'D.Bool '[]+all input = unsafePerformIO $ ATen.cast1 ATen.Managed.all_t input++-- | any+-- See https://pytorch.org/docs/stable/tensors.html#torch.BoolTensor.any.+--+-- >>> t = any (fromJust [False, False] :: CPUTensor 'D.Bool '[2])+-- >>> toInt t == 1+-- False+--+-- >>> t = any (fromJust [False, True] :: CPUTensor 'D.Bool '[2])+-- >>> toInt t == 1+-- True+--+-- >>> t = any (fromJust [True, True] :: CPUTensor 'D.Bool '[2])+-- >>> toInt t == 1+-- True+any ::+  forall shape device.+  -- | input+  Tensor device 'D.Bool shape ->+  -- | output+  Tensor device 'D.Bool '[]+any input = unsafePerformIO $ ATen.cast1 ATen.Managed.any_t input++data KeepOrDropDim = KeepDim | DropDim++class KnownKeepOrDropDim keepOrDropDim where+  keepOrDropDimVal :: Bool++instance KnownKeepOrDropDim KeepDim where+  keepOrDropDimVal = True++instance KnownKeepOrDropDim DropDim where+  keepOrDropDimVal = False++type family ConditionalDropDimension (shape :: [Nat]) (dim :: Nat) (keepOrDropDim :: KeepOrDropDim) :: [Nat] where+  ConditionalDropDimension '[] _ _ = TypeError (Text "The specified dimension is not available.")+  ConditionalDropDimension (x : xs) 0 KeepDim = 1 ': xs+  ConditionalDropDimension (x : xs) 0 DropDim = xs+  ConditionalDropDimension (x : xs) i keepOrDropDim = x ': ConditionalDropDimension xs (i - 1) keepOrDropDim++-- | allDim+-- See https://pytorch.org/docs/stable/tensors.html#torch.BoolTensor.all.+--+-- >>> t = fromJust [[True, True], [True, False], [True, True], [True, True]] :: CPUTensor 'D.Bool '[4, 2]+--+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [Bool]) $ allDim @1 @DropDim t+-- (Bool,([4],[True,False,True,True]))+--+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [[Bool]]) $ allDim @1 @KeepDim t+-- (Bool,([4,1],[[True],[False],[True],[True]]))+--+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [Bool]) $ allDim @0 @DropDim t+-- (Bool,([2],[True,False]))+--+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [[Bool]]) $ allDim @0 @KeepDim t+-- (Bool,([1,2],[[True,False]]))+allDim ::+  forall dim keepOrDropDim shape' shape device.+  ( KnownNat dim,+    KnownKeepOrDropDim keepOrDropDim,+    shape' ~ ConditionalDropDimension shape dim keepOrDropDim+  ) =>+  -- | input+  Tensor device 'D.Bool shape ->+  -- | output+  Tensor device 'D.Bool shape'+allDim input =+  unsafePerformIO $+    ATen.cast3 ATen.Managed.all_tlb input (natValI @dim) (keepOrDropDimVal @keepOrDropDim)++-- | anyDim+-- See https://pytorch.org/docs/stable/tensors.html#torch.BoolTensor.any.+--+-- >>> t = fromJust [[True, True], [True, False], [True, True], [True, True]] :: CPUTensor 'D.Bool '[4, 2]+--+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [Bool]) $ anyDim @1 @DropDim t+-- (Bool,([4],[True,True,True,True]))+--+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [[Bool]]) $ anyDim @1 @KeepDim t+-- (Bool,([4,1],[[True],[True],[True],[True]]))+--+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [Bool]) $ anyDim @0 @DropDim t+-- (Bool,([2],[True,True]))+--+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [[Bool]]) $ anyDim @0 @KeepDim t+-- (Bool,([1,2],[[True,True]]))+anyDim ::+  forall dim keepOrDropDim shape' shape device.+  ( KnownNat dim,+    KnownKeepOrDropDim keepOrDropDim,+    shape' ~ ConditionalDropDimension shape dim keepOrDropDim+  ) =>+  -- | input+  Tensor device 'D.Bool shape ->+  -- | output+  Tensor device 'D.Bool shape'+anyDim input = unsafePerformIO $ ATen.cast3 ATen.Managed.any_tlb input (natValI @dim) (keepOrDropDimVal @keepOrDropDim)++-- | dropout+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+-- TODO: get rid of IO by exposing the RNG state+-- TODO: can we use D.Scalar for the dropout probability?+--+-- >>> t = ones :: CPUTensor 'D.Float '[3,2]+-- >>> t' <- dropout 0.5 False t+-- >>> dtype &&& shape $ t'+-- (Float,[3,2])+-- >>> t'' <- dropout 0.5 False t+-- >>> t ==. t''+-- Tensor Bool [3,2] [[ 1,  1],+--                    [ 1,  1],+--                    [ 1,  1]]+-- >>> t''' <- dropout 0.0 True t+-- >>> t ==. t'''+-- Tensor Bool [3,2] [[ 1,  1],+--                    [ 1,  1],+--                    [ 1,  1]]+-- >>> t'''' <- dropout 1.0 True t+-- >>> t''''+-- Tensor Float [3,2] [[ 0.0000,  0.0000],+--                     [ 0.0000,  0.0000],+--                     [ 0.0000,  0.0000]]+dropout ::+  forall shape dtype device.+  -- | dropout probability+  Double ->+  -- | whether or not to activate dropout+  Bool ->+  -- | input+  Tensor device dtype shape ->+  -- | output+  IO (Tensor device dtype shape)+dropout p train input = ATen.cast3 ATen.Managed.dropout_tdb input p train++-- | featureDropout+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+-- TODO: why not IO?+-- TODO: can we use D.Scalar for the dropout probability?+--+-- >>> c = featureDropout 0.1 True (ones :: CPUTensor 'D.Float '[2,2])+-- >>> dtype &&& shape $ c+-- (Float,[2,2])+featureDropout ::+  forall shape dtype device.+  -- | dropout probability+  Double ->+  -- | whether or not to activate dropout+  Bool ->+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+featureDropout p train input =+  unsafePerformIO $ ATen.cast3 ATen.Managed.feature_dropout_tdb input p train++-- | alphaDropout+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+-- TODO: why not IO?+-- TODO: can we use D.Scalar for the dropout probability?+--+-- >>> c = alphaDropout 0.1 True (ones :: CPUTensor 'D.Float '[2,2])+-- >>> dtype &&& shape $ c+-- (Float,[2,2])+alphaDropout ::+  forall shape dtype device.+  -- | dropout probability+  Double ->+  -- | whether or not to activate dropout+  Bool ->+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+alphaDropout p train input =+  unsafePerformIO $ ATen.cast3 ATen.Managed.alpha_dropout_tdb input p train++-- | featureAlphaDropout+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+-- TODO: why not IO?+-- TODO: can we use D.Scalar for the dropout probability?+--+-- >>> c = featureAlphaDropout 0.1 True (ones :: CPUTensor 'D.Float '[2,2])+-- >>> dtype &&& shape $ c+-- (Float,[2,2])+featureAlphaDropout ::+  forall shape dtype device.+  -- | dropout probability+  Double ->+  -- | whether or not to activate dropout+  Bool ->+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+featureAlphaDropout p train input =+  unsafePerformIO $ ATen.cast3 ATen.Managed.feature_alpha_dropout_tdb input p train++-- | acos+--+-- >>> dtype &&& shape $ acos (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+acos ::+  forall shape dtype device.+  (StandardFloatingPointDTypeValidation device dtype) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+acos input = unsafePerformIO $ ATen.cast1 ATen.Managed.acos_t input++-- | avgPool1d+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> t = avgPool1d @1 @1 @0 (ones :: CPUTensor 'D.Float '[1,3,4])+-- >>> shape t+-- [1,3,4]+-- >>> :t t+-- t :: Tensor '(D.CPU, 0) 'D.Float [1, 3, 4]+avgPool1d ::+  forall+    kernelSize+    stride+    padding+    channelSize+    inputSize+    batchSize+    outputSize+    dtype+    device.+  ( All KnownNat '[kernelSize, stride, padding, channelSize, inputSize, batchSize],+    ConvSideCheck inputSize kernelSize stride padding outputSize+  ) =>+  -- | input+  Tensor device dtype '[batchSize, channelSize, inputSize] ->+  -- | output+  Tensor device dtype '[batchSize, channelSize, outputSize]+avgPool1d input =+  unsafePerformIO $+    ATen.cast6+      ATen.Managed.avg_pool1d_tlllbb+      input+      (natValI @kernelSize)+      (natValI @stride)+      (natValI @padding)+      False+      True++-- | adaptiveAvgPool1d+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> t = adaptiveAvgPool1d @8 (ones :: CPUTensor 'D.Float '[1,3,16])+-- >>> shape t+-- [1,3,8]+-- >>> :t t+-- t :: Tensor '(D.CPU, 0) 'D.Float [1, 3, 8]+adaptiveAvgPool1d ::+  forall outputSize channelSize inputSize batchSize dtype device.+  (All KnownNat '[channelSize, inputSize, batchSize, outputSize]) =>+  -- | input+  Tensor device dtype '[batchSize, channelSize, inputSize] ->+  -- | output+  Tensor device dtype '[batchSize, channelSize, outputSize]+adaptiveAvgPool1d input =+  unsafePerformIO $+    ATen.cast2 ATen.Managed.adaptive_avg_pool1d_tl input (natValI @outputSize)++-- | adaptiveMaxPool1d+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> tt = adaptiveMaxPool1d @8 (ones :: CPUTensor 'D.Float '[1,3,16])+-- >>> shape . fst $ tt+-- [1,3,8]+-- >>> :t tt+-- tt+--   :: (Tensor '(D.CPU, 0) 'D.Float [1, 3, 8],+--       Tensor '(D.CPU, 0) D.Int64 [1, 3, 8])+adaptiveMaxPool1d ::+  forall outputSize channelSize inputSize batchSize dtype device.+  (All KnownNat '[channelSize, inputSize, batchSize, outputSize]) =>+  -- | input+  Tensor device dtype '[batchSize, channelSize, inputSize] ->+  -- | output+  ( Tensor device dtype '[batchSize, channelSize, outputSize],+    Tensor device 'D.Int64 '[batchSize, channelSize, outputSize]+  )+adaptiveMaxPool1d input =+  unsafePerformIO $+    ATen.cast2 ATen.Managed.adaptive_max_pool1d_tl input (natValI @outputSize)++-- | addmv+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+-- TODO: can we use D.Scalar for beta and alpha?+--+-- >>> t = addmv 1 1 (ones :: CPUTensor 'D.Float '[3,2]) (zeros :: CPUTensor 'D.Float '[2]) (ones :: CPUTensor 'D.Float '[])+-- >>> dtype &&& shape $ t+-- (Float,[3])+-- >>> :t t+-- t :: Tensor '(D.CPU, 0) 'D.Float '[3]+addmv ::+  forall shape' shape n m dtype device.+  ( KnownNat n,+    KnownNat m,+    shape' ~ Broadcast shape '[n]+  ) =>+  -- | beta+  Float ->+  -- | alpha+  Float ->+  -- | matrix+  Tensor device dtype '[n, m] ->+  -- | vector+  Tensor device dtype '[m] ->+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape'+addmv beta alpha mat vec input = unsafePerformIO $ ATen.cast5 ATen.Managed.addmv_tttss input mat vec beta alpha++-- affine_grid_generator :: Tensor device dtype shape -> [Int] -> Tensor device dtype shape+-- affine_grid_generator _theta _size = unsafePerformIO $ (ATen.cast2 ATen.Managed.affine_grid_generator_tl) _theta _size++-- | allclose+--+-- >>> allclose 0.1 0.1 True (ones :: CPUTensor 'D.Float '[3,3]) (ones :: CPUTensor 'D.Float '[3,3])+-- True+allclose ::+  forall shape dtype device.+  -- | relative tolerance+  Double ->+  -- | absolute tolerance+  Double ->+  -- | whether or not NaN equals NaN+  Bool ->+  -- | input tensor+  Tensor device dtype shape ->+  -- | other input tensor+  Tensor device dtype shape ->+  -- | output+  Bool+allclose rtol atol equalNaN input other =+  unsafePerformIO $ ATen.cast5 ATen.Managed.allclose_ttddb input other rtol atol equalNaN++-- | argmax+-- See https://pytorch.org/docs/stable/torch.html#torch.argmax.+--+-- >>> t = fromJust [[0, 1], [-1, 2], [0, 1], [0, -2]] :: CPUTensor 'D.Float '[4, 2]+--+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [Int]) $ argmax @1 @DropDim t+-- (Int64,([4],[1,1,1,0]))+--+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [[Int]]) $ argmax @1 @KeepDim t+-- (Int64,([4,1],[[1],[1],[1],[0]]))+--+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [Int]) $ argmax @0 @DropDim t+-- (Int64,([2],[0,1]))+--+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [[Int]]) $ argmax @0 @KeepDim t+-- (Int64,([1,2],[[0,1]]))+argmax ::+  forall dim keepOrDropDim shape' shape dtype device.+  ( KnownNat dim,+    KnownKeepOrDropDim keepOrDropDim,+    shape' ~ ConditionalDropDimension shape dim keepOrDropDim,+    StandardDTypeValidation device dtype+  ) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device 'D.Int64 shape'+argmax input =+  unsafePerformIO $+    ATen.cast3+      ATen.Managed.argmax_tlb+      input+      (natValI @dim)+      (keepOrDropDimVal @keepOrDropDim)++-- | argmin+-- See https://pytorch.org/docs/stable/torch.html#torch.argmin.+--+-- >>> t = fromJust [[0, 1], [-1, 2], [0, 1], [0, -2]] :: CPUTensor 'D.Float '[4, 2]+--+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [Int]) $ argmin @1 @DropDim t+-- (Int64,([4],[0,0,0,1]))+--+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [[Int]]) $ argmin @1 @KeepDim t+-- (Int64,([4,1],[[0],[0],[0],[1]]))+--+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [Int]) $ argmin @0 @DropDim t+-- (Int64,([2],[1,3]))+--+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [[Int]]) $ argmin @0 @KeepDim t+-- (Int64,([1,2],[[1,3]]))+argmin ::+  forall dim keepOrDropDim shape' shape dtype device.+  ( KnownNat dim,+    KnownKeepOrDropDim keepOrDropDim,+    shape' ~ ConditionalDropDimension shape dim keepOrDropDim,+    StandardDTypeValidation device dtype+  ) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device 'D.Int64 shape'+argmin input =+  unsafePerformIO $+    ATen.cast3+      ATen.Managed.argmin_tlb+      input+      (natValI @dim)+      (keepOrDropDimVal @keepOrDropDim)++-- as_strided :: Tensor device dtype shape -> [Int] -> [Int] -> Int -> Tensor device dtype shape+-- as_strided _input _size _stride _storage_offset = unsafePerformIO $ (ATen.cast4 ATen.Managed.as_strided_tlll) _input _size _stride _storage_offset++-- | asin+--+-- >>> dtype &&& shape $ asin (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+asin ::+  forall shape dtype device.+  (StandardFloatingPointDTypeValidation device dtype) =>+  Tensor device dtype shape ->+  Tensor device dtype shape+asin input = unsafePerformIO $ ATen.cast1 ATen.Managed.asin_t input++-- | atan+--+-- >>> dtype &&& shape $ atan (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+atan ::+  forall shape dtype device.+  (StandardFloatingPointDTypeValidation device dtype) =>+  Tensor device dtype shape ->+  Tensor device dtype shape+atan input = unsafePerformIO $ ATen.cast1 ATen.Managed.atan_t input++-- | baddbmm+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> t = baddbmm 1 1 (ones :: CPUTensor 'D.Float '[5,3,2]) (zeros :: CPUTensor 'D.Float '[5,2,4]) (ones :: CPUTensor 'D.Float '[])+-- >>> dtype &&& shape $ t+-- (Float,[5,3,4])+-- >>> :t t+-- t :: Tensor '(D.CPU, 0) 'D.Float [5, 3, 4]+baddbmm ::+  forall shape' shape batchSize n m k dtype device.+  ( KnownNat n,+    KnownNat m,+    KnownNat k,+    shape' ~ Broadcast shape '[batchSize, n, m]+  ) =>+  -- | beta+  Float ->+  -- | alpha+  Float ->+  -- | first batch+  Tensor device dtype '[batchSize, n, k] ->+  -- | second batch+  Tensor device dtype '[batchSize, k, m] ->+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape'+baddbmm beta alpha batch1 batch2 input = unsafePerformIO $ ATen.cast5 ATen.Managed.baddbmm_tttss input batch1 batch2 beta alpha++-- batch_norm :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Bool -> Double -> Double -> Bool -> Tensor device dtype shape+-- batch_norm _input _weight _bias _running_mean _running_var _training _momentum _eps _cudnn_enabled = unsafePerformIO $ (ATen.cast9 ATen.Managed.batch_norm_tttttbddb) _input _weight _bias _running_mean _running_var _training _momentum _eps _cudnn_enabled++-- bilinear :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape+-- bilinear _input1 _input2 _weight _bias = unsafePerformIO $ (ATen.cast4 ATen.Managed.bilinear_tttt) _input1 _input2 _weight _bias++-- binary_cross_entropy_with_logits :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Int -> Tensor device dtype shape+-- binary_cross_entropy_with_logits _input _target _weight _pos_weight _reduction = unsafePerformIO $ (ATen.cast5 ATen.Managed.binary_cross_entropy_with_logits_ttttl) _input _target _weight _pos_weight _reduction++-- bincount :: Tensor device dtype shape -> Tensor device dtype shape -> Int -> Tensor device dtype shape+-- bincount _input _weights _minlength = unsafePerformIO $ (ATen.cast3 ATen.Managed.bincount_ttl) _input _weights _minlength++-- | batched matrix multiplication+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> dtype &&& shape $ bmm (ones :: CPUTensor 'D.Float '[5,3,2]) (zeros :: CPUTensor 'D.Float '[5,2,4])+-- (Float,[5,3,4])+bmm ::+  forall batchSize n m k dtype device.+  -- | input+  Tensor device dtype '[batchSize, n, k] ->+  -- | other input+  Tensor device dtype '[batchSize, k, m] ->+  -- | output+  Tensor device dtype '[batchSize, n, m]+bmm input other = unsafePerformIO $ ATen.cast2 ATen.Managed.bmm_tt input other++-- | BroadcastTensorsImpl+--+-- >>> type Ty = BroadcastTensorsImpl '[] 'Nothing+-- >>> :kind! Ty+-- Ty :: Maybe ([Natural], D.DType, (D.DeviceType, Natural))+-- = Nothing+-- >>> type Ty = BroadcastTensorsImpl '[Tensor '(D.CPU, 0) 'D.Float '[1, 3], Tensor '(D.CPU, 0) 'D.Float '[2, 1]] Nothing+-- >>> :kind! Ty+-- Ty :: Maybe ([Natural], D.DType, (D.DeviceType, Natural))+-- = Just '([2, 3], 'D.Float, '(D.CPU, 0))+-- >>> type Ty = BroadcastTensorsImpl '[Tensor '(D.CPU, 0) 'D.Float '[1, 3], Tensor '(D.CPU, 0) 'D.Float '[2, 1], Tensor '(D.CPU, 0) 'D.Float '[5, 1, 1]] 'Nothing+-- >>> :kind! Ty+-- Ty :: Maybe ([Natural], D.DType, (D.DeviceType, Natural))+-- = Just '([5, 2, 3], 'D.Float, '(D.CPU, 0))+-- >>> type Ty = BroadcastTensorsImpl '[Tensor '(D.CPU, 0) 'D.Float '[1, 3], Tensor '(D.CPU, 0) 'D.Float '[2, 1], Tensor '(D.CPU, 0) 'D.Float '[1, 5, 1]] 'Nothing+-- >>> :kind! Ty+-- Ty :: Maybe ([Natural], D.DType, (D.DeviceType, Natural))+-- = Nothing+type family BroadcastTensorsImpl (tensors :: [a]) (acc :: Maybe ([Nat], D.DType, (D.DeviceType, Nat))) :: Maybe ([Nat], D.DType, (D.DeviceType, Nat)) where+  BroadcastTensorsImpl '[] 'Nothing = 'Nothing+  BroadcastTensorsImpl '[] ('Just '(reverseShape, dtype, device)) = 'Just '(Reverse reverseShape, dtype, device)+  BroadcastTensorsImpl (Tensor device dtype shape ': tensors) 'Nothing = BroadcastTensorsImpl tensors ('Just '(Reverse shape, dtype, device))+  BroadcastTensorsImpl (Tensor device dtype shape ': tensors) ('Just '(reverseShape', dtype, device)) = BroadcastTensorsImpl tensors (MaybeTriple (ComputeBroadcast (Reverse shape) reverseShape') ('Just dtype) ('Just device))+  BroadcastTensorsImpl (Tensor device dtype shape ': _) ('Just _) = Nothing++type family BroadcastTensorsCheck (tensors :: [a]) (result :: Maybe ([Nat], D.DType, (D.DeviceType, Nat))) :: [a] where+  BroadcastTensorsCheck tensors 'Nothing =+    TypeError+      ( Text "Cannot broadcast tensors due to incompatible shapes and/or dtypes: "+          :<>: ShowType tensors+      )+  BroadcastTensorsCheck tensors ('Just '(shape, dtype, device)) = HReplicateR (ListLength tensors) (Tensor device dtype shape)++type BroadcastTensors tensors =+  BroadcastTensorsCheck tensors (BroadcastTensorsImpl tensors 'Nothing)++-- | broadcast tensors+-- TODO: broadcastTensors returns garbage data and is hence broken+-- See https://pytorch.org/docs/stable/_modules/torch/functional.html#broadcast_tensors.+--+-- >>> x = ones :: CPUTensor 'D.Float '[1, 3]+-- >>> y = ones :: CPUTensor 'D.Float '[2, 1]+-- >>> z = ones :: CPUTensor 'D.Float '[5, 1, 1]+--+-- -- >>> x' :. y' :. z' :. HNil = broadcastTensors (x :. y :. z :. HNil)+-- -- >>> :type x'+-- -- x' :: Tensor '(D.CPU, 0) 'D.Float '[5, 2, 3]+-- -- >>> dtype &&& shape &&& (\t -> D.asValue (toDynamic t) :: [[[Float]]]) $ x'+-- -- >>> :type y'+-- -- y' :: Tensor '(D.CPU, 0) 'D.Float '[5, 2, 3]+-- -- >>> dtype &&& shape &&& (\t -> D.asValue (toDynamic t) :: [[[Float]]]) $ y'+-- -- >>> :type z'+-- -- z' :: Tensor '(D.CPU, 0) 'D.Float '[5, 2, 3]+-- -- >>> dtype &&& shape &&& (\t -> D.asValue (toDynamic t) :: [[[Float]]]) $ z'+broadcastTensors ::+  forall tensors tensors'.+  ( tensors' ~ BroadcastTensors tensors,+    ATen.Castable (HList tensors) [D.ATenTensor],+    ATen.Castable (HList tensors') [D.ATenTensor]+  ) =>+  -- | input list of tensors+  HList tensors ->+  -- | output list of tensors+  HList tensors'+broadcastTensors tensors = unsafePerformIO $ ATen.cast1 ATen.Managed.broadcast_tensors_l tensors++type family CatImpl (dim :: Nat) (tensors :: [a]) (acc :: Maybe ([Nat], D.DType, (D.DeviceType, Nat))) :: Maybe ([Nat], D.DType, (D.DeviceType, Nat)) where+  CatImpl _ '[] acc = acc+  CatImpl dim (Tensor device dtype shape ': tensors) acc = CatImpl dim tensors (MaybeTriple (ComputeCatShape dim shape acc) (ComputeCatDType dtype acc) (ComputeCatDevice device acc))++type family ComputeCatShape (dim :: Nat) (shape :: [Nat]) (acc :: Maybe ([Nat], D.DType, (D.DeviceType, Nat))) :: Maybe [Nat] where+  ComputeCatShape 0 (x ': xs) Nothing = Just (x ': xs)+  ComputeCatShape dim (x ': xs) Nothing = AppendToMaybe x (ComputeCatShape (dim - 1) xs Nothing)+  ComputeCatShape 0 (x ': xs) (Just '(y ': xs, _, _)) = Just ((x + y) ': xs)+  ComputeCatShape dim (x ': xs) (Just '(x ': ys, dtype, device)) = AppendToMaybe x (ComputeCatShape (dim - 1) xs (Just '(ys, dtype, device)))+  ComputeCatShape _ _ _ = Nothing++type family ComputeCatDType (dtype :: D.DType) (acc :: Maybe ([Nat], D.DType, (D.DeviceType, Nat))) :: Maybe D.DType where+  ComputeCatDType dtype Nothing = Just dtype+  ComputeCatDType dtype (Just '(_, dtype, _)) = Just dtype+  ComputeCatDType _ _ = Nothing++type family ComputeCatDevice (device :: (D.DeviceType, Nat)) (acc :: Maybe ([Nat], D.DType, (D.DeviceType, Nat))) :: Maybe (D.DeviceType, Nat) where+  ComputeCatDevice device Nothing = Just device+  ComputeCatDevice device (Just '(_, _, device)) = Just device+  ComputeCatDevice _ _ = Nothing++type family CatCheck (res :: Maybe ([Nat], D.DType, (D.DeviceType, Nat))) :: ([Nat], D.DType, (D.DeviceType, Nat)) where+  CatCheck 'Nothing = TypeError (Text "Concatenation impossible.")+  CatCheck ('Just '(shape, dtype, device)) = '(shape, dtype, device)++-- | Cat+--+-- >>> type Ty = Cat 0 '[Tensor '(D.CPU, 0) 'D.Float '[1]]+-- >>> :kind! Ty+-- Ty :: ([Natural], D.DType, (D.DeviceType, Natural))+-- = '( '[1], 'D.Float, '(D.CPU, 0))+-- >>> type Ty = Cat 0 '[Tensor '(D.CPU, 0) 'D.Float '[1], Tensor '(D.CPU, 0) 'D.Float '[2]]+-- >>> :kind! Ty+-- Ty :: ([Natural], D.DType, (D.DeviceType, Natural))+-- = '( '[3], 'D.Float, '(D.CPU, 0))+-- >>> type Ty = Cat 0 '[Tensor '(D.CPU, 0) 'D.Float '[1, 3], Tensor '(D.CPU, 0) 'D.Float '[2, 3]]+-- >>> :kind! Ty+-- Ty :: ([Natural], D.DType, (D.DeviceType, Natural))+-- = '([3, 3], 'D.Float, '(D.CPU, 0))+-- >>> type Ty = Cat 1 '[Tensor '(D.CPU, 0) 'D.Float '[3, 1], Tensor '(D.CPU, 0) 'D.Float '[3, 2]]+-- >>> :kind! Ty+-- Ty :: ([Natural], D.DType, (D.DeviceType, Natural))+-- = '([3, 3], 'D.Float, '(D.CPU, 0))+-- >>> type Ty = Cat 1 '[Tensor '(D.CPU, 0) 'D.Float '[2, 5, 4, 2], Tensor '(D.CPU, 0) 'D.Float '[2, 1, 4, 2], Tensor '(D.CPU, 0) 'D.Float '[2, 3, 4, 2], Tensor '(D.CPU, 0) 'D.Float '[2, 1, 4, 2]]+-- >>> :kind! Ty+-- Ty :: ([Natural], D.DType, (D.DeviceType, Natural))+-- = '([2, 10, 4, 2], 'D.Float, '(D.CPU, 0))+type Cat dim tensors = CatCheck (CatImpl dim tensors Nothing)++-- | cat+--+-- >>> t = ones :: CPUTensor 'D.Float '[2,2]+-- >>> t' = cat @0 (t :. HNil)+-- >>> :type t'+-- t' :: Tensor '(D.CPU, 0) 'D.Float [2, 2]+-- >>> dtype &&& shape &&& (\t'' -> D.asValue (toDynamic t'') :: [[Float]]) $ t'+-- (Float,([2,2],[[1.0,1.0],[1.0,1.0]]))+-- >>> t' = cat @1 (t :. HNil)+-- >>> :type t'+-- t' :: Tensor '(D.CPU, 0) 'D.Float [2, 2]+-- >>> dtype &&& shape &&& (\t'' -> D.asValue (toDynamic t'') :: [[Float]]) $ t'+-- (Float,([2,2],[[1.0,1.0],[1.0,1.0]]))+-- >>> t' = cat @0 (t :. t :. t :. HNil)+-- >>> :type t'+-- t' :: Tensor '(D.CPU, 0) 'D.Float [6, 2]+-- >>> dtype &&& shape &&& (\t'' -> D.asValue (toDynamic t'') :: [[Float]]) $ t'+-- (Float,([6,2],[[1.0,1.0],[1.0,1.0],[1.0,1.0],[1.0,1.0],[1.0,1.0],[1.0,1.0]]))+-- >>> t' = cat @1 (t :. t :. t :. HNil)+-- >>> :type t'+-- t' :: Tensor '(D.CPU, 0) 'D.Float [2, 6]+-- >>> dtype &&& shape &&& (\t'' -> D.asValue (toDynamic t'') :: [[Float]]) $ t'+-- (Float,([2,6],[[1.0,1.0,1.0,1.0,1.0,1.0],[1.0,1.0,1.0,1.0,1.0,1.0]]))+cat ::+  forall dim shape dtype device tensors.+  ( KnownNat dim,+    '(shape, dtype, device) ~ Cat dim tensors,+    ATen.Castable (HList tensors) [D.ATenTensor]+  ) =>+  -- | input list of tensors+  HList tensors ->+  -- | output tensor+  Tensor device dtype shape+cat tensors = unsafePerformIO $ ATen.cast2 ATen.Managed.cat_ll tensors (natValI @dim :: Int)++-- chain_matmul :: [Tensor device dtype shape] -> Tensor device dtype shape+-- chain_matmul _matrices = unsafePerformIO $ (ATen.cast1 ATen.Managed.chain_matmul_l) _matrices++type family ChunkImpl (chunkShapes :: Maybe [[Nat]]) (dtype :: D.DType) (device :: (D.DeviceType, Nat)) :: Maybe a where+  ChunkImpl (Just '[]) _ _ = Just '[]+  ChunkImpl (Just (shape ': shapes)) dtype device = AppendToMaybe (Tensor device dtype shape) (ChunkImpl (Just shapes) dtype device)+  ChunkImpl Nothing _ _ = Nothing++type family ChunkCheck (shape :: [Nat]) (dim :: Nat) (result :: Maybe a) :: a where+  ChunkCheck shape dim Nothing = DimOutOfBound shape dim+  ChunkCheck _ _ (Just result) = result++type family ComputeChunksChunkGo (n' :: Nat) (r :: Nat) (cmp :: Ordering) (cmp' :: Ordering) :: [Nat] where+  ComputeChunksChunkGo n' r GT _ = n' ': ComputeChunksChunkGo n' (r - n') (CmpNat (r - n') n') (CmpNat (r - n') 0)+  ComputeChunksChunkGo n' r EQ _ = n' ': ComputeChunksChunkGo n' (r - n') (CmpNat (r - n') n') (CmpNat (r - n') 0)+  ComputeChunksChunkGo n' r _ GT = '[r]+  ComputeChunksChunkGo n' _ _ _ = '[]++type family ComputeChunksChunkGo0 (n' :: Nat) (chunks :: Nat) :: [Nat] where+  ComputeChunksChunkGo0 _ 0 = '[]+  ComputeChunksChunkGo0 n' chunks = n' ': (ComputeChunksChunkGo0 n' (chunks - 1))++type family ComputeChunks (n :: Maybe Nat) (chunks :: Nat) :: Maybe [Nat] where+  ComputeChunks (Just n) chunks = Just (ComputeChunks' n chunks (Mod n chunks))+  ComputeChunks Nothing _ = Nothing++type family ComputeChunks' (n :: Nat) (chunks :: Nat) (m :: Nat) :: [Nat] where+  ComputeChunks' n chunks 0 = ComputeChunksChunkGo0 (Div n chunks) chunks+  ComputeChunks' n chunks _ = ComputeChunksChunkGo (Div (n + chunks - 1) chunks) n (CmpNat n (Div (n + chunks - 1) chunks)) (CmpNat n 0)++type family ChunkShapesImpl (chunks :: Maybe [Nat]) (dim :: Nat) (shape :: [Nat]) :: Maybe [[Nat]] where+  ChunkShapesImpl (Just (n ': ns)) dim shape = AppendToMaybe' (ReplaceDim dim shape n) (ChunkShapesImpl (Just ns) dim shape)+  ChunkShapesImpl (Just '[]) _ _ = Just '[]+  ChunkShapesImpl Nothing _ _ = Nothing++type ChunkShapes chunks dim shape = ChunkShapesImpl (ComputeChunks (ExtractDim dim shape) chunks) dim shape++type Chunk chunks dim shape dtype device = ChunkCheck shape dim (ChunkImpl (ChunkShapes chunks dim shape) dtype device)++-- | chunk+--+-- -- >>> :type chunk @3 @1 (ones :: CPUTensor 'D.Float '[2, 2])+-- -- chunk @3 @1 (ones :: CPUTensor 'D.Float '[2, 2])+-- --   :: HList+-- --        '[Tensor '(D.CPU, 0) 'D.Float '[2, 1],+-- --          Tensor '(D.CPU, 0) 'D.Float '[2, 1]]+-- >>> t0 :. t1 :. HNil = chunk @3 @1 (ones :: CPUTensor 'D.Float '[2, 2])+-- >>> dtype &&& shape $ t0+-- (Float,[2,1])+-- >>> dtype &&& shape $ t1+-- (Float,[2,1])+--+-- -- >>> :type chunk @3 @1 (ones :: CPUTensor 'D.Float '[1, 0, 3])+-- -- chunk @3 @1 (ones :: CPUTensor 'D.Float '[1, 0, 3])+-- --   :: HList+-- --        '[Tensor '(D.CPU, 0) 'D.Float '[1, 0, 3],+-- --          Tensor '(D.CPU, 0) 'D.Float '[1, 0, 3],+-- --          Tensor '(D.CPU, 0) 'D.Float '[1, 0, 3]]+-- >>> t0 :. t1 :. t2 :. HNil = chunk @3 @1 (ones :: CPUTensor 'D.Float '[1, 0, 3])+-- >>> dtype &&& shape $ t0+-- (Float,[1,0,3])+-- >>> dtype &&& shape $ t1+-- (Float,[1,0,3])+-- >>> dtype &&& shape $ t2+-- (Float,[1,0,3])+--+-- -- >>> :type chunk @6 @0 (ones :: CPUTensor 'D.Float '[19, 4])+-- -- chunk @6 @0 (ones :: CPUTensor 'D.Float '[19, 4])+-- --   :: HList+-- --        '[Tensor '(D.CPU, 0) 'D.Float '[4, 4],+-- --          Tensor '(D.CPU, 0) 'D.Float '[4, 4],+-- --          Tensor '(D.CPU, 0) 'D.Float '[4, 4],+-- --          Tensor '(D.CPU, 0) 'D.Float '[4, 4],+-- --          Tensor '(D.CPU, 0) 'D.Float '[3, 4]]+-- >>> t0 :. t1 :. t2 :. t3 :. t4 :. HNil = chunk @6 @0 (ones :: CPUTensor 'D.Float '[19, 4])+-- >>> dtype &&& shape $ t0+-- (Float,[4,4])+-- >>> dtype &&& shape $ t1+-- (Float,[4,4])+-- >>> dtype &&& shape $ t2+-- (Float,[4,4])+-- >>> dtype &&& shape $ t3+-- (Float,[4,4])+-- >>> dtype &&& shape $ t4+-- (Float,[3,4])+chunk ::+  forall chunks dim shape dtype device tensorChunks.+  ( KnownNat chunks,+    KnownNat dim,+    tensorChunks ~ Chunk chunks dim shape dtype device,+    ATen.Castable (HList tensorChunks) [D.ATenTensor]+  ) =>+  -- | input tensor+  Tensor device dtype shape ->+  -- | output list of tensors+  HList tensorChunks+chunk input =+  unsafePerformIO $+    ATen.cast3 ATen.Managed.chunk_tll input (natValI @chunks :: Int) (natValI @dim :: Int)++-- | clamp+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+-- TODO: can we use D.Scalar for the minimum and maximum values?+--+-- >>> dtype &&& shape $ clamp 0 1 (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+clamp ::+  forall shape dtype device a.+  (D.Scalar a) =>+  -- | minimum value+  a ->+  -- | maximum value+  a ->+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+clamp min max input = unsafePerformIO $ ATen.cast3 ATen.Managed.clamp_tss input min max++-- | clampMax+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+-- TODO: can we use D.Scalar for the maximum value?+--+-- >>> dtype &&& shape $ clampMax 1 (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+clampMax ::+  forall shape dtype device a.+  (D.Scalar a) =>+  -- | maximum value+  a ->+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+clampMax max input = unsafePerformIO $ ATen.cast2 ATen.Managed.clamp_max_ts input max++-- | clampMin+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+-- TODO: can we use D.Scalar for the minimum value?+--+-- >>> dtype &&& shape $ clampMin 0 (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+clampMin ::+  forall shape dtype device a.+  (D.Scalar a) =>+  -- | minimum value+  a ->+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+clampMin min input = unsafePerformIO $ ATen.cast2 ATen.Managed.clamp_min_ts input min++-- | cudnnIsAcceptable+-- TODO: calling this probably makes only sense when the device is CUDA+cudnnIsAcceptable ::+  forall shape dtype device.+  -- | input+  Tensor device dtype shape ->+  -- | output+  Bool+cudnnIsAcceptable input =+  unsafePerformIO $ ATen.cast1 ATen.Managed.cudnn_is_acceptable_t input++-- constant_pad_nd :: Tensor device dtype shape -> [Int] -> Float -> Tensor device dtype shape+-- constant_pad_nd _input _pad _value = unsafePerformIO $ (ATen.cast3 ATen.Managed.constant_pad_nd_tls) _input _pad _value++constantPadNd1d ::+  forall (pad :: (Nat, Nat)) n dtype device.+  (All KnownNat '[Torch.Typed.Auxiliary.Fst pad, Torch.Typed.Auxiliary.Snd pad, n]) =>+  Float ->+  Tensor device dtype '[n] ->+  Tensor device dtype '[n + Torch.Typed.Auxiliary.Fst pad + Torch.Typed.Auxiliary.Snd pad]+constantPadNd1d value input =+  unsafePerformIO $+    ATen.cast3+      ATen.Managed.constant_pad_nd_tls+      input+      ([natValI @(Torch.Typed.Auxiliary.Fst pad), natValI @(Torch.Typed.Auxiliary.Snd pad)] :: [Int])+      value++-- convolution :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> [Int] -> [Int] -> [Int] -> Bool -> [Int] -> Int -> Tensor device dtype shape+-- convolution _input _weight _bias _stride _padding _dilation _transposed _output_padding _groups = unsafePerformIO $ (ATen.cast9 ATen.Managed.convolution_tttlllbll) _input _weight _bias _stride _padding _dilation _transposed _output_padding _groups++type ConvSideCheck (inputSize :: Nat) (kernelSize :: Nat) (stride :: Nat) (padding :: Nat) (outputSize :: Nat) =+  ( -- kernel size and stride must be > 0+    1 <= kernelSize,+    1 <= stride,+    -- kernel size can't be greater than actual input size+    -- ToDo: Do not use '>=' on constraint to avoid reduction-stack-overflow.+    (kernelSize - 1) <= (inputSize + (2 * padding)),+    -- output size must be greater than 0+    1 <= outputSize,+    -- output formulation:+    outputSize ~ ConvOutputSize inputSize kernelSize stride padding+  )++-- | ConvOutputSize+--+-- >>> :kind! ConvOutputSize 4 1 1 0+-- ConvOutputSize 4 1 1 0 :: Natural+-- = 4+type family ConvOutputSize (inputSize :: Nat) (kernelSize :: Nat) (stride :: Nat) (padding :: Nat) :: Nat where+  ConvOutputSize inputSize kernelSize stride padding = (Div ((inputSize + (2 * padding)) - kernelSize) stride) + 1++-- | conv1d+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> t = conv1d @1 @0 (ones :: CPUTensor 'D.Float '[10, 3, 1]) (ones :: CPUTensor 'D.Float '[10]) (ones :: CPUTensor 'D.Float '[1, 3, 4])+-- >>> :type t+-- t :: Tensor '(D.CPU, 0) 'D.Float [1, 10, 4]+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [[[Float]]]) $ t+-- (Float,([1,10,4],[[[4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0]]]))+conv1d ::+  forall+    (stride :: Nat)+    (padding :: Nat)+    inputChannelSize+    outputChannelSize+    kernelSize+    inputSize+    batchSize+    outputSize+    dtype+    device.+  ( All+      KnownNat+      '[ stride,+         padding,+         inputChannelSize,+         outputChannelSize,+         kernelSize,+         inputSize,+         batchSize,+         outputSize+       ],+    ConvSideCheck inputSize kernelSize stride padding outputSize+  ) =>+  -- | weight+  Tensor device dtype '[outputChannelSize, inputChannelSize, kernelSize] ->+  -- | bias+  Tensor device dtype '[outputChannelSize] ->+  -- | input+  Tensor device dtype '[batchSize, inputChannelSize, inputSize] ->+  -- | output+  Tensor device dtype '[batchSize, outputChannelSize, outputSize]+conv1d weight bias input =+  unsafePerformIO $+    ATen.cast7+      ATen.Managed.conv1d_tttllll+      input+      weight+      bias+      (natValI @stride :: Int)+      (natValI @padding :: Int)+      (1 :: Int)+      (1 :: Int)++-- | conv2d+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> t = conv2d @'(1, 1) @'(0, 0) (ones :: CPUTensor 'D.Float '[10, 3, 1, 1]) (ones :: CPUTensor 'D.Float '[10]) (ones :: CPUTensor 'D.Float '[1, 3, 4, 5])+-- >>> :type t+-- t :: Tensor '(D.CPU, 0) 'D.Float [1, 10, 4, 5]+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [[[[Float]]]]) $ t+-- (Float,([1,10,4,5],[[[[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0]]]]))+conv2d ::+  forall+    (stride :: (Nat, Nat))+    (padding :: (Nat, Nat))+    inputChannelSize+    outputChannelSize+    kernelSize0+    kernelSize1+    inputSize0+    inputSize1+    batchSize+    outputSize0+    outputSize1+    dtype+    device.+  ( All+      KnownNat+      '[ Torch.Typed.Auxiliary.Fst stride,+         Torch.Typed.Auxiliary.Snd stride,+         Torch.Typed.Auxiliary.Fst padding,+         Torch.Typed.Auxiliary.Snd padding,+         inputChannelSize,+         outputChannelSize,+         kernelSize0,+         kernelSize1,+         inputSize0,+         inputSize1,+         batchSize,+         outputSize0,+         outputSize1+       ],+    ConvSideCheck inputSize0 kernelSize0 (Torch.Typed.Auxiliary.Fst stride) (Torch.Typed.Auxiliary.Fst padding) outputSize0,+    ConvSideCheck inputSize1 kernelSize1 (Torch.Typed.Auxiliary.Snd stride) (Torch.Typed.Auxiliary.Snd padding) outputSize1+  ) =>+  -- | weight+  Tensor device dtype '[outputChannelSize, inputChannelSize, kernelSize0, kernelSize1] ->+  -- | bias+  Tensor device dtype '[outputChannelSize] ->+  -- | input+  Tensor device dtype '[batchSize, inputChannelSize, inputSize0, inputSize1] ->+  -- | output+  Tensor device dtype '[batchSize, outputChannelSize, outputSize0, outputSize1]+conv2d weight bias input =+  unsafePerformIO $+    ATen.cast7+      ATen.Managed.conv2d_tttllll+      input+      weight+      bias+      ([natValI @(Torch.Typed.Auxiliary.Fst stride), natValI @(Torch.Typed.Auxiliary.Snd stride)] :: [Int])+      ([natValI @(Torch.Typed.Auxiliary.Fst padding), natValI @(Torch.Typed.Auxiliary.Snd padding)] :: [Int])+      ([1, 1] :: [Int])+      (1 :: Int)++-- | conv3d+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> t = conv3d @'(1, 1, 1) @'(0, 0, 0) (ones :: CPUTensor 'D.Float '[10, 3, 1, 1, 1]) (ones :: CPUTensor 'D.Float '[10]) (ones :: CPUTensor 'D.Float '[1, 3, 4, 5, 6])+-- >>> :type t+-- t :: Tensor '(D.CPU, 0) 'D.Float [1, 10, 4, 5, 6]+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [[[[[Float]]]]]) $ t+-- (Float,([1,10,4,5,6],[[[[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]]],[[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]]],[[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]]],[[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]]],[[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]]],[[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]]],[[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]]],[[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]]],[[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]]],[[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]]]]]))+conv3d ::+  forall+    (stride :: (Nat, Nat, Nat))+    (padding :: (Nat, Nat, Nat))+    inputChannelSize+    outputChannelSize+    kernelSize0+    kernelSize1+    kernelSize2+    inputSize0+    inputSize1+    inputSize2+    batchSize+    outputSize0+    outputSize1+    outputSize2+    dtype+    device.+  ( All+      KnownNat+      '[ Fst3 stride,+         Snd3 stride,+         Trd3 stride,+         Fst3 padding,+         Snd3 padding,+         Trd3 padding,+         inputChannelSize,+         outputChannelSize,+         kernelSize0,+         kernelSize1,+         kernelSize2,+         inputSize0,+         inputSize1,+         inputSize2,+         batchSize+       ],+    ConvSideCheck inputSize0 kernelSize0 (Fst3 stride) (Fst3 padding) outputSize0,+    ConvSideCheck inputSize1 kernelSize1 (Snd3 stride) (Snd3 padding) outputSize1,+    ConvSideCheck inputSize2 kernelSize2 (Trd3 stride) (Trd3 padding) outputSize2+  ) =>+  -- | weight+  Tensor device dtype '[outputChannelSize, inputChannelSize, kernelSize0, kernelSize1, kernelSize2] ->+  -- | bias+  Tensor device dtype '[outputChannelSize] ->+  -- | input+  Tensor device dtype '[batchSize, inputChannelSize, inputSize0, inputSize1, inputSize2] ->+  -- | output+  Tensor device dtype '[batchSize, outputChannelSize, outputSize0, outputSize1, outputSize2]+conv3d weight bias input =+  unsafePerformIO $+    ATen.cast7+      ATen.Managed.conv3d_tttllll+      input+      weight+      bias+      ([natValI @(Fst3 stride), natValI @(Snd3 stride), natValI @(Trd3 stride)] :: [Int])+      ([natValI @(Fst3 padding), natValI @(Snd3 padding), natValI @(Trd3 padding)] :: [Int])+      ([1, 1, 1] :: [Int])+      (1 :: Int)++-- | convTBC+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+-- 1D convolution over an input of shape `[timeSize, batchSize, inputChannels]`.++-- >>> dtype &&& shape $ convTBC @1 (ones :: CPUTensor 'D.Float '[1,4,5]) (ones :: CPUTensor 'D.Float '[5]) (ones :: CPUTensor 'D.Float '[3,3,4])+-- (Float,[5,3,5])+-- >>> dtype &&& shape $ convTBC @0 (ones :: CPUTensor 'D.Float '[1,4,5]) (ones :: CPUTensor 'D.Float '[5]) (ones :: CPUTensor 'D.Float '[2,3,4])+-- (Float,[3,3,5])+-- >>> dtype &&& shape $ convTBC @0 (ones :: CPUTensor 'D.Float '[2,4,5]) (ones :: CPUTensor 'D.Float '[5]) (ones :: CPUTensor 'D.Float '[2,3,4])+-- (Float,[2,3,5])+convTBC ::+  forall padding timeSize batchSize kernelSize inputChannels outputChannels dtype device.+  (KnownNat padding) =>+  Tensor device dtype '[kernelSize, inputChannels, outputChannels] ->+  Tensor device dtype '[outputChannels] ->+  Tensor device dtype '[timeSize, batchSize, inputChannels] ->+  Tensor device dtype '[timeSize + padding * 2 + 1 - kernelSize, batchSize, outputChannels]+convTBC weight bias input =+  unsafePerformIO $ ATen.cast4 ATen.Managed.conv_tbc_tttl input weight bias (natValI @padding)++-- | convTranspose1d+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> t = convTranspose1d @1 @0 (ones :: CPUTensor 'D.Float '[3, 10, 1]) (ones :: CPUTensor 'D.Float '[10]) (ones :: CPUTensor 'D.Float '[1, 3, 4])+-- >>> :type t+-- t :: Tensor '(D.CPU, 0) 'D.Float [1, 10, 4]+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [[[Float]]]) $ t+-- (Float,([1,10,4],[[[4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0]]]))+convTranspose1d ::+  forall+    (stride :: Nat)+    (padding :: Nat)+    inputChannelSize+    outputChannelSize+    kernelSize+    inputSize+    batchSize+    outputSize+    dtype+    device.+  ( All+      KnownNat+      '[ stride,+         padding,+         inputChannelSize,+         outputChannelSize,+         kernelSize,+         inputSize,+         batchSize,+         outputSize+       ],+    ConvSideCheck inputSize kernelSize stride padding outputSize+  ) =>+  -- | weight+  Tensor device dtype '[inputChannelSize, outputChannelSize, kernelSize] ->+  -- | bias+  Tensor device dtype '[outputChannelSize] ->+  -- | input+  Tensor device dtype '[batchSize, inputChannelSize, inputSize] ->+  -- | output+  Tensor device dtype '[batchSize, outputChannelSize, outputSize]+convTranspose1d weight bias input =+  unsafePerformIO $+    ATen.cast7+      ATen.Managed.conv_transpose1d_tttllll+      input+      weight+      bias+      (natValI @stride :: Int)+      (natValI @padding :: Int)+      (0 :: Int)+      (1 :: Int)++-- | convTranspose2d+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> t = convTranspose2d @'(1, 1) @'(0, 0) (ones :: CPUTensor 'D.Float '[3, 10, 1, 1]) (ones :: CPUTensor 'D.Float '[10]) (ones :: CPUTensor 'D.Float '[1, 3, 4, 5])+-- >>> :type t+-- t :: Tensor '(D.CPU, 0) 'D.Float [1, 10, 4, 5]+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [[[[Float]]]]) $ t+-- (Float,([1,10,4,5],[[[[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0]]]]))+convTranspose2d ::+  forall+    (stride :: (Nat, Nat))+    (padding :: (Nat, Nat))+    inputChannelSize+    outputChannelSize+    kernelSize0+    kernelSize1+    inputSize0+    inputSize1+    batchSize+    outputSize0+    outputSize1+    dtype+    device.+  ( All+      KnownNat+      '[ Torch.Typed.Auxiliary.Fst stride,+         Torch.Typed.Auxiliary.Snd stride,+         Torch.Typed.Auxiliary.Fst padding,+         Torch.Typed.Auxiliary.Snd padding,+         inputChannelSize,+         outputChannelSize,+         kernelSize0,+         kernelSize1,+         inputSize0,+         inputSize1,+         batchSize,+         outputSize0,+         outputSize1+       ],+    ConvSideCheck inputSize0 kernelSize0 (Torch.Typed.Auxiliary.Fst stride) (Torch.Typed.Auxiliary.Fst padding) outputSize0,+    ConvSideCheck inputSize1 kernelSize1 (Torch.Typed.Auxiliary.Snd stride) (Torch.Typed.Auxiliary.Snd padding) outputSize1+  ) =>+  -- | weight+  Tensor device dtype '[inputChannelSize, outputChannelSize, kernelSize0, kernelSize1] ->+  -- | bias+  Tensor device dtype '[outputChannelSize] ->+  -- | input+  Tensor device dtype '[batchSize, inputChannelSize, inputSize0, inputSize1] ->+  -- | output+  Tensor device dtype '[batchSize, outputChannelSize, outputSize0, outputSize1]+convTranspose2d weight bias input =+  unsafePerformIO $+    ATen.cast7+      ATen.Managed.conv_transpose2d_tttllll+      input+      weight+      bias+      ([natValI @(Torch.Typed.Auxiliary.Fst stride), natValI @(Torch.Typed.Auxiliary.Snd stride)] :: [Int])+      ([natValI @(Torch.Typed.Auxiliary.Fst padding), natValI @(Torch.Typed.Auxiliary.Snd padding)] :: [Int])+      ([0, 0] :: [Int])+      (1 :: Int)++-- | convTranspose3d+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> t = convTranspose3d @'(1, 1, 1) @'(0, 0, 0) (ones :: CPUTensor 'D.Float '[3, 10, 1, 1, 1]) (ones :: CPUTensor 'D.Float '[10]) (ones :: CPUTensor 'D.Float '[1, 3, 4, 5, 6])+-- >>> :type t+-- t :: Tensor '(D.CPU, 0) 'D.Float [1, 10, 4, 5, 6]+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [[[[[Float]]]]]) $ t+-- (Float,([1,10,4,5,6],[[[[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]]],[[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]]],[[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]]],[[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]]],[[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]]],[[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]]],[[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]]],[[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]]],[[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]]],[[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]],[[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0],[4.0,4.0,4.0,4.0,4.0,4.0]]]]]))+convTranspose3d ::+  forall+    (stride :: (Nat, Nat, Nat))+    (padding :: (Nat, Nat, Nat))+    inputChannelSize+    outputChannelSize+    kernelSize0+    kernelSize1+    kernelSize2+    inputSize0+    inputSize1+    inputSize2+    batchSize+    outputSize0+    outputSize1+    outputSize2+    dtype+    device.+  ( All+      KnownNat+      '[ Fst3 stride,+         Snd3 stride,+         Trd3 stride,+         Fst3 padding,+         Snd3 padding,+         Trd3 padding,+         inputChannelSize,+         outputChannelSize,+         kernelSize0,+         kernelSize1,+         kernelSize2,+         inputSize0,+         inputSize1,+         inputSize2,+         batchSize+       ],+    ConvSideCheck inputSize0 kernelSize0 (Fst3 stride) (Fst3 padding) outputSize0,+    ConvSideCheck inputSize1 kernelSize1 (Snd3 stride) (Snd3 padding) outputSize1,+    ConvSideCheck inputSize2 kernelSize2 (Trd3 stride) (Trd3 padding) outputSize2+  ) =>+  -- | weight+  Tensor device dtype '[inputChannelSize, outputChannelSize, kernelSize0, kernelSize1, kernelSize2] ->+  -- | bias+  Tensor device dtype '[outputChannelSize] ->+  -- | input+  Tensor device dtype '[batchSize, inputChannelSize, inputSize0, inputSize1, inputSize2] ->+  -- | output+  Tensor device dtype '[batchSize, outputChannelSize, outputSize0, outputSize1, outputSize2]+convTranspose3d weight bias input =+  unsafePerformIO $+    ATen.cast7+      ATen.Managed.conv_transpose3d_tttllll+      input+      weight+      bias+      ([natValI @(Fst3 stride), natValI @(Snd3 stride), natValI @(Trd3 stride)] :: [Int])+      ([natValI @(Fst3 padding), natValI @(Snd3 padding), natValI @(Trd3 padding)] :: [Int])+      ([0, 0, 0] :: [Int])+      (1 :: Int)++-- | cosh+--+-- >>> dtype &&& shape $ cosh (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+cosh ::+  forall shape dtype device.+  (StandardFloatingPointDTypeValidation device dtype) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+cosh input = unsafePerformIO $ ATen.cast1 ATen.Managed.cosh_t input++-- cosine_embedding_loss :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Double -> Int -> Tensor device dtype shape+-- cosine_embedding_loss _input1 _input2 _target _margin _reduction = unsafePerformIO $ (ATen.cast5 ATen.Managed.cosine_embedding_loss_tttdl) _input1 _input2 _target _margin _reduction++-- cudnn_affine_grid_generator :: Tensor device dtype shape -> Int -> Int -> Int -> Int -> Tensor device dtype shape+-- cudnn_affine_grid_generator _theta _N _C _H _W = unsafePerformIO $ (ATen.cast5 ATen.Managed.cudnn_affine_grid_generator_tllll) _theta _N _C _H _W++-- cudnn_batch_norm :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Bool -> Double -> Double -> (Tensor device dtype shape,Tensor device dtype shape,Tensor device dtype shape)+-- cudnn_batch_norm _input _weight _bias _running_mean _running_var _training _exponential_average_factor _epsilon = unsafePerformIO $ (ATen.cast8 ATen.Managed.cudnn_batch_norm_tttttbdd) _input _weight _bias _running_mean _running_var _training _exponential_average_factor _epsilon++-- cudnn_convolution :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> [Int] -> [Int] -> [Int] -> Int -> Bool -> Bool -> Tensor device dtype shape+-- cudnn_convolution _input _weight _bias _padding _stride _dilation _groups _benchmark _deterministic = unsafePerformIO $ (ATen.cast9 ATen.Managed.cudnn_convolution_tttllllbb) _input _weight _bias _padding _stride _dilation _groups _benchmark _deterministic++-- cudnn_convolution_transpose :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> [Int] -> [Int] -> [Int] -> [Int] -> Int -> Bool -> Bool -> Tensor device dtype shape+-- cudnn_convolution_transpose _input _weight _bias _padding _output_padding _stride _dilation _groups _benchmark _deterministic = unsafePerformIO $ (ATen.ATen.cast10 ATen.Managed.cudnn_convolution_transpose_tttlllllbb) _input _weight _bias _padding _output_padding _stride _dilation _groups _benchmark _deterministic++-- cudnn_grid_sampler :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape+-- cudnn_grid_sampler _input _grid = unsafePerformIO $ (ATen.cast2 ATen.Managed.cudnn_grid_sampler_tt) _input _grid++-- | Det+--+-- >>> :kind! Det '[2,2]+-- Det '[2,2] :: [Natural]+-- = '[]+-- >>> :kind! Det '[3,2,2]+-- Det '[3,2,2] :: [Natural]+-- = '[3]+type family Det (shape :: [Nat]) :: [Nat] where+  Det (n : n : '[]) = '[]+  Det (b : n : n : '[]) = '[b]+  Det _ = TypeError (Text "This shape must be square matrix or batch + squre matrix.")++-- | det+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> dtype &&& shape $ det (ones :: CPUTensor 'D.Float '[2,2])+-- (Float,[])+-- >>> dtype &&& shape $ det (ones :: CPUTensor 'D.Float '[3,2,2])+-- (Float,[3])+det ::+  forall shape dtype device.+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype (Det shape)+det input = unsafePerformIO $ ATen.cast1 ATen.Managed.det_t input++type family DimsDistinctAscendingCheck (dim1 :: Nat) (dim2 :: Nat) (cmp :: Ordering) :: Constraint where+  DimsDistinctAscendingCheck _ _ 'LT = ()+  DimsDistinctAscendingCheck dim1 dim2 _ =+    TypeError+      ( Text "Dimensions must be distinct and in ascending order, but got "+          :<>: ShowType dim1+          :<>: Text ", "+          :<>: ShowType dim2+      )++type family DimsDistinctAscending (dim1 :: Nat) (dim2 :: Nat) :: Constraint where+  DimsDistinctAscending dim1 dim2 = DimsDistinctAscendingCheck dim1 dim2 (CmpNat dim1 dim2)++type family DiagEmbedShapeImpl (dim1 :: Nat) (dim2 :: Nat) (shape :: [Nat]) (n :: Nat) :: [Nat] where+  DiagEmbedShapeImpl dim1 dim2 shape n = Insert dim1 n (Insert (dim2 - 1) n (Init shape))++type family DiagEmbedShape (index :: Nat) (dim1 :: Nat) (dim2 :: Nat) (shape :: [Nat]) :: [Nat] where+  DiagEmbedShape index dim1 dim2 shape = DiagEmbedShapeImpl dim1 dim2 shape (Last shape + index)++-- | diagEmbed+--+-- >>> dtype &&& shape $ diagEmbed @0 @1 @2 Upper (ones :: CPUTensor 'D.Float '[2,3])+-- (Float,[2,3,3])+-- >>> dtype &&& shape $ diagEmbed @1 @0 @2 Upper (ones :: CPUTensor 'D.Float '[2,3])+-- (Float,[4,2,4])+diagEmbed ::+  forall index dim1 dim2 shape shape' device dtype.+  ( KnownNat index,+    KnownNat dim1,+    KnownNat dim2,+    shape' ~ DiagEmbedShape index dim1 dim2 shape,+    DimsDistinctAscending dim1 dim2,+    StandardDTypeValidation device dtype+  ) =>+  Tri ->+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape'+diagEmbed tri t =+  unsafePerformIO $+    ATen.cast4+      ATen.Managed.diag_embed_tlll+      t+      (if isUpper tri then natValI @index else - natValI @index)+      (natValI @dim1)+      (natValI @dim2)++type family DiagflatShapeImpl (d :: Nat) :: [Nat] where+  DiagflatShapeImpl d = '[d, d]++type family DiagflatShape (index :: Nat) (shape :: [Nat]) :: [Nat] where+  DiagflatShape index shape = DiagflatShapeImpl (Numel shape + index)++-- | diagflat+--+-- >>> dtype &&& shape $ diagflat @0 Upper (ones :: CPUTensor 'D.Float '[3])+-- (Float,[3,3])+-- >>> dtype &&& shape $ diagflat @1 Upper (ones :: CPUTensor 'D.Float '[3])+-- (Float,[4,4])+-- >>> dtype &&& shape $ diagflat @0 Upper (ones :: CPUTensor 'D.Float '[2,2])+-- (Float,[4,4])+diagflat ::+  forall index shape shape' device dtype.+  ( KnownNat index,+    shape' ~ DiagflatShape index shape,+    StandardDTypeValidation device dtype+  ) =>+  Tri ->+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape'+diagflat tri t = unsafePerformIO $+  ATen.cast2 ATen.Managed.diagflat_tl t $+    case tri of+      Upper -> natValI @index+      Lower -> - natValI @index++type family NDimAtLeastCheck (ndim :: Nat) (shape :: [Nat]) (cmp :: Ordering) :: Constraint where+  NDimAtLeastCheck ndim shape 'GT =+    TypeError+      ( Text "Input must have at least "+          :<>: ShowType ndim+          :<>: Text " dimensions, but got "+          :<>: ShowType (ListLength shape)+      )+  NDimAtLeastCheck _ _ _ = ()++type family NDimAtLeast (ndim :: Nat) (shape :: [Nat]) :: Constraint where+  NDimAtLeast ndim shape = NDimAtLeastCheck ndim shape (CmpNat ndim (ListLength shape))++type family DiagonalShape (tri :: Tri) (index :: Nat) (dim1 :: Nat) (dim2 :: Nat) (shape :: [Nat]) :: [Nat] where+  DiagonalShape tri index dim1 dim2 shape =+    Remove (Remove shape dim2) dim1 ++ '[DiagSize tri index (Index shape dim1) (Index shape dim2)]++-- | diagonal+--+-- >>> dtype &&& shape $ diagonal @'Upper @0 @0 @1 (ones :: CPUTensor 'D.Float '[3,3])+-- (Float,[3])+-- >>> dtype &&& shape $ diagonal @'Upper @1 @0 @1 (ones :: CPUTensor 'D.Float '[3,3])+-- (Float,[2])+-- >>> dtype &&& shape $ diagonal @'Lower @1 @1 @2 (ones :: CPUTensor 'D.Float '[2,5,4,2])+-- (Float,[2,2,4])+diagonal ::+  forall tri index dim1 dim2 shape shape' device dtype.+  ( KnownTri tri,+    KnownNat index,+    KnownNat dim1,+    KnownNat dim2,+    NDimAtLeast 2 shape,+    DimsDistinctAscending dim1 dim2,+    shape' ~ DiagonalShape tri index dim1 dim2 shape,+    StandardDTypeValidation device dtype+  ) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape'+diagonal t =+  unsafePerformIO $+    ATen.cast4+      ATen.Managed.diagonal_tlll+      t+      (if isUpper (triVal @tri) then natValI @index else - natValI @index)+      (natValI @dim1)+      (natValI @dim2)++type family DotDTypeIsValid (device :: (D.DeviceType, Nat)) (dtype :: D.DType) :: Constraint where+  DotDTypeIsValid '(D.CPU, 0) dtype =+    ( DTypeIsNotBool '(D.CPU, 0) dtype,+      DTypeIsNotHalf '(D.CPU, 0) dtype+    )+  DotDTypeIsValid '( 'D.CUDA, deviceIndex) dtype = DTypeIsFloatingPoint '( 'D.CUDA, deviceIndex) dtype+  DotDTypeIsValid '( 'D.MPS, 0) dtype = DTypeIsFloatingPoint '( 'D.MPS, 0) dtype+  DotDTypeIsValid '(deviceType, _) dtype = UnsupportedDTypeForDevice deviceType dtype++-- | dot product+-- Note that this function does not broadcast.+dot ::+  forall size dtype device.+  DotDTypeIsValid device dtype =>+  -- | input+  Tensor device dtype '[size] ->+  -- | other input+  Tensor device dtype '[size] ->+  -- | dot product+  Tensor device dtype '[]+dot input other = unsafePerformIO $ ATen.cast2 ATen.Managed.dot_tt input other++-- einsum :: String -> [Tensor device dtype shape] -> Tensor device dtype shape+-- einsum _equation _tensors = unsafePerformIO $ (ATen.cast2 ATen.Managed.einsum_sl) _equation _tensors++class KnownMaybeNat (n :: Maybe Nat) where+  maybeNatVal :: Maybe Integer++instance (KnownNat n) => KnownMaybeNat (Just n) where+  maybeNatVal = Just . natVal $ Proxy @n++instance KnownMaybeNat Nothing where+  maybeNatVal = Nothing++type family PaddingIdxCheck (idx :: Maybe Nat) (numEmbeds :: Nat) :: Constraint where+  PaddingIdxCheck (Just n) numEmbeds = n + 1 <= numEmbeds+  PaddingIdxCheck Nothing _ = ()++-- | embedding+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+-- TODO: what about sparsity here?+-- TODO: what output dtypes are supported?+--+-- >>> weights = fromJust [[1, 1], [2, 2], [3, 3], [4, 4]] :: CPUTensor 'D.Float '[4, 2]+-- >>> indices = fromJust [[0], [2], [0], [1]] :: CPUTensor 'D.Int64 '[4, 1]+-- >>> t = embedding @('Just 1) False False weights indices+-- >>> :type t+-- t :: Tensor '(D.CPU, 0) 'D.Float [4, 1, 2]+--+-- -- libtorch 1.7+-- -- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [[[Float]]]) $ t+-- -- (Float,([4,1,2],[[[1.0,1.0]],[[3.0,3.0]],[[1.0,1.0]],[[2.0,2.0]]]))+-- --+-- -- libtorch 1.8+-- -- The behavior of libtorch 1.8 changes. See https://github.com/pytorch/pytorch/issues/53368+-- -- (Float,([4,1,2],[[[1.0,1.0]],[[3.0,3.0]],[[1.0,1.0]],[[0.0,0.0]]]))+-- --+-- -- libtorch 1.8.1+-- -- The behavior of libtorch 1.8.1 is reverted.+-- -- (Float,([4,1,2],[[[1.0,1.0]],[[3.0,3.0]],[[1.0,1.0]],[[2.0,2.0]]]))+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [[[Float]]]) $ t+-- (Float,([4,1,2],[[[1.0,1.0]],[[3.0,3.0]],[[1.0,1.0]],[[2.0,2.0]]]))+-- >>> t = embedding @'Nothing False False weights indices+-- >>> :type t+-- t :: Tensor '(D.CPU, 0) 'D.Float [4, 1, 2]+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [[[Float]]]) $ t+-- (Float,([4,1,2],[[[1.0,1.0]],[[3.0,3.0]],[[1.0,1.0]],[[2.0,2.0]]]))+embedding ::+  forall (paddingIdx :: Maybe Nat) numEmbeds embedDim shape dtype device.+  ( KnownMaybeNat paddingIdx,+    PaddingIdxCheck paddingIdx numEmbeds+  ) =>+  -- | whether or not to scale the gradient by the frequencies+  Bool ->+  -- | whether or not the embedding is sparse+  Bool ->+  -- | weights+  Tensor device dtype '[numEmbeds, embedDim] ->+  -- | indices+  Tensor device 'D.Int64 shape ->+  -- | output+  Tensor device dtype (Reverse (embedDim ': Reverse shape))+embedding scaleGradByFreq sparse weights indices =+  unsafePerformIO $ ATen.cast5 ATen.Managed.embedding_ttlbb weights indices paddingIdx scaleGradByFreq sparse+  where+    paddingIdx :: Int+    paddingIdx = case maybeNatVal @paddingIdx of+      Just idx -> fromIntegral idx+      Nothing -> -1++-- embedding_bag :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Bool -> Int -> Bool -> Tensor device dtype shape -> (Tensor device dtype shape,Tensor device dtype shape,Tensor device dtype shape,Tensor device dtype shape)+-- embedding_bag _weight _indices _offsets _scale_grad_by_freq _mode _sparse _per_sample_weights = unsafePerformIO $ (ATen.cast7 ATen.Managed.embedding_bag_tttblbt) _weight _indices _offsets _scale_grad_by_freq _mode _sparse _per_sample_weights++-- | emptyLike+-- TODO: this seems quite unsafe, the values of this tensor will be random+--+-- >>> t <- emptyLike (ones :: CPUTensor 'D.Float '[3,4,5])+-- >>> dtype &&& shape $ t+-- (Float,[3,4,5])+emptyLike ::+  forall shape dtype device.+  -- | input+  Tensor device dtype shape ->+  -- | output+  IO (Tensor device dtype shape)+emptyLike input = ATen.cast1 ATen.Managed.empty_like_t input++-- | erfc+--+-- >>> dtype &&& shape $ erfc (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+erfc ::+  forall shape dtype device.+  (StandardFloatingPointDTypeValidation device dtype) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+erfc input = unsafePerformIO $ ATen.cast1 ATen.Managed.erfc_t input++-- | expm1+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> dtype &&& shape $ expm1 (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+expm1 ::+  forall shape dtype device.+  (StandardFloatingPointDTypeValidation device dtype) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+expm1 input = unsafePerformIO $ ATen.cast1 ATen.Managed.expm1_t input++-- | expand+-- TODO: figure out what the `implicit` boolean value does+--+-- >>> t = ones :: CPUTensor 'D.Float '[2]+-- >>> t' = expand @'[3, 1, 2] False t+-- >>> dtype &&& shape $ t'+-- (Float,[3,1,2])+-- >>> t'' = expand @'[3, 1, 2] True t+-- >>> dtype &&& shape $ t''+-- (Float,[3,1,2])+-- >>> toInt (all (t' ==. t'')) == 1+-- True+expand ::+  forall shape' shape dtype device.+  ( KnownShape shape',+    shape' ~ Broadcast shape shape'+  ) =>+  -- | some boolean value with unknown function+  Bool ->+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape'+expand someBool input = unsafePerformIO $ ATen.cast3 ATen.Managed.tensor_expand_lb input (shapeVal @shape') someBool++-- flatten :: Tensor device dtype shape -> Int -> Int -> Tensor device dtype shape+-- flatten _input _start_dim _end_dim = unsafePerformIO $ (ATen.cast3 ATen.Managed.flatten_tll) _input _start_dim _end_dim++-- | flattenAll+--+-- >>> t = flattenAll (ones :: CPUTensor 'D.Float '[3,2])+-- >>> dtype &&& shape $ t+-- (Float,[6])+-- >>> :t t+-- t :: Tensor '(D.CPU, 0) 'D.Float '[6]+flattenAll ::+  forall shape dtype device.+  KnownShape shape =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype '[Product shape]+flattenAll input =+  unsafePerformIO $ ATen.cast3 ATen.Managed.flatten_tll input (0 :: Int) (-1 :: Int)++-- | frac+--+-- >>> dtype &&& shape $ frac (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+frac ::+  forall shape dtype device.+  (StandardFloatingPointDTypeValidation device dtype) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+frac input = unsafePerformIO $ ATen.cast1 ATen.Managed.frac_t input++-- | full like+--+-- >>> dtype &&& shape $ fullLike 3.0 (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+fullLike ::+  forall shape dtype device.+  -- | fill value+  Float ->+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+fullLike fillValue input =+  unsafePerformIO $ ATen.cast2 ATen.Managed.full_like_ts input fillValue++-- grid_sampler :: Tensor device dtype shape -> Tensor device dtype shape -> Int -> Int -> Tensor device dtype shape+-- grid_sampler _input _grid _interpolation_mode _padding_mode = unsafePerformIO $ (ATen.cast4 ATen.Managed.grid_sampler_ttll) _input _grid _interpolation_mode _padding_mode++-- grid_sampler_2d :: Tensor device dtype shape -> Tensor device dtype shape -> Int -> Int -> Tensor device dtype shape+-- grid_sampler_2d _input _grid _interpolation_mode _padding_mode = unsafePerformIO $ (ATen.cast4 ATen.Managed.grid_sampler_2d_ttll) _input _grid _interpolation_mode _padding_mode++-- grid_sampler_3d :: Tensor device dtype shape -> Tensor device dtype shape -> Int -> Int -> Tensor device dtype shape+-- grid_sampler_3d _input _grid _interpolation_mode _padding_mode = unsafePerformIO $ (ATen.cast4 ATen.Managed.grid_sampler_3d_ttll) _input _grid _interpolation_mode _padding_mode++-- hinge_embedding_loss :: Tensor device dtype shape -> Tensor device dtype shape -> Double -> Int -> Tensor device dtype shape+-- hinge_embedding_loss _input _target _margin _reduction = unsafePerformIO $ (ATen.cast4 ATen.Managed.hinge_embedding_loss_ttdl) _input _target _margin _reduction++-- ger :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape+-- ger _input _vec2 = unsafePerformIO $ (ATen.cast2 ATen.Managed.ger_tt) _input _vec2++-- group_norm :: Tensor device dtype shape -> Int -> Tensor device dtype shape -> Tensor device dtype shape -> Double -> Bool -> Tensor device dtype shape+-- group_norm _input _num_groups _weight _bias _eps _cudnn_enabled = unsafePerformIO $ (ATen.cast6 ATen.Managed.group_norm_tlttdb) _input _num_groups _weight _bias _eps _cudnn_enabled++-- fft :: Tensor device dtype shape -> Int -> Bool -> Tensor device dtype shape+-- fft _input _signal_ndim _normalized = unsafePerformIO $ (ATen.cast3 ATen.Managed.fft_tlb) _input _signal_ndim _normalized++-- ifft :: Tensor device dtype shape -> Int -> Bool -> Tensor device dtype shape+-- ifft _input _signal_ndim _normalized = unsafePerformIO $ (ATen.cast3 ATen.Managed.ifft_tlb) _input _signal_ndim _normalized++-- rfft :: Tensor device dtype shape -> Int -> Bool -> Bool -> Tensor device dtype shape+-- rfft _input _signal_ndim _normalized _onesided = unsafePerformIO $ (ATen.cast4 ATen.Managed.rfft_tlbb) _input _signal_ndim _normalized _onesided++-- irfft :: Tensor device dtype shape -> Int -> Bool -> Bool -> [Int] -> Tensor device dtype shape+-- irfft _input _signal_ndim _normalized _onesided _signal_sizes = unsafePerformIO $ (ATen.cast5 ATen.Managed.irfft_tlbbl) _input _signal_ndim _normalized _onesided _signal_sizes++-- index :: Tensor device dtype shape -> [Tensor device dtype shape] -> Tensor device dtype shape+-- index _input _indices = unsafePerformIO $ (ATen.cast2 ATen.Managed.index_tl) _input _indices++-- index_copy :: Tensor device dtype shape -> Int -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape+-- index_copy _input _dim _index _source = unsafePerformIO $ (ATen.cast4 ATen.Managed.index_copy_tltt) _input _dim _index _source++-- index_put :: Tensor device dtype shape -> [Tensor device dtype shape] -> Tensor device dtype shape -> Bool -> Tensor device dtype shape+-- index_put _input _indices _values _accumulate = unsafePerformIO $ (ATen.cast4 ATen.Managed.index_put_tltb) _input _indices _values _accumulate++-- instance_norm :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Bool -> Double -> Double -> Bool -> Tensor device dtype shape+-- instance_norm _input _weight _bias _running_mean _running_var _use_input_stats _momentum _eps _cudnn_enabled = unsafePerformIO $ (ATen.cast9 ATen.Managed.instance_norm_tttttbddb) _input _weight _bias _running_mean _running_var _use_input_stats _momentum _eps _cudnn_enabled++-- | isclose+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> dtype &&& shape $ isclose 0.1 0.1 False (ones :: CPUTensor 'D.Float '[3,2]) (ones :: CPUTensor 'D.Float '[3,2])+-- (Bool,[3,2])+isclose ::+  forall shape dtype device.+  -- | relative tolerance+  Double ->+  -- | absolute tolerance+  Double ->+  -- | whether or not NaN equals NaN+  Bool ->+  -- | input tensor+  Tensor device dtype shape ->+  -- | other input tensor+  Tensor device dtype shape ->+  -- | output+  Tensor device 'D.Bool shape+isclose rtol atol equalNaN input other =+  unsafePerformIO $ ATen.cast5 ATen.Managed.isclose_ttddb input other rtol atol equalNaN++-- | is NaN+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> dtype &&& shape $ isNaN (ones :: CPUTensor 'D.Float '[3,2])+-- (Bool,[3,2])+isNaN ::+  forall shape dtype device.+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device 'D.Bool shape+isNaN input = unsafePerformIO $ ATen.cast1 ATen.Managed.isnan_t input++-- | is distributed+isDistributed ::+  forall shape dtype device.+  -- | input+  Tensor device dtype shape ->+  -- | output+  Bool+isDistributed input = unsafePerformIO $ ATen.cast1 ATen.Managed.is_distributed_t input++-- | is floating point+-- TODO: this can be decided statically+isFloatingPoint ::+  forall shape dtype device.+  -- | input+  Tensor device dtype shape ->+  -- | output+  Bool+isFloatingPoint input = unsafePerformIO $ ATen.cast1 ATen.Managed.is_floating_point_t input++-- | is complex+isComplex ::+  forall shape dtype device.+  -- | input+  Tensor device dtype shape ->+  -- | output+  Bool+isComplex input = unsafePerformIO $ ATen.cast1 ATen.Managed.is_complex_t input++-- | is non-zero+-- this operation is only defined for tensors with shape '[] or '[1]+isNonZero ::+  forall shape dtype device.+  (Numel shape ~ 1) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Bool+isNonZero input = unsafePerformIO $ ATen.cast1 ATen.Managed.is_nonzero_t input++-- | is same size+-- TODO: this can be decided statically+isSameSize ::+  forall shape shape' dtype device.+  -- | input tensor+  Tensor device dtype shape ->+  -- | other input tensor+  Tensor device dtype shape' ->+  -- | output+  Bool+isSameSize input other =+  unsafePerformIO $ ATen.cast2 ATen.Managed.is_same_size_tt input other++isSigned ::+  forall shape dtype device.+  -- | input+  Tensor device dtype shape ->+  -- | output+  Bool+isSigned input = unsafePerformIO $ ATen.cast1 ATen.Managed.is_signed_t input++-- kl_div :: Tensor device dtype shape -> Tensor device dtype shape -> Int -> Tensor device dtype shape+-- kl_div _input _target _reduction = unsafePerformIO $ (ATen.cast3 ATen.Managed.kl_div_ttl) _input _target _reduction++-- kthvalue :: Tensor device dtype shape -> Int -> Int -> Bool -> (Tensor device dtype shape,Tensor device dtype shape)+-- kthvalue _input _k _dim _keepdim = unsafePerformIO $ (ATen.cast4 ATen.Managed.kthvalue_tllb) _input _k _dim _keepdim++-- | layerNorm+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+-- TODO: figure out if and when CUDNN works here, tie it also to the `device`+--+-- >>> t = layerNorm @'[1, 2] @'[2, 1, 2] @'D.Float @'(D.CPU, 0) ones ones 0.01 ones+-- >>> :type t+-- t :: Tensor '(D.CPU, 0) 'D.Float [2, 1, 2]+-- >>> dtype &&& shape $ t+-- (Float,[2,1,2])+layerNorm ::+  forall normalizedShape shape dtype device.+  ( KnownShape normalizedShape,+    IsSuffixOf normalizedShape shape+  ) =>+  -- | weight+  Tensor device dtype normalizedShape ->+  -- | bias+  Tensor device dtype normalizedShape ->+  -- | eps+  Double ->+  -- | input tensor+  Tensor device dtype shape ->+  -- | output tensor+  Tensor device dtype shape+layerNorm weight bias eps input =+  unsafePerformIO $+    ATen.cast6+      ATen.Managed.layer_norm_tlttdb+      input+      (shapeVal @normalizedShape)+      weight+      bias+      eps+      ( cudnnIsAcceptable weight+          && cudnnIsAcceptable bias+          && cudnnIsAcceptable input+      )++-- native_layer_norm :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Int -> Int -> Double -> (Tensor device dtype shape,Tensor device dtype shape,Tensor device dtype shape)+-- native_layer_norm _input _weight _bias _M _N _eps = unsafePerformIO $ (ATen.cast6 ATen.Managed.native_layer_norm_tttlld) _input _weight _bias _M _N _eps++-- | linear+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+-- https://pytorch.org/docs/stable/_modules/torch/nn/functional.html#linear+--+-- >>> w = fromJust [[-0.5, -2,  0.5], [1.5, -0.5, 0.5]] :: CPUTensor 'D.Float '[2, 3]+-- >>> b = fromJust [0, 0.5] :: CPUTensor 'D.Float '[2]+-- >>> t = fromJust [[-2, 0.5, 1], [0.5, 0, 0], [0, 1, 0], [0, 0, 0], [1, -1, 0]] :: CPUTensor 'D.Float '[5, 3]+-- >>> t' = linear w b t+-- >>> :type t'+-- t' :: Tensor '(D.CPU, 0) 'D.Float [5, 2]+-- >>> dtype &&& shape &&& (\t'' -> D.asValue (toDynamic t'') :: [[Float]]) $ t'+-- (Float,([5,2],[[0.5,-2.25],[-0.25,1.25],[-2.0,0.0],[0.0,0.5],[1.5,2.5]]))+linear ::+  forall batchSize inputFeatures outputFeatures dtype device.+  Tensor device dtype '[outputFeatures, inputFeatures] ->+  Tensor device dtype '[outputFeatures] ->+  Tensor device dtype '[batchSize, inputFeatures] ->+  Tensor device dtype '[batchSize, outputFeatures]+linear weight bias input = unsafePerformIO $ ATen.cast3 ATen.Managed.linear_ttt input weight bias++-- | linear'+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+-- TODO: can we use the ATen linear function or not here?+-- https://pytorch.org/docs/stable/_modules/torch/nn/functional.html#linear+--+-- >>> w = fromJust [[-0.5, -2,  0.5], [1.5, -0.5, 0.5]] :: CPUTensor 'D.Float '[2, 3]+-- >>> b = fromJust [0, 0.5] :: CPUTensor 'D.Float '[2]+-- >>> t = fromJust [[-2, 0.5, 1], [0.5, 0, 0], [0, 1, 0], [0, 0, 0], [1, -1, 0]] :: CPUTensor 'D.Float '[5, 3]+-- >>> t' = linear' w b t+-- >>> :type t'+-- t' :: Tensor '(D.CPU, 0) 'D.Float [5, 2]+-- >>> dtype &&& shape &&& (\t'' -> D.asValue (toDynamic t'') :: [[Float]]) $ t'+-- (Float,([5,2],[[0.5,-2.25],[-0.25,1.25],[-2.0,0.0],[0.0,0.5],[1.5,2.5]]))+-- >>> t = fromJust [[[[-2, 0.5, 1], [0.5, 0, 0], [0, 1, 0], [0, 0, 0], [1, -1, 0]], [[-2, 0.5, 1], [0.5, 0, 0], [0, 1, 0], [0, 0, 0], [1, -1, 0]]]] :: CPUTensor 'D.Float '[1, 2, 5, 3]+-- >>> t' = linear' w b t+-- >>> :type t'+-- t' :: Tensor '(D.CPU, 0) 'D.Float [1, 2, 5, 2]+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [[[[Float]]]]) $ t'+-- (Float,([1,2,5,2],[[[[0.5,-2.25],[-0.25,1.25],[-2.0,0.0],[0.0,0.5],[1.5,2.5]],[[0.5,-2.25],[-0.25,1.25],[-2.0,0.0],[0.0,0.5],[1.5,2.5]]]]))+linear' ::+  forall (inputFeatures :: Nat) (outputFeatures :: Nat) (shape :: [Nat]) (shape' :: [Nat]) dtype device (shape'' :: [Nat]).+  ( shape'' ~ MatMul shape '[inputFeatures, outputFeatures],+    shape' ~ Broadcast shape'' shape''+  ) =>+  -- | weight+  Tensor device dtype '[outputFeatures, inputFeatures] ->+  -- | bias+  Tensor device dtype '[outputFeatures] ->+  -- | input+  Tensor device dtype shape ->+  -- | output+  -- linear' weight bias input = Torch.Static.add (matmul input $ transpose @0 @1 weight) bias+  Tensor device dtype shape'+linear' weight bias input = unsafePerformIO $ ATen.cast3 ATen.Managed.linear_ttt input weight bias++-- | mkldnnLinear+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+-- TODO: mkldnnLinear does not return a usuable tensor value and is hence broken+-- TODO: figure out `device` for this+--+-- >>> w = fromJust [[-0.5, -2,  0.5], [1.5, -0.5, 0.5]] :: CPUTensor 'D.Float '[2, 3]+-- >>> b = fromJust [0, 0.5] :: CPUTensor 'D.Float '[2]+-- >>> t = fromJust [[-2, 0.5, 1], [0.5, 0, 0], [0, 1, 0], [0, 0, 0], [1, -1, 0]] :: CPUTensor 'D.Float '[5, 3]+--+-- -- >>> t' = mkldnnLinear (toMKLDNN w) (toMKLDNN b) (toMKLDNN t)+-- -- >>> :type t'+-- -- t' :: Tensor '(D.CPU, 0) 'D.Float '[5, 2]+-- -- >>> dtype &&& shape &&& (\t'' -> D.asValue (toDynamic t'') :: [[Float]]) $ t'+-- -- (Float,([5,2],[[0.5,-2.25],[-0.25,1.25],[-2.0,0.0],[0.0,0.5],[1.5,2.5]]))+mkldnnLinear ::+  forall batchSize inputFeatures outputFeatures dtype device.+  -- | weight+  Tensor device dtype '[outputFeatures, inputFeatures] ->+  -- | bias+  Tensor device dtype '[outputFeatures] ->+  -- | input+  Tensor device dtype '[batchSize, inputFeatures] ->+  -- | output+  Tensor device dtype '[batchSize, outputFeatures]+mkldnnLinear weight bias input = unsafePerformIO $ ATen.cast3 ATen.Managed.mkldnn_linear_ttt input weight bias++-- fbgemm_linear_int8_weight :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Float -> Float -> Tensor device dtype shape -> Tensor device dtype shape+-- fbgemm_linear_int8_weight _input _weight _packed _col_offsets _weight_scale _weight_zero_point _bias = unsafePerformIO $ (ATen.cast7 ATen.Managed.fbgemm_linear_int8_weight_ttttsst) _input _weight _packed _col_offsets _weight_scale _weight_zero_point _bias++-- fbgemm_linear_quantize_weight :: Tensor device dtype shape -> (Tensor device dtype shape,Tensor device dtype shape,Double,Int)+-- fbgemm_linear_quantize_weight _input = unsafePerformIO $ (ATen.cast1 ATen.Managed.fbgemm_linear_quantize_weight_t) _input++-- fbgemm_pack_gemm_matrix_fp16 :: Tensor device dtype shape -> Tensor device dtype shape+-- fbgemm_pack_gemm_matrix_fp16 _input = unsafePerformIO $ (ATen.cast1 ATen.Managed.fbgemm_pack_gemm_matrix_fp16_t) _input++-- fbgemm_linear_fp16_weight :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape+-- fbgemm_linear_fp16_weight _input _packed_weight _bias = unsafePerformIO $ (ATen.cast3 ATen.Managed.fbgemm_linear_fp16_weight_ttt) _input _packed_weight _bias++-- fbgemm_pack_quantized_matrix :: Tensor device dtype shape -> Int -> Int -> Tensor device dtype shape+-- fbgemm_pack_quantized_matrix _input _K _N = unsafePerformIO $ (ATen.cast3 ATen.Managed.fbgemm_pack_quantized_matrix_tll) _input _K _N++-- fbgemm_is_cpu_supported :: Bool+-- fbgemm_is_cpu_supported  = unsafePerformIO $ (cast0 ATen.Managed.fbgemm_is_cpu_supported)++-- | log+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+-- TODO: will log throw for negative numbers or just generate NaNs? should we return a Maybe?+--+-- >>> dtype &&& shape $ log (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+log ::+  forall shape dtype device.+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+log input = unsafePerformIO $ ATen.cast1 ATen.Managed.log_t input++-- | logDet+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+-- TODO: will logDet throw? and if so, should we return a Maybe?+--+-- >>> dtype &&& shape $ logDet (ones :: CPUTensor 'D.Float '[2,2])+-- (Float,[])+-- >>> dtype &&& shape $ logDet (ones :: CPUTensor 'D.Float '[3,2,2])+-- (Float,[3])+logDet ::+  forall shape' shape dtype device.+  (shape' ~ Det shape) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape'+logDet input = unsafePerformIO $ ATen.cast1 ATen.Managed.logdet_t input++-- | logarithm of the sum of the exponentials+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+-- See https://pytorch.org/docs/stable/torch.html#torch.logsumexp.+--+-- >>> t = fromJust [[5, 1], [3, 2], [4, 1], [2, 7]] :: CPUTensor 'D.Float '[4, 2]+--+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [Float]) $ logSumExp @1 @DropDim t+-- (Float,([4],[5.01815,3.3132617,4.0485873,7.0067153]))+--+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [[Float]]) $ logSumExp @1 @KeepDim t+-- (Float,([4,1],[[5.01815],[3.3132617],[4.0485873],[7.0067153]]))+--+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [Float]) $ logSumExp @0 @DropDim t+-- (Float,([2],[5.44019,7.0116277]))+--+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [[Float]]) $ logSumExp @0 @KeepDim t+-- (Float,([1,2],[[5.44019,7.0116277]]))+logSumExp ::+  forall dim keepOrDropDim shape' shape dtype device.+  ( KnownNat dim,+    KnownKeepOrDropDim keepOrDropDim,+    Reifies dtype D.DType,+    DTypeIsFloatingPoint device dtype,+    shape' ~ ConditionalDropDimension shape dim keepOrDropDim+  ) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape'+logSumExp input =+  unsafePerformIO $+    ATen.cast3+      ATen.Managed.logsumexp_tlb+      input+      (natValI @dim)+      (keepOrDropDimVal @keepOrDropDim)++-- margin_ranking_loss :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Double -> Int -> Tensor device dtype shape+-- margin_ranking_loss _input1 _input2 _target _margin _reduction = unsafePerformIO $ (ATen.cast5 ATen.Managed.margin_ranking_loss_tttdl) _input1 _input2 _target _margin _reduction++-- | matrixPower+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+-- TODO: figure out input shape restrictions, should be matrix or a batched matrix+-- TODO: figure out restrictions on the power, can it be zero or negative?+--+-- >>> dtype &&& shape $ matrixPower 2 (ones :: CPUTensor 'D.Float '[3,4,4])+-- (Float,[3,4,4])+matrixPower ::+  forall shape' shape dtype device.+  (shape' ~ Square shape) =>+  -- | power+  Int ->+  -- | input matrix+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape'+matrixPower n input = unsafePerformIO $ ATen.cast2 ATen.Managed.matrix_power_tl input n++-- | maxValues+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> t = ones :: CPUTensor 'D.Float '[3,4,5]+-- >>> dtype &&& shape $ maxValues @0 @KeepDim t+-- (Float,[1,4,5])+-- >>> dtype &&& shape $ maxValues @0 @DropDim t+-- (Float,[4,5])+-- >>> dtype &&& shape $ maxValues @1 @KeepDim t+-- (Float,[3,1,5])+-- >>> dtype &&& shape $ maxValues @1 @DropDim t+-- (Float,[3,5])+maxValues ::+  forall dim keepOrDropDim shape' shape dtype device.+  ( KnownNat dim,+    KnownKeepOrDropDim keepOrDropDim,+    shape' ~ ConditionalDropDimension shape dim keepOrDropDim+  ) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape'+maxValues input =+  unsafePerformIO $+    ATen.cast3+      ATen.Managed.max_values_tlb+      input+      (natValI @dim)+      (keepOrDropDimVal @keepOrDropDim)++-- | minValues+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> t = ones :: CPUTensor 'D.Float '[3,4,5]+-- >>> dtype &&& shape $ minValues @0 @KeepDim t+-- (Float,[1,4,5])+-- >>> dtype &&& shape $ minValues @0 @DropDim t+-- (Float,[4,5])+-- >>> dtype &&& shape $ minValues @1 @KeepDim t+-- (Float,[3,1,5])+-- >>> dtype &&& shape $ minValues @1 @DropDim t+-- (Float,[3,5])+minValues ::+  forall dim keepOrDropDim shape' shape dtype device.+  ( KnownNat dim,+    KnownKeepOrDropDim keepOrDropDim,+    shape' ~ ConditionalDropDimension shape dim keepOrDropDim+  ) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape'+minValues input =+  unsafePerformIO $+    ATen.cast3+      ATen.Managed.min_values_tlb+      input+      (natValI @dim)+      (keepOrDropDimVal @keepOrDropDim)++-- | maxPool1d+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> t = maxPool1d @1 @1 @0 (ones :: CPUTensor 'D.Float '[1,3,4])+-- >>> shape t+-- [1,3,4]+-- >>> :t t+-- t :: Tensor '(D.CPU, 0) 'D.Float [1, 3, 4]+maxPool1d ::+  forall kernelSize stride padding channelSize inputSize batchSize outputSize dtype device.+  ( All+      KnownNat+      '[ kernelSize,+         stride,+         padding,+         channelSize,+         inputSize,+         batchSize+       ],+    ConvSideCheck inputSize kernelSize stride padding outputSize+  ) =>+  -- | input+  Tensor device dtype '[batchSize, channelSize, inputSize] ->+  -- | output+  Tensor device dtype '[batchSize, channelSize, outputSize]+maxPool1d input =+  unsafePerformIO $+    ATen.cast6+      ATen.Managed.max_pool1d_tllllb+      input+      (natValI @kernelSize)+      (natValI @stride)+      (natValI @padding)+      (1 :: Int)+      False++-- max_pool1d_with_indices :: Tensor device dtype shape -> Int -> Int -> Int -> Int -> Bool -> (Tensor device dtype shape,Tensor device dtype shape)+-- max_pool1d_with_indices _input _kernel_size _stride _padding _dilation _ceil_mode = unsafePerformIO $ (ATen.cast6 ATen.Managed.max_pool1d_with_indices_tllllb) _input _kernel_size _stride _padding _dilation _ceil_mode++-- | maxPool2d+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> t = maxPool2d @'(1,1) @'(1,1) @'(0,0) (ones :: CPUTensor 'D.Float '[1,3,4,5]) -- Skip warning+-- ...+-- >>> shape t+-- [1,3,4,5]+-- >>> :t t+-- t :: Tensor '(D.CPU, 0) 'D.Float [1, 3, 4, 5]+maxPool2d ::+  forall kernelSize stride padding channelSize inputSize0 inputSize1 batchSize outputSize0 outputSize1 dtype device.+  ( All+      KnownNat+      '[ Torch.Typed.Auxiliary.Fst kernelSize,+         Torch.Typed.Auxiliary.Snd kernelSize,+         Torch.Typed.Auxiliary.Fst stride,+         Torch.Typed.Auxiliary.Snd stride,+         Torch.Typed.Auxiliary.Fst padding,+         Torch.Typed.Auxiliary.Snd padding,+         channelSize,+         inputSize0,+         inputSize1,+         batchSize+       ],+    ConvSideCheck inputSize0 (Torch.Typed.Auxiliary.Fst kernelSize) (Torch.Typed.Auxiliary.Fst stride) (Torch.Typed.Auxiliary.Fst padding) outputSize0,+    ConvSideCheck inputSize1 (Torch.Typed.Auxiliary.Snd kernelSize) (Torch.Typed.Auxiliary.Snd stride) (Torch.Typed.Auxiliary.Snd padding) outputSize1+  ) =>+  -- | input+  Tensor device dtype '[batchSize, channelSize, inputSize0, inputSize1] ->+  -- | output+  Tensor device dtype '[batchSize, channelSize, outputSize0, outputSize1]+maxPool2d input =+  unsafePerformIO $+    ATen.cast6+      ATen.Managed.max_pool2d_tllllb+      input+      ([natValI @(Torch.Typed.Auxiliary.Fst kernelSize), natValI @(Torch.Typed.Auxiliary.Snd kernelSize)] :: [Int])+      ([natValI @(Torch.Typed.Auxiliary.Fst stride), natValI @(Torch.Typed.Auxiliary.Snd stride)] :: [Int])+      ([natValI @(Torch.Typed.Auxiliary.Fst padding), natValI @(Torch.Typed.Auxiliary.Snd padding)] :: [Int])+      ([1, 1] :: [Int])+      False++-- | mkldnnMaxPool2d+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+-- TODO: does this function work, that is, does it return values without throwing? when does it work?+-- TODO: this should probably be only callable if the device is MKLDNN?+-- -- >>> t = mkldnnMaxPool2d @'(1,1) @'(1,1) @'(0,0) (toMKLDNN (ones :: CPUTensor 'D.Float '[1,3,4,5]))+-- -- >>> shape t+-- -- [1,3,4,5]+-- -- >>> :t t+-- -- t :: Tensor '(D.CPU, 0) 'D.Float '[1, 3, 4, 5]+mkldnnMaxPool2d ::+  forall kernelSize stride padding channelSize inputSize0 inputSize1 batchSize outputSize0 outputSize1 dtype device.+  ( All+      KnownNat+      '[ Torch.Typed.Auxiliary.Fst kernelSize,+         Torch.Typed.Auxiliary.Snd kernelSize,+         Torch.Typed.Auxiliary.Fst stride,+         Torch.Typed.Auxiliary.Snd stride,+         Torch.Typed.Auxiliary.Fst padding,+         Torch.Typed.Auxiliary.Snd padding,+         channelSize,+         inputSize0,+         inputSize1,+         batchSize+       ],+    ConvSideCheck inputSize0 (Torch.Typed.Auxiliary.Fst kernelSize) (Torch.Typed.Auxiliary.Fst stride) (Torch.Typed.Auxiliary.Fst padding) outputSize0,+    ConvSideCheck inputSize1 (Torch.Typed.Auxiliary.Snd kernelSize) (Torch.Typed.Auxiliary.Snd stride) (Torch.Typed.Auxiliary.Snd padding) outputSize1+  ) =>+  -- | input+  Tensor device dtype '[batchSize, channelSize, inputSize0, inputSize1] ->+  -- | output+  Tensor device dtype '[batchSize, channelSize, outputSize0, outputSize1]+mkldnnMaxPool2d input =+  unsafePerformIO $+    ATen.cast6+      ATen.Managed.mkldnn_max_pool2d_tllllb+      input+      ([natValI @(Torch.Typed.Auxiliary.Fst kernelSize), natValI @(Torch.Typed.Auxiliary.Snd kernelSize)] :: [Int])+      ([natValI @(Torch.Typed.Auxiliary.Fst stride), natValI @(Torch.Typed.Auxiliary.Snd stride)] :: [Int])+      ([natValI @(Torch.Typed.Auxiliary.Fst padding), natValI @(Torch.Typed.Auxiliary.Snd padding)] :: [Int])+      ([1, 1] :: [Int])+      False++-- | quantizedMaxPool2d+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+-- TODO: what are quantized functions and when are they available?+-- -- >>> t = quantizedMaxPool2d @'(1,1) @'(1,1) @'(0,0) (ones :: CPUTensor 'D.Float '[1,3,4,5])+-- -- >>> shape t+-- -- [1,3,4,5]+-- -- >>> :t t+-- -- t :: Tensor 'D.Float '[1, 3, 4, 5]+quantizedMaxPool2d ::+  forall kernelSize stride padding channelSize inputSize0 inputSize1 batchSize outputSize0 outputSize1 dtype device.+  ( All+      KnownNat+      '[ Torch.Typed.Auxiliary.Fst kernelSize,+         Torch.Typed.Auxiliary.Snd kernelSize,+         Torch.Typed.Auxiliary.Fst stride,+         Torch.Typed.Auxiliary.Snd stride,+         Torch.Typed.Auxiliary.Fst padding,+         Torch.Typed.Auxiliary.Snd padding,+         channelSize,+         inputSize0,+         inputSize1,+         batchSize+       ],+    ConvSideCheck inputSize0 (Torch.Typed.Auxiliary.Fst kernelSize) (Torch.Typed.Auxiliary.Fst stride) (Torch.Typed.Auxiliary.Fst padding) outputSize0,+    ConvSideCheck inputSize1 (Torch.Typed.Auxiliary.Snd kernelSize) (Torch.Typed.Auxiliary.Snd stride) (Torch.Typed.Auxiliary.Snd padding) outputSize1+  ) =>+  -- | input+  Tensor device dtype '[batchSize, channelSize, inputSize0, inputSize1] ->+  -- | output+  Tensor device dtype '[batchSize, channelSize, outputSize0, outputSize1]+quantizedMaxPool2d input =+  unsafePerformIO $+    ATen.cast5+      ATen.Managed.quantized_max_pool2d_tllll+      input+      ([natValI @(Torch.Typed.Auxiliary.Fst kernelSize), natValI @(Torch.Typed.Auxiliary.Snd kernelSize)] :: [Int])+      ([natValI @(Torch.Typed.Auxiliary.Fst stride), natValI @(Torch.Typed.Auxiliary.Snd stride)] :: [Int])+      ([natValI @(Torch.Typed.Auxiliary.Fst padding), natValI @(Torch.Typed.Auxiliary.Snd padding)] :: [Int])+      ([1, 1] :: [Int])++-- | maxPool3d+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> t = maxPool3d @'(1,1,1) @'(1,1,1) @'(0,0,0) (ones :: CPUTensor 'D.Float '[1,3,4,5,6])+-- >>> shape t+-- [1,3,4,5,6]+-- >>> :t t+-- t :: Tensor '(D.CPU, 0) 'D.Float [1, 3, 4, 5, 6]+maxPool3d ::+  forall+    kernelSize+    stride+    padding+    channelSize+    inputSize0+    inputSize1+    inputSize2+    batchSize+    outputSize0+    outputSize1+    outputSize2+    dtype+    device.+  ( All+      KnownNat+      '[ Fst3 kernelSize,+         Snd3 kernelSize,+         Trd3 kernelSize,+         Fst3 stride,+         Snd3 stride,+         Trd3 stride,+         Fst3 padding,+         Snd3 padding,+         Trd3 padding,+         channelSize,+         inputSize0,+         inputSize1,+         inputSize2,+         batchSize+       ],+    ConvSideCheck inputSize0 (Fst3 kernelSize) (Fst3 stride) (Fst3 padding) outputSize0,+    ConvSideCheck inputSize1 (Snd3 kernelSize) (Snd3 stride) (Snd3 padding) outputSize1,+    ConvSideCheck inputSize2 (Trd3 kernelSize) (Trd3 stride) (Trd3 padding) outputSize2+  ) =>+  -- | input+  Tensor device dtype '[batchSize, channelSize, inputSize0, inputSize1, inputSize2] ->+  -- | output+  Tensor device dtype '[batchSize, channelSize, outputSize0, outputSize1, outputSize2]+maxPool3d input =+  unsafePerformIO $+    ATen.cast6+      ATen.Managed.max_pool3d_tllllb+      input+      ( [ natValI @(Fst3 kernelSize),+          natValI @(Snd3 kernelSize),+          natValI @(Trd3 kernelSize)+        ] ::+          [Int]+      )+      ([natValI @(Fst3 stride), natValI @(Snd3 stride), natValI @(Trd3 stride)] :: [Int])+      ([natValI @(Fst3 padding), natValI @(Snd3 padding), natValI @(Trd3 padding)] :: [Int])+      ([1, 1, 1] :: [Int])+      False++-- | maskedFill+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> t = ones :: CPUTensor 'D.Float '[2, 1, 3]+-- >>> m = fromJust [[False], [True], [False]] :: CPUTensor 'D.Bool '[3, 1]+-- >>> t' = maskedFill @Float m 0.5 t+-- >>> :type t'+-- t' :: Tensor '(D.CPU, 0) 'D.Float [2, 3, 3]+-- >>> dtype &&& shape &&& (\u -> D.asValue (toDynamic u) :: [[[Float]]]) $ t'+-- (Float,([2,3,3],[[[1.0,1.0,1.0],[0.5,0.5,0.5],[1.0,1.0,1.0]],[[1.0,1.0,1.0],[0.5,0.5,0.5],[1.0,1.0,1.0]]]))+maskedFill ::+  forall a shape shape' shape'' dtype device.+  (D.Scalar a, shape'' ~ Broadcast shape shape') =>+  -- | mask+  Tensor device 'D.Bool shape' ->+  -- | fill value+  a ->+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape''+maskedFill mask value input =+  unsafePerformIO $ ATen.cast3 ATen.Managed.masked_fill_tts input mask value++-- mkldnn_convolution :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> [Int] -> [Int] -> [Int] -> Int -> Tensor device dtype shape+-- mkldnn_convolution _input _weight _bias _padding _stride _dilation _groups = unsafePerformIO $ (ATen.cast7 ATen.Managed.mkldnn_convolution_tttllll) _input _weight _bias _padding _stride _dilation _groups++-- miopen_batch_norm :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Bool -> Double -> Double -> (Tensor device dtype shape,Tensor device dtype shape,Tensor device dtype shape)+-- miopen_batch_norm _input _weight _bias _running_mean _running_var _training _exponential_average_factor _epsilon = unsafePerformIO $ (ATen.cast8 ATen.Managed.miopen_batch_norm_tttttbdd) _input _weight _bias _running_mean _running_var _training _exponential_average_factor _epsilon++-- miopen_convolution :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> [Int] -> [Int] -> [Int] -> Int -> Bool -> Bool -> Tensor device dtype shape+-- miopen_convolution _input _weight _bias _padding _stride _dilation _groups _benchmark _deterministic = unsafePerformIO $ (ATen.cast9 ATen.Managed.miopen_convolution_tttllllbb) _input _weight _bias _padding _stride _dilation _groups _benchmark _deterministic++-- miopen_convolution_transpose :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> [Int] -> [Int] -> [Int] -> [Int] -> Int -> Bool -> Bool -> Tensor device dtype shape+-- miopen_convolution_transpose _input _weight _bias _padding _output_padding _stride _dilation _groups _benchmark _deterministic = unsafePerformIO $ (ATen.ATen.cast10 ATen.Managed.miopen_convolution_transpose_tttlllllbb) _input _weight _bias _padding _output_padding _stride _dilation _groups _benchmark _deterministic++-- miopen_depthwise_convolution :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> [Int] -> [Int] -> [Int] -> Int -> Bool -> Bool -> Tensor device dtype shape+-- miopen_depthwise_convolution _input _weight _bias _padding _stride _dilation _groups _benchmark _deterministic = unsafePerformIO $ (ATen.cast9 ATen.Managed.miopen_depthwise_convolution_tttllllbb) _input _weight _bias _padding _stride _dilation _groups _benchmark _deterministic++-- miopen_rnn :: Tensor device dtype shape -> [Tensor device dtype shape] -> Int -> Tensor device dtype shape -> Tensor device dtype shape -> Int -> Int -> Int -> Bool -> Double -> Bool -> Bool -> [Int] -> Tensor device dtype shape -> (Tensor device dtype shape,Tensor device dtype shape,Tensor device dtype shape,Tensor device dtype shape,Tensor device dtype shape)+-- miopen_rnn _input _weight _weight_stride0 _hx _cx _mode _hidden_size _num_layers _batch_first _dropout _train _bidirectional _batch_sizes _dropout_state = unsafePerformIO $ (ATen.ATen.cast14 ATen.Managed.miopen_rnn_tllttlllbdbblt) _input _weight _weight_stride0 _hx _cx _mode _hidden_size _num_layers _batch_first _dropout _train _bidirectional _batch_sizes _dropout_state++-- | matrix-matrix multiplication+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> dtype &&& shape $ mm (ones :: CPUTensor 'D.Float '[3,2]) (zeros :: CPUTensor 'D.Float '[2,4])+-- (Float,[3,4])+mm ::+  forall n k m dtype device.+  -- | first input matrix+  Tensor device dtype '[n, k] ->+  -- | second input matrix+  Tensor device dtype '[k, m] ->+  -- | output matrix+  Tensor device dtype '[n, m]+mm a b = unsafePerformIO $ ATen.cast2 ATen.Managed.mm_tt a b++-- | matrix-vector multiplication+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> dtype &&& shape $ mv (ones :: CPUTensor 'D.Float '[3,2]) (zeros :: CPUTensor 'D.Float '[2])+-- (Float,[3])+mv ::+  forall n m dtype device.+  -- | input matrix+  Tensor device dtype '[n, m] ->+  -- | input vector+  Tensor device dtype '[m] ->+  -- | output vector+  Tensor device dtype '[n]+mv input vec = unsafePerformIO $ ATen.cast2 ATen.Managed.mv_tt input vec++-- mvlgamma :: Tensor device dtype shape -> Int -> Tensor device dtype shape+-- mvlgamma _input _p = unsafePerformIO $ (ATen.cast2 ATen.Managed.mvlgamma_tl) _input _p++type family+  NarrowCheck+    (mbCurrent :: Maybe Nat)+    (mbUpdated :: Maybe [Nat])+    (shape :: [Nat])+    (dim :: Nat)+    (start :: Nat)+    (length :: Nat) ::+    [Nat]+  where+  NarrowCheck Nothing _ sh d _ _ = DimOutOfBound sh d+  NarrowCheck (Just c) Nothing sh d s l = DimOutOfBound sh d+  NarrowCheck _ (Just r) _ _ _ _ = r++type family Narrow' (dim :: Nat) (shape :: [Nat]) (current :: Maybe Nat) (start :: Nat) (length :: Nat) :: Maybe [Nat] where+  Narrow' d sh (Just c) s l =+    If+      ((s + l) <=? c)+      (ReplaceDim d sh l)+      ( TypeError+          ( Text "The end of the requested narrow segment "+              :<>: ShowType (s + l)+              :<>: Text " would be larger than current size "+              :<>: ShowType c+              :<>: Text " at dimension "+              :<>: ShowType d+          )+      )+  Narrow' d sh Nothing s l =+    TypeError+      ( Text "Requested narrow dimension "+          :<>: ShowType d+          :<>: Text " doesnt exist in "+          :<>: ShowType sh+      )++type family Narrow (shape :: [Nat]) (dim :: Nat) (start :: Nat) (length :: Nat) :: [Nat] where+  Narrow shape dim start length =+    NarrowCheck (ExtractDim dim shape) (Narrow' dim shape (ExtractDim dim shape) start length) shape dim start length++-- | "Narrow" a tensor by returning a tensor that is a slice from 'start' of length 'length' along 'dim'+--+-- >>> dtype &&& shape $ narrow @0 @0 @2 (ones :: CPUTensor 'D.Float '[3,3,3])+-- (Float,[2,3,3])+-- >>> dtype &&& shape $ narrow @1 @1 @2 (ones :: CPUTensor 'D.Half '[3,3,3])+-- (Half,[3,2,3])+-- >>> dtype &&& shape $ narrow @1 @1 @2 (ones :: CPUTensor 'D.Bool '[3,3,3])+-- (Bool,[3,2,3])+narrow ::+  forall dim start length shape mbSize mbNewShape dtype device.+  ( All KnownNat '[dim, start, length],+    All KnownNat shape+  ) =>+  Tensor device dtype shape ->+  Tensor device dtype (Narrow shape dim start length)+narrow _input = unsafePerformIO $ (ATen.cast4 ATen.Managed.narrow_tlll) _input _dim _start _length+  where+    _dim = natValI @dim+    _start = natValI @start+    _length = natValI @length++-- native_batch_norm :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Bool -> Double -> Double -> (Tensor device dtype shape,Tensor device dtype shape,Tensor device dtype shape)+-- native_batch_norm _input _weight _bias _running_mean _running_var _training _momentum _eps = unsafePerformIO $ (ATen.cast8 ATen.Managed.native_batch_norm_tttttbdd) _input _weight _bias _running_mean _running_var _training _momentum _eps++-- batch_norm_stats :: Tensor device dtype shape -> Double -> (Tensor device dtype shape,Tensor device dtype shape)+-- batch_norm_stats _input _eps = unsafePerformIO $ (ATen.cast2 ATen.Managed.batch_norm_stats_td) _input _eps++-- batch_norm_elemt :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Double -> Tensor device dtype shape+-- batch_norm_elemt _input _weight _bias _mean _invstd _eps = unsafePerformIO $ (ATen.cast6 ATen.Managed.batch_norm_elemt_tttttd) _input _weight _bias _mean _invstd _eps++-- batch_norm_gather_stats :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Double -> Double -> Int -> (Tensor device dtype shape,Tensor device dtype shape)+-- batch_norm_gather_stats _input _mean _invstd _running_mean _running_var _momentum _eps _count = unsafePerformIO $ (ATen.cast8 ATen.Managed.batch_norm_gather_stats_tttttddl) _input _mean _invstd _running_mean _running_var _momentum _eps _count++-- batch_norm_gather_stats_with_counts :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Double -> Double -> [Int] -> (Tensor device dtype shape,Tensor device dtype shape)+-- batch_norm_gather_stats_with_counts _input _mean _invstd _running_mean _running_var _momentum _eps _counts = unsafePerformIO $ (ATen.cast8 ATen.Managed.batch_norm_gather_stats_with_counts_tttttddl) _input _mean _invstd _running_mean _running_var _momentum _eps _counts++-- batch_norm_update_stats :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Double -> (Tensor device dtype shape,Tensor device dtype shape)+-- batch_norm_update_stats _input _running_mean _running_var _momentum = unsafePerformIO $ (ATen.cast4 ATen.Managed.batch_norm_update_stats_tttd) _input _running_mean _running_var _momentum++-- | onesLike+--+-- >>> dtype &&& shape $ onesLike (ones :: CPUTensor 'D.Float '[3,4,5])+-- (Float,[3,4,5])+onesLike ::+  forall shape dtype device.+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+onesLike input = unsafePerformIO $ ATen.cast1 ATen.Managed.ones_like_t input++-- pairwise_distance :: Tensor device dtype shape -> Tensor device dtype shape -> Double -> Double -> Bool -> Tensor device dtype shape+-- pairwise_distance _x1 _x2 _p _eps _keepdim = unsafePerformIO $ (ATen.cast5 ATen.Managed.pairwise_distance_ttddb) _x1 _x2 _p _eps _keepdim++-- cdist :: Tensor device dtype shape -> Tensor device dtype shape -> Double -> Tensor device dtype shape+-- cdist _x1 _x2 _p = unsafePerformIO $ (ATen.cast3 ATen.Managed.cdist_ttd) _x1 _x2 _p++-- pdist :: Tensor device dtype shape -> Double -> Tensor device dtype shape+-- pdist _input _p = unsafePerformIO $ (ATen.cast2 ATen.Managed.pdist_td) _input _p++-- cosine_similarity :: Tensor device dtype shape -> Tensor device dtype shape -> Int -> Double -> Tensor device dtype shape+-- cosine_similarity _x1 _x2 _dim _eps = unsafePerformIO $ (ATen.cast4 ATen.Managed.cosine_similarity_ttld) _x1 _x2 _dim _eps++-- pixel_shuffle :: Tensor device dtype shape -> Int -> Tensor device dtype shape+-- pixel_shuffle _input _upscale_factor = unsafePerformIO $ (ATen.cast2 ATen.Managed.pixel_shuffle_tl) _input _upscale_factor++-- pin_memory :: Tensor device dtype shape -> Tensor device dtype shape+-- pin_memory _input = unsafePerformIO $ (ATen.cast1 ATen.Managed.pin_memory_t) _input++-- pinverse :: Tensor device dtype shape -> Double -> Tensor device dtype shape+-- pinverse _input _rcond = unsafePerformIO $ (ATen.cast2 ATen.Managed.pinverse_td) _input _rcond++-- poisson_nll_loss :: Tensor device dtype shape -> Tensor device dtype shape -> Bool -> Bool -> Double -> Int -> Tensor device dtype shape+-- poisson_nll_loss _input _target _log_input _full _eps _reduction = unsafePerformIO $ (ATen.cast6 ATen.Managed.poisson_nll_loss_ttbbdl) _input _target _log_input _full _eps _reduction++-- | randLike+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> t <- randLike (ones :: CPUTensor 'D.Float '[3,4,5])+-- >>> dtype &&& shape $ t+-- (Float,[3,4,5])+randLike ::+  forall shape dtype device.+  -- | input+  Tensor device dtype shape ->+  -- | output+  IO (Tensor device dtype shape)+randLike = ATen.cast1 ATen.Managed.rand_like_t++-- | randnLike+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> t <- randnLike (ones :: CPUTensor 'D.Float '[3,4,5])+-- >>> dtype &&& shape $ t+-- (Float,[3,4,5])+randnLike ::+  forall shape dtype device.+  -- | input+  Tensor device dtype shape ->+  -- | output+  IO (Tensor device dtype shape)+randnLike = ATen.cast1 ATen.Managed.randn_like_t++-- | reciprocal+--+-- >>> dtype &&& shape $ reciprocal (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+reciprocal ::+  forall shape dtype device.+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+reciprocal _input = unsafePerformIO $ (ATen.cast1 ATen.Managed.reciprocal_t) _input++-- | negate+-- TODO: probably not defined for `D.Bool` tensors+--+-- >>> dtype &&& shape $ neg (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+neg ::+  forall shape dtype device.+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+neg input = unsafePerformIO $ ATen.cast1 ATen.Managed.neg_t input++-- | round+-- TODO: probably only defined for floating point tensors+--+-- >>> dtype &&& shape $ round (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+round ::+  forall shape dtype device.+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+round input = unsafePerformIO $ ATen.cast1 ATen.Managed.round_t input++-- | prelu activation function+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> dtype &&& shape $ prelu (ones :: CPUTensor 'D.Float '[]) (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+prelu ::+  forall shape dtype device.+  -- | weight+  Tensor device dtype '[] ->+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+prelu weight input = unsafePerformIO $ ATen.cast2 ATen.Managed.prelu_tt input weight++type family GeluDTypeIsValid (device :: (D.DeviceType, Nat)) (dtype :: D.DType) :: Constraint where+  GeluDTypeIsValid '(D.CPU, 0) dtype =+    ( DTypeIsFloatingPoint '(D.CPU, 0) dtype,+      DTypeIsNotHalf '(D.CPU, 0) dtype+    )+  GeluDTypeIsValid '( 'D.CUDA, deviceIndex) dtype =+    ( DTypeIsFloatingPoint '( 'D.CUDA, deviceIndex) dtype,+      DTypeIsNotHalf '( 'D.CUDA, deviceIndex) dtype+    )+  GeluDTypeIsValid '( 'D.MPS, 0) dtype =+    ( DTypeIsFloatingPoint '( 'D.MPS, 0) dtype,+      DTypeIsNotHalf '( 'D.MPS, 0) dtype+    )+  GeluDTypeIsValid '(deviceType, _) dtype = UnsupportedDTypeForDevice deviceType dtype++-- | gelu activation function+--+-- >>> dtype &&& shape $ round (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+gelu ::+  forall shape dtype device.+  (GeluDTypeIsValid device dtype) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+gelu input = unsafePerformIO $ ATen.cast1 ATen.Managed.gelu_t input++-- hardshrink :: Tensor device dtype shape -> Float -> Tensor device dtype shape+-- hardshrink _input _lambd = unsafePerformIO $ (ATen.cast2 ATen.Managed.hardshrink_ts) _input _lambd++-- | rsqrt+--+-- >>> dtype &&& shape $ rsqrt (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+rsqrt ::+  forall shape dtype device.+  (StandardFloatingPointDTypeValidation device dtype) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+rsqrt input = unsafePerformIO $ ATen.cast1 ATen.Managed.rsqrt_t input++-- | celu activation function+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> dtype &&& shape $ celu 3.0 (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+celu ::+  forall shape dtype device.+  -- | alpha+  Float ->+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+celu alpha input = unsafePerformIO $ ATen.cast2 ATen.Managed.celu_ts input alpha++-- slice :: Tensor device dtype shape -> Int -> Int -> Int -> Int -> Tensor device dtype shape+-- slice _input _dim _start _end _step = unsafePerformIO $ (ATen.cast5 ATen.Managed.slice_tllll) _input _dim _start _end _step++-- slogdet :: Tensor device dtype shape -> (Tensor device dtype shape,Tensor device dtype shape)+-- slogdet _input = unsafePerformIO $ (ATen.cast1 ATen.Managed.slogdet_t) _input++-- smm :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape+-- smm _input _mat2 = unsafePerformIO $ (ATen.cast2 ATen.Managed.smm_tt) _input _mat2++-- split :: Tensor device dtype shape -> Int -> Int -> [Tensor device dtype shape]+-- split _input _split_size _dim = unsafePerformIO $ (ATen.cast3 ATen.Managed.split_tll) _input _split_size _dim++-- split_with_sizes :: Tensor device dtype shape -> [Int] -> Int -> [Tensor device dtype shape]+-- split_with_sizes _input _split_sizes _dim = unsafePerformIO $ (ATen.cast3 ATen.Managed.split_with_sizes_tll) _input _split_sizes _dim++-- sspaddmm :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Float -> Float -> Tensor device dtype shape+-- sspaddmm _input _mat1 _mat2 _beta _alpha = unsafePerformIO $ (ATen.cast5 ATen.Managed.sspaddmm_tttss) _input _mat1 _mat2 _beta _alpha++type family StackImpl (dim :: Nat) (tensors :: [a]) (count :: Nat) :: Maybe ([Nat], D.DType, (D.DeviceType, Nat)) where+  StackImpl dim '[] count = Nothing+  StackImpl dim (Tensor device dtype shape ': '[]) count = MaybeTriple (ComputeStackShape shape dim count) (Just dtype) (Just device)+  StackImpl dim (Tensor device dtype shape ': Tensor device dtype shape ': tensors) count = StackImpl dim (Tensor device dtype shape ': tensors) (count + 1)+  StackImpl _ _ _ = Nothing++type family MaybePair (a' :: Maybe a) (b' :: Maybe b) :: Maybe (a, b) where+  MaybePair Nothing _ = Nothing+  MaybePair _ Nothing = Nothing+  MaybePair (Just a') (Just b') = Just '(a', b')++type family MaybeTriple (a' :: Maybe a) (b' :: Maybe b) (c' :: Maybe c) :: Maybe (a, b, c) where+  MaybeTriple Nothing _ _ = Nothing+  MaybeTriple _ Nothing _ = Nothing+  MaybeTriple _ _ Nothing = Nothing+  MaybeTriple (Just a') (Just b') (Just c') = Just '(a', b', c')++type family ComputeStackShape (shape :: [Nat]) (dim :: Nat) (count :: Nat) :: Maybe [Nat] where+  ComputeStackShape _ _ 0 = Nothing+  ComputeStackShape xs 0 count = Just (count ': xs)+  ComputeStackShape (x ': xs) dim count = AppendToMaybe x (ComputeStackShape xs (dim - 1) count)+  ComputeStackShape '[] _ _ = Nothing++type family StackCheck (res :: Maybe ([Nat], D.DType, (D.DeviceType, Nat))) :: ([Nat], D.DType, (D.DeviceType, Nat)) where+  StackCheck 'Nothing = TypeError (Text "Stacking impossible.")+  StackCheck ('Just '(shape, dtype, device)) = '(shape, dtype, device)++-- | Stack+--+-- >>> type Ty = Stack 0 '[Tensor '(D.CPU, 0) 'D.Float '[]]+-- >>> :kind! Ty+-- Ty :: ([Natural], D.DType, (D.DeviceType, Natural))+-- = '( '[1], 'D.Float, '(D.CPU, 0))+-- >>> type Ty = Stack 0 '[Tensor '(D.CPU, 0) 'D.Float '[2,2]]+-- >>> :kind! Ty+-- Ty :: ([Natural], D.DType, (D.DeviceType, Natural))+-- = '([1, 2, 2], 'D.Float, '(D.CPU, 0))+-- >>> type Ty = Stack 1 '[Tensor '(D.CPU, 0) 'D.Float '[2,2]]+-- >>> :kind! Ty+-- Ty :: ([Natural], D.DType, (D.DeviceType, Natural))+-- = '([2, 1, 2], 'D.Float, '(D.CPU, 0))+-- >>> type Ty = Stack 2 '[Tensor '(D.CPU, 0) 'D.Float '[2,2]]+-- >>> :kind! Ty+-- Ty :: ([Natural], D.DType, (D.DeviceType, Natural))+-- = '([2, 2, 1], 'D.Float, '(D.CPU, 0))+-- >>> type Ty = Stack 2 '[Tensor '(D.CPU, 0) 'D.Float '[2,2], Tensor '(D.CPU, 0) 'D.Float '[2,2], Tensor '(D.CPU, 0) 'D.Float '[2,2]]+-- >>> :kind! Ty+-- Ty :: ([Natural], D.DType, (D.DeviceType, Natural))+-- = '([2, 2, 3], 'D.Float, '(D.CPU, 0))+type Stack dim tensors = StackCheck (StackImpl dim tensors 1)++-- | stack+--+-- >>> t = ones :: CPUTensor 'D.Float '[]+-- >>> t' = stack @0 (t :. HNil)+-- >>> :type t'+-- t' :: Tensor '(D.CPU, 0) 'D.Float '[1]+-- >>> dtype &&& shape &&& (\t'' -> D.asValue (toDynamic t'') :: [Float]) $ t'+-- (Float,([1],[1.0]))+-- >>> t = ones :: CPUTensor 'D.Float '[2,2]+-- >>> t' = stack @0 (t :. HNil)+-- >>> :type t'+-- t' :: Tensor '(D.CPU, 0) 'D.Float [1, 2, 2]+-- >>> dtype &&& shape &&& (\t'' -> D.asValue (toDynamic t'') :: [[[Float]]]) $ t'+-- (Float,([1,2,2],[[[1.0,1.0],[1.0,1.0]]]))+-- >>> t' = stack @1 (t :. HNil)+-- >>> :type t'+-- t' :: Tensor '(D.CPU, 0) 'D.Float [2, 1, 2]+-- >>> dtype &&& shape &&& (\t'' -> D.asValue (toDynamic t'') :: [[[Float]]]) $ t'+-- (Float,([2,1,2],[[[1.0,1.0]],[[1.0,1.0]]]))+-- >>> t' = stack @2 (t :. HNil)+-- >>> :type t'+-- t' :: Tensor '(D.CPU, 0) 'D.Float [2, 2, 1]+-- >>> dtype &&& shape &&& (\t'' -> D.asValue (toDynamic t'') :: [[[Float]]]) $ t'+-- (Float,([2,2,1],[[[1.0],[1.0]],[[1.0],[1.0]]]))+-- >>> t' = stack @2 (t :. t :. t :. HNil)+-- >>> :type t'+-- t' :: Tensor '(D.CPU, 0) 'D.Float [2, 2, 3]+-- >>> dtype &&& shape &&& (\t'' -> D.asValue (toDynamic t'') :: [[[Float]]]) $ t'+-- (Float,([2,2,3],[[[1.0,1.0,1.0],[1.0,1.0,1.0]],[[1.0,1.0,1.0],[1.0,1.0,1.0]]]))+stack ::+  forall dim shape dtype device tensors.+  ( KnownNat dim,+    '(shape, dtype, device) ~ Stack dim tensors,+    ATen.Castable (HList tensors) [D.ATenTensor]+  ) =>+  -- | input list of tensors+  HList tensors ->+  -- | output+  Tensor device dtype shape+stack tensors = unsafePerformIO $ ATen.cast2 ATen.Managed.stack_ll tensors (natValI @dim :: Int)++vecStack ::+  forall dim n shape dtype device.+  (KnownNat dim, KnownNat n) =>+  -- | Input list of tensors+  Vector n (Tensor device dtype shape) ->+  -- | Output list of tensors+  Tensor device dtype (Insert dim n shape)+vecStack tensors = unsafePerformIO $ ATen.cast2 ATen.Managed.stack_ll tensors (natValI @dim :: Int)++-- stft :: Tensor device dtype shape -> Int -> Int -> Int -> Tensor device dtype shape -> Bool -> Bool -> Tensor device dtype shape+-- stft _input _n_fft _hop_length _win_length _window _normalized _onesided = unsafePerformIO $ (ATen.cast7 ATen.Managed.stft_tllltbb) _input _n_fft _hop_length _win_length _window _normalized _onesided++-- stride :: Tensor device dtype shape -> Int -> Int+-- stride _input _dim = unsafePerformIO $ (ATen.cast2 ATen.Managed.stride_tl) _input _dim++-- | t+--+-- dtype &&& shape $ t ones :: CPUTensor 'D.Float '[3,2]+-- (Float,[3,2])+t ::+  forall shape dtype device.+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+t _input = unsafePerformIO $ (ATen.cast1 ATen.Managed.t_t) _input++-- | tan+--+-- >>> dtype &&& shape $ tan (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+tan ::+  forall shape dtype device.+  (StandardFloatingPointDTypeValidation device dtype) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+tan input = unsafePerformIO $ ATen.cast1 ATen.Managed.tan_t input++-- tensordot :: Tensor device dtype shape -> Tensor device dtype shape -> [Int] -> [Int] -> Tensor device dtype shape+-- tensordot _input _other _dims_input _dims_other = unsafePerformIO $ (ATen.cast4 ATen.Managed.tensordot_ttll) _input _other _dims_input _dims_other++-- threshold :: Tensor device dtype shape -> Float -> Float -> Tensor device dtype shape+-- threshold _input _threshold _value = unsafePerformIO $ (ATen.cast3 ATen.Managed.threshold_tss) _input _threshold _value++-- one_hot :: Tensor device dtype shape -> Int -> Tensor device dtype shape+-- one_hot _input _num_classes = unsafePerformIO $ (ATen.cast2 ATen.Managed.one_hot_tl) _input _num_classes++-- flip :: Tensor device dtype shape -> [Int] -> Tensor device dtype shape+-- flip _input _dims = unsafePerformIO $ (ATen.cast2 ATen.Managed.flip_tl) _input _dims++-- roll :: Tensor device dtype shape -> Int -> Int -> Tensor device dtype shape+-- roll _input _shifts _dims = unsafePerformIO $ (ATen.cast3 ATen.Managed.roll_tll) _input _shifts _dims++-- rot90 :: Tensor device dtype shape -> Int -> [Int] -> Tensor device dtype shape+-- rot90 _input _k _dims = unsafePerformIO $ (ATen.cast3 ATen.Managed.rot90_tll) _input _k _dims++-- triplet_margin_loss :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Double -> Double -> Double -> Bool -> Int -> Tensor device dtype shape+-- triplet_margin_loss _anchor _positive _negative _margin _p _eps _swap _reduction = unsafePerformIO $ (ATen.cast8 ATen.Managed.triplet_margin_loss_tttdddbl) _anchor _positive _negative _margin _p _eps _swap _reduction++-- | trunc+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> dtype &&& shape $ trunc (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+trunc ::+  forall shape dtype device.+  (StandardFloatingPointDTypeValidation device dtype) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+trunc input = unsafePerformIO $ ATen.cast1 ATen.Managed.trunc_t input++-- unique_dim :: Tensor device dtype shape -> Int -> Bool -> Bool -> Bool -> (Tensor device dtype shape,Tensor device dtype shape,Tensor device dtype shape)+-- unique_dim _input _dim _sorted _return_inverse _return_counts = unsafePerformIO $ (ATen.cast5 ATen.Managed.unique_dim_tlbbb) _input _dim _sorted _return_inverse _return_counts++-- unique_consecutive :: Tensor device dtype shape -> Bool -> Bool -> Int -> (Tensor device dtype shape,Tensor device dtype shape,Tensor device dtype shape)+-- unique_consecutive _input _return_inverse _return_counts _dim = unsafePerformIO $ (ATen.cast4 ATen.Managed.unique_consecutive_tbbl) _input _return_inverse _return_counts _dim++-- unique_dim_consecutive :: Tensor device dtype shape -> Int -> Bool -> Bool -> (Tensor device dtype shape,Tensor device dtype shape,Tensor device dtype shape)+-- unique_dim_consecutive _input _dim _return_inverse _return_counts = unsafePerformIO $ (ATen.cast4 ATen.Managed.unique_dim_consecutive_tlbb) _input _dim _return_inverse _return_counts++-- | UnsqueezeImpl+--+-- >>> :kind! UnsqueezeImpl '[4] 0+-- UnsqueezeImpl '[4] 0 :: Maybe [Natural]+-- = Just [1, 4]+-- >>> :kind! UnsqueezeImpl '[4] 1+-- UnsqueezeImpl '[4] 1 :: Maybe [Natural]+-- = Just [4, 1]+-- >>> :kind! UnsqueezeImpl '[4] 2+-- UnsqueezeImpl '[4] 2 :: Maybe [Natural]+-- = Nothing+type family UnsqueezeImpl (shape :: [a]) (dim :: Nat) :: Maybe [a] where+  UnsqueezeImpl xs 0 = Just (1 ': xs)+  UnsqueezeImpl (x ': xs) dim = AppendToMaybe x (UnsqueezeImpl xs (dim - 1))+  UnsqueezeImpl '[] _ = Nothing++type family UnsqueezeCheck (shape :: [a]) (dim :: Nat) (result :: Maybe [a]) :: [a] where+  UnsqueezeCheck shape dim Nothing =+    TypeError+      ( Text "Cannot unsqueeze the tensor since the specified dimension "+          :<>: ShowType dim+          :<>: Text " is too large (the tensor is only "+          :<>: ShowType (ListLength shape)+          :<>: Text "D)"+      )+  UnsqueezeCheck _ _ (Just shape') = shape'++type Unsqueeze shape dim = UnsqueezeCheck shape dim (UnsqueezeImpl shape dim)++-- | unsqueeze+--+-- >>> t = fromJust [1, 2, 3, 4] :: CPUTensor 'D.Int64 '[4]+-- >>> t' = unsqueeze @0 t+-- >>> :type t'+-- t' :: Tensor '(D.CPU, 0) D.Int64 [1, 4]+-- >>> dtype &&& shape &&& (\u -> D.asValue (toDynamic u) :: [[Int]]) $ t'+-- (Int64,([1,4],[[1,2,3,4]]))+-- >>> t'' = unsqueeze @1 t+-- >>> :type t''+-- t'' :: Tensor '(D.CPU, 0) D.Int64 [4, 1]+-- >>> dtype &&& shape &&& (\u -> D.asValue (toDynamic u) :: [[Int]]) $ t''+-- (Int64,([4,1],[[1],[2],[3],[4]]))+unsqueeze ::+  forall dim shape shape' dtype device.+  (KnownNat dim, shape' ~ Unsqueeze shape dim) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape'+unsqueeze input = unsafePerformIO $ ATen.cast2 ATen.Managed.unsqueeze_tl input (natValI @dim)++type family SqueezeAll (shape :: [Nat]) :: [Nat] where+  SqueezeAll '[] = '[]+  SqueezeAll (1 ': xs) = SqueezeAll xs+  SqueezeAll (x ': xs) = x ': SqueezeAll xs++-- | squeeze all dimensions+--+-- >>> dtype &&& shape $ squeezeAll (ones :: CPUTensor 'D.Float '[2,1,2,1,2])+-- (Float,[2,2,2])+-- >>> squeezeAll (ones :: CPUTensor 'D.Float '[2,1,2,1,2])+-- Tensor Float [2,2,2] [[[ 1.0000   ,  1.0000   ],+--                        [ 1.0000   ,  1.0000   ]],+--                       [[ 1.0000   ,  1.0000   ],+--                        [ 1.0000   ,  1.0000   ]]]+squeezeAll ::+  forall shape shape' dtype device.+  (shape' ~ SqueezeAll shape) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape'+squeezeAll input = unsafePerformIO $ ATen.cast1 ATen.Managed.squeeze_t input++type family SqueezeDimImpl (shape :: [a]) (dim :: Nat) :: Maybe [a] where+  SqueezeDimImpl (1 ': xs) 0 = Just xs+  SqueezeDimImpl _ 0 = Nothing+  SqueezeDimImpl (x ': xs) dim = AppendToMaybe x (SqueezeDimImpl xs (dim - 1))+  SqueezeDimImpl _ _ = Nothing++type family SqueezeDimCheck (shape :: [a]) (dim :: Nat) (result :: Maybe [a]) :: [a] where+  SqueezeDimCheck shape dim Nothing = TypeError (Text "The tensor cannot be squeezed at the specified dimension " :<>: ShowType dim)+  SqueezeDimCheck _ _ ('Just shape') = shape'++-- | Calculate the output shape of a squeeze along a given dimension+--+-- >>> :kind! SqueezeDim '[2,1,2] 1+-- SqueezeDim '[2,1,2] 1 :: [Natural]+-- = [2, 2]+type SqueezeDim shape dim = SqueezeDimCheck shape dim (SqueezeDimImpl shape dim)++-- | squeeze a particular dimension+--+-- >>> dtype &&& shape $ squeezeDim @1 (ones :: CPUTensor 'D.Float '[2,1,2,1,2])+-- (Float,[2,2,1,2])+-- >>> dtype &&& shape $ squeezeDim @3 (ones :: CPUTensor 'D.Float '[2,1,2,1,2])+-- (Float,[2,1,2,2])+squeezeDim ::+  forall dim shape shape' dtype device.+  (KnownNat dim, shape' ~ SqueezeDim shape dim) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape'+squeezeDim input = unsafePerformIO $ ATen.cast2 ATen.Managed.squeeze_tl input (natValI @dim)++-- | return a tensor of elements selected from either input or other, depending on condition.+where' ::+  forall shape shape' shape'' shape''' shape'''' dtype device.+  ( shape'' ~ Broadcast shape shape',+    shape'''' ~ Broadcast shape''' shape''+  ) =>+  -- | condition+  Tensor device 'D.Bool shape ->+  -- | input+  Tensor device dtype shape' ->+  -- | other+  Tensor device dtype shape''' ->+  Tensor device dtype shape''''+where' _condition _input _other = unsafePerformIO $ (ATen.cast3 ATen.Managed.where_ttt) _condition _input _other++-- where_ :: Tensor device dtype shape -> [Tensor device dtype shape]+-- where_ _condition = unsafePerformIO $ (ATen.cast1 ATen.Managed.where_t) _condition++-- norm_except_dim :: Tensor device dtype shape -> Int -> Int -> Tensor device dtype shape+-- norm_except_dim _v _pow _dim = unsafePerformIO $ (ATen.cast3 ATen.Managed.norm_except_dim_tll) _v _pow _dim++-- | zerosLike+--+-- >>> dtype &&& shape $ zerosLike (ones :: CPUTensor 'D.Float '[3,4,5])+-- (Float,[3,4,5])+zerosLike ::+  forall shape dtype device.+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+zerosLike input = unsafePerformIO $ ATen.cast1 ATen.Managed.zeros_like_t input++-- native_norm :: Tensor device dtype shape -> Float -> Tensor device dtype shape+-- native_norm _input _p = unsafePerformIO $ (ATen.cast2 ATen.Managed.native_norm_ts) _input _p++-- | clone+--+-- >>> t <- clone (ones :: CPUTensor 'D.Float '[3,2])+-- >>> dtype &&& shape $ t+-- (Float,[3,2])+clone ::+  forall shape dtype device.+  Tensor device dtype shape ->+  IO (Tensor device dtype shape)+clone input = ATen.cast1 ATen.Managed.clone_t input++-- s_native_addmm :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Float -> Float -> Tensor device dtype shape+-- s_native_addmm _input _mat1 _mat2 _beta _alpha = unsafePerformIO $ (ATen.cast5 ATen.Managed.s_native_addmm_tttss) _input _mat1 _mat2 _beta _alpha++-- | addmm+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+-- TODO: can we use D.Scalar here for beta and alpha?+--+-- >>> t = addmm 1 1 (ones :: CPUTensor 'D.Float '[3,2]) (zeros :: CPUTensor 'D.Float '[2,4]) (ones :: CPUTensor 'D.Float '[])+-- >>> dtype &&& shape $ t+-- (Float,[3,4])+-- >>> :t t+-- t :: Tensor '(D.CPU, 0) 'D.Float [3, 4]+addmm ::+  forall shape' shape n k m dtype device.+  ( All KnownNat '[n, k, m],+    shape' ~ Broadcast shape '[n, m]+  ) =>+  -- | beta+  Float ->+  -- | alpha+  Float ->+  -- | first input matrix+  Tensor device dtype '[n, k] ->+  -- | second input matrix+  Tensor device dtype '[k, m] ->+  -- | input tensor+  Tensor device dtype shape ->+  -- | output tensor+  Tensor device dtype shape'+addmm beta alpha mat1 mat2 input = unsafePerformIO $ ATen.cast5 ATen.Managed.addmm_tttss input mat1 mat2 beta alpha++-- hspmm :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape+-- hspmm _mat1 _mat2 = unsafePerformIO $ (ATen.cast2 ATen.Managed.hspmm_tt) _mat1 _mat2++-- | numel+-- TODO: since this is decidable at compile time, this should probably be calculated from the tensor type instead+numel ::+  forall shape dtype device.+  -- | input+  Tensor device dtype shape ->+  -- | output+  Int+numel input = unsafePerformIO $ ATen.cast1 ATen.Managed.tensor_numel input++-- unbind :: Tensor device dtype shape -> Int -> [Tensor device dtype shape]+-- unbind _input _dim = unsafePerformIO $ (ATen.cast2 ATen.Managed.unbind_tl) _input _dim++-- mkldnn_reorder_conv2d_weight :: Tensor device dtype shape -> (Int,Int) -> (Int,Int) -> (Int,Int) -> Int -> Tensor device dtype shape+-- mkldnn_reorder_conv2d_weight _input _padding _stride _dilation _groups = unsafePerformIO $ (ATen.cast5 ATen.Managed.mkldnn_reorder_conv2d_weight_tllll) _input _padding _stride _dilation _groups++--quantize_linear :: Tensor device dtype shape -> Double -> Int -> DType -> Tensor device dtype shape+--quantize_linear _input _scale _zero_point _dtype = unsafePerformIO $ (ATen.cast4 ATen.Managed.quantize_linear_tdls) _input _scale _zero_point _dtype++--quantize_linear_per_channel :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> [Int] -> DType -> Tensor device dtype shape+--quantize_linear_per_channel _input _scales _zero_points _axis _dtype = unsafePerformIO $ (ATen.cast5 ATen.Managed.quantize_linear_per_channel_tttls) _input _scales _zero_points _axis _dtype++-- dequantize :: Tensor device dtype shape -> Tensor device dtype shape+-- dequantize _input = unsafePerformIO $ (ATen.cast1 ATen.Managed.dequantize_t) _input++-- | qScale+-- TODO: are there any restrictions on the dtype?+qScale ::+  forall shape dtype device.+  -- | input+  Tensor device dtype shape ->+  -- | output+  Double+qScale input = unsafePerformIO $ ATen.cast1 ATen.Managed.q_scale_t input++-- | qZeroPoint+-- TODO: are there any restrictions on the dtype?+qZeroPoint ::+  forall shape dtype device.+  -- | input+  Tensor device dtype shape ->+  -- | output+  Int+qZeroPoint input = unsafePerformIO $ ATen.cast1 ATen.Managed.q_zero_point_t input++-- int_repr :: Tensor device dtype shape -> Tensor device dtype shape+-- int_repr _input = unsafePerformIO $ (ATen.cast1 ATen.Managed.int_repr_t) _input++-- fake_quantize_per_tensor_affine :: Tensor device dtype shape -> Double -> Int -> Int -> Int -> Tensor device dtype shape+-- fake_quantize_per_tensor_affine _input _scale _zero_point _quant_min _quant_max = unsafePerformIO $ (ATen.cast5 ATen.Managed.fake_quantize_per_tensor_affine_tdlll) _input _scale _zero_point _quant_min _quant_max++-- meshgrid :: [Tensor device dtype shape] -> [Tensor device dtype shape]+-- meshgrid _tensors = unsafePerformIO $ (ATen.cast1 ATen.Managed.meshgrid_l) _tensors++-- cartesian_prod :: [Tensor device dtype shape] -> Tensor device dtype shape+-- cartesian_prod _tensors = unsafePerformIO $ (ATen.cast1 ATen.Managed.cartesian_prod_l) _tensors++-- combinations :: Tensor device dtype shape -> Int -> Bool -> Tensor device dtype shape+-- combinations _input _r _with_replacement = unsafePerformIO $ (ATen.cast3 ATen.Managed.combinations_tlb) _input _r _with_replacement++-- | The directional specification of a recurrent function+data RNNDirectionality+  = -- | Forward and backward along the sequential axis using independant parameters for each.+    Bidirectional+  | -- | Forward along the sequential axis.+    Unidirectional+  deriving (Show, Generic) -- TODO:  We could also have BidirectionalTied weights.++type family NumberOfDirections (directionality :: RNNDirectionality) :: Nat where+  NumberOfDirections Bidirectional = 2+  NumberOfDirections Unidirectional = 1++class KnownRNNDirectionality (directionality :: RNNDirectionality) where+  rnnBidirectional :: Bool++instance KnownRNNDirectionality Bidirectional where+  rnnBidirectional = True++instance KnownRNNDirectionality Unidirectional where+  rnnBidirectional = False++-- | Specification for the sequential axis of a recurrent function.+data RNNShapeOrder+  = -- | Input is of shape (Batch, Sequence, Features)+    BatchFirst+  | -- | Input is of shape (Sequence, Batch, Features)+    SequenceFirst+  deriving (Show, Generic)++class KnownRNNShapeOrder (shapeOrder :: RNNShapeOrder) where+  rnnBatchFirst :: Bool++instance KnownRNNShapeOrder BatchFirst where+  rnnBatchFirst = True++instance KnownRNNShapeOrder SequenceFirst where+  rnnBatchFirst = False++type family RNNShape (shapeOrder :: RNNShapeOrder) (seqLen :: Nat) (batchSize :: Nat) (featureSize :: Nat) :: [Nat] where+  RNNShape BatchFirst seqLen batchSize featureSize = '[batchSize, seqLen, featureSize]+  RNNShape SequenceFirst seqLen batchSize featureSize = '[seqLen, batchSize, featureSize]++type LSTMWIShape hiddenSize inputSize = '[4 * hiddenSize, inputSize]++type LSTMWHShape hiddenSize inputSize = '[4 * hiddenSize, hiddenSize]++type LSTMBIShape hiddenSize inputSize = '[4 * hiddenSize]++type LSTMBHShape hiddenSize inputSize = '[4 * hiddenSize]++type family LSTMRImpl (inputSize :: Nat) (hiddenSize :: Nat) (numLayers :: Nat) (directionality :: RNNDirectionality) :: [[Nat]] where+  LSTMRImpl inputSize hiddenSize 1 'Unidirectional =+    '[ LSTMWIShape hiddenSize inputSize,+       LSTMWHShape hiddenSize inputSize,+       LSTMBIShape hiddenSize inputSize,+       LSTMBHShape hiddenSize inputSize+     ]+  LSTMRImpl inputSize hiddenSize numLayers 'Unidirectional =+    LSTMRImpl inputSize hiddenSize (numLayers - 1) 'Unidirectional+      ++ '[ LSTMWIShape hiddenSize (hiddenSize * NumberOfDirections 'Unidirectional),+            LSTMWHShape hiddenSize (hiddenSize * NumberOfDirections 'Unidirectional),+            LSTMBIShape hiddenSize (hiddenSize * NumberOfDirections 'Unidirectional),+            LSTMBHShape hiddenSize (hiddenSize * NumberOfDirections 'Unidirectional)+          ]+  LSTMRImpl inputSize hiddenSize 1 'Bidirectional =+    '[ LSTMWIShape hiddenSize inputSize,+       LSTMWHShape hiddenSize inputSize,+       LSTMBIShape hiddenSize inputSize,+       LSTMBHShape hiddenSize inputSize,+       LSTMWIShape hiddenSize inputSize,+       LSTMWHShape hiddenSize inputSize,+       LSTMBIShape hiddenSize inputSize,+       LSTMBHShape hiddenSize inputSize+     ]+  LSTMRImpl inputSize hiddenSize numLayers 'Bidirectional =+    LSTMRImpl inputSize hiddenSize (numLayers - 1) 'Bidirectional+      ++ '[ LSTMWIShape hiddenSize (hiddenSize * NumberOfDirections 'Bidirectional),+            LSTMWHShape hiddenSize (hiddenSize * NumberOfDirections 'Bidirectional),+            LSTMBIShape hiddenSize (hiddenSize * NumberOfDirections 'Bidirectional),+            LSTMBHShape hiddenSize (hiddenSize * NumberOfDirections 'Bidirectional),+            LSTMWIShape hiddenSize (hiddenSize * NumberOfDirections 'Bidirectional),+            LSTMWHShape hiddenSize (hiddenSize * NumberOfDirections 'Bidirectional),+            LSTMBIShape hiddenSize (hiddenSize * NumberOfDirections 'Bidirectional),+            LSTMBHShape hiddenSize (hiddenSize * NumberOfDirections 'Bidirectional)+          ]++type family LSTMR' (shapes :: [[Nat]]) (dtype :: D.DType) (device :: (D.DeviceType, Nat)) :: [a] where+  LSTMR' '[] dtype device = '[]+  LSTMR' (shape ': shapes) dtype device = Tensor device dtype shape ': LSTMR' shapes dtype device++type LSTMR inputSize hiddenSize numLayers directionality dtype device = LSTMR' (LSTMRImpl inputSize hiddenSize numLayers directionality) dtype device++-- | lstm+-- Parameters for this ATen function are non-trivially provided.  See the+-- `Typed.NN.LSTM` module for doctests.+lstm ::+  forall+    shapeOrder+    directionality+    numLayers+    seqLen+    batchSize+    inputSize+    outputSize+    hiddenSize+    inputShape+    outputShape+    hxShape+    tensorParameters+    dtype+    device.+  ( KnownNat numLayers,+    KnownRNNShapeOrder shapeOrder,+    KnownRNNDirectionality directionality,+    outputSize ~ (hiddenSize * NumberOfDirections directionality),+    inputShape ~ RNNShape shapeOrder seqLen batchSize inputSize,+    outputShape ~ RNNShape shapeOrder seqLen batchSize outputSize,+    hxShape ~ '[numLayers * NumberOfDirections directionality, batchSize, hiddenSize],+    tensorParameters ~ LSTMR inputSize hiddenSize numLayers directionality dtype device,+    ATen.Castable (HList tensorParameters) [D.ATenTensor]+  ) =>+  HList tensorParameters ->+  Double ->+  Bool ->+  (Tensor device dtype hxShape, Tensor device dtype hxShape) ->+  Tensor device dtype inputShape ->+  ( Tensor device dtype outputShape,+    Tensor device dtype hxShape,+    Tensor device dtype hxShape+  )+lstm tensorParameters dropoutProb dropoutOn (cc, hc) input =+  unsafePerformIO $+    ATen.cast9+      ATen.Managed.lstm_tllbldbbb+      input+      hx+      tensorParameters+      hasBiases+      numLayers+      dropoutProb+      dropoutOn+      (rnnBidirectional @directionality)+      (rnnBatchFirst @shapeOrder)+  where+    hasBiases = True+    hx :: [Tensor device dtype hxShape]+    hx = [cc, hc]+    numLayers :: I.Int64+    numLayers = fromIntegral $ natValI @numLayers++-- | lstmCell+--+-- >>> dtype &&& shape $ fst $ lstmCell (ones :: CPUTensor 'D.Float '[12,2]) (ones :: CPUTensor 'D.Float '[12,3]) (ones :: CPUTensor 'D.Float '[12]) (ones :: CPUTensor 'D.Float '[12]) ((ones :: CPUTensor 'D.Float '[2,3]), (ones :: CPUTensor 'D.Float '[2,3])) (ones :: CPUTensor 'D.Float '[2,2])+-- (Float,[2,3])+lstmCell ::+  forall inputSize hiddenSize batchSize dtype device.+  Tensor device dtype '[4 * hiddenSize, inputSize] ->+  Tensor device dtype '[4 * hiddenSize, hiddenSize] ->+  Tensor device dtype '[4 * hiddenSize] ->+  Tensor device dtype '[4 * hiddenSize] ->+  ( Tensor device dtype '[batchSize, hiddenSize],+    Tensor device dtype '[batchSize, hiddenSize]+  ) ->+  Tensor device dtype '[batchSize, inputSize] ->+  ( Tensor device dtype '[batchSize, hiddenSize],+    Tensor device dtype '[batchSize, hiddenSize]+  )+lstmCell wi wh bi bh (cc, hc) input =+  unsafePerformIO $+    ATen.cast6 ATen.Managed.lstm_cell_tltttt input hx wi wh bi bh+  where+    hx = [cc, hc] :: [Tensor device dtype '[batchSize, hiddenSize]]++type GRUWIShape hiddenSize inputSize = '[3 * hiddenSize, inputSize]++type GRUWHShape hiddenSize inputSize = '[3 * hiddenSize, hiddenSize]++type GRUBIShape hiddenSize inputSize = '[3 * hiddenSize]++type GRUBHShape hiddenSize inputSize = '[3 * hiddenSize]++type family GRURImpl (inputSize :: Nat) (hiddenSize :: Nat) (numLayers :: Nat) (directionality :: RNNDirectionality) :: [[Nat]] where+  GRURImpl inputSize hiddenSize 1 'Unidirectional =+    '[ GRUWIShape hiddenSize inputSize,+       GRUWHShape hiddenSize inputSize,+       GRUBIShape hiddenSize inputSize,+       GRUBHShape hiddenSize inputSize+     ]+  GRURImpl inputSize hiddenSize numLayers 'Unidirectional =+    GRURImpl inputSize hiddenSize (numLayers - 1) 'Unidirectional+      ++ '[ GRUWIShape hiddenSize (hiddenSize * NumberOfDirections 'Unidirectional),+            GRUWHShape hiddenSize (hiddenSize * NumberOfDirections 'Unidirectional),+            GRUBIShape hiddenSize (hiddenSize * NumberOfDirections 'Unidirectional),+            GRUBHShape hiddenSize (hiddenSize * NumberOfDirections 'Unidirectional)+          ]+  GRURImpl inputSize hiddenSize 1 'Bidirectional =+    '[ GRUWIShape hiddenSize inputSize,+       GRUWHShape hiddenSize inputSize,+       GRUBIShape hiddenSize inputSize,+       GRUBHShape hiddenSize inputSize,+       GRUWIShape hiddenSize inputSize,+       GRUWHShape hiddenSize inputSize,+       GRUBIShape hiddenSize inputSize,+       GRUBHShape hiddenSize inputSize+     ]+  GRURImpl inputSize hiddenSize numLayers 'Bidirectional =+    GRURImpl inputSize hiddenSize (numLayers - 1) 'Bidirectional+      ++ '[ GRUWIShape hiddenSize (hiddenSize * NumberOfDirections 'Bidirectional),+            GRUWHShape hiddenSize (hiddenSize * NumberOfDirections 'Bidirectional),+            GRUBIShape hiddenSize (hiddenSize * NumberOfDirections 'Bidirectional),+            GRUBHShape hiddenSize (hiddenSize * NumberOfDirections 'Bidirectional),+            GRUWIShape hiddenSize (hiddenSize * NumberOfDirections 'Bidirectional),+            GRUWHShape hiddenSize (hiddenSize * NumberOfDirections 'Bidirectional),+            GRUBIShape hiddenSize (hiddenSize * NumberOfDirections 'Bidirectional),+            GRUBHShape hiddenSize (hiddenSize * NumberOfDirections 'Bidirectional)+          ]++type family GRUR' (shapes :: [[Nat]]) (dtype :: D.DType) (device :: (D.DeviceType, Nat)) :: [a] where+  GRUR' '[] dtype device = '[]+  GRUR' (shape ': shapes) dtype device = Tensor device dtype shape ': GRUR' shapes dtype device++type GRUR inputSize hiddenSize numLayers directionality dtype device = GRUR' (GRURImpl inputSize hiddenSize numLayers directionality) dtype device++-- | gru+-- Parameters for this ATen function are non-trivially provided.  See the+-- `Typed.NN.GRU` module for doctests.+gru ::+  forall+    shapeOrder+    directionality+    numLayers+    seqLen+    batchSize+    inputSize+    outputSize+    hiddenSize+    inputShape+    outputShape+    hcShape+    tensorParameters+    dtype+    device.+  ( KnownNat numLayers,+    KnownRNNShapeOrder shapeOrder,+    KnownRNNDirectionality directionality,+    outputSize ~ (hiddenSize * NumberOfDirections directionality),+    inputShape ~ RNNShape shapeOrder seqLen batchSize inputSize,+    outputShape ~ RNNShape shapeOrder seqLen batchSize outputSize,+    hcShape ~ '[numLayers * NumberOfDirections directionality, batchSize, hiddenSize],+    tensorParameters ~ GRUR inputSize hiddenSize numLayers directionality dtype device,+    ATen.Castable (HList tensorParameters) [D.ATenTensor]+  ) =>+  HList tensorParameters ->+  Double ->+  Bool ->+  Tensor device dtype hcShape ->+  Tensor device dtype inputShape ->+  ( Tensor device dtype outputShape,+    Tensor device dtype hcShape+  )+gru tensorParameters dropoutProb dropoutOn hc input =+  unsafePerformIO $+    ATen.cast9+      ATen.Managed.gru_ttlbldbbb+      input+      hc+      tensorParameters+      hasBiases+      numLayers+      dropoutProb+      dropoutOn+      (rnnBidirectional @directionality)+      (rnnBatchFirst @shapeOrder)+  where+    hasBiases = True+    numLayers :: I.Int64+    numLayers = fromIntegral $ natValI @numLayers++-- | gruCell+--+-- >>> dtype &&& shape $ gruCell (ones :: CPUTensor 'D.Float '[9,2]) (ones :: CPUTensor 'D.Float '[9,3]) (ones :: CPUTensor 'D.Float '[9]) (ones :: CPUTensor 'D.Float '[9]) (ones :: CPUTensor 'D.Float '[2,3]) (ones :: CPUTensor 'D.Float '[2,2])+-- (Float,[2,3])+gruCell ::+  forall inputSize hiddenSize batchSize dtype device.+  Tensor device dtype '[3 * hiddenSize, inputSize] ->+  Tensor device dtype '[3 * hiddenSize, hiddenSize] ->+  Tensor device dtype '[3 * hiddenSize] ->+  Tensor device dtype '[3 * hiddenSize] ->+  Tensor device dtype '[batchSize, hiddenSize] ->+  Tensor device dtype '[batchSize, inputSize] ->+  Tensor device dtype '[batchSize, hiddenSize]+gruCell wi wh bi bh hx input =+  unsafePerformIO $+    ATen.cast6 ATen.Managed.gru_cell_tttttt input hx wi wh bi bh++-- rnn_tanh_cell :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape+-- rnn_tanh_cell _input _hx _w_ih _w_hh _b_ih _b_hh = unsafePerformIO $ (ATen.cast6 ATen.Managed.rnn_tanh_cell_tttttt) _input _hx _w_ih _w_hh _b_ih _b_hh++-- rnn_relu_cell :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape+-- rnn_relu_cell _input _hx _w_ih _w_hh _b_ih _b_hh = unsafePerformIO $ (ATen.cast6 ATen.Managed.rnn_relu_cell_tttttt) _input _hx _w_ih _w_hh _b_ih _b_hh++-- quantized_lstm :: Tensor device dtype shape -> [Tensor device dtype shape] -> [Tensor device dtype shape] -> Bool -> Int -> Double -> Bool -> Bool -> Bool -> DType -> (Tensor device dtype shape,Tensor device dtype shape,Tensor device dtype shape)+-- quantized_lstm _input _hx _params _has_biases _num_layers _dropout _train _bidirectional _batch_first _dtype = unsafePerformIO $ (ATen.ATen.cast10 ATen.Managed.quantized_lstm_tllbldbbbs) _input _hx _params _has_biases _num_layers _dropout _train _bidirectional _batch_first _dtype++-- quantized_lstm_cell :: Tensor device dtype shape -> [Tensor device dtype shape] -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Float -> Float -> Float -> Float -> (Tensor device dtype shape,Tensor device dtype shape)+-- quantized_lstm_cell _input _hx _w_ih _w_hh _b_ih _b_hh _packed_ih _packed_hh _col_offsets_ih _col_offsets_hh _scale_ih _scale_hh _zero_point_ih _zero_point_hh = unsafePerformIO $ (ATen.ATen.cast14 ATen.Managed.quantized_lstm_cell_tlttttttttssss) _input _hx _w_ih _w_hh _b_ih _b_hh _packed_ih _packed_hh _col_offsets_ih _col_offsets_hh _scale_ih _scale_hh _zero_point_ih _zero_point_hh++-- quantized_gru_cell :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Float -> Float -> Float -> Float -> Tensor device dtype shape+-- quantized_gru_cell _input _hx _w_ih _w_hh _b_ih _b_hh _packed_ih _packed_hh _col_offsets_ih _col_offsets_hh _scale_ih _scale_hh _zero_point_ih _zero_point_hh = unsafePerformIO $ (ATen.ATen.cast14 ATen.Managed.quantized_gru_cell_ttttttttttssss) _input _hx _w_ih _w_hh _b_ih _b_hh _packed_ih _packed_hh _col_offsets_ih _col_offsets_hh _scale_ih _scale_hh _zero_point_ih _zero_point_hh++-- quantized_rnn_relu_cell :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Float -> Float -> Float -> Float -> Tensor device dtype shape+-- quantized_rnn_relu_cell _input _hx _w_ih _w_hh _b_ih _b_hh _packed_ih _packed_hh _col_offsets_ih _col_offsets_hh _scale_ih _scale_hh _zero_point_ih _zero_point_hh = unsafePerformIO $ (ATen.ATen.cast14 ATen.Managed.quantized_rnn_relu_cell_ttttttttttssss) _input _hx _w_ih _w_hh _b_ih _b_hh _packed_ih _packed_hh _col_offsets_ih _col_offsets_hh _scale_ih _scale_hh _zero_point_ih _zero_point_hh++-- quantized_rnn_tanh_cell :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Float -> Float -> Float -> Float -> Tensor device dtype shape+-- quantized_rnn_tanh_cell _input _hx _w_ih _w_hh _b_ih _b_hh _packed_ih _packed_hh _col_offsets_ih _col_offsets_hh _scale_ih _scale_hh _zero_point_ih _zero_point_hh = unsafePerformIO $ (ATen.ATen.cast14 ATen.Managed.quantized_rnn_tanh_cell_ttttttttttssss) _input _hx _w_ih _w_hh _b_ih _b_hh _packed_ih _packed_hh _col_offsets_ih _col_offsets_hh _scale_ih _scale_hh _zero_point_ih _zero_point_hh++-- masked_scatter :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape+-- masked_scatter _input _mask _source = unsafePerformIO $ (ATen.cast3 ATen.Managed.masked_scatter_ttt) _input _mask _source++-- index_add :: Tensor device dtype shape -> Int -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape+-- index_add _input _dim _index _source = unsafePerformIO $ (ATen.cast4 ATen.Managed.index_add_tltt) _input _dim _index _source++-- scatter_add :: Tensor device dtype shape -> Int -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape+-- scatter_add _input _dim _index _src = unsafePerformIO $ (ATen.cast4 ATen.Managed.scatter_add_tltt) _input _dim _index _src++-- addbmm :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Float -> Float -> Tensor device dtype shape+-- addbmm _input _batch1 _batch2 _beta _alpha = unsafePerformIO $ (ATen.cast5 ATen.Managed.addbmm_tttss) _input _batch1 _batch2 _beta _alpha++-- cross :: Tensor device dtype shape -> Tensor device dtype shape -> Int -> Tensor device dtype shape+-- cross _input _other _dim = unsafePerformIO $ (ATen.cast3 ATen.Managed.cross_ttl) _input _other _dim++type family MatrixOrMatrixBatch (shape :: [Nat]) :: [Nat] where+  MatrixOrMatrixBatch (n : m : '[]) = '[n, m]+  MatrixOrMatrixBatch (b : n : m : '[]) = '[b, n, m]+  MatrixOrMatrixBatch _ = TypeError (Text "The input must be matrix or a batch of matrices.")++-- | triu+-- TODO: triu is not implemented for D.Bool, or maybe numeric type is lifted?+--+-- >>> t = ones :: CPUTensor 'D.Float '[3, 4]+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [[Float]]) $ triu 0 t+-- (Float,([3,4],[[1.0,1.0,1.0,1.0],[0.0,1.0,1.0,1.0],[0.0,0.0,1.0,1.0]]))+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [[Float]]) $ triu 1 t+-- (Float,([3,4],[[0.0,1.0,1.0,1.0],[0.0,0.0,1.0,1.0],[0.0,0.0,0.0,1.0]]))+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [[Float]]) $ triu (-1) t+-- (Float,([3,4],[[1.0,1.0,1.0,1.0],[1.0,1.0,1.0,1.0],[0.0,1.0,1.0,1.0]]))+triu ::+  forall shape dtype device.+  (shape ~ MatrixOrMatrixBatch shape) =>+  -- | diagonal+  Int ->+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+triu diagonal input = unsafePerformIO $ ATen.cast2 ATen.Managed.triu_tl input diagonal++-- | tril+-- TODO: tril is not implemented for D.Bool, or maybe numeric type is lifted?+--+-- >>> t = ones :: CPUTensor 'D.Float '[3, 4]+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [[Float]]) $ tril 0 t+-- (Float,([3,4],[[1.0,0.0,0.0,0.0],[1.0,1.0,0.0,0.0],[1.0,1.0,1.0,0.0]]))+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [[Float]]) $ tril 1 t+-- (Float,([3,4],[[1.0,1.0,0.0,0.0],[1.0,1.0,1.0,0.0],[1.0,1.0,1.0,1.0]]))+-- >>> dtype &&& shape &&& (\t' -> D.asValue (toDynamic t') :: [[Float]]) $ tril (-1) t+-- (Float,([3,4],[[0.0,0.0,0.0,0.0],[1.0,0.0,0.0,0.0],[1.0,1.0,0.0,0.0]]))+tril ::+  forall shape dtype device.+  (shape ~ MatrixOrMatrixBatch shape) =>+  -- | diagonal+  Int ->+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+tril diagonal input = unsafePerformIO $ ATen.cast2 ATen.Managed.tril_tl input diagonal++-- | trace+--+-- >>> dtype &&& shape $ trace (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+trace ::+  forall shape dtype device.+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+trace _input = unsafePerformIO $ (ATen.cast1 ATen.Managed.trace_t) _input++-- take :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape+-- take _input _index = unsafePerformIO $ (ATen.cast2 ATen.Managed.take_tt) _input _index++-- index_select :: Tensor device dtype shape -> Int -> Tensor device dtype shape -> Tensor device dtype shape+-- index_select _input _dim _index = unsafePerformIO $ (ATen.cast3 ATen.Managed.index_select_tlt) _input _dim _index++maskedSelect ::+  forall shape shape' shape'' dtype device.+  (shape'' ~ Broadcast shape shape') =>+  Tensor device 'D.Bool shape ->+  Tensor device dtype shape' ->+  UnknownShapeTensor device dtype+maskedSelect mask input = UnknownShapeTensor $ unsafePerformIO $ ATen.cast2 ATen.Managed.masked_select_tt input mask++-- | nonzero+--+-- >>> dtype &&& shape $ nonzero (zeros :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+nonzero ::+  forall shape dtype device.+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+nonzero _input = unsafePerformIO $ (ATen.cast1 ATen.Managed.nonzero_t) _input++-- nonzero_numpy :: Tensor device dtype shape -> [Tensor device dtype shape]+-- nonzero_numpy _input = unsafePerformIO $ (ATen.cast1 ATen.Managed.nonzero_numpy_t) _input++-- | GatherDimImpl+--+-- >>> :kind! GatherDimImpl '[2, 1, 1] '[2, 4, 1] 1+-- GatherDimImpl '[2, 1, 1] '[2, 4, 1] 1 :: Maybe [Natural]+-- = Just [2, 4, 1]+-- >>> :kind! GatherDimImpl '[2, 1, 1] '[2, 4, 2] 1+-- GatherDimImpl '[2, 1, 1] '[2, 4, 2] 1 :: Maybe [Natural]+-- = Nothing+-- >>> :kind! GatherDimImpl '[2, 1, 1] '[2, 0, 1] 1+-- GatherDimImpl '[2, 1, 1] '[2, 0, 1] 1 :: Maybe [Natural]+-- = Nothing+-- >>> :kind! GatherDimImpl '[2, 1, 1] '[2, 1] 1+-- GatherDimImpl '[2, 1, 1] '[2, 1] 1 :: Maybe [Natural]+-- = Nothing+-- >>> :kind! GatherDimImpl '[2, 1, 1] '[2, 1, 3] 2+-- GatherDimImpl '[2, 1, 1] '[2, 1, 3] 2 :: Maybe [Natural]+-- = Just [2, 1, 3]+type family GatherDimImpl (shape :: [Nat]) (shape' :: [Nat]) (dim :: Nat) :: Maybe [Nat] where+  GatherDimImpl (x ': xs) (y ': xs) 0 = If (1 <=? y) (Just (y ': xs)) Nothing+  GatherDimImpl (x ': xs) (x ': ys) dim = AppendToMaybe x (GatherDimImpl xs ys (dim - 1))+  GatherDimImpl _ _ _ = Nothing++type family GatherDimCheck (shape :: [a]) (shape' :: [a]) (dim :: Nat) (result :: Maybe [a]) :: [a] where+  GatherDimCheck shape shape' dim Nothing =+    TypeError+      ( Text "Cannot gather the tensor at dimension "+          :<>: ShowType dim+          :<>: Text " using index of shape "+          :<>: ShowType shape'+      )+  GatherDimCheck _ _ _ (Just shape'') = shape''++-- | Calculate the output shape of a gather operation for a given index shape along a given axis+--+-- >>> :kind! GatherDim '[2, 1, 1] '[2, 1, 3] 2+-- GatherDim '[2, 1, 1] '[2, 1, 3] 2 :: [Natural]+-- = [2, 1, 3]+type GatherDim shape shape' dim = GatherDimCheck shape shape' dim (GatherDimImpl shape shape' dim)++-- | gather values along an axis for a specified dimension.+gatherDim ::+  forall dim shape shape' dtype device.+  (KnownNat dim, shape' ~ GatherDim shape shape' dim) =>+  -- | the indices of elements to gather+  Tensor device 'D.Int64 shape' ->+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape'+gatherDim index input = unsafePerformIO $ ATen.cast4 ATen.Managed.gather_tltb input (natValI @dim) index False++-- addcmul :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Float -> Tensor device dtype shape+-- addcmul _input _tensor1 _tensor2 _value = unsafePerformIO $ (ATen.cast4 ATen.Managed.addcmul_ttts) _input _tensor1 _tensor2 _value++-- addcdiv :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Float -> Tensor device dtype shape+-- addcdiv _input _tensor1 _tensor2 _value = unsafePerformIO $ (ATen.cast4 ATen.Managed.addcdiv_ttts) _input _tensor1 _tensor2 _value++-- lstsq :: Tensor device dtype shape -> Tensor device dtype shape -> (Tensor device dtype shape,Tensor device dtype shape)+-- lstsq _input _A = unsafePerformIO $ (ATen.cast2 ATen.Managed.lstsq_tt) _input _A++-- triangular_solve :: Tensor device dtype shape -> Tensor device dtype shape -> Bool -> Bool -> Bool -> (Tensor device dtype shape,Tensor device dtype shape)+-- triangular_solve _input _A _upper _transpose _unitriangular = unsafePerformIO $ (ATen.cast5 ATen.Managed.triangular_solve_ttbbb) _input _A _upper _transpose _unitriangular++-- qr :: Tensor device dtype shape -> Bool -> (Tensor device dtype shape,Tensor device dtype shape)+-- qr _input _some = unsafePerformIO $ (ATen.cast2 ATen.Managed.qr_tb) _input _some++-- ormqr :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Bool -> Bool -> Tensor device dtype shape+-- ormqr _input _input2 _input3 _left _transpose = unsafePerformIO $ (ATen.cast5 ATen.Managed.ormqr_tttbb) _input _input2 _input3 _left _transpose++-- lu_solve :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape+-- lu_solve _input _LU_data _LU_pivots = unsafePerformIO $ (ATen.cast3 ATen.Managed.lu_solve_ttt) _input _LU_data _LU_pivots++-- | lgamma function+--+-- >>> dtype &&& shape $ lgamma (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+lgamma ::+  forall shape dtype device.+  (StandardFloatingPointDTypeValidation device dtype) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+lgamma input = unsafePerformIO $ ATen.cast1 ATen.Managed.lgamma_t input++-- | digamma function+--+-- >>> dtype &&& shape $ digamma (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+digamma ::+  forall shape dtype device.+  (StandardFloatingPointDTypeValidation device dtype) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+digamma input = unsafePerformIO $ ATen.cast1 ATen.Managed.digamma_t input++-- | polygamma function+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+polygamma ::+  forall shape dtype device.+  -- | order+  Int ->+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+polygamma n input = unsafePerformIO $ ATen.cast2 ATen.Managed.polygamma_lt n input++-- | inverse of the error function+--+-- >>> dtype &&& shape $ erfinv (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+erfinv ::+  forall shape dtype device.+  (StandardFloatingPointDTypeValidation device dtype) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+erfinv input = unsafePerformIO $ ATen.cast1 ATen.Managed.erfinv_t input++-- dist :: Tensor device dtype shape -> Tensor device dtype shape -> Float -> Tensor device dtype shape+-- dist _input _other _p = unsafePerformIO $ (ATen.cast3 ATen.Managed.dist_tts) _input _other _p++-- atan2 :: Tensor device dtype shape -> Tensor device dtype shape -> Tensor device dtype shape+-- atan2 _input _other = unsafePerformIO $ (ATen.cast2 ATen.Managed.atan2_tt) _input _other++-- histc :: Tensor device dtype shape -> Int -> Float -> Float -> Tensor device dtype shape+-- histc _input _bins _min _max = unsafePerformIO $ (ATen.cast4 ATen.Managed.histc_tlss) _input _bins _min _max++-- | minAll+--+-- >>> dtype &&& shape $ minAll (ones :: CPUTensor 'D.Float '[2,2])+-- (Float,[])+minAll ::+  forall shape dtype device.+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype '[]+minAll input = unsafePerformIO $ ATen.cast1 ATen.Managed.min_t input++type family DropValue (shape :: [Nat]) (i :: Nat) :: [Nat] where+  DropValue '[] _ = TypeError (Text "Can not find a element in the list.")+  DropValue (x : xs) 0 = xs+  DropValue (x : xs) i = x ': DropValue xs (i -1)++type family DropNamedValue (shape :: Shape) (i :: Size) :: Shape where+  DropNamedValue '[] _ = TypeError (Text "Can not find a element in the list.")+  DropNamedValue (x : xs) x = xs+  DropNamedValue (x : xs) y = x ': DropNamedValue xs y++-- | minDim+--+-- >>> t = ones :: CPUTensor 'D.Float '[3,4,5]+-- >>> dtype &&& shape $ fst $ minDim @0 t+-- (Float,[4,5])+-- >>> dtype &&& shape $ fst $ minDim @1 t+-- (Float,[3,5])+-- >>> dtype &&& shape $ fst $ minDim @2 t+-- (Float,[3,4])+minDim ::+  forall d shape dtype device.+  (KnownNat d) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  ( Tensor device dtype (DropValue shape d),+    Tensor device 'D.Int64 (DropValue shape d)+  )+minDim input = unsafePerformIO $ ATen.cast2 ATen.Managed.min_tl input (natValI @d)++-- | maxAll+--+-- >>> dtype &&& shape $ maxAll (ones :: CPUTensor 'D.Float '[2,2])+-- (Float,[])+maxAll ::+  forall shape dtype device.+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype '[]+maxAll input = unsafePerformIO $ ATen.cast1 ATen.Managed.max_t input++-- | maxDim+--+-- >>> t = ones :: CPUTensor 'D.Float '[3,4,5]+-- >>> dtype &&& shape $ fst $ maxDim @0 t+-- (Float,[4,5])+-- >>> dtype &&& shape $ fst $ maxDim @1 t+-- (Float,[3,5])+-- >>> dtype &&& shape $ fst $ maxDim @2 t+-- (Float,[3,4])+maxDim ::+  forall d shape dtype device.+  (KnownNat d) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  ( Tensor device dtype (DropValue shape d),+    Tensor device 'D.Int64 (DropValue shape d)+  )+maxDim input = unsafePerformIO $ ATen.cast2 ATen.Managed.max_tl input (natValI @d)++type family HasDim (dim :: Nat) (shape :: [Nat]) :: Constraint where+  HasDim _ '[] = TypeError (Text "The dimension of the argument is incorrect.")+  HasDim 0 (_ ': _) = ()+  HasDim n (_ ': xs) = HasDim (n -1) xs++-- | sortDim+--+-- >>> t = ones :: CPUTensor 'D.Float '[3,4,5]+-- >>> dtype &&& shape $ fst $ sortDim @0 True t+-- (Float,[3,4,5])+-- >>> dtype &&& shape $ snd $ sortDim @0 True t+-- (Int64,[3,4,5])+sortDim ::+  forall dim shape dtype device.+  ( KnownNat dim,+    HasDim dim shape+  ) =>+  Bool ->+  Tensor device dtype shape ->+  ( Tensor device dtype shape,+    Tensor device D.Int64 shape+  )+sortDim _descending _input =+  let (a, b) = func (toDynamic _input)+   in (UnsafeMkTensor a, UnsafeMkTensor b)+  where+    func :: D.Tensor -> (D.Tensor, D.Tensor)+    func _input = unsafePerformIO $ (ATen.cast3 ATen.Managed.sort_tlb) _input _dim _descending+    _dim = natValI @dim++-- | sortNamedDim+--+-- >>> import Torch.Typed.Factories+-- >>> import Data.Default.Class+-- >>> t = def :: NamedTensor '( D.CPU, 0) 'D.Float '[Vector 3, Vector 4, Vector 5]+-- >>> dtype &&& shape $ fst $ sortNamedDim @(Vector 3) True t+-- (Float,[3,4,5])+-- >>> dtype &&& shape $ snd $ sortNamedDim @(Vector 3) True t+-- (Int64,[3,4,5])+sortNamedDim ::+  forall dim shape dtype device.+  ( KnownNat (FindDim dim shape)+  ) =>+  Bool ->+  NamedTensor device dtype shape ->+  ( NamedTensor device dtype shape,+    NamedTensor device D.Int64 shape+  )+sortNamedDim _descending _input =+  let (a, b) = func (toDynamic _input)+   in (FromTensor $ UnsafeMkTensor a, FromTensor $ UnsafeMkTensor b)+  where+    func :: D.Tensor -> (D.Tensor, D.Tensor)+    func _input = unsafePerformIO $ (ATen.cast3 ATen.Managed.sort_tlb) _input _dim _descending+    _dim = natValI @(FindDim dim shape)++-- | argSortDim+--+-- >>> t = ones :: CPUTensor 'D.Float '[3,4,5]+-- >>> dtype &&& shape $ argSortDim @0 True t+-- (Int64,[3,4,5])+argSortDim ::+  forall dim shape dtype device.+  ( KnownNat dim,+    HasDim dim shape+  ) =>+  Bool ->+  Tensor device dtype shape ->+  Tensor device D.Int64 shape+argSortDim _descending _input = unsafePerformIO $ (ATen.cast3 ATen.Managed.argsort_tlb) _input _dim _descending+  where+    _dim = natValI @dim++argSortNamedDim ::+  forall dim shape dtype device.+  ( KnownNat (FindDim dim shape)+  ) =>+  Bool ->+  NamedTensor device dtype shape ->+  NamedTensor device D.Int64 shape+argSortNamedDim _descending _input = unsafePerformIO $ (ATen.cast3 ATen.Managed.argsort_tlb) _input _dim _descending+  where+    _dim = natValI @(FindDim dim shape)++type family TopKCheck (k :: Nat) (shape :: [Nat]) (dim :: Nat) (satd :: Maybe Nat) (result :: Maybe a) :: a where+  TopKCheck _ shape dim _ Nothing = DimOutOfBound shape dim+  TopKCheck _ shape dim Nothing _ = DimOutOfBound shape dim+  TopKCheck k shape dim (Just v) (Just result) = If (k <=? v) result (TypeError (Text "k must be less than or equal to the number of elements in the requested dimension."))++type TopK k shape dim = TopKCheck k shape dim (ExtractDim dim shape) (ReplaceDim dim shape k)++type family TopKDeviceAndDTypeCheck dtype (device :: (D.DeviceType, Nat)) :: Constraint where+  TopKDeviceAndDTypeCheck D.Bool _ = (TypeError (Text "topk is not defined for Bool tensors."))+  TopKDeviceAndDTypeCheck D.Half '(D.CPU, _) = (TypeError (Text "topk is not defined for Half types on CPU."))+  TopKDeviceAndDTypeCheck _ _ = ()++-- | Returns the k largest (if largest is `True`) elements of the given input tensor along a given dimension.+--+-- >>> topk @3 @1 True True (ones :: CPUTensor 'D.Float '[2,3])+-- (Tensor Float [2,3] [[ 1.0000   ,  1.0000   ,  1.0000   ],+--                     [ 1.0000   ,  1.0000   ,  1.0000   ]],Tensor Int64 [2,3] [[ 0,  1,  2],+--                     [ 0,  1,  2]])+-- >>> topk @0 @1 True True (ones :: CPUTensor 'D.Float '[2,3])+-- (Tensor Float [2,0] [[],+--                     []],Tensor Int64 [2,0] [[],+--                     []])+topk ::+  forall k dim shape' shape dtype device.+  ( KnownNat k,+    KnownNat dim,+    All KnownNat shape,+    TopKDeviceAndDTypeCheck dtype device,+    shape' ~ TopK k shape dim+  ) =>+  -- | if we're returning the top k largest (or, if False, the top k smallest)+  Bool ->+  -- | if the resulting k elements are themselves sorted+  Bool ->+  -- | input+  Tensor device dtype shape ->+  -- | output+  (Tensor device dtype shape', Tensor device 'D.Int64 shape')+topk _largest _sorted _input = unsafePerformIO $ (ATen.cast5 ATen.Managed.topk_tllbb) _input _k _dim _largest _sorted+  where+    _k = natValI @k+    _dim = natValI @dim++-- renorm :: Tensor device dtype shape -> Float -> Int -> Float -> Tensor device dtype shape+-- renorm _input _p _dim _maxnorm = unsafePerformIO $ (ATen.cast4 ATen.Managed.renorm_tsls) _input _p _dim _maxnorm++-- equal :: Tensor device dtype shape -> Tensor device dtype shape -> Bool+-- equal _input _other = unsafePerformIO $ (ATen.cast2 ATen.Managed.equal_tt) _input _other++-- | alias+--+-- >>> dtype &&& shape $ alias (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+alias ::+  forall shape dtype device.+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+alias _input = unsafePerformIO $ (ATen.cast1 ATen.Managed.alias_t) _input++-- | L1 loss+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> dtype &&& shape $ l1Loss @ReduceNone (ones :: CPUTensor 'D.Float '[2,2]) (ones :: CPUTensor 'D.Float '[2,2])+-- (Float,[2,2])+-- >>> dtype &&& shape $ l1Loss @ReduceSum (ones :: CPUTensor 'D.Float '[2,2]) (ones :: CPUTensor 'D.Float '[2,2])+-- (Float,[])+l1Loss ::+  forall reduction shape dtype device.+  (KnownReduction reduction) =>+  -- | prediciton+  Tensor device dtype shape ->+  -- | target+  Tensor device dtype shape ->+  -- | loss+  Tensor device dtype (ConditionalReduction shape reduction)+l1Loss prediction target =+  unsafePerformIO $+    ATen.cast3 ATen.Managed.l1_loss_ttl prediction target (reductionVal @reduction)++-- multi_margin_loss :: Tensor device dtype shape -> Tensor device dtype shape -> Float -> Float -> Tensor device dtype shape -> Int -> Tensor device dtype shape+-- multi_margin_loss _input _target _p _margin _weight _reduction = unsafePerformIO $ (ATen.cast6 ATen.Managed.multi_margin_loss_ttsstl) _input _target _p _margin _weight _reduction++-- multilabel_margin_loss :: Tensor device dtype shape -> Tensor device dtype shape -> Int -> Tensor device dtype shape+-- multilabel_margin_loss _input _target _reduction = unsafePerformIO $ (ATen.cast3 ATen.Managed.multilabel_margin_loss_ttl) _input _target _reduction++-- | negative log likelihood loss+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+-- See https://pytorch.org/docs/stable/nn.functional.html?highlight=nll_loss#torch.nn.functional.nll_loss.+--+-- >>> input <- randn @'[3, 5] @'D.Float @'(D.CPU, 0)+-- >>> target = fromJust [1, 0, 4] :: CPUTensor 'D.Int64 '[3]+-- >>> weight = ones @'[5] @'D.Float @'(D.CPU, 0)+-- >>> dtype &&& shape $ nllLoss @ReduceNone @3 @5 @'[] weight (-100) (logSoftmax @1 input) target+-- (Float,[3])+-- >>> dtype &&& shape $ nllLoss @ReduceMean @3 @5 @'[] weight (-100) (logSoftmax @1 input) target+-- (Float,[])+-- >>> input <- randn @'[3, 5, 2] @'D.Float @'(D.CPU, 0)+-- >>> target = fromJust [[1, 1], [0, 1], [4, 0]] :: CPUTensor 'D.Int64 '[3, 2]+-- >>> weight = ones @'[5] @'D.Float @'(D.CPU, 0)+-- >>> dtype &&& shape $ nllLoss @ReduceNone @3 @5 @'[2] weight (-100) (logSoftmax @1 input) target+-- (Float,[3,2])+-- >>> dtype &&& shape $ nllLoss @ReduceMean @3 @5 @'[2] weight (-100) (logSoftmax @1 input) target+-- (Float,[])+-- >>> input <- randn @'[3, 5, 1, 2] @'D.Float @'(D.CPU, 0)+-- >>> target = fromJust [[[1, 1]], [[0, 1]], [[4, 0]]] :: CPUTensor 'D.Int64 '[3, 1, 2]+-- >>> weight = ones @'[5] @'D.Float @'(D.CPU, 0)+-- >>> dtype &&& shape $ nllLoss @ReduceNone @3 @5 @'[1, 2] weight (-100) (logSoftmax @1 input) target+-- (Float,[3,1,2])+-- >>> dtype &&& shape $ nllLoss @ReduceMean @3 @5 @'[1, 2] weight (-100) (logSoftmax @1 input) target+-- (Float,[])+-- >>> input <- randn @'[3, 5, 2, 1, 2] @'D.Float @'(D.CPU, 0)+-- >>> target = fromJust [[[[1, 1]], [[0, 2]]], [[[0, 1]], [[1, 0]]], [[[4, 0]], [[1, 2]]]] :: CPUTensor 'D.Int64 '[3, 2, 1, 2]+-- >>> weight = ones @'[5] @'D.Float @'(D.CPU, 0)+-- >>> dtype &&& shape $ nllLoss @ReduceNone @3 @5 @'[2, 1, 2] weight (-100) (logSoftmax @1 input) target+-- (Float,[3,2,1,2])+-- >>> dtype &&& shape $ nllLoss @ReduceMean @3 @5 @'[2, 1, 2] weight (-100) (logSoftmax @1 input) target+-- (Float,[])+nllLoss ::+  forall reduction n c ds dtype device.+  (KnownReduction reduction, KnownNat n, KnownNat c, KnownShape ds) =>+  -- | weight+  Tensor device dtype '[c] ->+  -- | ignore which index+  Int ->+  -- | prediction+  Tensor device dtype (n ': c ': ds) ->+  -- | target+  Tensor device 'D.Int64 (n ': ds) ->+  -- | loss+  Tensor device dtype (ConditionalReduction (n ': ds) reduction)+nllLoss weight ignoreIndex prediction target = case shapeVal @ds of+  [] ->+    unsafePerformIO $+      ATen.cast5+        ATen.Managed.nll_loss_tttll+        prediction+        target+        weight+        (reductionVal @reduction)+        ignoreIndex+  [_h, _w] ->+    unsafePerformIO $+      ATen.cast5+        ATen.Managed.nll_loss2d_tttll+        prediction+        target+        weight+        (reductionVal @reduction)+        ignoreIndex+  h : t -> case reductionVal @reduction of+    0 -> UnsafeMkTensor . (D.reshape ((natValI @n) : h : t)) $ out+    _ -> UnsafeMkTensor out+    where+      t' = [1, foldl (*) h t]+      input' = D.reshape (natValI @n : natValI @c : t') (toDynamic prediction)+      target' = D.reshape (natValI @n : t') (toDynamic target)+      out =+        unsafePerformIO $+          ATen.cast5+            ATen.Managed.nll_loss2d_tttll+            input'+            target'+            weight+            (reductionVal @reduction)+            ignoreIndex++-- | smooth L1 loss+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> dtype &&& shape $ smoothL1Loss @ReduceNone (ones :: CPUTensor 'D.Float '[2,2]) (ones :: CPUTensor 'D.Float '[2,2])+-- (Float,[2,2])+-- >>> dtype &&& shape $ smoothL1Loss @ReduceSum (ones :: CPUTensor 'D.Float '[2,2]) (ones :: CPUTensor 'D.Float '[2,2])+-- (Float,[])+smoothL1Loss ::+  forall reduction shape dtype device.+  (KnownReduction reduction) =>+  -- | prediction+  Tensor device dtype shape ->+  -- | target+  Tensor device dtype shape ->+  -- | loss+  Tensor device dtype (ConditionalReduction shape reduction)+smoothL1Loss prediction target =+  unsafePerformIO $+    ATen.cast3 ATen.Managed.smooth_l1_loss_ttl prediction target (reductionVal @reduction)++-- | soft margin loss+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> dtype &&& shape $ softMarginLoss @ReduceNone (ones :: CPUTensor 'D.Float '[2,2]) (ones :: CPUTensor 'D.Float '[2,2])+-- (Float,[2,2])+-- >>> dtype &&& shape $ softMarginLoss @ReduceSum (ones :: CPUTensor 'D.Float '[2,2]) (ones :: CPUTensor 'D.Float '[2,2])+-- (Float,[])+softMarginLoss ::+  forall reduction shape dtype device.+  (KnownReduction reduction) =>+  -- | prediction+  Tensor device dtype shape ->+  -- | target+  Tensor device dtype shape ->+  -- | loss+  Tensor device dtype (ConditionalReduction shape reduction)+softMarginLoss prediciton target =+  unsafePerformIO $+    ATen.cast3+      ATen.Managed.soft_margin_loss_ttl+      prediciton+      target+      (reductionVal @reduction)++-- | elu+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> dtype &&& shape $ elu 0.1 0.1 0.3 (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+elu ::+  forall shape dtype a device.+  (D.Scalar a, StandardFloatingPointDTypeValidation device dtype) =>+  -- | alpha+  a ->+  -- | scale+  a ->+  -- | input scale+  a ->+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+elu alpha scale inputScale input =+  unsafePerformIO $ ATen.cast4 ATen.Managed.elu_tsss input alpha scale inputScale++-- | glu+-- -- >>> dtype &&& shape $ glu (ones :: CPUTensor 'D.Float '[3,2]) 1+-- -- (Float,[3,1])+-- -- >>> dtype &&& shape $ glu (ones :: CPUTensor 'D.Float '[3,2]) 3+-- -- (Float,[3,2])+-- glu :: Tensor device dtype shape -> Int -> Tensor device dtype shape+-- glu _input _dim = unsafePerformIO $ (ATen.cast2 ATen.Managed.glu_tl) _input _dim++-- | hard tanh+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> dtype &&& shape $ hardTanh 0 1 (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+hardTanh ::+  forall shape dtype device.+  -- | minimum value+  Float ->+  -- | maximum value+  Float ->+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+hardTanh min_val max_val input =+  unsafePerformIO $ ATen.cast3 ATen.Managed.hardtanh_tss input min_val max_val++-- | leaky relu+--+-- >>> dtype &&& shape $ leakyRelu 0.01 (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+leakyRelu ::+  forall a shape dtype device.+  (D.Scalar a, StandardFloatingPointDTypeValidation device dtype) =>+  -- | negative slope+  a ->+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+leakyRelu negativeSlope input =+  unsafePerformIO $ ATen.cast2 ATen.Managed.leaky_relu_ts input negativeSlope++-- | logarithm of the sigmoid+--+-- >>> dtype &&& shape $ logSigmoid (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+logSigmoid ::+  forall shape dtype device.+  (StandardFloatingPointDTypeValidation device dtype) =>+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+logSigmoid input = unsafePerformIO $ ATen.cast1 ATen.Managed.log_sigmoid_t input++-- | softplus+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+-- See https://pytorch.org/docs/stable/nn.functional.html?highlight=softplus#torch.nn.functional.softplus.+--+-- >>> dtype &&& shape &&& (\t -> D.asValue (toDynamic t) :: [[Float]]) $ softplus 1 20 (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,([3,2],[[1.3132616,1.3132616],[1.3132616,1.3132616],[1.3132616,1.3132616]]))+softplus ::+  forall a shape dtype device.+  D.Scalar a =>+  a ->+  a ->+  Tensor device dtype shape ->+  Tensor device dtype shape+softplus beta threshold input = unsafePerformIO $ ATen.cast3 ATen.Managed.softplus_tss input beta threshold++-- | soft shrink+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> dtype &&& shape $ softShrink 0.2 (ones :: CPUTensor 'D.Float '[3,2])+-- (Float,[3,2])+softShrink ::+  forall shape dtype device.+  -- | lambda+  Float ->+  -- | input+  Tensor device dtype shape ->+  -- | output+  Tensor device dtype shape+softShrink lambda input =+  unsafePerformIO $ ATen.cast2 ATen.Managed.softshrink_ts input lambda++-- | adaptive averaged 2-D pooling+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> t = adaptiveAvgPool2d @'(8,16) (ones :: CPUTensor 'D.Float '[1,3,16,32])+-- >>> shape t+-- [1,3,8,16]+-- >>> :t t+-- t :: Tensor '(D.CPU, 0) 'D.Float [1, 3, 8, 16]+adaptiveAvgPool2d ::+  forall outputSize channelSize inputSize0 inputSize1 batchSize dtype device.+  ( All+      KnownNat+      '[ channelSize,+         inputSize0,+         inputSize1,+         batchSize,+         Torch.Typed.Auxiliary.Fst outputSize,+         Torch.Typed.Auxiliary.Snd outputSize+       ]+  ) =>+  -- | input+  Tensor device dtype '[batchSize, channelSize, inputSize0, inputSize1] ->+  -- | output+  Tensor device dtype '[batchSize, channelSize, Torch.Typed.Auxiliary.Fst outputSize, Torch.Typed.Auxiliary.Snd outputSize]+adaptiveAvgPool2d input =+  unsafePerformIO $+    ATen.cast2+      ATen.Managed.adaptive_avg_pool2d_tl+      input+      ([natValI @(Torch.Typed.Auxiliary.Fst outputSize), natValI @(Torch.Typed.Auxiliary.Snd outputSize)] :: [Int])++-- | MKLDNN adaptive averaged 2-D pooling+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+-- TODO: broken?+-- TODO: only defined for MKLDNN device?+-- TODO: test for availability of MKLDNN device?+-- TODO: merge with adaptiveAvgPool2d and dispatch based on (availability of MKLDNN) device in the function body?+--+-- -- >>> t = mkldnnAdaptiveAvgPool2d @'(8,16) (toMKLDNN (ones :: CPUTensor 'D.Float '[1,3,16,32]))+-- -- >>> shape t+-- -- [1,3,8,16]+-- -- >>> :t t+-- -- t :: Tensor '(D.CPU, 0) 'D.Float '[1, 3, 8, 16]+mkldnnAdaptiveAvgPool2d ::+  forall outputSize channelSize inputSize0 inputSize1 batchSize dtype device.+  ( All+      KnownNat+      '[ channelSize,+         inputSize0,+         inputSize1,+         batchSize,+         Torch.Typed.Auxiliary.Fst outputSize,+         Torch.Typed.Auxiliary.Snd outputSize+       ]+  ) =>+  -- | input+  Tensor device dtype '[batchSize, channelSize, inputSize0, inputSize1] ->+  -- | output+  Tensor device dtype '[batchSize, channelSize, Torch.Typed.Auxiliary.Fst outputSize, Torch.Typed.Auxiliary.Snd outputSize]+mkldnnAdaptiveAvgPool2d input =+  unsafePerformIO $+    ATen.cast2+      ATen.Managed.adaptive_avg_pool2d_tl+      input+      ([natValI @(Torch.Typed.Auxiliary.Fst outputSize), natValI @(Torch.Typed.Auxiliary.Snd outputSize)] :: [Int])++-- | adaptive averaged 3-D pooling+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> t = adaptiveAvgPool3d @'(8,16,2) (ones :: CPUTensor 'D.Float '[1,3,16,32,4])+-- >>> shape t+-- [1,3,8,16,2]+-- >>> :t t+-- t :: Tensor '(D.CPU, 0) 'D.Float [1, 3, 8, 16, 2]+adaptiveAvgPool3d ::+  forall+    outputSize+    channelSize+    inputSize0+    inputSize1+    inputSize2+    batchSize+    dtype+    device.+  ( All+      KnownNat+      '[ channelSize,+         inputSize0,+         inputSize1,+         inputSize2,+         batchSize,+         Fst3 outputSize,+         Snd3 outputSize,+         Trd3 outputSize+       ]+  ) =>+  -- | input+  Tensor device dtype '[batchSize, channelSize, inputSize0, inputSize1, inputSize2] ->+  -- | output+  Tensor device dtype '[batchSize, channelSize, Fst3 outputSize, Snd3 outputSize, Trd3 outputSize]+adaptiveAvgPool3d input =+  unsafePerformIO $+    ATen.cast2+      ATen.Managed.adaptive_avg_pool3d_tl+      input+      ( [ natValI @(Fst3 outputSize),+          natValI @(Snd3 outputSize),+          natValI @(Trd3 outputSize)+        ] ::+          [Int]+      )++-- | adaptive 2-D max-pool+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> (t, t') = adaptiveMaxPool2d @'(8,16) (ones :: CPUTensor 'D.Float '[1,3,16,32])+-- >>> shape t+-- [1,3,8,16]+-- >>> :t t+-- t :: Tensor '(D.CPU, 0) 'D.Float [1, 3, 8, 16]+adaptiveMaxPool2d ::+  forall outputSize channelSize inputSize0 inputSize1 batchSize dtype device.+  ( All+      KnownNat+      '[ channelSize,+         inputSize0,+         inputSize1,+         batchSize,+         Torch.Typed.Auxiliary.Fst outputSize,+         Torch.Typed.Auxiliary.Snd outputSize+       ]+  ) =>+  -- | input+  Tensor device dtype '[batchSize, channelSize, inputSize0, inputSize1] ->+  -- | output+  ( Tensor device dtype '[batchSize, channelSize, Torch.Typed.Auxiliary.Fst outputSize, Torch.Typed.Auxiliary.Snd outputSize],+    Tensor device 'D.Int64 '[batchSize, channelSize, Torch.Typed.Auxiliary.Fst outputSize, Torch.Typed.Auxiliary.Snd outputSize]+  )+adaptiveMaxPool2d input =+  unsafePerformIO $+    ATen.cast2+      ATen.Managed.adaptive_max_pool2d_tl+      input+      ([natValI @(Torch.Typed.Auxiliary.Fst outputSize), natValI @(Torch.Typed.Auxiliary.Snd outputSize)] :: [Int])++-- | adaptive 3-D max-pool+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> (t, t') = adaptiveMaxPool3d @'(8,16,2) (ones :: CPUTensor 'D.Float '[1,3,16,32,4])+-- >>> shape t+-- [1,3,8,16,2]+-- >>> :t t+-- t :: Tensor '(D.CPU, 0) 'D.Float [1, 3, 8, 16, 2]+adaptiveMaxPool3d ::+  forall+    outputSize+    channelSize+    inputSize0+    inputSize1+    inputSize2+    batchSize+    dtype+    device.+  ( All+      KnownNat+      '[ channelSize,+         inputSize0,+         inputSize1,+         inputSize2,+         batchSize,+         Fst3 outputSize,+         Snd3 outputSize,+         Trd3 outputSize+       ]+  ) =>+  -- | input+  Tensor device dtype '[batchSize, channelSize, inputSize0, inputSize1, inputSize2] ->+  -- | output+  ( Tensor device dtype '[batchSize, channelSize, Fst3 outputSize, Snd3 outputSize, Trd3 outputSize],+    Tensor device 'D.Int64 '[batchSize, channelSize, Fst3 outputSize, Snd3 outputSize, Trd3 outputSize]+  )+adaptiveMaxPool3d input =+  unsafePerformIO $+    (ATen.cast2 ATen.Managed.adaptive_max_pool3d_tl)+      input+      ( [ natValI @(Fst3 outputSize),+          natValI @(Snd3 outputSize),+          natValI @(Trd3 outputSize)+        ] ::+          [Int]+      )++-- | averaged 2-D pooling+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> t = avgPool2d @'(1,1) @'(1,1) @'(0,0) (ones :: CPUTensor 'D.Float '[1,3,4,5])+-- >>> shape t+-- [1,3,4,5]+-- >>> :t t+-- t :: Tensor '(D.CPU, 0) 'D.Float [1, 3, 4, 5]+avgPool2d ::+  forall+    kernelSize+    stride+    padding+    channelSize+    inputSize0+    inputSize1+    batchSize+    outputSize0+    outputSize1+    dtype+    device.+  ( All+      KnownNat+      '[ Torch.Typed.Auxiliary.Fst kernelSize,+         Torch.Typed.Auxiliary.Snd kernelSize,+         Torch.Typed.Auxiliary.Fst stride,+         Torch.Typed.Auxiliary.Snd stride,+         Torch.Typed.Auxiliary.Fst padding,+         Torch.Typed.Auxiliary.Snd padding,+         channelSize,+         inputSize0,+         inputSize1,+         batchSize+       ],+    ConvSideCheck inputSize0 (Torch.Typed.Auxiliary.Fst kernelSize) (Torch.Typed.Auxiliary.Fst stride) (Torch.Typed.Auxiliary.Fst padding) outputSize0,+    ConvSideCheck inputSize1 (Torch.Typed.Auxiliary.Snd kernelSize) (Torch.Typed.Auxiliary.Snd stride) (Torch.Typed.Auxiliary.Snd padding) outputSize1+  ) =>+  -- | input+  Tensor device dtype '[batchSize, channelSize, inputSize0, inputSize1] ->+  -- | output+  Tensor device dtype '[batchSize, channelSize, outputSize0, outputSize1]+avgPool2d input =+  unsafePerformIO $+    ATen.cast7+      ATen.Managed.avg_pool2d_tlllbbl+      input+      ([natValI @(Torch.Typed.Auxiliary.Fst kernelSize), natValI @(Torch.Typed.Auxiliary.Snd kernelSize)] :: [Int])+      ([natValI @(Torch.Typed.Auxiliary.Fst stride), natValI @(Torch.Typed.Auxiliary.Snd stride)] :: [Int])+      ([natValI @(Torch.Typed.Auxiliary.Fst padding), natValI @(Torch.Typed.Auxiliary.Snd padding)] :: [Int])+      False+      True+      (1 :: Int)++-- | averaged 3-D pooling+-- TODO: probably only defined for floating point tensors, or maybe numeric type is lifted?+--+-- >>> t = avgPool3d @'(1,1,1) @'(1,1,1) @'(0,0,0) (ones :: CPUTensor 'D.Float '[1,3,4,5,6])+-- >>> shape t+-- [1,3,4,5,6]+-- >>> :t t+-- t :: Tensor '(D.CPU, 0) 'D.Float [1, 3, 4, 5, 6]+avgPool3d ::+  forall+    kernelSize+    stride+    padding+    channelSize+    inputSize0+    inputSize1+    inputSize2+    batchSize+    outputSize0+    outputSize1+    outputSize2+    dtype+    device.+  ( All+      KnownNat+      '[ Fst3 kernelSize,+         Snd3 kernelSize,+         Trd3 kernelSize,+         Fst3 stride,+         Snd3 stride,+         Trd3 stride,+         Fst3 padding,+         Snd3 padding,+         Trd3 padding,+         channelSize,+         inputSize0,+         inputSize1,+         inputSize2,+         batchSize+       ],+    ConvSideCheck inputSize0 (Fst3 kernelSize) (Fst3 stride) (Fst3 padding) outputSize0,+    ConvSideCheck inputSize1 (Snd3 kernelSize) (Snd3 stride) (Snd3 padding) outputSize1,+    ConvSideCheck inputSize2 (Trd3 kernelSize) (Trd3 stride) (Trd3 padding) outputSize2+  ) =>+  -- | input+  Tensor device dtype '[batchSize, channelSize, inputSize0, inputSize1, inputSize2] ->+  -- | output+  Tensor device dtype '[batchSize, channelSize, outputSize0, outputSize1, outputSize2]+avgPool3d input =+  unsafePerformIO $+    ATen.cast7+      ATen.Managed.avg_pool3d_tlllbbl+      input+      ( [ natValI @(Fst3 kernelSize),+          natValI @(Snd3 kernelSize),+          natValI @(Trd3 kernelSize)+        ] ::+          [Int]+      )+      ([natValI @(Fst3 stride), natValI @(Snd3 stride), natValI @(Trd3 stride)] :: [Int])+      ([natValI @(Fst3 padding), natValI @(Snd3 padding), natValI @(Trd3 padding)] :: [Int])+      False+      True+      (1 :: Int)++-- fractional_max_pool2d :: Tensor device dtype shape -> (Int,Int) -> (Int,Int) -> Tensor device dtype shape -> (Tensor device dtype shape,Tensor device dtype shape)+-- fractional_max_pool2d _input _kernel_size _output_size _random_samples = unsafePerformIO $ (ATen.cast4 ATen.Managed.fractional_max_pool2d_tllt) _input _kernel_size _output_size _random_samples++-- fractional_max_pool3d :: Tensor device dtype shape -> (Int,Int,Int) -> (Int,Int,Int) -> Tensor device dtype shape -> (Tensor device dtype shape,Tensor device dtype shape)+-- fractional_max_pool3d _input _kernel_size _output_size _random_samples = unsafePerformIO $ (ATen.cast4 ATen.Managed.fractional_max_pool3d_tllt) _input _kernel_size _output_size _random_samples++-- max_pool2d_with_indices :: Tensor device dtype shape -> (Int,Int) -> (Int,Int) -> (Int,Int) -> (Int,Int) -> Bool -> (Tensor device dtype shape,Tensor device dtype shape)+-- max_pool2d_with_indices _input _kernel_size _stride _padding _dilation _ceil_mode = unsafePerformIO $ (ATen.cast6 ATen.Managed.max_pool2d_with_indices_tllllb) _input _kernel_size _stride _padding _dilation _ceil_mode++-- max_pool3d_with_indices :: Tensor device dtype shape -> (Int,Int,Int) -> (Int,Int,Int) -> (Int,Int,Int) -> (Int,Int,Int) -> Bool -> (Tensor device dtype shape,Tensor device dtype shape)+-- max_pool3d_with_indices _input _kernel_size _stride _padding _dilation _ceil_mode = unsafePerformIO $ (ATen.cast6 ATen.Managed.max_pool3d_with_indices_tllllb) _input _kernel_size _stride _padding _dilation _ceil_mode++-- max_unpool2d :: Tensor device dtype shape -> Tensor device dtype shape -> (Int,Int) -> Tensor device dtype shape+-- max_unpool2d _input _indices _output_size = unsafePerformIO $ (ATen.cast3 ATen.Managed.max_unpool2d_ttl) _input _indices _output_size++-- max_unpool3d :: Tensor device dtype shape -> Tensor device dtype shape -> (Int,Int,Int) -> (Int,Int,Int) -> (Int,Int,Int) -> Tensor device dtype shape+-- max_unpool3d _input _indices _output_size _stride _padding = unsafePerformIO $ (ATen.cast5 ATen.Managed.max_unpool3d_ttlll) _input _indices _output_size _stride _padding++-- reflection_pad1d :: Tensor device dtype shape -> (Int,Int) -> Tensor device dtype shape+-- reflection_pad1d _input _padding = unsafePerformIO $ (ATen.cast2 ATen.Managed.reflection_pad1d_tl) _input _padding++-- reflection_pad2d :: Tensor device dtype shape -> (Int,Int,Int,Int) -> Tensor device dtype shape+-- reflection_pad2d _input _padding = unsafePerformIO $ (ATen.cast2 ATen.Managed.reflection_pad2d_tl) _input _padding++-- replication_pad1d :: Tensor device dtype shape -> (Int,Int) -> Tensor device dtype shape+-- replication_pad1d _input _padding = unsafePerformIO $ (ATen.cast2 ATen.Managed.replication_pad1d_tl) _input _padding++-- replication_pad2d :: Tensor device dtype shape -> (Int,Int,Int,Int) -> Tensor device dtype shape+-- replication_pad2d _input _padding = unsafePerformIO $ (ATen.cast2 ATen.Managed.replication_pad2d_tl) _input _padding++-- replication_pad3d :: Tensor device dtype shape -> (Int,Int,Int,Int,Int,Int) -> Tensor device dtype shape+-- replication_pad3d _input _padding = unsafePerformIO $ (ATen.cast2 ATen.Managed.replication_pad3d_tl) _input _padding++-- upsample_linear1d :: Tensor device dtype shape -> Int -> Bool -> Tensor device dtype shape+-- upsample_linear1d _input _output_size _align_corners = unsafePerformIO $ (ATen.cast3 ATen.Managed.upsample_linear1d_tlb) _input _output_size _align_corners++type family Upsample2dCheck shape h w where+  Upsample2dCheck (b : c : w : h : '[]) h' w' =+    If+      (h <=? h')+      ( If+          (w <=? w')+          (b : c : w' : h' : '[])+          (TypeError (Text "Target width must be greater than current width!"))+      )+      (TypeError (Text "Target height must be greater than current height!"))+  Upsample2dCheck _ _ _ = TypeError (Text "Shape must be 4 dimensional!")++type Upsample2d shape h w = Upsample2dCheck shape h w++-- | Applies a 2D bilinear upsampling to an input signal composed of several input channels.+--+-- >>> (dtype &&& shape) $ upsample_bilinear2d @3 @5 False (ones :: CPUTensor 'D.Float '[2,3,2,2])+-- (Float,[2,3,3,5])+upsample_bilinear2d ::+  forall w h shape dtype device.+  (KnownNat h, KnownNat w, All KnownNat shape) =>+  -- | if True, the corner pixels of the input and output tensors are aligned, and thus preserving the values at those pixels.+  Bool ->+  Tensor device dtype shape ->+  Tensor device dtype (Upsample2d shape h w)+upsample_bilinear2d _align_corners _input =+  unsafePerformIO $ (ATen.cast3 ATen.Managed.upsample_bilinear2d_tlb) _input ([w, h] :: [Int]) _align_corners+  where+    w = natValI @w :: Int+    h = natValI @h :: Int++-- | Applies a 2D bicubic upsampling to an input signal composed of several input channels.+--+-- >>> (dtype &&& shape) $ upsample_bicubic2d @3 @5 False (ones :: CPUTensor 'D.Float '[2,3,2,2])+-- (Float,[2,3,3,5])+upsample_bicubic2d ::+  forall w h shape dtype device.+  (KnownNat h, KnownNat w, All KnownNat shape) =>+  Bool ->+  Tensor device dtype shape ->+  Tensor device dtype (Upsample2d shape h w)+upsample_bicubic2d _align_corners _input = unsafePerformIO $ (ATen.cast3 ATen.Managed.upsample_bicubic2d_tlb) _input ([w, h] :: [Int]) _align_corners+  where+    w = natValI @w :: Int+    h = natValI @h :: Int++-- upsample_trilinear3d :: Tensor device dtype shape -> (Int,Int,Int) -> Bool -> Tensor device dtype shape+-- upsample_trilinear3d _input _output_size _align_corners = unsafePerformIO $ (ATen.cast3 ATen.Managed.upsample_trilinear3d_tlb) _input _output_size _align_corners++-- upsample_nearest1d :: Tensor device dtype shape -> Int -> Tensor device dtype shape+-- upsample_nearest1d _input _output_size = unsafePerformIO $ (ATen.cast2 ATen.Managed.upsample_nearest1d_tl) _input _output_size++-- | Applies a 2D bicubic upsampling to an input signal composed of several input channels.+--+-- >>> (dtype &&& shape) $ upsample_nearest2d @3 @5 (ones :: CPUTensor 'D.Float '[2,3,2,2])+-- (Float,[2,3,3,5])+upsample_nearest2d ::+  forall w h shape dtype device.+  (KnownNat h, KnownNat w, All KnownNat shape) =>+  Tensor device dtype shape ->+  Tensor device dtype (Upsample2d shape h w)+upsample_nearest2d _input = unsafePerformIO $ (ATen.cast2 ATen.Managed.upsample_nearest2d_tl) _input ([w, h] :: [Int])+  where+    w = natValI @w :: Int+    h = natValI @h :: Int++-- upsample_nearest3d :: Tensor device dtype shape -> (Int,Int,Int) -> Tensor device dtype shape+-- upsample_nearest3d _input _output_size = unsafePerformIO $ (ATen.cast2 ATen.Managed.upsample_nearest3d_tl) _input _output_size++-- conv_dilated2d :: Tensor device dtype shape -> Tensor device dtype shape -> (Int,Int) -> Tensor device dtype shape -> (Int,Int) -> (Int,Int) -> (Int,Int) -> Tensor device dtype shape+-- conv_dilated2d _input _weight _kernel_size _bias _stride _padding _dilation = unsafePerformIO $ (ATen.cast7 ATen.Managed.conv_dilated2d_ttltlll) _input _weight _kernel_size _bias _stride _padding _dilation++-- conv_dilated3d :: Tensor device dtype shape -> Tensor device dtype shape -> (Int,Int,Int) -> Tensor device dtype shape -> (Int,Int,Int) -> (Int,Int,Int) -> (Int,Int,Int) -> Tensor device dtype shape+-- conv_dilated3d _input _weight _kernel_size _bias _stride _padding _dilation = unsafePerformIO $ (ATen.cast7 ATen.Managed.conv_dilated3d_ttltlll) _input _weight _kernel_size _bias _stride _padding _dilation++-- col2im :: Tensor device dtype shape -> (Int,Int) -> (Int,Int) -> (Int,Int) -> (Int,Int) -> (Int,Int) -> Tensor device dtype shape+-- col2im _input _output_size _kernel_size _dilation _padding _stride = unsafePerformIO $ (ATen.cast6 ATen.Managed.col2im_tlllll) _input _output_size _kernel_size _dilation _padding _stride++-- im2col :: Tensor device dtype shape -> (Int,Int) -> (Int,Int) -> (Int,Int) -> (Int,Int) -> Tensor device dtype shape+-- im2col _input _kernel_size _dilation _padding _stride = unsafePerformIO $ (ATen.cast5 ATen.Managed.im2col_tllll) _input _kernel_size _dilation _padding _stride
+ src/Torch/Typed/Lens.hs view
@@ -0,0 +1,160 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}++module Torch.Typed.Lens where++import Control.Applicative (liftA2)+import Control.Monad.State.Strict+import Control.Monad (forM)+import Data.Kind+import Data.Maybe (fromJust)+import Data.Proxy+import Data.Reflection hiding (D)+import Data.Type.Bool+import Data.Vector.Sized (Vector)+import GHC.Generics+import GHC.TypeLits+import System.IO.Unsafe+import qualified Torch.DType as D+import qualified Torch.Device as D+import qualified Torch.Functional as D hiding (select)+import qualified Torch.Functional.Internal as I+import qualified Torch.Internal.Managed.Type.TensorIndex as ATen+import Torch.Lens (Lens, Lens', Traversal, Traversal')+import qualified Torch.Tensor as T+import Torch.Typed.Auxiliary hiding (If)+import Torch.Typed.Tensor++class HasName (name :: Type -> Type) shape where+  name :: Traversal' (NamedTensor device dtype shape) (NamedTensor device dtype (DropName name shape))+  default name :: (KnownNat (NamedIdx name shape)) => Traversal' (NamedTensor device dtype shape) (NamedTensor device dtype (DropName name shape))+  name func s = func'+    where+      dimension :: Int+      dimension = natValI @(NamedIdx name shape)+      func' = (\v -> (fromUnnamed . UnsafeMkTensor $ D.stack (D.Dim dimension) (map toDynamic v))) <$> swapA (map func a') (pure [])+      s' = toDynamic s+      swapA [] v = v+      swapA (x : xs) v = swapA xs (liftA2 (\a b -> b ++ [a]) x v)+      a' :: [NamedTensor device dtype (DropName name shape)]+      a' = map (fromUnnamed . UnsafeMkTensor) $ I.unbind s' dimension++instance (KnownNat (NamedIdx name shape)) => HasName name shape++class HasField (field :: Symbol) shape where+  field :: Lens' (NamedTensor device dtype shape) (NamedTensor device dtype (DropField field shape))+  default field :: (FieldIdx field shape) => Lens' (NamedTensor device dtype shape) (NamedTensor device dtype (DropField field shape))+  field func s = fmap func' (func a')+    where+      index = fieldIdx @field @shape Proxy+      func' :: NamedTensor device dtype (DropField field shape) -> NamedTensor device dtype shape+      func' v = fromUnnamed . UnsafeMkTensor $ T.maskedFill s' index (toDynamic v)+      s' = toDynamic s+      a' :: NamedTensor device dtype (DropField field shape)+      a' = fromUnnamed . UnsafeMkTensor $ (s' T.! index)++instance {-# OVERLAPS #-} FieldIdx field shape => HasField field shape++type family GHasField (field :: Symbol) f :: Bool where+  GHasField field (S1 ('MetaSel ('Just field) _ _ _) _) = 'True+  GHasField field (S1 ('MetaSel _ _ _ _) _) = 'False+  GHasField field (D1 _ f) = GHasField field f+  GHasField field (C1 _ f) = GHasField field f+  GHasField field (l :*: r) = GHasField field l || GHasField field r+  GHasField field (l :+: r) = GHasField field l || GHasField field r+  GHasField field (K1 _ _) = 'False+  GHasField field U1 = 'False+  GHasField field (Vector n) = 'False+  GHasField field a = GHasField field (Rep (a ()))++type family DropField (field :: Symbol) (a :: [Type -> Type]) :: [Type -> Type] where+  DropField field '[] = '[]+  DropField field (x ': xs) = If (GHasField field x) xs (x ': DropField field xs)++type family DropName (name :: Type -> Type) (a :: [Type -> Type]) :: [Type -> Type] where+  DropName name '[] = '[]+  DropName name (name ': xs) = xs+  DropName name (x ': xs) = x ': DropName name xs++instance {-# OVERLAPS #-} T.TensorIndex [Maybe Int] where+  pushIndex vec list_of_maybe_int = unsafePerformIO $ do+    idx <- forM list_of_maybe_int $ \i -> do+      case i of+        Nothing -> T.RawTensorIndex <$> ATen.newTensorIndexWithSlice 0 maxBound 1+        Just v -> T.RawTensorIndex <$> ATen.newTensorIndexWithInt (fromIntegral v)+    return $ idx ++ vec++type family NamedIdx (name :: Type -> Type) (shape :: [Type -> Type]) :: Nat where+  NamedIdx name '[] = TypeError (Text "There is not the name in the shape.")+  NamedIdx name (name ': xs) = 0+  NamedIdx name (x ': xs) = NamedIdx name xs + 1++class FieldIdx (field :: Symbol) (a :: [Type -> Type]) where+  -- | Return field-id+  fieldIdx :: Proxy a -> [Maybe Int]++instance FieldIdx field '[] where+  fieldIdx _ = []++instance (FieldId field (x ()), FieldIdx field xs) => FieldIdx field (x ': xs) where+  fieldIdx _ = fieldId @field @(x ()) Proxy : fieldIdx @field @xs Proxy++class FieldId (field :: Symbol) a where+  -- | Return field-id+  fieldId :: Proxy a -> Maybe Int+  default fieldId :: (Generic a, GFieldId field (Rep a)) => Proxy a -> Maybe Int+  fieldId _ = gfieldId @field (Proxy :: Proxy (Rep a))++instance FieldId field (Vector n v) where+  fieldId _ = Nothing++instance {-# OVERLAPS #-} (Generic s, GFieldId field (Rep s)) => FieldId field s++class GFieldId (field :: Symbol) (a :: Type -> Type) where+  gfieldId :: Proxy a -> Maybe Int+  gfieldId p = fst $ gfieldId' @field @a p+  gfieldId' :: Proxy a -> (Maybe Int, Int)++instance (GFieldId field f) => GFieldId field (M1 D t f) where+  gfieldId' _ = gfieldId' @field (Proxy :: Proxy f)++instance (GFieldId field f) => GFieldId field (M1 C t f) where+  gfieldId' _ = gfieldId' @field (Proxy :: Proxy f)++instance (KnownSymbol field, KnownSymbol field_) => GFieldId field (S1 ('MetaSel ('Just field_) p f b) (Rec0 a)) where+  gfieldId' _ =+    if symbolVal (Proxy :: Proxy field) == symbolVal (Proxy :: Proxy field_)+      then (Just 0, 1)+      else (Nothing, 1)++instance GFieldId field (K1 c f) where+  gfieldId' _ = (Nothing, 1)++instance GFieldId field U1 where+  gfieldId' _ = (Nothing, 1)++instance (GFieldId field f, GFieldId field g) => GFieldId field (f :*: g) where+  gfieldId' _ =+    case (gfieldId' @field (Proxy :: Proxy f), gfieldId' @field (Proxy :: Proxy g)) of+      ((Nothing, t0), (Nothing, t1)) -> (Nothing, t0 + t1)+      ((Nothing, t0), (Just v1, t1)) -> (Just (v1 + t0), t1 + t0)+      ((Just v0, t0), (_, t1)) -> (Just v0, t0 + t1)++instance (GFieldId field f, GFieldId field g) => GFieldId field (f :+: g) where+  gfieldId' _ =+    case (gfieldId' @field (Proxy :: Proxy f), gfieldId' @field (Proxy :: Proxy g)) of+      ((Nothing, _), a1) -> a1+      (a0@(Just _, _), _) -> a0
+ src/Torch/Typed/NN.hs view
@@ -0,0 +1,46 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PartialTypeSignatures #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE DuplicateRecordFields #-}++{-# OPTIONS_GHC -Wno-partial-type-signatures #-}++module Torch.Typed.NN+  ( module Torch.Typed.NN,+    module Torch.Typed.NN.Convolution,+    module Torch.Typed.NN.Normalization,+    module Torch.Typed.NN.Recurrent,+    module Torch.Typed.NN.Transformer,+    module Torch.Typed.NN.Linear,+    module Torch.Typed.NN.Dropout,+    module Torch.Typed.NN.Sparse,+    module Torch.Typed.NN.DataParallel,+    Torch.NN.HasForward (..),+  )+where++import Torch.NN (HasForward (..))+import Torch.Typed.NN.Convolution+import Torch.Typed.NN.DataParallel+import Torch.Typed.NN.Dropout+import Torch.Typed.NN.Linear+import Torch.Typed.NN.Normalization+import Torch.Typed.NN.Recurrent+import Torch.Typed.NN.Sparse+import Torch.Typed.NN.Transformer
+ src/Torch/Typed/NN/Convolution.hs view
@@ -0,0 +1,655 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE OverloadedRecordDot #-}+{-# LANGUAGE DuplicateRecordFields #-}++module Torch.Typed.NN.Convolution where++import Data.Proxy+import GHC.Generics+import GHC.TypeLits+import qualified Torch.DType as D+import qualified Torch.Device as D+import Torch.NN (HasForward (..), Randomizable (..))+import Torch.Typed.Auxiliary+import Torch.Typed.Factories+import Torch.Typed.Functional+import Torch.Typed.Parameter+import Torch.Typed.Tensor++data+  Conv1dSpec+    (inputChannelSize :: Nat)+    (outputChannelSize :: Nat)+    (kernelSize :: Nat)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  = Conv1dSpec+  deriving (Show, Eq)++data+  Conv1d+    (inputChannelSize :: Nat)+    (outputChannelSize :: Nat)+    (kernelSize :: Nat)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  where+  Conv1d ::+    forall inputChannelSize outputChannelSize kernelSize dtype device.+    { weight :: Parameter device dtype '[outputChannelSize, inputChannelSize, kernelSize],+      bias :: Parameter device dtype '[outputChannelSize]+    } ->+    Conv1d+      inputChannelSize+      outputChannelSize+      kernelSize+      dtype+      device+  deriving (Show, Generic, Parameterized)++-- | conv1d+conv1dForward ::+  forall stride padding inputChannelSize outputChannelSize kernelSize inputSize batchSize outputSize dtype device.+  ( All+      KnownNat+      '[ stride,+         padding,+         inputChannelSize,+         outputChannelSize,+         kernelSize,+         inputSize,+         batchSize,+         outputSize+       ],+    ConvSideCheck inputSize kernelSize stride padding outputSize+  ) =>+  Conv1d inputChannelSize outputChannelSize kernelSize dtype device ->+  Tensor device dtype '[batchSize, inputChannelSize, inputSize] ->+  Tensor device dtype '[batchSize, outputChannelSize, outputSize]+conv1dForward Conv1d {..} input =+  conv1d @stride @padding+    (toDependent weight)+    (toDependent bias)+    input++instance+  ( All+      KnownNat+      '[ stride,+         padding,+         inputChannelSize,+         outputChannelSize,+         kernelSize,+         inputSize,+         batchSize,+         outputSize+       ],+    ConvSideCheck inputSize kernelSize stride padding outputSize+  ) =>+  HasForward (Conv1d inputChannelSize outputChannelSize kernelSize dtype device) (Tensor device dtype '[batchSize, inputChannelSize, inputSize], Proxy stride, Proxy padding) (Tensor device dtype '[batchSize, outputChannelSize, outputSize])+  where+  forward model (input, Proxy, Proxy) = conv1dForward @stride @padding model input+  forwardStoch = (pure .) . forward++instance+  ( KnownNat inputChannelSize,+    KnownNat outputChannelSize,+    KnownNat kernelSize,+    KnownDType dtype,+    KnownDevice device,+    RandDTypeIsValid device dtype+  ) =>+  Randomizable+    (Conv1dSpec inputChannelSize outputChannelSize kernelSize dtype device)+    (Conv1d inputChannelSize outputChannelSize kernelSize dtype device)+  where+  sample Conv1dSpec =+    Conv1d <$> (makeIndependent =<< randn) <*> (makeIndependent =<< randn)++data+  Conv2dSpec+    (inputChannelSize :: Nat)+    (outputChannelSize :: Nat)+    (kernelSize0 :: Nat)+    (kernelSize1 :: Nat)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  = Conv2dSpec+  deriving (Show, Eq)++data+  Conv2d+    (inputChannelSize :: Nat)+    (outputChannelSize :: Nat)+    (kernelSize0 :: Nat)+    (kernelSize1 :: Nat)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  where+  Conv2d ::+    forall inputChannelSize outputChannelSize kernelSize0 kernelSize1 dtype device.+    { weight :: Parameter device dtype '[outputChannelSize, inputChannelSize, kernelSize0, kernelSize1],+      bias :: Parameter device dtype '[outputChannelSize]+    } ->+    Conv2d+      inputChannelSize+      outputChannelSize+      kernelSize0+      kernelSize1+      dtype+      device+  deriving (Show, Generic, Parameterized)++-- | conv2d+conv2dForward ::+  forall stride padding inputChannelSize outputChannelSize kernelSize0 kernelSize1 inputSize0 inputSize1 batchSize outputSize0 outputSize1 dtype device.+  ( All+      KnownNat+      '[ Torch.Typed.Auxiliary.Fst stride,+         Torch.Typed.Auxiliary.Snd stride,+         Torch.Typed.Auxiliary.Fst padding,+         Torch.Typed.Auxiliary.Snd padding,+         inputChannelSize,+         outputChannelSize,+         kernelSize0,+         kernelSize1,+         inputSize0,+         inputSize1,+         batchSize,+         outputSize0,+         outputSize1+       ],+    ConvSideCheck inputSize0 kernelSize0 (Torch.Typed.Auxiliary.Fst stride) (Torch.Typed.Auxiliary.Fst padding) outputSize0,+    ConvSideCheck inputSize1 kernelSize1 (Torch.Typed.Auxiliary.Snd stride) (Torch.Typed.Auxiliary.Snd padding) outputSize1+  ) =>+  Conv2d inputChannelSize outputChannelSize kernelSize0 kernelSize1 dtype device ->+  Tensor device dtype '[batchSize, inputChannelSize, inputSize0, inputSize1] ->+  Tensor device dtype '[batchSize, outputChannelSize, outputSize0, outputSize1]+conv2dForward Conv2d {..} input =+  conv2d @stride @padding+    (toDependent weight)+    (toDependent bias)+    input++instance+  ( All+      KnownNat+      '[ Torch.Typed.Auxiliary.Fst stride,+         Torch.Typed.Auxiliary.Snd stride,+         Torch.Typed.Auxiliary.Fst padding,+         Torch.Typed.Auxiliary.Snd padding,+         inputChannelSize,+         outputChannelSize,+         kernelSize0,+         kernelSize1,+         inputSize0,+         inputSize1,+         batchSize,+         outputSize0,+         outputSize1+       ],+    ConvSideCheck inputSize0 kernelSize0 (Torch.Typed.Auxiliary.Fst stride) (Torch.Typed.Auxiliary.Fst padding) outputSize0,+    ConvSideCheck inputSize1 kernelSize1 (Torch.Typed.Auxiliary.Snd stride) (Torch.Typed.Auxiliary.Snd padding) outputSize1+  ) =>+  HasForward (Conv2d inputChannelSize outputChannelSize kernelSize0 kernelSize1 dtype device) (Tensor device dtype '[batchSize, inputChannelSize, inputSize0, inputSize1], Proxy stride, Proxy padding) (Tensor device dtype '[batchSize, outputChannelSize, outputSize0, outputSize1])+  where+  forward model (input, Proxy, Proxy) = conv2dForward @stride @padding model input+  forwardStoch = (pure .) . forward++instance+  ( KnownNat inputChannelSize,+    KnownNat outputChannelSize,+    KnownNat kernelSize0,+    KnownNat kernelSize1,+    KnownDType dtype,+    KnownDevice device,+    RandDTypeIsValid device dtype+  ) =>+  Randomizable+    (Conv2dSpec inputChannelSize outputChannelSize kernelSize0 kernelSize1 dtype device)+    (Conv2d inputChannelSize outputChannelSize kernelSize0 kernelSize1 dtype device)+  where+  sample Conv2dSpec =+    Conv2d <$> (makeIndependent =<< randn) <*> (makeIndependent =<< randn)++data+  Conv3dSpec+    (inputChannelSize :: Nat)+    (outputChannelSize :: Nat)+    (kernelSize0 :: Nat)+    (kernelSize1 :: Nat)+    (kernelSize2 :: Nat)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  = Conv3dSpec+  deriving (Show, Eq)++data+  Conv3d+    (inputChannelSize :: Nat)+    (outputChannelSize :: Nat)+    (kernelSize0 :: Nat)+    (kernelSize1 :: Nat)+    (kernelSize2 :: Nat)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  where+  Conv3d ::+    forall inputChannelSize outputChannelSize kernelSize0 kernelSize1 kernelSize2 dtype device.+    { weight :: Parameter device dtype '[outputChannelSize, inputChannelSize, kernelSize0, kernelSize1, kernelSize2],+      bias :: Parameter device dtype '[outputChannelSize]+    } ->+    Conv3d+      inputChannelSize+      outputChannelSize+      kernelSize0+      kernelSize1+      kernelSize2+      dtype+      device+  deriving (Show, Generic, Parameterized)++-- | conv3d+conv3dForward ::+  forall stride padding inputChannelSize outputChannelSize kernelSize0 kernelSize1 kernelSize2 inputSize0 inputSize1 inputSize2 batchSize outputSize0 outputSize1 outputSize2 dtype device.+  ( All+      KnownNat+      '[ Fst3 stride,+         Snd3 stride,+         Trd3 stride,+         Fst3 padding,+         Snd3 padding,+         Trd3 padding,+         inputChannelSize,+         outputChannelSize,+         kernelSize0,+         kernelSize1,+         kernelSize2,+         inputSize0,+         inputSize1,+         inputSize2,+         batchSize+       ],+    ConvSideCheck inputSize0 kernelSize0 (Fst3 stride) (Fst3 padding) outputSize0,+    ConvSideCheck inputSize1 kernelSize1 (Snd3 stride) (Snd3 padding) outputSize1,+    ConvSideCheck inputSize2 kernelSize2 (Trd3 stride) (Trd3 padding) outputSize2+  ) =>+  Conv3d inputChannelSize outputChannelSize kernelSize0 kernelSize1 kernelSize2 dtype device ->+  Tensor device dtype '[batchSize, inputChannelSize, inputSize0, inputSize1, inputSize2] ->+  Tensor device dtype '[batchSize, outputChannelSize, outputSize0, outputSize1, outputSize2]+conv3dForward Conv3d {..} input =+  conv3d @stride @padding+    (toDependent weight)+    (toDependent bias)+    input++instance+  ( All+      KnownNat+      '[ Fst3 stride,+         Snd3 stride,+         Trd3 stride,+         Fst3 padding,+         Snd3 padding,+         Trd3 padding,+         inputChannelSize,+         outputChannelSize,+         kernelSize0,+         kernelSize1,+         kernelSize2,+         inputSize0,+         inputSize1,+         inputSize2,+         batchSize+       ],+    ConvSideCheck inputSize0 kernelSize0 (Fst3 stride) (Fst3 padding) outputSize0,+    ConvSideCheck inputSize1 kernelSize1 (Snd3 stride) (Snd3 padding) outputSize1,+    ConvSideCheck inputSize2 kernelSize2 (Trd3 stride) (Trd3 padding) outputSize2+  ) =>+  HasForward (Conv3d inputChannelSize outputChannelSize kernelSize0 kernelSize1 kernelSize2 dtype device) (Tensor device dtype '[batchSize, inputChannelSize, inputSize0, inputSize1, inputSize2], Proxy stride, Proxy padding) (Tensor device dtype '[batchSize, outputChannelSize, outputSize0, outputSize1, outputSize2])+  where+  forward model (input, Proxy, Proxy) = conv3dForward @stride @padding model input+  forwardStoch = (pure .) . forward++instance+  ( KnownNat inputChannelSize,+    KnownNat outputChannelSize,+    KnownNat kernelSize0,+    KnownNat kernelSize1,+    KnownNat kernelSize2,+    KnownDType dtype,+    KnownDevice device,+    RandDTypeIsValid device dtype+  ) =>+  Randomizable+    (Conv3dSpec inputChannelSize outputChannelSize kernelSize0 kernelSize1 kernelSize2 dtype device)+    (Conv3d inputChannelSize outputChannelSize kernelSize0 kernelSize1 kernelSize2 dtype device)+  where+  sample Conv3dSpec =+    Conv3d <$> (makeIndependent =<< randn) <*> (makeIndependent =<< randn)++data+  ConvTranspose1dSpec+    (inputChannelSize :: Nat)+    (outputChannelSize :: Nat)+    (kernelSize :: Nat)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  = ConvTranspose1dSpec+  deriving (Show, Eq)++data+  ConvTranspose1d+    (inputChannelSize :: Nat)+    (outputChannelSize :: Nat)+    (kernelSize :: Nat)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  where+  ConvTranspose1d ::+    forall inputChannelSize outputChannelSize kernelSize dtype device.+    { weight :: Parameter device dtype '[inputChannelSize, outputChannelSize, kernelSize],+      bias :: Parameter device dtype '[outputChannelSize]+    } ->+    ConvTranspose1d+      inputChannelSize+      outputChannelSize+      kernelSize+      dtype+      device+  deriving (Show, Generic, Parameterized)++-- | convTranspose1d+convTranspose1dForward ::+  forall stride padding inputChannelSize outputChannelSize kernelSize inputSize batchSize outputSize dtype device.+  ( All+      KnownNat+      '[ stride,+         padding,+         inputChannelSize,+         outputChannelSize,+         kernelSize,+         inputSize,+         batchSize,+         outputSize+       ],+    ConvSideCheck inputSize kernelSize stride padding outputSize+  ) =>+  ConvTranspose1d inputChannelSize outputChannelSize kernelSize dtype device ->+  Tensor device dtype '[batchSize, inputChannelSize, inputSize] ->+  Tensor device dtype '[batchSize, outputChannelSize, outputSize]+convTranspose1dForward ConvTranspose1d {..} input =+  convTranspose1d @stride @padding+    (toDependent weight)+    (toDependent bias)+    input++instance+  ( All+      KnownNat+      '[ stride,+         padding,+         inputChannelSize,+         outputChannelSize,+         kernelSize,+         inputSize,+         batchSize,+         outputSize+       ],+    ConvSideCheck inputSize kernelSize stride padding outputSize+  ) =>+  HasForward (ConvTranspose1d inputChannelSize outputChannelSize kernelSize dtype device) (Tensor device dtype '[batchSize, inputChannelSize, inputSize], Proxy stride, Proxy padding) (Tensor device dtype '[batchSize, outputChannelSize, outputSize])+  where+  forward model (input, Proxy, Proxy) = convTranspose1dForward @stride @padding model input+  forwardStoch = (pure .) . forward++instance+  ( KnownNat inputChannelSize,+    KnownNat outputChannelSize,+    KnownNat kernelSize,+    KnownDType dtype,+    KnownDevice device,+    RandDTypeIsValid device dtype+  ) =>+  Randomizable+    (ConvTranspose1dSpec inputChannelSize outputChannelSize kernelSize dtype device)+    (ConvTranspose1d inputChannelSize outputChannelSize kernelSize dtype device)+  where+  sample ConvTranspose1dSpec =+    ConvTranspose1d <$> (makeIndependent =<< randn) <*> (makeIndependent =<< randn)++data+  ConvTranspose2dSpec+    (inputChannelSize :: Nat)+    (outputChannelSize :: Nat)+    (kernelSize0 :: Nat)+    (kernelSize1 :: Nat)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  = ConvTranspose2dSpec+  deriving (Show, Eq)++data+  ConvTranspose2d+    (inputChannelSize :: Nat)+    (outputChannelSize :: Nat)+    (kernelSize0 :: Nat)+    (kernelSize1 :: Nat)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  where+  ConvTranspose2d ::+    forall inputChannelSize outputChannelSize kernelSize0 kernelSize1 dtype device.+    { weight :: Parameter device dtype '[inputChannelSize, outputChannelSize, kernelSize0, kernelSize1],+      bias :: Parameter device dtype '[outputChannelSize]+    } ->+    ConvTranspose2d+      inputChannelSize+      outputChannelSize+      kernelSize0+      kernelSize1+      dtype+      device+  deriving (Show, Generic, Parameterized)++-- | convTranspose2d+convTranspose2dForward ::+  forall stride padding inputChannelSize outputChannelSize kernelSize0 kernelSize1 inputSize0 inputSize1 batchSize outputSize0 outputSize1 dtype device.+  ( All+      KnownNat+      '[ Torch.Typed.Auxiliary.Fst stride,+         Torch.Typed.Auxiliary.Snd stride,+         Torch.Typed.Auxiliary.Fst padding,+         Torch.Typed.Auxiliary.Snd padding,+         inputChannelSize,+         outputChannelSize,+         kernelSize0,+         kernelSize1,+         inputSize0,+         inputSize1,+         batchSize,+         outputSize0,+         outputSize1+       ],+    ConvSideCheck inputSize0 kernelSize0 (Torch.Typed.Auxiliary.Fst stride) (Torch.Typed.Auxiliary.Fst padding) outputSize0,+    ConvSideCheck inputSize1 kernelSize1 (Torch.Typed.Auxiliary.Snd stride) (Torch.Typed.Auxiliary.Snd padding) outputSize1+  ) =>+  ConvTranspose2d inputChannelSize outputChannelSize kernelSize0 kernelSize1 dtype device ->+  Tensor device dtype '[batchSize, inputChannelSize, inputSize0, inputSize1] ->+  Tensor device dtype '[batchSize, outputChannelSize, outputSize0, outputSize1]+convTranspose2dForward ConvTranspose2d {..} input =+  convTranspose2d @stride @padding+    (toDependent weight)+    (toDependent bias)+    input++instance+  ( All+      KnownNat+      '[ Torch.Typed.Auxiliary.Fst stride,+         Torch.Typed.Auxiliary.Snd stride,+         Torch.Typed.Auxiliary.Fst padding,+         Torch.Typed.Auxiliary.Snd padding,+         inputChannelSize,+         outputChannelSize,+         kernelSize0,+         kernelSize1,+         inputSize0,+         inputSize1,+         batchSize,+         outputSize0,+         outputSize1+       ],+    ConvSideCheck inputSize0 kernelSize0 (Torch.Typed.Auxiliary.Fst stride) (Torch.Typed.Auxiliary.Fst padding) outputSize0,+    ConvSideCheck inputSize1 kernelSize1 (Torch.Typed.Auxiliary.Snd stride) (Torch.Typed.Auxiliary.Snd padding) outputSize1+  ) =>+  HasForward (ConvTranspose2d inputChannelSize outputChannelSize kernelSize0 kernelSize1 dtype device) (Tensor device dtype '[batchSize, inputChannelSize, inputSize0, inputSize1], Proxy stride, Proxy padding) (Tensor device dtype '[batchSize, outputChannelSize, outputSize0, outputSize1])+  where+  forward model (input, Proxy, Proxy) = convTranspose2dForward @stride @padding model input+  forwardStoch = (pure .) . forward++instance+  ( KnownNat inputChannelSize,+    KnownNat outputChannelSize,+    KnownNat kernelSize0,+    KnownNat kernelSize1,+    KnownDType dtype,+    KnownDevice device,+    RandDTypeIsValid device dtype+  ) =>+  Randomizable+    (ConvTranspose2dSpec inputChannelSize outputChannelSize kernelSize0 kernelSize1 dtype device)+    (ConvTranspose2d inputChannelSize outputChannelSize kernelSize0 kernelSize1 dtype device)+  where+  sample ConvTranspose2dSpec =+    ConvTranspose2d <$> (makeIndependent =<< randn) <*> (makeIndependent =<< randn)++data+  ConvTranspose3dSpec+    (inputChannelSize :: Nat)+    (outputChannelSize :: Nat)+    (kernelSize0 :: Nat)+    (kernelSize1 :: Nat)+    (kernelSize2 :: Nat)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  = ConvTranspose3dSpec+  deriving (Show, Eq)++data+  ConvTranspose3d+    (inputChannelSize :: Nat)+    (outputChannelSize :: Nat)+    (kernelSize0 :: Nat)+    (kernelSize1 :: Nat)+    (kernelSize2 :: Nat)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  where+  ConvTranspose3d ::+    forall inputChannelSize outputChannelSize kernelSize0 kernelSize1 kernelSize2 dtype device.+    { weight :: Parameter device dtype '[inputChannelSize, outputChannelSize, kernelSize0, kernelSize1, kernelSize2],+      bias :: Parameter device dtype '[outputChannelSize]+    } ->+    ConvTranspose3d+      inputChannelSize+      outputChannelSize+      kernelSize0+      kernelSize1+      kernelSize2+      dtype+      device+  deriving (Show, Generic, Parameterized)++-- | convTranspose3d+convTranspose3dForward ::+  forall stride padding inputChannelSize outputChannelSize kernelSize0 kernelSize1 kernelSize2 inputSize0 inputSize1 inputSize2 batchSize outputSize0 outputSize1 outputSize2 dtype device.+  ( All+      KnownNat+      '[ Fst3 stride,+         Snd3 stride,+         Trd3 stride,+         Fst3 padding,+         Snd3 padding,+         Trd3 padding,+         inputChannelSize,+         outputChannelSize,+         kernelSize0,+         kernelSize1,+         kernelSize2,+         inputSize0,+         inputSize1,+         inputSize2,+         batchSize+       ],+    ConvSideCheck inputSize0 kernelSize0 (Fst3 stride) (Fst3 padding) outputSize0,+    ConvSideCheck inputSize1 kernelSize1 (Snd3 stride) (Snd3 padding) outputSize1,+    ConvSideCheck inputSize2 kernelSize2 (Trd3 stride) (Trd3 padding) outputSize2+  ) =>+  ConvTranspose3d inputChannelSize outputChannelSize kernelSize0 kernelSize1 kernelSize2 dtype device ->+  Tensor device dtype '[batchSize, inputChannelSize, inputSize0, inputSize1, inputSize2] ->+  Tensor device dtype '[batchSize, outputChannelSize, outputSize0, outputSize1, outputSize2]+convTranspose3dForward ConvTranspose3d {..} input =+  convTranspose3d @stride @padding+    (toDependent weight)+    (toDependent bias)+    input++instance+  ( All+      KnownNat+      '[ Fst3 stride,+         Snd3 stride,+         Trd3 stride,+         Fst3 padding,+         Snd3 padding,+         Trd3 padding,+         inputChannelSize,+         outputChannelSize,+         kernelSize0,+         kernelSize1,+         kernelSize2,+         inputSize0,+         inputSize1,+         inputSize2,+         batchSize+       ],+    ConvSideCheck inputSize0 kernelSize0 (Fst3 stride) (Fst3 padding) outputSize0,+    ConvSideCheck inputSize1 kernelSize1 (Snd3 stride) (Snd3 padding) outputSize1,+    ConvSideCheck inputSize2 kernelSize2 (Trd3 stride) (Trd3 padding) outputSize2+  ) =>+  HasForward (ConvTranspose3d inputChannelSize outputChannelSize kernelSize0 kernelSize1 kernelSize2 dtype device) (Tensor device dtype '[batchSize, inputChannelSize, inputSize0, inputSize1, inputSize2], Proxy stride, Proxy padding) (Tensor device dtype '[batchSize, outputChannelSize, outputSize0, outputSize1, outputSize2])+  where+  forward model (input, Proxy, Proxy) = convTranspose3dForward @stride @padding model input+  forwardStoch = (pure .) . forward++instance+  ( KnownNat inputChannelSize,+    KnownNat outputChannelSize,+    KnownNat kernelSize0,+    KnownNat kernelSize1,+    KnownNat kernelSize2,+    KnownDType dtype,+    KnownDevice device,+    RandDTypeIsValid device dtype+  ) =>+  Randomizable+    (ConvTranspose3dSpec inputChannelSize outputChannelSize kernelSize0 kernelSize1 kernelSize2 dtype device)+    (ConvTranspose3d inputChannelSize outputChannelSize kernelSize0 kernelSize1 kernelSize2 dtype device)+  where+  sample ConvTranspose3dSpec =+    ConvTranspose3d <$> (makeIndependent =<< randn) <*> (makeIndependent =<< randn)
+ src/Torch/Typed/NN/DataParallel.hs view
@@ -0,0 +1,144 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}++module Torch.Typed.NN.DataParallel where++import Control.Concurrent.Async+import Data.Kind+import GHC.TypeLits+import qualified Torch.Device as D+import Torch.HList+import qualified Torch.Internal.Cast as ATen+import qualified Torch.Internal.Class as ATen+import Torch.NN (HasForward (..))+import qualified Torch.Tensor as D+import Torch.Typed.Autograd+import Torch.Typed.Device+import Torch.Typed.Optim++data ForwardConcurrentlyF = ForwardConcurrentlyF | ForwardConcurrentlyStochF++instance+  ( HasForward model input output+  ) =>+  Apply' ForwardConcurrentlyF (model, input) (Concurrently output)+  where+  apply' ForwardConcurrentlyF (model, input) = Concurrently . pure . forward model $ input+  apply' ForwardConcurrentlyStochF (model, input) = Concurrently . forwardStoch model $ input++-- Run a `model` concurrently on an `input`.+--+-- The `model` is replicated over the supplied `devices'`, and the `input` is scattered+-- over them as well. Then the `forward` function of the replicated `models` is run+-- concurrently on the scattered `inputs`. Finally, the `outputs` are gathered on the+-- target `device'`+--+-- >>> model <- A.sample (LinearSpec @1 @1 @'D.Float @'( 'D.CPU, 0))+-- >>> t = ones @'[2, 1] @'D.Float @'( 'D.CPU, 0)+--+-- >>> :t forward model t+-- forward model t :: IO (Tensor '( 'D.CPU, 0) 'D.Float '[2, 1])+-- >>> forward model t+-- Tensor Float [2,1] [[ 0.2478   ],+--                     [ 0.2478   ]]+--+-- >>> :t forwardConcurrently' @'[ '( 'D.CPU, 0), '( 'D.CUDA, 0)] @'( 'D.CPU, 0) model t+-- forwardConcurrently' @'[ '( 'D.CPU, 0), '( 'D.CUDA, 0)] @'( 'D.CPU, 0) model t+--   :: IO (Tensor '( 'D.CPU, 0) 'D.Float '[2, 1])+-- >>> forwardConcurrently' @'[ '( 'D.CPU, 0), '( 'D.CUDA, 0)] @'( 'D.CPU, 0) model t+-- Tensor Float [2,1] [[ 0.2478   ],+--                     [ 0.2478   ]]+forwardConcurrently',+  forwardConcurrentlyStoch' ::+    forall devices' device' device model input output models inputs outputs.+    ( 'Just device ~ GetDevice model,+      'Just device ~ GetDevice input,+      HasScatter devices' device input inputs,+      HasReplicate devices' device model models,+      HZipWithM Concurrently ForwardConcurrentlyF models inputs outputs,+      HasGather device' devices' outputs output+    ) =>+    model ->+    input ->+    IO output+forwardConcurrently' model input = do+  let models = Torch.Typed.Device.replicate @devices' @device @model @models model+      inputs = scatter @devices' @device @input @inputs input+  outputs <- runConcurrently $ forwardConcurrently models inputs+  let output = gather @device' @devices' @outputs @output outputs+  return output+forwardConcurrentlyStoch' model input = do+  let models = Torch.Typed.Device.replicate @devices' @device @model @models model+      inputs = scatter @devices' @device @input @inputs input+  outputs <- runConcurrently $ forwardConcurrentlyStoch models inputs+  let output = gather @device' @devices' @outputs @output outputs+  return output++forwardConcurrently,+  forwardConcurrentlyStoch ::+    forall models inputs outputs.+    HZipWithM Concurrently ForwardConcurrentlyF models inputs outputs =>+    HList models ->+    HList inputs ->+    Concurrently (HList outputs)+forwardConcurrently = hzipWithM ForwardConcurrentlyF+forwardConcurrentlyStoch = hzipWithM ForwardConcurrentlyStochF++class HasGradConcurrently device' devices parameters losses gradients | device' devices parameters losses -> gradients where+  gradConcurrently :: HList parameters -> HList losses -> Concurrently (HList gradients)++data GradConcurrentlyF = GradConcurrentlyF++instance+  ( HasGrad (HList parameters) (HList gradients),+    ATen.Castable (HList gradients) [D.ATenTensor]+  ) =>+  Apply' GradConcurrentlyF (HList parameters, Loss device dtype) (Concurrently (HList gradients))+  where+  apply' GradConcurrentlyF (parameters, loss) = Concurrently . pure . grad loss $ parameters++instance+  ( HZipWithM Concurrently GradConcurrentlyF parameters losses gradients',+    ReduceGradients device' devices gradients' gradients+  ) =>+  HasGradConcurrently device' devices parameters losses gradients+  where+  gradConcurrently parameters losses =+    let gradients = hzipWithM GradConcurrentlyF parameters losses+     in reduceGradients @device' @devices <$> gradients++class ReduceGradients (device' :: (D.DeviceType, Nat)) (devices :: [(D.DeviceType, Nat)]) xxs ys | device' devices xxs -> ys where+  reduceGradients :: HList xxs -> HList ys++instance+  {-# OVERLAPS #-}+  ( HasToDevice device' device (HList xs) (HList ys)+  ) =>+  ReduceGradients device' (device ': '[]) ((HList (xs :: [Type])) ': '[]) ys+  where+  reduceGradients (xs :. HNil) = Torch.Typed.Device.toDevice @device' @device xs++data SumF = SumF++instance Num y => Apply' SumF (y, y) y where+  apply' _ = sum++instance+  {-# OVERLAPPABLE #-}+  ( HasToDevice device' device (HList xs) (HList ys),+    ReduceGradients device' devices xxs ys,+    HZipWith SumF ys ys ys,+    1 <= ListLength xxs+  ) =>+  ReduceGradients device' (device ': devices) ((HList (xs :: [Type])) ': xxs) ys+  where+  reduceGradients (xs :. xxs) = hzipWith SumF (Torch.Typed.Device.toDevice @device' @device xs) (reduceGradients @device' @devices @xxs xxs)
+ src/Torch/Typed/NN/Dropout.hs view
@@ -0,0 +1,42 @@+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}++module Torch.Typed.NN.Dropout where++import GHC.Generics+import System.IO.Unsafe+import Torch.NN (HasForward (..), Randomizable (..))+import Torch.Typed.Functional+import Torch.Typed.Parameter+import Torch.Typed.Tensor++data DropoutSpec where+  DropoutSpec ::+    {dropoutProbSpec :: Double} ->+    DropoutSpec+  deriving (Show, Eq)++data Dropout where+  Dropout ::+    {dropoutProb :: Double} ->+    Dropout+  deriving (Show, Generic, Parameterized)++dropoutForward ::+  forall shape dtype device.+  Dropout ->+  Bool ->+  Tensor device dtype shape ->+  IO (Tensor device dtype shape)+dropoutForward Dropout {..} dropoutTrain = dropout dropoutProb dropoutTrain++instance HasForward Dropout (Tensor device dtype shape) (Tensor device dtype shape) where+  forward dropout input = unsafePerformIO $ dropoutForward dropout False input+  forwardStoch dropout input = dropoutForward dropout True input++instance Randomizable DropoutSpec Dropout where+  sample DropoutSpec {..} = return $ Dropout dropoutProbSpec
+ src/Torch/Typed/NN/Linear.hs view
@@ -0,0 +1,83 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PartialTypeSignatures #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE OverloadedRecordDot #-}+{-# LANGUAGE DuplicateRecordFields #-}+{-# OPTIONS_GHC -Wno-partial-type-signatures #-}++module Torch.Typed.NN.Linear where++import GHC.Generics+import GHC.TypeLits+import qualified Torch.DType as D+import qualified Torch.Device as D+import Torch.NN (HasForward (..), Randomizable (..))+import Torch.Typed.Factories+import Torch.Typed.Functional+import Torch.Typed.Parameter+import Torch.Typed.Tensor++data+  LinearSpec+    (inputFeatures :: Nat)+    (outputFeatures :: Nat)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  = LinearSpec+  deriving (Show, Eq)++data+  Linear+    (inputFeatures :: Nat)+    (outputFeatures :: Nat)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  where+  Linear ::+    forall inputFeatures outputFeatures dtype device.+    { weight :: Parameter device dtype '[outputFeatures, inputFeatures],+      bias :: Parameter device dtype '[outputFeatures]+    } ->+    Linear inputFeatures outputFeatures dtype device+  deriving (Show, Generic, Parameterized)++-- | linear+-- The constraints on this one are _very_ involved, so the partial signatures+-- make the code significantly cleaner.+linearForward ::+  _ =>+  Linear _ _ _ _ ->+  Tensor _ _ _ ->+  Tensor _ _ _+linearForward Linear {..} input = linear' (toDependent weight) (toDependent bias) input++instance+  ( shape'' ~ MatMul shape '[inputFeatures, outputFeatures],+    shape' ~ Broadcast shape'' shape''+  ) =>+  HasForward (Linear inputFeatures outputFeatures dtype device) (Tensor device dtype shape) (Tensor device dtype shape')+  where+  forward = linearForward+  forwardStoch = (pure .) . forward++instance+  ( KnownNat inputFeatures,+    KnownNat outputFeatures,+    KnownDType dtype,+    KnownDevice device,+    RandDTypeIsValid device dtype+  ) =>+  Randomizable+    (LinearSpec inputFeatures outputFeatures dtype device)+    (Linear inputFeatures outputFeatures dtype device)+  where+  sample LinearSpec =+    Linear <$> (makeIndependent =<< randn) <*> (makeIndependent =<< randn)
+ src/Torch/Typed/NN/Normalization.hs view
@@ -0,0 +1,76 @@+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE UndecidableInstances #-}++module Torch.Typed.NN.Normalization where++import GHC.Generics+import GHC.TypeLits+import qualified Torch.DType as D+import qualified Torch.Device as D+import Torch.NN (HasForward (..), Randomizable (..))+import Torch.Typed.Auxiliary+import Torch.Typed.Factories+import Torch.Typed.Functional+import Torch.Typed.Parameter+import Torch.Typed.Tensor++data LayerNormSpec (normalizedShape :: [Nat]) (dtype :: D.DType) (device :: (D.DeviceType, Nat)) where+  LayerNormSpec ::+    forall normalizedShape dtype device.+    {layerNormEpsSpec :: Double} ->+    LayerNormSpec normalizedShape dtype device+  deriving (Show, Eq)++data LayerNorm (normalizedShape :: [Nat]) (dtype :: D.DType) (device :: (D.DeviceType, Nat)) where+  LayerNorm ::+    { layerNormWeight :: Parameter device dtype normalizedShape,+      layerNormBias :: Parameter device dtype normalizedShape,+      layerNormEps :: Double+    } ->+    LayerNorm normalizedShape dtype device+  deriving (Show, Generic, Parameterized)++layerNormForward ::+  forall normalizedShape shape dtype device.+  ( IsSuffixOf normalizedShape shape,+    KnownShape normalizedShape+  ) =>+  LayerNorm normalizedShape dtype device ->+  Tensor device dtype shape ->+  Tensor device dtype shape+layerNormForward LayerNorm {..} =+  layerNorm @normalizedShape+    (toDependent layerNormWeight)+    (toDependent layerNormBias)+    layerNormEps++instance+  ( IsSuffixOf normalizedShape shape,+    KnownShape normalizedShape+  ) =>+  HasForward (LayerNorm normalizedShape dtype device) (Tensor device dtype shape) (Tensor device dtype shape)+  where+  forward = layerNormForward+  forwardStoch = (pure .) . forward++instance+  ( TensorOptions normalizedShape dtype device,+    RandDTypeIsValid device dtype+  ) =>+  Randomizable+    (LayerNormSpec normalizedShape dtype device)+    (LayerNorm normalizedShape dtype device)+  where+  sample LayerNormSpec {..} =+    LayerNorm+      <$> (makeIndependent =<< randn)+      <*> (makeIndependent =<< randn)+      <*> pure layerNormEpsSpec
+ src/Torch/Typed/NN/Recurrent.hs view
@@ -0,0 +1,15 @@+module Torch.Typed.NN.Recurrent+  ( module Torch.Typed.NN.Recurrent,+    module Torch.Typed.NN.Recurrent.Auxiliary,+    module Torch.Typed.NN.Recurrent.GRU,+    module Torch.Typed.NN.Recurrent.LSTM,+    module Torch.Typed.NN.Recurrent.Cell.GRU,+    module Torch.Typed.NN.Recurrent.Cell.LSTM,+  )+where++import Torch.Typed.NN.Recurrent.Auxiliary+import Torch.Typed.NN.Recurrent.Cell.GRU+import Torch.Typed.NN.Recurrent.Cell.LSTM+import Torch.Typed.NN.Recurrent.GRU+import Torch.Typed.NN.Recurrent.LSTM
+ src/Torch/Typed/NN/Recurrent/Auxiliary.hs view
@@ -0,0 +1,43 @@+{-# LANGUAGE DeriveGeneric #-}++module Torch.Typed.NN.Recurrent.Auxiliary where++import GHC.Generics+import Torch.Functional (mulScalar, subScalar)+import Torch.Tensor++data RNNInitialization+  = ConstantInitialization+  | LearnedInitialization+  deriving (Show, Generic)++-- TODO: This is taken from the initializers example code and should be replaced with cannonical,+-- tested versions. However, even a potentially incorrect implementation will likely perform+-- better than an ad-hoc random-normal distribution.++-- | Fan-in / Fan-out scaling calculation+calculateFan :: [Int] -> (Int, Int)+calculateFan shape+  | dimT < 2 =+    error+      "Fan in and fan out can not be computed for tensor with fewer than 2 dimensions"+  | dimT == 2 =+    (numInputFmaps, numOutputFmaps)+  | otherwise =+    (numInputFmaps * receptiveFieldSize, numOutputFmaps * receptiveFieldSize)+  where+    dimT = length shape+    numInputFmaps = shape !! 1+    numOutputFmaps = shape !! 0+    receptiveFieldSize = product $ tail shape++-- | Xavier Initialization - Uniform+xavierUniformFIXME :: Tensor -> Float -> [Int] -> IO Tensor+xavierUniformFIXME init gain shape =+  pure $+    subScalar bound $+      mulScalar (bound * 2.0) init+  where+    (fanIn, fanOut) = calculateFan shape+    std = gain * sqrt (2.0 / (fromIntegral fanIn + fromIntegral fanOut))+    bound = sqrt 3.0 * std
+ src/Torch/Typed/NN/Recurrent/Cell/GRU.hs view
@@ -0,0 +1,142 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedLists #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE UndecidableSuperClasses #-}+{-# LANGUAGE NoStarIsType #-}+{-# OPTIONS_GHC -fconstraint-solver-iterations=0 #-}+{-# OPTIONS_GHC -fplugin GHC.TypeLits.Extra.Solver #-}+{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-}+{-# OPTIONS_GHC -fplugin GHC.TypeLits.Normalise #-}++module Torch.Typed.NN.Recurrent.Cell.GRU where++import Data.List+  ( foldl',+    scanl',+  )+import GHC.Generics+import GHC.TypeLits+import qualified Torch.DType as D+import qualified Torch.Device as D+import qualified Torch.NN as A+import Torch.Typed.Factories+import Torch.Typed.Functional hiding (linear)+import Torch.Typed.NN.Dropout+import Torch.Typed.Parameter+import Torch.Typed.Tensor++-- | A specification for a gated recurrent unit (GRU) cell.+data+  GRUCellSpec+    (inputDim :: Nat)+    (hiddenDim :: Nat)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  = -- | Weights and biases are drawn from the standard normal distibution (having mean 0 and variance 1)+    GRUCellSpec+  deriving (Show, Eq, Ord, Generic, Enum, Bounded)++-- | A gated recurrent unit (GRU) cell.+data+  GRUCell+    (inputDim :: Nat)+    (hiddenDim :: Nat)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat)) = GRUCell+  { -- | input-to-hidden weights+    gruCell_w_ih :: Parameter device dtype '[3 * hiddenDim, inputDim],+    -- | hidden-to-hidden weights+    gruCell_w_hh :: Parameter device dtype '[3 * hiddenDim, hiddenDim],+    -- | input-to-hidden bias+    gruCell_b_ih :: Parameter device dtype '[3 * hiddenDim],+    -- | hidden-to-hidden bias+    gruCell_b_hh :: Parameter device dtype '[3 * hiddenDim]+  }+  deriving (Show, Generic, Parameterized)++instance+  ( KnownDevice device,+    KnownDType dtype,+    KnownNat inputDim,+    KnownNat hiddenDim,+    RandDTypeIsValid device dtype+  ) =>+  A.Randomizable+    (GRUCellSpec inputDim hiddenDim dtype device)+    (GRUCell inputDim hiddenDim dtype device)+  where+  sample GRUCellSpec =+    GRUCell+      <$> (makeIndependent =<< randn)+      <*> (makeIndependent =<< randn)+      <*> (makeIndependent =<< randn)+      <*> (makeIndependent =<< randn)++-- | A single recurrent step of a `GRUCell`+gruCellForward ::+  forall inputDim hiddenDim batchSize dtype device.+  ( KnownDType dtype,+    KnownNat inputDim,+    KnownNat hiddenDim,+    KnownNat batchSize+  ) =>+  -- | The cell+  GRUCell inputDim hiddenDim dtype device ->+  -- | The current Hidden state+  Tensor device dtype '[batchSize, hiddenDim] ->+  -- | The input+  Tensor device dtype '[batchSize, inputDim] ->+  -- | The subsequent Hidden state+  Tensor device dtype '[batchSize, hiddenDim]+gruCellForward GRUCell {..} =+  gruCell+    (toDependent gruCell_w_ih)+    (toDependent gruCell_w_hh)+    (toDependent gruCell_b_ih)+    (toDependent gruCell_b_hh)++-- | foldl' for lists of tensors unsing a `GRUCell`+gruFold ::+  forall inputDim hiddenDim batchSize dtype device.+  ( KnownDType dtype,+    KnownNat inputDim,+    KnownNat hiddenDim,+    KnownNat batchSize+  ) =>+  GRUCell inputDim hiddenDim dtype device ->+  -- | The initial Hidden state+  Tensor device dtype '[batchSize, hiddenDim] ->+  -- | The list of inputs+  [Tensor device dtype '[batchSize, inputDim]] ->+  -- | The final Hidden state+  Tensor device dtype '[batchSize, hiddenDim]+gruFold cell = foldl' (gruCellForward cell)++-- | scanl' for lists of tensors unsing a `GRUCell`+gruCellScan ::+  forall inputDim hiddenDim batchSize dtype device.+  ( KnownDType dtype,+    KnownNat inputDim,+    KnownNat hiddenDim,+    KnownNat batchSize+  ) =>+  GRUCell inputDim hiddenDim dtype device ->+  -- | The initial Hidden state+  Tensor device dtype '[batchSize, hiddenDim] ->+  -- | The list of inputs+  [Tensor device dtype '[batchSize, inputDim]] ->+  -- | All subsequent Hidden states+  [Tensor device dtype '[batchSize, hiddenDim]]+gruCellScan cell = scanl' (gruCellForward cell)
+ src/Torch/Typed/NN/Recurrent/Cell/LSTM.hs view
@@ -0,0 +1,155 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedLists #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE UndecidableSuperClasses #-}+{-# LANGUAGE NoStarIsType #-}+{-# OPTIONS_GHC -fconstraint-solver-iterations=0 #-}+{-# OPTIONS_GHC -fplugin GHC.TypeLits.Extra.Solver #-}+{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-}+{-# OPTIONS_GHC -fplugin GHC.TypeLits.Normalise #-}++module Torch.Typed.NN.Recurrent.Cell.LSTM where++import Data.List+  ( foldl',+    scanl',+  )+import GHC.Generics+import GHC.TypeLits+import qualified Torch.DType as D+import qualified Torch.Device as D+import qualified Torch.NN as A+import Torch.Typed.Factories+import Torch.Typed.Functional hiding (linear)+import Torch.Typed.NN.Dropout+import Torch.Typed.Parameter+import Torch.Typed.Tensor++-- | A specification for a long, short-term memory (LSTM) cell.+data+  LSTMCellSpec+    (inputDim :: Nat)+    (hiddenDim :: Nat)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  = -- | Weights and biases are drawn from the standard normal distibution (having mean 0 and variance 1)+    LSTMCellSpec+  deriving (Show, Eq, Ord, Generic, Enum, Bounded)++-- | A long, short-term memory cell.+data+  LSTMCell+    (inputDim :: Nat)+    (hiddenDim :: Nat)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat)) = LSTMCell+  { -- | input-to-hidden weights+    lstmCell_w_ih :: Parameter device dtype '[4 * hiddenDim, inputDim],+    -- | hidden-to-hidden weights+    lstmCell_w_hh :: Parameter device dtype '[4 * hiddenDim, hiddenDim],+    -- | input-to-hidden bias+    lstmCell_b_ih :: Parameter device dtype '[4 * hiddenDim],+    -- | hidden-to-hidden bias+    lstmCell_b_hh :: Parameter device dtype '[4 * hiddenDim]+  }+  deriving (Show, Generic, Parameterized)++instance+  ( KnownDevice device,+    KnownDType dtype,+    KnownNat inputDim,+    KnownNat hiddenDim,+    RandDTypeIsValid device dtype+  ) =>+  A.Randomizable+    (LSTMCellSpec inputDim hiddenDim dtype device)+    (LSTMCell inputDim hiddenDim dtype device)+  where+  sample LSTMCellSpec =+    LSTMCell+      <$> (makeIndependent =<< randn)+      <*> (makeIndependent =<< randn)+      <*> (makeIndependent =<< randn)+      <*> (makeIndependent =<< randn)++-- | A single recurrent step of an `LSTMCell`+lstmCellForward ::+  forall inputDim hiddenDim batchSize dtype device.+  ( KnownDType dtype,+    KnownNat inputDim,+    KnownNat hiddenDim,+    KnownNat batchSize+  ) =>+  -- | The cell+  LSTMCell inputDim hiddenDim dtype device ->+  -- | The current (Hidden, Cell) state+  ( Tensor device dtype '[batchSize, hiddenDim],+    Tensor device dtype '[batchSize, hiddenDim]+  ) ->+  -- | The input+  Tensor device dtype '[batchSize, inputDim] ->+  -- | The subsequent (Hidden, Cell) state+  ( Tensor device dtype '[batchSize, hiddenDim],+    Tensor device dtype '[batchSize, hiddenDim]+  )+lstmCellForward LSTMCell {..} =+  lstmCell+    (toDependent lstmCell_w_ih)+    (toDependent lstmCell_w_hh)+    (toDependent lstmCell_b_ih)+    (toDependent lstmCell_b_hh)++-- | foldl' for lists of tensors unsing an `LSTMCell`+lstmCellFold ::+  forall inputDim hiddenDim batchSize dtype device.+  ( KnownDType dtype,+    KnownNat inputDim,+    KnownNat hiddenDim,+    KnownNat batchSize+  ) =>+  LSTMCell inputDim hiddenDim dtype device ->+  -- | The initial (Hidden, Cell) state+  ( Tensor device dtype '[batchSize, hiddenDim],+    Tensor device dtype '[batchSize, hiddenDim]+  ) ->+  -- | The list of inputs+  [Tensor device dtype '[batchSize, inputDim]] ->+  -- | The final (Hidden, Cell) state+  ( Tensor device dtype '[batchSize, hiddenDim],+    Tensor device dtype '[batchSize, hiddenDim]+  )+lstmCellFold cell = foldl' (lstmCellForward cell)++-- | scanl' for lists of tensors unsing an `LSTMCell`+lstmCellScan ::+  forall inputDim hiddenDim batchSize dtype device.+  ( KnownDType dtype,+    KnownNat inputDim,+    KnownNat hiddenDim,+    KnownNat batchSize+  ) =>+  LSTMCell inputDim hiddenDim dtype device ->+  -- | The initial (Hidden, Cell) state+  ( Tensor device dtype '[batchSize, hiddenDim],+    Tensor device dtype '[batchSize, hiddenDim]+  ) ->+  -- | The list of inputs+  [Tensor device dtype '[batchSize, inputDim]] ->+  -- | All subsequent (Hidden, Cell) states+  [ ( Tensor device dtype '[batchSize, hiddenDim],+      Tensor device dtype '[batchSize, hiddenDim]+    )+  ]+lstmCellScan cell = scanl' (lstmCellForward cell)
+ src/Torch/Typed/NN/Recurrent/GRU.hs view
@@ -0,0 +1,787 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedLists #-}+{-# LANGUAGE PartialTypeSignatures #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE QuantifiedConstraints #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE StrictData #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE UndecidableSuperClasses #-}+{-# LANGUAGE NoStarIsType #-}+{-# OPTIONS_GHC -fno-warn-partial-type-signatures #-}+{-# OPTIONS_GHC -fplugin GHC.TypeLits.Extra.Solver #-}+{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-}+{-# OPTIONS_GHC -fplugin GHC.TypeLits.Normalise #-}++module Torch.Typed.NN.Recurrent.GRU where++import Data.Kind+import Data.Proxy (Proxy (..))+import Foreign.ForeignPtr+import GHC.Generics+import GHC.TypeLits+import GHC.TypeLits.Extra+import System.Environment+import System.IO.Unsafe+import qualified Torch.Autograd as A+import qualified Torch.DType as D+import qualified Torch.Device as D+import qualified Torch.Functional as D+import Torch.HList+import qualified Torch.Internal.Cast as ATen+import qualified Torch.Internal.Class as ATen+import qualified Torch.Internal.Managed.Type.Tensor as ATen+import qualified Torch.Internal.Type as ATen+import qualified Torch.NN as A+import qualified Torch.Tensor as D+import qualified Torch.TensorFactories as D+import Torch.Typed.Factories+import Torch.Typed.Functional hiding (sqrt)+import Torch.Typed.NN.Dropout+import Torch.Typed.NN.Recurrent.Auxiliary+import Torch.Typed.Parameter+import Torch.Typed.Tensor+import Prelude hiding (tanh)++data+  GRULayerSpec+    (inputSize :: Nat)+    (hiddenSize :: Nat)+    (directionality :: RNNDirectionality)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  = GRULayerSpec+  deriving (Show, Eq)++data+  GRULayer+    (inputSize :: Nat)+    (hiddenSize :: Nat)+    (directionality :: RNNDirectionality)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  where+  GRUUnidirectionalLayer ::+    Parameter device dtype (GRUWIShape hiddenSize inputSize) ->+    Parameter device dtype (GRUWHShape hiddenSize inputSize) ->+    Parameter device dtype (GRUBIShape hiddenSize inputSize) ->+    Parameter device dtype (GRUBHShape hiddenSize inputSize) ->+    GRULayer inputSize hiddenSize 'Unidirectional dtype device+  GRUBidirectionalLayer ::+    Parameter device dtype (GRUWIShape hiddenSize inputSize) ->+    Parameter device dtype (GRUWHShape hiddenSize inputSize) ->+    Parameter device dtype (GRUBIShape hiddenSize inputSize) ->+    Parameter device dtype (GRUBHShape hiddenSize inputSize) ->+    Parameter device dtype (GRUWIShape hiddenSize inputSize) ->+    Parameter device dtype (GRUWHShape hiddenSize inputSize) ->+    Parameter device dtype (GRUBIShape hiddenSize inputSize) ->+    Parameter device dtype (GRUBHShape hiddenSize inputSize) ->+    GRULayer inputSize hiddenSize 'Bidirectional dtype device++deriving instance Show (GRULayer inputSize hiddenSize directionality dtype device)++instance Parameterized (GRULayer inputSize hiddenSize 'Unidirectional dtype device) where+  type+    Parameters (GRULayer inputSize hiddenSize 'Unidirectional dtype device) =+      '[ Parameter device dtype (GRUWIShape hiddenSize inputSize),+         Parameter device dtype (GRUWHShape hiddenSize inputSize),+         Parameter device dtype (GRUBIShape hiddenSize inputSize),+         Parameter device dtype (GRUBHShape hiddenSize inputSize)+       ]+  flattenParameters (GRUUnidirectionalLayer wi wh bi bh) =+    wi :. wh :. bi :. bh :. HNil+  replaceParameters _ (wi :. wh :. bi :. bh :. HNil) =+    GRUUnidirectionalLayer wi wh bi bh++instance Parameterized (GRULayer inputSize hiddenSize 'Bidirectional dtype device) where+  type+    Parameters (GRULayer inputSize hiddenSize 'Bidirectional dtype device) =+      '[ Parameter device dtype (GRUWIShape hiddenSize inputSize),+         Parameter device dtype (GRUWHShape hiddenSize inputSize),+         Parameter device dtype (GRUBIShape hiddenSize inputSize),+         Parameter device dtype (GRUBHShape hiddenSize inputSize),+         Parameter device dtype (GRUWIShape hiddenSize inputSize),+         Parameter device dtype (GRUWHShape hiddenSize inputSize),+         Parameter device dtype (GRUBIShape hiddenSize inputSize),+         Parameter device dtype (GRUBHShape hiddenSize inputSize)+       ]+  flattenParameters (GRUBidirectionalLayer wi wh bi bh wi' wh' bi' bh') =+    wi :. wh :. bi :. bh :. wi' :. wh' :. bi' :. bh' :. HNil+  replaceParameters _ (wi :. wh :. bi :. bh :. wi' :. wh' :. bi' :. bh' :. HNil) =+    GRUBidirectionalLayer wi wh bi bh wi' wh' bi' bh'++instance+  ( RandDTypeIsValid device dtype,+    KnownNat inputSize,+    KnownNat hiddenSize,+    KnownDType dtype,+    KnownDevice device+  ) =>+  A.Randomizable+    (GRULayerSpec inputSize hiddenSize 'Unidirectional dtype device)+    (GRULayer inputSize hiddenSize 'Unidirectional dtype device)+  where+  sample _ =+    GRUUnidirectionalLayer+      <$> (makeIndependent =<< xavierUniformGRU)+      <*> (makeIndependent =<< xavierUniformGRU)+      <*> (makeIndependent =<< pure zeros)+      <*> (makeIndependent =<< pure zeros)++instance+  ( RandDTypeIsValid device dtype,+    KnownNat inputSize,+    KnownNat hiddenSize,+    KnownDType dtype,+    KnownDevice device+  ) =>+  A.Randomizable+    (GRULayerSpec inputSize hiddenSize 'Bidirectional dtype device)+    (GRULayer inputSize hiddenSize 'Bidirectional dtype device)+  where+  sample _ =+    GRUBidirectionalLayer+      <$> (makeIndependent =<< xavierUniformGRU)+      <*> (makeIndependent =<< xavierUniformGRU)+      <*> (makeIndependent =<< pure zeros)+      <*> (makeIndependent =<< pure zeros)+      <*> (makeIndependent =<< xavierUniformGRU)+      <*> (makeIndependent =<< xavierUniformGRU)+      <*> (makeIndependent =<< pure zeros)+      <*> (makeIndependent =<< pure zeros)++data+  GRULayerStackSpec+    (inputSize :: Nat)+    (hiddenSize :: Nat)+    (numLayers :: Nat)+    (directionality :: RNNDirectionality)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  = GRULayerStackSpec+  deriving (Show, Eq)++-- Input-to-hidden, hidden-to-hidden, and bias parameters for a mulilayered+-- (and optionally) bidirectional GRU.+--+data+  GRULayerStack+    (inputSize :: Nat)+    (hiddenSize :: Nat)+    (numLayers :: Nat)+    (directionality :: RNNDirectionality)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  where+  GRULayer1 ::+    GRULayer inputSize hiddenSize directionality dtype device ->+    GRULayerStack inputSize hiddenSize 1 directionality dtype device+  GRULayerK ::+    GRULayer (hiddenSize * NumberOfDirections directionality) hiddenSize directionality dtype device ->+    GRULayerStack inputSize hiddenSize numLayers directionality dtype device ->+    GRULayerStack inputSize hiddenSize (numLayers + 1) directionality dtype device++deriving instance Show (GRULayerStack inputSize hiddenSize numLayers directionality dtype device)++class GRULayerStackParameterized (flag :: Bool) inputSize hiddenSize numLayers directionality dtype device where+  type GRULayerStackParameters flag inputSize hiddenSize numLayers directionality dtype device :: [Type]+  gruLayerStackFlattenParameters ::+    Proxy flag ->+    GRULayerStack inputSize hiddenSize numLayers directionality dtype device ->+    HList (GRULayerStackParameters flag inputSize hiddenSize numLayers directionality dtype device)+  gruLayerStackReplaceParameters ::+    Proxy flag ->+    GRULayerStack inputSize hiddenSize numLayers directionality dtype device ->+    HList (GRULayerStackParameters flag inputSize hiddenSize numLayers directionality dtype device) ->+    GRULayerStack inputSize hiddenSize numLayers directionality dtype device++instance+  Parameterized (GRULayer inputSize hiddenSize directionality dtype device) =>+  GRULayerStackParameterized 'False inputSize hiddenSize 1 directionality dtype device+  where+  type+    GRULayerStackParameters 'False inputSize hiddenSize 1 directionality dtype device =+      Parameters (GRULayer inputSize hiddenSize directionality dtype device)+  gruLayerStackFlattenParameters _ (GRULayer1 gruLayer) = flattenParameters gruLayer+  gruLayerStackReplaceParameters _ (GRULayer1 gruLayer) parameters = GRULayer1 $ replaceParameters gruLayer parameters++instance+  ( Parameterized+      ( GRULayer+          (hiddenSize * NumberOfDirections directionality)+          hiddenSize+          directionality+          dtype+          device+      ),+    Parameterized (GRULayerStack inputSize hiddenSize (numLayers - 1) directionality dtype device),+    HAppendFD+      (Parameters (GRULayerStack inputSize hiddenSize (numLayers - 1) directionality dtype device))+      (Parameters (GRULayer (hiddenSize * NumberOfDirections directionality) hiddenSize directionality dtype device))+      (Parameters (GRULayerStack inputSize hiddenSize (numLayers - 1) directionality dtype device) ++ Parameters (GRULayer (hiddenSize * NumberOfDirections directionality) hiddenSize directionality dtype device)),+    1 <= numLayers,+    numLayersM1 ~ numLayers - 1,+    0 <= numLayersM1+  ) =>+  GRULayerStackParameterized 'True inputSize hiddenSize numLayers directionality dtype device+  where+  type+    GRULayerStackParameters 'True inputSize hiddenSize numLayers directionality dtype device =+      Parameters (GRULayerStack inputSize hiddenSize (numLayers - 1) directionality dtype device)+        ++ Parameters (GRULayer (hiddenSize * NumberOfDirections directionality) hiddenSize directionality dtype device)+  gruLayerStackFlattenParameters _ (GRULayerK gruLayer gruLayerStack) =+    let parameters = flattenParameters gruLayer+        parameters' = flattenParameters @(GRULayerStack inputSize hiddenSize numLayersM1 directionality dtype device) gruLayerStack+     in parameters' `happendFD` parameters+  gruLayerStackReplaceParameters _ (GRULayerK gruLayer gruLayerStack) parameters'' =+    let (parameters', parameters) = hunappendFD parameters''+        gruLayer' = replaceParameters gruLayer parameters+        gruLayerStack' = replaceParameters @(GRULayerStack inputSize hiddenSize numLayersM1 directionality dtype device) gruLayerStack parameters'+     in GRULayerK gruLayer' gruLayerStack'++instance+  ( 1 <= numLayers,+    (2 <=? numLayers) ~ flag,+    GRULayerStackParameterized flag inputSize hiddenSize numLayers directionality dtype device+  ) =>+  Parameterized (GRULayerStack inputSize hiddenSize numLayers directionality dtype device)+  where+  type+    Parameters (GRULayerStack inputSize hiddenSize numLayers directionality dtype device) =+      GRULayerStackParameters (2 <=? numLayers) inputSize hiddenSize numLayers directionality dtype device+  flattenParameters = gruLayerStackFlattenParameters (Proxy :: Proxy flag)+  replaceParameters = gruLayerStackReplaceParameters (Proxy :: Proxy flag)++class GRULayerStackRandomizable (flag :: Bool) inputSize hiddenSize numLayers directionality dtype device where+  gruLayerStackSample ::+    Proxy flag ->+    GRULayerStackSpec inputSize hiddenSize numLayers directionality dtype device ->+    IO (GRULayerStack inputSize hiddenSize numLayers directionality dtype device)++instance+  ( A.Randomizable+      (GRULayerSpec inputSize hiddenSize directionality dtype device)+      (GRULayer inputSize hiddenSize directionality dtype device)+  ) =>+  GRULayerStackRandomizable 'False inputSize hiddenSize 1 directionality dtype device+  where+  gruLayerStackSample _ _ = GRULayer1 <$> (sample $ GRULayerSpec @inputSize @hiddenSize @directionality @dtype @device)++instance+  ( 1 <= numLayers,+    A.Randomizable+      (GRULayerSpec (hiddenSize * NumberOfDirections directionality) hiddenSize directionality dtype device)+      (GRULayer (hiddenSize * NumberOfDirections directionality) hiddenSize directionality dtype device),+    A.Randomizable+      (GRULayerStackSpec inputSize hiddenSize (numLayers - 1) directionality dtype device)+      (GRULayerStack inputSize hiddenSize (numLayers - 1) directionality dtype device)+  ) =>+  GRULayerStackRandomizable 'True inputSize hiddenSize numLayers directionality dtype device+  where+  gruLayerStackSample _ _ =+    GRULayerK+      <$> (sample $ GRULayerSpec @(hiddenSize * NumberOfDirections directionality) @hiddenSize @directionality @dtype @device)+      <*> ( sample+              @(GRULayerStackSpec inputSize hiddenSize (numLayers - 1) directionality dtype device)+              @(GRULayerStack inputSize hiddenSize (numLayers - 1) directionality dtype device)+              $ GRULayerStackSpec+          )++instance+  ( 1 <= numLayers,+    (2 <=? numLayers) ~ flag,+    RandDTypeIsValid device dtype,+    KnownDType dtype,+    KnownDevice device,+    GRULayerStackRandomizable flag inputSize hiddenSize numLayers directionality dtype device+  ) =>+  Randomizable+    (GRULayerStackSpec inputSize hiddenSize numLayers directionality dtype device)+    (GRULayerStack inputSize hiddenSize numLayers directionality dtype device)+  where+  sample = gruLayerStackSample (Proxy :: Proxy flag)++newtype+  GRUSpec+    (inputSize :: Nat)+    (hiddenSize :: Nat)+    (numLayers :: Nat)+    (directionality :: RNNDirectionality)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  = GRUSpec DropoutSpec+  deriving (Show, Generic)++data+  GRU+    (inputSize :: Nat)+    (hiddenSize :: Nat)+    (numLayers :: Nat)+    (directionality :: RNNDirectionality)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  where+  GRU ::+    (1 <= numLayers) =>+    { gru_layer_stack :: GRULayerStack inputSize hiddenSize numLayers directionality dtype device,+      gru_dropout :: Dropout+    } ->+    GRU inputSize hiddenSize numLayers directionality dtype device++deriving instance Show (GRU inputSize hiddenSize numLayers directionality dtype device)++instance+  (1 <= numLayers) =>+  Generic (GRU inputSize hiddenSize numLayers directionality dtype device)+  where+  type+    Rep (GRU inputSize hiddenSize numLayers directionality dtype device) =+      Rec0 (GRULayerStack inputSize hiddenSize numLayers directionality dtype device)+        :*: Rec0 Dropout+  from (GRU {..}) = K1 gru_layer_stack :*: K1 gru_dropout+  to (K1 layerStack :*: K1 dropout) = GRU layerStack dropout++instance+  ( 1 <= numLayers,+    Parameterized (GRULayerStack inputSize hiddenSize numLayers directionality dtype device),+    HAppendFD+      (Parameters (GRULayerStack inputSize hiddenSize numLayers directionality dtype device))+      (Parameters Dropout)+      ( Parameters (GRULayerStack inputSize hiddenSize numLayers directionality dtype device)+          ++ Parameters Dropout+      )+  ) =>+  Parameterized (GRU inputSize hiddenSize numLayers directionality dtype device)++-- TODO: when we have cannonical initializers do this correctly:+-- https://github.com/pytorch/pytorch/issues/9221+-- https://discuss.pytorch.org/t/initializing-rnn-gru-and-gru-correctly/23605++-- | Helper to do xavier uniform initializations on weight matrices and+-- orthagonal initializations for the gates. (When implemented.)+xavierUniformGRU ::+  forall device dtype hiddenSize featureSize.+  ( KnownDType dtype,+    KnownNat hiddenSize,+    KnownNat featureSize,+    KnownDevice device,+    RandDTypeIsValid device dtype+  ) =>+  IO (Tensor device dtype '[3 * hiddenSize, featureSize])+xavierUniformGRU = do+  init <- randn :: IO (Tensor device dtype '[3 * hiddenSize, featureSize])+  UnsafeMkTensor+    <$> xavierUniformFIXME+      (toDynamic init)+      (5.0 / 3)+      (shape @device @dtype @'[3 * hiddenSize, featureSize] init)++instance+  ( KnownDType dtype,+    KnownDevice device,+    KnownNat inputSize,+    KnownNat hiddenSize,+    KnownNat (NumberOfDirections directionality),+    RandDTypeIsValid device dtype,+    A.Randomizable+      (GRULayerStackSpec inputSize hiddenSize numLayers directionality dtype device)+      (GRULayerStack inputSize hiddenSize numLayers directionality dtype device),+    1 <= numLayers+  ) =>+  A.Randomizable+    (GRUSpec inputSize hiddenSize numLayers directionality dtype device)+    (GRU inputSize hiddenSize numLayers directionality dtype device)+  where+  sample (GRUSpec dropoutSpec) =+    GRU+      <$> A.sample (GRULayerStackSpec @inputSize @hiddenSize @numLayers @directionality @dtype @device)+      <*> A.sample dropoutSpec++-- | A specification for a long, short-term memory layer.+data+  GRUWithInitSpec+    (inputSize :: Nat)+    (hiddenSize :: Nat)+    (numLayers :: Nat)+    (directionality :: RNNDirectionality)+    (initialization :: RNNInitialization)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  where+  -- | Weights drawn from Xavier-Uniform+  --   with zeros-value initialized biases and cell states.+  GRUWithZerosInitSpec ::+    forall inputSize hiddenSize numLayers directionality dtype device.+    GRUSpec inputSize hiddenSize numLayers directionality dtype device ->+    GRUWithInitSpec inputSize hiddenSize numLayers directionality 'ConstantInitialization dtype device+  -- | Weights drawn from Xavier-Uniform+  --   with zeros-value initialized biases+  --   and user-provided cell states.+  GRUWithConstInitSpec ::+    forall inputSize hiddenSize numLayers directionality dtype device.+    GRUSpec inputSize hiddenSize numLayers directionality dtype device ->+    -- | The initial values of the hidden state+    Tensor device dtype '[numLayers * NumberOfDirections directionality, hiddenSize] ->+    GRUWithInitSpec inputSize hiddenSize numLayers directionality 'ConstantInitialization dtype device+  -- | Weights drawn from Xavier-Uniform+  --   with zeros-value initialized biases+  --   and learned cell states.+  GRUWithLearnedInitSpec ::+    forall inputSize hiddenSize numLayers directionality dtype device.+    GRUSpec inputSize hiddenSize numLayers directionality dtype device ->+    -- | The initial (learnable)+    -- values of the hidden state+    Tensor device dtype '[numLayers * NumberOfDirections directionality, hiddenSize] ->+    GRUWithInitSpec inputSize hiddenSize numLayers directionality 'LearnedInitialization dtype device++deriving instance Show (GRUWithInitSpec inputSize hiddenSize numLayers directionality initialization dtype device)++-- | A long, short-term memory layer with either fixed initial+-- states for the memory cells and hidden state or learnable+-- inital states for the memory cells and hidden state.+data+  GRUWithInit+    (inputSize :: Nat)+    (hiddenSize :: Nat)+    (numLayers :: Nat)+    (directionality :: RNNDirectionality)+    (initialization :: RNNInitialization)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  where+  GRUWithConstInit ::+    forall inputSize hiddenSize numLayers directionality dtype device.+    { gruWithConstInit_gru :: GRU inputSize hiddenSize numLayers directionality dtype device,+      gruWithConstInit_h :: Tensor device dtype '[numLayers * NumberOfDirections directionality, hiddenSize]+    } ->+    GRUWithInit+      inputSize+      hiddenSize+      numLayers+      directionality+      'ConstantInitialization+      dtype+      device+  GRUWithLearnedInit ::+    forall inputSize hiddenSize numLayers directionality dtype device.+    { gruWithLearnedInit_gru :: GRU inputSize hiddenSize numLayers directionality dtype device,+      gruWithLearnedInit_h :: Parameter device dtype '[numLayers * NumberOfDirections directionality, hiddenSize]+    } ->+    GRUWithInit+      inputSize+      hiddenSize+      numLayers+      directionality+      'LearnedInitialization+      dtype+      device++deriving instance Show (GRUWithInit inputSize hiddenSize numLayers directionality initialization dtype device)++instance Generic (GRUWithInit inputSize hiddenSize numLayers directionality 'ConstantInitialization dtype device) where+  type+    Rep (GRUWithInit inputSize hiddenSize numLayers directionality 'ConstantInitialization dtype device) =+      Rec0 (GRU inputSize hiddenSize numLayers directionality dtype device)+        :*: Rec0 (Tensor device dtype '[numLayers * NumberOfDirections directionality, hiddenSize])+  from (GRUWithConstInit {..}) = K1 gruWithConstInit_gru :*: K1 gruWithConstInit_h+  to (K1 gru :*: K1 h) = GRUWithConstInit gru h++instance Generic (GRUWithInit inputSize hiddenSize numLayers directionality 'LearnedInitialization dtype device) where+  type+    Rep (GRUWithInit inputSize hiddenSize numLayers directionality 'LearnedInitialization dtype device) =+      Rec0 (GRU inputSize hiddenSize numLayers directionality dtype device)+        :*: Rec0 (Parameter device dtype '[numLayers * NumberOfDirections directionality, hiddenSize])+  from (GRUWithLearnedInit {..}) = K1 gruWithLearnedInit_gru :*: K1 gruWithLearnedInit_h+  to (K1 gru :*: K1 h) = GRUWithLearnedInit gru h++instance+  ( Parameterized (GRU inputSize hiddenSize numLayers directionality dtype device),+    HAppendFD+      (Parameters (GRU inputSize hiddenSize numLayers directionality dtype device))+      '[]+      ( Parameters (GRU inputSize hiddenSize numLayers directionality dtype device) ++ '[]+      )+  ) =>+  Parameterized (GRUWithInit inputSize hiddenSize numLayers directionality 'ConstantInitialization dtype device)++instance+  ( Parameterized (GRU inputSize hiddenSize numLayers directionality dtype device),+    HAppendFD+      (Parameters (GRU inputSize hiddenSize numLayers directionality dtype device))+      '[Parameter device dtype '[numLayers * NumberOfDirections directionality, hiddenSize]]+      ( Parameters (GRU inputSize hiddenSize numLayers directionality dtype device)+          ++ '[Parameter device dtype '[numLayers * NumberOfDirections directionality, hiddenSize]]+      )+  ) =>+  Parameterized (GRUWithInit inputSize hiddenSize numLayers directionality 'LearnedInitialization dtype device)++instance+  ( KnownNat hiddenSize,+    KnownNat numLayers,+    KnownNat (NumberOfDirections directionality),+    KnownDType dtype,+    KnownDevice device,+    A.Randomizable+      (GRUSpec inputSize hiddenSize numLayers directionality dtype device)+      (GRU inputSize hiddenSize numLayers directionality dtype device)+  ) =>+  A.Randomizable+    (GRUWithInitSpec inputSize hiddenSize numLayers directionality 'ConstantInitialization dtype device)+    (GRUWithInit inputSize hiddenSize numLayers directionality 'ConstantInitialization dtype device)+  where+  sample (GRUWithZerosInitSpec gruSpec) =+    GRUWithConstInit+      <$> A.sample gruSpec+      <*> pure zeros+  sample (GRUWithConstInitSpec gruSpec h) =+    GRUWithConstInit+      <$> A.sample gruSpec+      <*> pure h++instance+  ( KnownNat hiddenSize,+    KnownNat numLayers,+    KnownNat (NumberOfDirections directionality),+    KnownDType dtype,+    KnownDevice device,+    A.Randomizable+      (GRUSpec inputSize hiddenSize numLayers directionality dtype device)+      (GRU inputSize hiddenSize numLayers directionality dtype device)+  ) =>+  A.Randomizable+    (GRUWithInitSpec inputSize hiddenSize numLayers directionality 'LearnedInitialization dtype device)+    (GRUWithInit inputSize hiddenSize numLayers directionality 'LearnedInitialization dtype device)+  where+  sample s@(GRUWithLearnedInitSpec gruSpec h) =+    GRUWithLearnedInit+      <$> A.sample gruSpec+      <*> (makeIndependent =<< pure h)++gruForward ::+  forall+    shapeOrder+    batchSize+    seqLen+    directionality+    initialization+    numLayers+    inputSize+    outputSize+    hiddenSize+    inputShape+    outputShape+    hcShape+    parameters+    tensorParameters+    dtype+    device.+  ( KnownNat (NumberOfDirections directionality),+    KnownNat numLayers,+    KnownNat batchSize,+    KnownNat hiddenSize,+    KnownRNNShapeOrder shapeOrder,+    KnownRNNDirectionality directionality,+    outputSize ~ (hiddenSize * NumberOfDirections directionality),+    inputShape ~ RNNShape shapeOrder seqLen batchSize inputSize,+    outputShape ~ RNNShape shapeOrder seqLen batchSize outputSize,+    hcShape ~ '[numLayers * NumberOfDirections directionality, batchSize, hiddenSize],+    parameters ~ Parameters (GRU inputSize hiddenSize numLayers directionality dtype device),+    Parameterized (GRU inputSize hiddenSize numLayers directionality dtype device),+    tensorParameters ~ GRUR inputSize hiddenSize numLayers directionality dtype device,+    ATen.Castable (HList tensorParameters) [D.ATenTensor],+    HMap' ToDependent parameters tensorParameters+  ) =>+  Bool ->+  GRUWithInit+    inputSize+    hiddenSize+    numLayers+    directionality+    initialization+    dtype+    device ->+  Tensor device dtype inputShape ->+  ( Tensor device dtype outputShape,+    Tensor device dtype hcShape+  )+gruForward dropoutOn (GRUWithConstInit gruModel@(GRU _ (Dropout dropoutProb)) hc) input =+  gru+    @shapeOrder+    @directionality+    @numLayers+    @seqLen+    @batchSize+    @inputSize+    @outputSize+    @hiddenSize+    @inputShape+    @outputShape+    @hcShape+    @tensorParameters+    @dtype+    @device+    (hmap' ToDependent . flattenParameters $ gruModel)+    dropoutProb+    dropoutOn+    hc'+    input+  where+    hc' =+      reshape @hcShape+        . expand+          @'[batchSize, numLayers * NumberOfDirections directionality, hiddenSize]+          False -- TODO: What does the bool do?+        $ hc+gruForward dropoutOn (GRUWithLearnedInit gruModel@(GRU _ (Dropout dropoutProb)) hc) input =+  gru+    @shapeOrder+    @directionality+    @numLayers+    @seqLen+    @batchSize+    @inputSize+    @outputSize+    @hiddenSize+    @inputShape+    @outputShape+    @hcShape+    @tensorParameters+    @dtype+    @device+    (hmap' ToDependent . flattenParameters $ gruModel)+    dropoutProb+    dropoutOn+    hc'+    input+  where+    hc' =+      reshape @hcShape+        . expand+          @'[batchSize, numLayers * NumberOfDirections directionality, hiddenSize]+          False -- TODO: What does the bool do?+        . toDependent+        $ hc++gruForwardWithDropout,+  gruForwardWithoutDropout ::+    forall+      shapeOrder+      batchSize+      seqLen+      directionality+      initialization+      numLayers+      inputSize+      outputSize+      hiddenSize+      inputShape+      outputShape+      hcShape+      parameters+      tensorParameters+      dtype+      device.+    ( KnownNat (NumberOfDirections directionality),+      KnownNat numLayers,+      KnownNat batchSize,+      KnownNat hiddenSize,+      KnownRNNShapeOrder shapeOrder,+      KnownRNNDirectionality directionality,+      outputSize ~ (hiddenSize * NumberOfDirections directionality),+      inputShape ~ RNNShape shapeOrder seqLen batchSize inputSize,+      outputShape ~ RNNShape shapeOrder seqLen batchSize outputSize,+      hcShape ~ '[numLayers * NumberOfDirections directionality, batchSize, hiddenSize],+      parameters ~ Parameters (GRU inputSize hiddenSize numLayers directionality dtype device),+      Parameterized (GRU inputSize hiddenSize numLayers directionality dtype device),+      tensorParameters ~ GRUR inputSize hiddenSize numLayers directionality dtype device,+      ATen.Castable (HList tensorParameters) [D.ATenTensor],+      HMap' ToDependent parameters tensorParameters+    ) =>+    GRUWithInit+      inputSize+      hiddenSize+      numLayers+      directionality+      initialization+      dtype+      device ->+    Tensor device dtype inputShape ->+    ( Tensor device dtype outputShape,+      Tensor device dtype hcShape+    )+-- ^ Forward propagate the `GRU` module and apply dropout on the outputs of each layer.+--+-- >>> input :: CPUTensor 'D.Float '[5,16,10] <- randn+-- >>> spec = GRUWithZerosInitSpec @10 @30 @3 @'Bidirectional @'D.Float @'( 'D.CPU, 0) (GRUSpec (DropoutSpec 0.5))+-- >>> model <- A.sample spec+-- >>> :t gruForwardWithDropout @'BatchFirst model input+-- gruForwardWithDropout @'BatchFirst model input+--   :: (Tensor '(D.CPU, 0) 'D.Float [5, 16, 60],+--       Tensor '(D.CPU, 0) 'D.Float [6, 5, 30])+-- >>> (a,b) = gruForwardWithDropout @'BatchFirst model input+-- >>> ((dtype a, shape a), (dtype b, shape b))+-- ((Float,[5,16,60]),(Float,[6,5,30]))+gruForwardWithDropout =+  gruForward+    @shapeOrder+    @batchSize+    @seqLen+    @directionality+    @initialization+    @numLayers+    @inputSize+    @outputSize+    @hiddenSize+    @inputShape+    @outputShape+    @hcShape+    @parameters+    @tensorParameters+    @dtype+    @device+    True+-- ^ Forward propagate the `GRU` module (without applying dropout on the outputs of each layer).+--+-- >>> input :: CPUTensor 'D.Float '[5,16,10] <- randn+-- >>> spec = GRUWithZerosInitSpec @10 @30 @3 @'Bidirectional @'D.Float @'( 'D.CPU, 0) (GRUSpec (DropoutSpec 0.5))+-- >>> model <- A.sample spec+-- >>> :t gruForwardWithoutDropout @'BatchFirst model input+-- gruForwardWithoutDropout @'BatchFirst model input+--   :: (Tensor '(D.CPU, 0) 'D.Float [5, 16, 60],+--       Tensor '(D.CPU, 0) 'D.Float [6, 5, 30])+-- >>> (a,b) = gruForwardWithoutDropout @'BatchFirst model input+-- >>> ((dtype a, shape a), (dtype b, shape b))+-- ((Float,[5,16,60]),(Float,[6,5,30]))+gruForwardWithoutDropout =+  gruForward+    @shapeOrder+    @batchSize+    @seqLen+    @directionality+    @initialization+    @numLayers+    @inputSize+    @outputSize+    @hiddenSize+    @inputShape+    @outputShape+    @hcShape+    @parameters+    @tensorParameters+    @dtype+    @device+    False
+ src/Torch/Typed/NN/Recurrent/LSTM.hs view
@@ -0,0 +1,930 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedLists #-}+{-# LANGUAGE PartialTypeSignatures #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE QuantifiedConstraints #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE StrictData #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE UndecidableSuperClasses #-}+{-# LANGUAGE NoStarIsType #-}+{-# OPTIONS_GHC -fno-warn-partial-type-signatures #-}+{-# OPTIONS_GHC -fplugin GHC.TypeLits.Extra.Solver #-}+{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-}+{-# OPTIONS_GHC -fplugin GHC.TypeLits.Normalise #-}++module Torch.Typed.NN.Recurrent.LSTM where++import Data.Kind+import Data.Proxy (Proxy (..))+import Foreign.ForeignPtr+import GHC.Generics+import GHC.TypeLits+import GHC.TypeLits.Extra+import System.Environment+import System.IO.Unsafe+import qualified Torch.Autograd as A+import qualified Torch.DType as D+import qualified Torch.Device as D+import qualified Torch.Functional as D+import Torch.HList+import qualified Torch.Internal.Cast as ATen+import qualified Torch.Internal.Class as ATen+import qualified Torch.Internal.Managed.Type.Tensor as ATen+import qualified Torch.Internal.Type as ATen+import qualified Torch.NN as A+import qualified Torch.Tensor as D+import qualified Torch.TensorFactories as D+import Torch.Typed.Factories+import Torch.Typed.Functional hiding (sqrt)+import Torch.Typed.NN.Dropout+import Torch.Typed.NN.Recurrent.Auxiliary+import Torch.Typed.Parameter+import Torch.Typed.Tensor+import Prelude hiding (tanh)++data+  LSTMLayerSpec+    (inputSize :: Nat)+    (hiddenSize :: Nat)+    (directionality :: RNNDirectionality)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  = LSTMLayerSpec+  deriving (Show, Eq)++data+  LSTMLayer+    (inputSize :: Nat)+    (hiddenSize :: Nat)+    (directionality :: RNNDirectionality)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  where+  LSTMUnidirectionalLayer ::+    Parameter device dtype (LSTMWIShape hiddenSize inputSize) ->+    Parameter device dtype (LSTMWHShape hiddenSize inputSize) ->+    Parameter device dtype (LSTMBIShape hiddenSize inputSize) ->+    Parameter device dtype (LSTMBHShape hiddenSize inputSize) ->+    LSTMLayer inputSize hiddenSize 'Unidirectional dtype device+  LSTMBidirectionalLayer ::+    Parameter device dtype (LSTMWIShape hiddenSize inputSize) ->+    Parameter device dtype (LSTMWHShape hiddenSize inputSize) ->+    Parameter device dtype (LSTMBIShape hiddenSize inputSize) ->+    Parameter device dtype (LSTMBHShape hiddenSize inputSize) ->+    Parameter device dtype (LSTMWIShape hiddenSize inputSize) ->+    Parameter device dtype (LSTMWHShape hiddenSize inputSize) ->+    Parameter device dtype (LSTMBIShape hiddenSize inputSize) ->+    Parameter device dtype (LSTMBHShape hiddenSize inputSize) ->+    LSTMLayer inputSize hiddenSize 'Bidirectional dtype device++deriving instance Show (LSTMLayer inputSize hiddenSize directionality dtype device)++instance Parameterized (LSTMLayer inputSize hiddenSize 'Unidirectional dtype device) where+  type+    Parameters (LSTMLayer inputSize hiddenSize 'Unidirectional dtype device) =+      '[ Parameter device dtype (LSTMWIShape hiddenSize inputSize),+         Parameter device dtype (LSTMWHShape hiddenSize inputSize),+         Parameter device dtype (LSTMBIShape hiddenSize inputSize),+         Parameter device dtype (LSTMBHShape hiddenSize inputSize)+       ]+  flattenParameters (LSTMUnidirectionalLayer wi wh bi bh) =+    wi :. wh :. bi :. bh :. HNil+  replaceParameters _ (wi :. wh :. bi :. bh :. HNil) =+    LSTMUnidirectionalLayer wi wh bi bh++instance Parameterized (LSTMLayer inputSize hiddenSize 'Bidirectional dtype device) where+  type+    Parameters (LSTMLayer inputSize hiddenSize 'Bidirectional dtype device) =+      '[ Parameter device dtype (LSTMWIShape hiddenSize inputSize),+         Parameter device dtype (LSTMWHShape hiddenSize inputSize),+         Parameter device dtype (LSTMBIShape hiddenSize inputSize),+         Parameter device dtype (LSTMBHShape hiddenSize inputSize),+         Parameter device dtype (LSTMWIShape hiddenSize inputSize),+         Parameter device dtype (LSTMWHShape hiddenSize inputSize),+         Parameter device dtype (LSTMBIShape hiddenSize inputSize),+         Parameter device dtype (LSTMBHShape hiddenSize inputSize)+       ]+  flattenParameters (LSTMBidirectionalLayer wi wh bi bh wi' wh' bi' bh') =+    wi :. wh :. bi :. bh :. wi' :. wh' :. bi' :. bh' :. HNil+  replaceParameters _ (wi :. wh :. bi :. bh :. wi' :. wh' :. bi' :. bh' :. HNil) =+    LSTMBidirectionalLayer wi wh bi bh wi' wh' bi' bh'++instance+  ( RandDTypeIsValid device dtype,+    KnownNat inputSize,+    KnownNat hiddenSize,+    KnownDType dtype,+    KnownDevice device+  ) =>+  A.Randomizable+    (LSTMLayerSpec inputSize hiddenSize 'Unidirectional dtype device)+    (LSTMLayer inputSize hiddenSize 'Unidirectional dtype device)+  where+  sample _ =+    LSTMUnidirectionalLayer+      <$> (makeIndependent =<< xavierUniformLSTM)+      <*> (makeIndependent =<< xavierUniformLSTM)+      <*> (makeIndependent =<< pure zeros)+      <*> (makeIndependent =<< pure zeros)++instance+  ( RandDTypeIsValid device dtype,+    KnownNat inputSize,+    KnownNat hiddenSize,+    KnownDType dtype,+    KnownDevice device+  ) =>+  A.Randomizable+    (LSTMLayerSpec inputSize hiddenSize 'Bidirectional dtype device)+    (LSTMLayer inputSize hiddenSize 'Bidirectional dtype device)+  where+  sample _ =+    LSTMBidirectionalLayer+      <$> (makeIndependent =<< xavierUniformLSTM)+      <*> (makeIndependent =<< xavierUniformLSTM)+      <*> (makeIndependent =<< pure zeros)+      <*> (makeIndependent =<< pure zeros)+      <*> (makeIndependent =<< xavierUniformLSTM)+      <*> (makeIndependent =<< xavierUniformLSTM)+      <*> (makeIndependent =<< pure zeros)+      <*> (makeIndependent =<< pure zeros)++instance A.Parameterized (LSTMLayer inputSize hiddenSize directionality dtype device) where+  flattenParameters (LSTMUnidirectionalLayer wi wh bi bh) =+    [ untypeParam wi,+      untypeParam wh,+      untypeParam bi,+      untypeParam bh+    ]+  flattenParameters (LSTMBidirectionalLayer wi wh bi bh wi' wh' bi' bh') =+    [ untypeParam wi,+      untypeParam wh,+      untypeParam bi,+      untypeParam bh,+      untypeParam wi',+      untypeParam wh',+      untypeParam bi',+      untypeParam bh'+    ]+  _replaceParameters (LSTMUnidirectionalLayer _wi _wh _bi _bh) = do+    wi <- A.nextParameter+    wh <- A.nextParameter+    bi <- A.nextParameter+    bh <- A.nextParameter+    return+      ( LSTMUnidirectionalLayer+          (UnsafeMkParameter wi)+          (UnsafeMkParameter wh)+          (UnsafeMkParameter bi)+          (UnsafeMkParameter bh)+      )+  _replaceParameters (LSTMBidirectionalLayer _wi _wh _bi _bh _wi' _wh' _bi' _bh') = do+    wi <- A.nextParameter+    wh <- A.nextParameter+    bi <- A.nextParameter+    bh <- A.nextParameter+    wi' <- A.nextParameter+    wh' <- A.nextParameter+    bi' <- A.nextParameter+    bh' <- A.nextParameter+    return+      ( LSTMBidirectionalLayer+          (UnsafeMkParameter wi)+          (UnsafeMkParameter wh)+          (UnsafeMkParameter bi)+          (UnsafeMkParameter bh)+          (UnsafeMkParameter wi')+          (UnsafeMkParameter wh')+          (UnsafeMkParameter bi')+          (UnsafeMkParameter bh')+      )++data+  LSTMLayerStackSpec+    (inputSize :: Nat)+    (hiddenSize :: Nat)+    (numLayers :: Nat)+    (directionality :: RNNDirectionality)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  = LSTMLayerStackSpec+  deriving (Show, Eq)++-- Input-to-hidden, hidden-to-hidden, and bias parameters for a mulilayered+-- (and optionally) bidirectional LSTM.+--+data+  LSTMLayerStack+    (inputSize :: Nat)+    (hiddenSize :: Nat)+    (numLayers :: Nat)+    (directionality :: RNNDirectionality)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  where+  LSTMLayer1 ::+    LSTMLayer inputSize hiddenSize directionality dtype device ->+    LSTMLayerStack inputSize hiddenSize 1 directionality dtype device+  LSTMLayerK ::+    LSTMLayer (hiddenSize * NumberOfDirections directionality) hiddenSize directionality dtype device ->+    LSTMLayerStack inputSize hiddenSize numLayers directionality dtype device ->+    LSTMLayerStack inputSize hiddenSize (numLayers + 1) directionality dtype device++deriving instance Show (LSTMLayerStack inputSize hiddenSize numLayers directionality dtype device)++class LSTMLayerStackParameterized (flag :: Bool) inputSize hiddenSize numLayers directionality dtype device where+  type LSTMLayerStackParameters flag inputSize hiddenSize numLayers directionality dtype device :: [Type]+  lstmLayerStackFlattenParameters ::+    Proxy flag ->+    LSTMLayerStack inputSize hiddenSize numLayers directionality dtype device ->+    HList (LSTMLayerStackParameters flag inputSize hiddenSize numLayers directionality dtype device)+  lstmLayerStackReplaceParameters ::+    Proxy flag ->+    LSTMLayerStack inputSize hiddenSize numLayers directionality dtype device ->+    HList (LSTMLayerStackParameters flag inputSize hiddenSize numLayers directionality dtype device) ->+    LSTMLayerStack inputSize hiddenSize numLayers directionality dtype device++instance+  Parameterized (LSTMLayer inputSize hiddenSize directionality dtype device) =>+  LSTMLayerStackParameterized 'False inputSize hiddenSize 1 directionality dtype device+  where+  type+    LSTMLayerStackParameters 'False inputSize hiddenSize 1 directionality dtype device =+      Parameters (LSTMLayer inputSize hiddenSize directionality dtype device)+  lstmLayerStackFlattenParameters _ (LSTMLayer1 lstmLayer) = flattenParameters lstmLayer+  lstmLayerStackReplaceParameters _ (LSTMLayer1 lstmLayer) parameters = LSTMLayer1 $ replaceParameters lstmLayer parameters++instance+  ( Parameterized+      ( LSTMLayer+          (hiddenSize * NumberOfDirections directionality)+          hiddenSize+          directionality+          dtype+          device+      ),+    Parameterized (LSTMLayerStack inputSize hiddenSize (numLayers - 1) directionality dtype device),+    HAppendFD+      (Parameters (LSTMLayerStack inputSize hiddenSize (numLayers - 1) directionality dtype device))+      (Parameters (LSTMLayer (hiddenSize * NumberOfDirections directionality) hiddenSize directionality dtype device))+      ( Parameters (LSTMLayerStack inputSize hiddenSize (numLayers - 1) directionality dtype device)+          ++ Parameters (LSTMLayer (hiddenSize * NumberOfDirections directionality) hiddenSize directionality dtype device)+      ),+    1 <= numLayers,+    numLayersM1 ~ numLayers - 1,+    0 <= numLayersM1+  ) =>+  LSTMLayerStackParameterized 'True inputSize hiddenSize numLayers directionality dtype device+  where+  type+    LSTMLayerStackParameters 'True inputSize hiddenSize numLayers directionality dtype device =+      Parameters (LSTMLayerStack inputSize hiddenSize (numLayers - 1) directionality dtype device)+        ++ Parameters (LSTMLayer (hiddenSize * NumberOfDirections directionality) hiddenSize directionality dtype device)+  lstmLayerStackFlattenParameters _ (LSTMLayerK lstmLayer lstmLayerStack) =+    let parameters = flattenParameters lstmLayer+        parameters' = flattenParameters @(LSTMLayerStack inputSize hiddenSize numLayersM1 directionality dtype device) lstmLayerStack+     in parameters' `happendFD` parameters+  lstmLayerStackReplaceParameters _ (LSTMLayerK lstmLayer lstmLayerStack) parameters'' =+    let (parameters', parameters) = hunappendFD parameters''+        lstmLayer' = replaceParameters lstmLayer parameters+        lstmLayerStack' = replaceParameters @(LSTMLayerStack inputSize hiddenSize (numLayers - 1) directionality dtype device) lstmLayerStack parameters'+     in LSTMLayerK lstmLayer' lstmLayerStack'++instance+  ( 1 <= numLayers,+    (2 <=? numLayers) ~ flag,+    LSTMLayerStackParameterized flag inputSize hiddenSize numLayers directionality dtype device+  ) =>+  Parameterized (LSTMLayerStack inputSize hiddenSize numLayers directionality dtype device)+  where+  type+    Parameters (LSTMLayerStack inputSize hiddenSize numLayers directionality dtype device) =+      LSTMLayerStackParameters (2 <=? numLayers) inputSize hiddenSize numLayers directionality dtype device+  flattenParameters = lstmLayerStackFlattenParameters (Proxy :: Proxy flag)+  replaceParameters = lstmLayerStackReplaceParameters (Proxy :: Proxy flag)++class LSTMLayerStackRandomizable (flag :: Bool) inputSize hiddenSize numLayers directionality dtype device where+  lstmLayerStackSample ::+    Proxy flag ->+    LSTMLayerStackSpec inputSize hiddenSize numLayers directionality dtype device ->+    IO (LSTMLayerStack inputSize hiddenSize numLayers directionality dtype device)++instance+  ( A.Randomizable+      (LSTMLayerSpec inputSize hiddenSize directionality dtype device)+      (LSTMLayer inputSize hiddenSize directionality dtype device)+  ) =>+  LSTMLayerStackRandomizable 'False inputSize hiddenSize 1 directionality dtype device+  where+  lstmLayerStackSample _ _ = LSTMLayer1 <$> (sample $ LSTMLayerSpec @inputSize @hiddenSize @directionality @dtype @device)++instance+  ( 1 <= numLayers,+    A.Randomizable+      (LSTMLayerSpec (hiddenSize * NumberOfDirections directionality) hiddenSize directionality dtype device)+      (LSTMLayer (hiddenSize * NumberOfDirections directionality) hiddenSize directionality dtype device),+    A.Randomizable+      (LSTMLayerStackSpec inputSize hiddenSize (numLayers - 1) directionality dtype device)+      (LSTMLayerStack inputSize hiddenSize (numLayers - 1) directionality dtype device)+  ) =>+  LSTMLayerStackRandomizable 'True inputSize hiddenSize numLayers directionality dtype device+  where+  lstmLayerStackSample _ _ =+    LSTMLayerK+      <$> (sample $ LSTMLayerSpec @(hiddenSize * NumberOfDirections directionality) @hiddenSize @directionality @dtype @device)+      <*> ( sample+              @(LSTMLayerStackSpec inputSize hiddenSize (numLayers - 1) directionality dtype device)+              @(LSTMLayerStack inputSize hiddenSize (numLayers - 1) directionality dtype device)+              $ LSTMLayerStackSpec+          )++instance+  ( 1 <= numLayers,+    (2 <=? numLayers) ~ flag,+    RandDTypeIsValid device dtype,+    KnownDType dtype,+    KnownDevice device,+    LSTMLayerStackRandomizable flag inputSize hiddenSize numLayers directionality dtype device+  ) =>+  Randomizable+    (LSTMLayerStackSpec inputSize hiddenSize numLayers directionality dtype device)+    (LSTMLayerStack inputSize hiddenSize numLayers directionality dtype device)+  where+  sample = lstmLayerStackSample (Proxy :: Proxy flag)++instance A.Parameterized (LSTMLayerStack inputSize hiddenSize numLayers directionality dtype device) where+  flattenParameters (LSTMLayer1 layer) =+    A.flattenParameters layer+  flattenParameters (LSTMLayerK stack layer) =+    A.flattenParameters stack+      ++ A.flattenParameters layer+  _replaceParameters (LSTMLayer1 layer) = do+    layer' <- A._replaceParameters layer+    return $ LSTMLayer1 layer'+  _replaceParameters (LSTMLayerK stack layer) = do+    stack' <- A._replaceParameters stack+    layer' <- A._replaceParameters layer+    return $ LSTMLayerK stack' layer'++newtype+  LSTMSpec+    (inputSize :: Nat)+    (hiddenSize :: Nat)+    (numLayers :: Nat)+    (directionality :: RNNDirectionality)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  = LSTMSpec DropoutSpec+  deriving (Show, Generic)++data+  LSTM+    (inputSize :: Nat)+    (hiddenSize :: Nat)+    (numLayers :: Nat)+    (directionality :: RNNDirectionality)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  where+  LSTM ::+    (1 <= numLayers) =>+    { lstm_layer_stack :: LSTMLayerStack inputSize hiddenSize numLayers directionality dtype device,+      lstm_dropout :: Dropout+    } ->+    LSTM inputSize hiddenSize numLayers directionality dtype device++deriving instance Show (LSTM inputSize hiddenSize numLayers directionality dtype device)++instance+  (1 <= numLayers) =>+  Generic (LSTM inputSize hiddenSize numLayers directionality dtype device)+  where+  type+    Rep (LSTM inputSize hiddenSize numLayers directionality dtype device) =+      Rec0 (LSTMLayerStack inputSize hiddenSize numLayers directionality dtype device)+        :*: Rec0 Dropout+  from (LSTM {..}) = K1 lstm_layer_stack :*: K1 lstm_dropout+  to (K1 layerStack :*: K1 dropout) = LSTM layerStack dropout++instance+  ( 1 <= numLayers,+    Parameterized (LSTMLayerStack inputSize hiddenSize numLayers directionality dtype device),+    HAppendFD+      (Parameters (LSTMLayerStack inputSize hiddenSize numLayers directionality dtype device))+      (Parameters Dropout)+      ( Parameters (LSTMLayerStack inputSize hiddenSize numLayers directionality dtype device)+          ++ Parameters Dropout+      )+  ) =>+  Parameterized (LSTM inputSize hiddenSize numLayers directionality dtype device)++-- TODO: when we have cannonical initializers do this correctly:+-- https://github.com/pytorch/pytorch/issues/9221+-- https://discuss.pytorch.org/t/initializing-rnn-gru-and-lstm-correctly/23605++instance A.Parameterized (LSTM inputSize hiddenSize numLayers directionality dtype device) where+  flattenParameters LSTM {..} = A.flattenParameters lstm_layer_stack+  _replaceParameters LSTM {..} = do+    lstm_layer_stack' <- A._replaceParameters lstm_layer_stack+    return $+      LSTM+        { lstm_layer_stack = lstm_layer_stack',+          ..+        }++-- | Helper to do xavier uniform initializations on weight matrices and+-- orthagonal initializations for the gates. (When implemented.)+xavierUniformLSTM ::+  forall device dtype hiddenSize featureSize.+  ( KnownDType dtype,+    KnownNat hiddenSize,+    KnownNat featureSize,+    KnownDevice device,+    RandDTypeIsValid device dtype+  ) =>+  IO (Tensor device dtype '[4 * hiddenSize, featureSize])+xavierUniformLSTM = do+  init <- randn :: IO (Tensor device dtype '[4 * hiddenSize, featureSize])+  UnsafeMkTensor+    <$> xavierUniformFIXME+      (toDynamic init)+      (5.0 / 3)+      (shape @device @dtype @'[4 * hiddenSize, featureSize] init)++instance+  ( KnownDType dtype,+    KnownDevice device,+    KnownNat inputSize,+    KnownNat hiddenSize,+    KnownNat (NumberOfDirections directionality),+    RandDTypeIsValid device dtype,+    A.Randomizable+      (LSTMLayerStackSpec inputSize hiddenSize numLayers directionality dtype device)+      (LSTMLayerStack inputSize hiddenSize numLayers directionality dtype device),+    1 <= numLayers+  ) =>+  A.Randomizable+    (LSTMSpec inputSize hiddenSize numLayers directionality dtype device)+    (LSTM inputSize hiddenSize numLayers directionality dtype device)+  where+  sample (LSTMSpec dropoutSpec) =+    LSTM+      <$> A.sample (LSTMLayerStackSpec @inputSize @hiddenSize @numLayers @directionality @dtype @device)+      <*> A.sample dropoutSpec++-- | A specification for a long, short-term memory layer.+data+  LSTMWithInitSpec+    (inputSize :: Nat)+    (hiddenSize :: Nat)+    (numLayers :: Nat)+    (directionality :: RNNDirectionality)+    (initialization :: RNNInitialization)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  where+  -- | Weights drawn from Xavier-Uniform+  --   with zeros-value initialized biases and cell states.+  LSTMWithZerosInitSpec ::+    forall inputSize hiddenSize numLayers directionality dtype device.+    LSTMSpec inputSize hiddenSize numLayers directionality dtype device ->+    LSTMWithInitSpec inputSize hiddenSize numLayers directionality 'ConstantInitialization dtype device+  -- | Weights drawn from Xavier-Uniform+  --   with zeros-value initialized biases+  --   and user-provided cell states.+  LSTMWithConstInitSpec ::+    forall inputSize hiddenSize numLayers directionality dtype device.+    LSTMSpec inputSize hiddenSize numLayers directionality dtype device ->+    -- | The initial values of the memory cell+    Tensor device dtype '[numLayers * NumberOfDirections directionality, hiddenSize] ->+    -- | The initial values of the hidden state+    Tensor device dtype '[numLayers * NumberOfDirections directionality, hiddenSize] ->+    LSTMWithInitSpec inputSize hiddenSize numLayers directionality 'ConstantInitialization dtype device+  -- | Weights drawn from Xavier-Uniform+  --   with zeros-value initialized biases+  --   and learned cell states.+  LSTMWithLearnedInitSpec ::+    forall inputSize hiddenSize numLayers directionality dtype device.+    LSTMSpec inputSize hiddenSize numLayers directionality dtype device ->+    -- | The initial (learnable)+    -- values of the memory cell+    Tensor device dtype '[numLayers * NumberOfDirections directionality, hiddenSize] ->+    -- | The initial (learnable)+    -- values of the hidden state+    Tensor device dtype '[numLayers * NumberOfDirections directionality, hiddenSize] ->+    LSTMWithInitSpec inputSize hiddenSize numLayers directionality 'LearnedInitialization dtype device++deriving instance Show (LSTMWithInitSpec inputSize hiddenSize numLayers directionality initialization dtype device)++-- | A long, short-term memory layer with either fixed initial+-- states for the memory cells and hidden state or learnable+-- inital states for the memory cells and hidden state.+data+  LSTMWithInit+    (inputSize :: Nat)+    (hiddenSize :: Nat)+    (numLayers :: Nat)+    (directionality :: RNNDirectionality)+    (initialization :: RNNInitialization)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  where+  LSTMWithConstInit ::+    forall inputSize hiddenSize numLayers directionality dtype device.+    { lstmWithConstInit_lstm :: LSTM inputSize hiddenSize numLayers directionality dtype device,+      lstmWithConstInit_c :: Tensor device dtype '[numLayers * NumberOfDirections directionality, hiddenSize],+      lstmWithConstInit_h :: Tensor device dtype '[numLayers * NumberOfDirections directionality, hiddenSize]+    } ->+    LSTMWithInit+      inputSize+      hiddenSize+      numLayers+      directionality+      'ConstantInitialization+      dtype+      device+  LSTMWithLearnedInit ::+    forall inputSize hiddenSize numLayers directionality dtype device.+    { lstmWithLearnedInit_lstm :: LSTM inputSize hiddenSize numLayers directionality dtype device,+      lstmWithLearnedInit_c :: Parameter device dtype '[numLayers * NumberOfDirections directionality, hiddenSize],+      lstmWithLearnedInit_h :: Parameter device dtype '[numLayers * NumberOfDirections directionality, hiddenSize]+    } ->+    LSTMWithInit+      inputSize+      hiddenSize+      numLayers+      directionality+      'LearnedInitialization+      dtype+      device++deriving instance Show (LSTMWithInit inputSize hiddenSize numLayers directionality initialization dtype device)++instance Generic (LSTMWithInit inputSize hiddenSize numLayers directionality 'ConstantInitialization dtype device) where+  type+    Rep (LSTMWithInit inputSize hiddenSize numLayers directionality 'ConstantInitialization dtype device) =+      Rec0 (LSTM inputSize hiddenSize numLayers directionality dtype device)+        :*: Rec0 (Tensor device dtype '[numLayers * NumberOfDirections directionality, hiddenSize])+        :*: Rec0 (Tensor device dtype '[numLayers * NumberOfDirections directionality, hiddenSize])+  from (LSTMWithConstInit {..}) = K1 lstmWithConstInit_lstm :*: K1 lstmWithConstInit_c :*: K1 lstmWithConstInit_h+  to (K1 lstm :*: K1 c :*: K1 h) = LSTMWithConstInit lstm c h++instance Generic (LSTMWithInit inputSize hiddenSize numLayers directionality 'LearnedInitialization dtype device) where+  type+    Rep (LSTMWithInit inputSize hiddenSize numLayers directionality 'LearnedInitialization dtype device) =+      Rec0 (LSTM inputSize hiddenSize numLayers directionality dtype device)+        :*: Rec0 (Parameter device dtype '[numLayers * NumberOfDirections directionality, hiddenSize])+        :*: Rec0 (Parameter device dtype '[numLayers * NumberOfDirections directionality, hiddenSize])+  from (LSTMWithLearnedInit {..}) = K1 lstmWithLearnedInit_lstm :*: K1 lstmWithLearnedInit_c :*: K1 lstmWithLearnedInit_h+  to (K1 lstm :*: K1 c :*: K1 h) = LSTMWithLearnedInit lstm c h++instance+  ( Parameterized (LSTM inputSize hiddenSize numLayers directionality dtype device),+    HAppendFD+      (Parameters (LSTM inputSize hiddenSize numLayers directionality dtype device))+      '[]+      (Parameters (LSTM inputSize hiddenSize numLayers directionality dtype device) ++ '[])+  ) =>+  Parameterized (LSTMWithInit inputSize hiddenSize numLayers directionality 'ConstantInitialization dtype device)++instance+  ( Parameterized (LSTM inputSize hiddenSize numLayers directionality dtype device),+    HAppendFD+      (Parameters (LSTM inputSize hiddenSize numLayers directionality dtype device))+      '[ Parameter+           device+           dtype+           '[numLayers * NumberOfDirections directionality, hiddenSize],+         Parameter+           device+           dtype+           '[numLayers * NumberOfDirections directionality, hiddenSize]+       ]+      ( Parameters (LSTM inputSize hiddenSize numLayers directionality dtype device)+          ++ '[ Parameter+                  device+                  dtype+                  '[numLayers * NumberOfDirections directionality, hiddenSize],+                Parameter+                  device+                  dtype+                  '[numLayers * NumberOfDirections directionality, hiddenSize]+              ]+      )+  ) =>+  Parameterized (LSTMWithInit inputSize hiddenSize numLayers directionality 'LearnedInitialization dtype device)++instance+  ( KnownNat hiddenSize,+    KnownNat numLayers,+    KnownNat (NumberOfDirections directionality),+    KnownDType dtype,+    KnownDevice device,+    A.Randomizable+      (LSTMSpec inputSize hiddenSize numLayers directionality dtype device)+      (LSTM inputSize hiddenSize numLayers directionality dtype device)+  ) =>+  A.Randomizable+    (LSTMWithInitSpec inputSize hiddenSize numLayers directionality 'ConstantInitialization dtype device)+    (LSTMWithInit inputSize hiddenSize numLayers directionality 'ConstantInitialization dtype device)+  where+  sample (LSTMWithZerosInitSpec lstmSpec) =+    LSTMWithConstInit+      <$> A.sample lstmSpec+      <*> pure zeros+      <*> pure zeros+  sample (LSTMWithConstInitSpec lstmSpec c h) =+    LSTMWithConstInit+      <$> A.sample lstmSpec+      <*> pure c+      <*> pure h++instance+  ( KnownNat hiddenSize,+    KnownNat numLayers,+    KnownNat (NumberOfDirections directionality),+    KnownDType dtype,+    KnownDevice device,+    A.Randomizable+      (LSTMSpec inputSize hiddenSize numLayers directionality dtype device)+      (LSTM inputSize hiddenSize numLayers directionality dtype device)+  ) =>+  A.Randomizable+    (LSTMWithInitSpec inputSize hiddenSize numLayers directionality 'LearnedInitialization dtype device)+    (LSTMWithInit inputSize hiddenSize numLayers directionality 'LearnedInitialization dtype device)+  where+  sample s@(LSTMWithLearnedInitSpec lstmSpec c h) =+    LSTMWithLearnedInit+      <$> A.sample lstmSpec+      <*> (makeIndependent =<< pure c)+      <*> (makeIndependent =<< pure h)++instance A.Parameterized (LSTMWithInit inputSize hiddenSize numLayers directionality initialization dtype device) where+  flattenParameters LSTMWithConstInit {..} =+    A.flattenParameters lstmWithConstInit_lstm+  flattenParameters LSTMWithLearnedInit {..} =+    A.flattenParameters lstmWithLearnedInit_lstm+      ++ fmap untypeParam [lstmWithLearnedInit_c, lstmWithLearnedInit_h]+  _replaceParameters LSTMWithConstInit {..} = do+    lstmWithConstInit_lstm' <- A._replaceParameters lstmWithConstInit_lstm+    return $+      LSTMWithConstInit+        { lstmWithConstInit_lstm = lstmWithConstInit_lstm',+          ..+        }+  _replaceParameters LSTMWithLearnedInit {..} = do+    lstmWithLearnedInit_lstm' <- A._replaceParameters lstmWithLearnedInit_lstm+    lstmWithLearnedInit_c' <- A.nextParameter+    lstmWithLearnedInit_h' <- A.nextParameter+    return $+      LSTMWithLearnedInit+        { lstmWithLearnedInit_lstm = lstmWithLearnedInit_lstm',+          lstmWithLearnedInit_c = UnsafeMkParameter lstmWithLearnedInit_c',+          lstmWithLearnedInit_h = UnsafeMkParameter lstmWithLearnedInit_h'+        }++lstmForward ::+  forall+    shapeOrder+    batchSize+    seqLen+    directionality+    initialization+    numLayers+    inputSize+    outputSize+    hiddenSize+    inputShape+    outputShape+    hxShape+    parameters+    tensorParameters+    dtype+    device.+  ( KnownNat (NumberOfDirections directionality),+    KnownNat numLayers,+    KnownNat batchSize,+    KnownNat hiddenSize,+    KnownRNNShapeOrder shapeOrder,+    KnownRNNDirectionality directionality,+    outputSize ~ (hiddenSize * NumberOfDirections directionality),+    inputShape ~ RNNShape shapeOrder seqLen batchSize inputSize,+    outputShape ~ RNNShape shapeOrder seqLen batchSize outputSize,+    hxShape ~ '[numLayers * NumberOfDirections directionality, batchSize, hiddenSize],+    parameters ~ Parameters (LSTM inputSize hiddenSize numLayers directionality dtype device),+    Parameterized (LSTM inputSize hiddenSize numLayers directionality dtype device),+    tensorParameters ~ LSTMR inputSize hiddenSize numLayers directionality dtype device,+    ATen.Castable (HList tensorParameters) [D.ATenTensor],+    HMap' ToDependent parameters tensorParameters+  ) =>+  Bool ->+  LSTMWithInit+    inputSize+    hiddenSize+    numLayers+    directionality+    initialization+    dtype+    device ->+  Tensor device dtype inputShape ->+  ( Tensor device dtype outputShape,+    Tensor device dtype hxShape,+    Tensor device dtype hxShape+  )+lstmForward dropoutOn (LSTMWithConstInit lstmModel@(LSTM _ (Dropout dropoutProb)) cc hc) input =+  lstm+    @shapeOrder+    @directionality+    @numLayers+    @seqLen+    @batchSize+    @inputSize+    @outputSize+    @hiddenSize+    @inputShape+    @outputShape+    @hxShape+    @tensorParameters+    @dtype+    @device+    (hmap' ToDependent . flattenParameters $ lstmModel)+    dropoutProb+    dropoutOn+    (cc', hc')+    input+  where+    cc' =+      reshape @hxShape+        . expand+          @'[batchSize, numLayers * NumberOfDirections directionality, hiddenSize]+          False -- TODO: What does the bool do?+        $ cc+    hc' =+      reshape @hxShape+        . expand+          @'[batchSize, numLayers * NumberOfDirections directionality, hiddenSize]+          False -- TODO: What does the bool do?+        $ hc+lstmForward dropoutOn (LSTMWithLearnedInit lstmModel@(LSTM _ (Dropout dropoutProb)) cc hc) input =+  lstm+    @shapeOrder+    @directionality+    @numLayers+    @seqLen+    @batchSize+    @inputSize+    @outputSize+    @hiddenSize+    @inputShape+    @outputShape+    @hxShape+    @tensorParameters+    @dtype+    @device+    (hmap' ToDependent . flattenParameters $ lstmModel)+    dropoutProb+    dropoutOn+    (cc', hc')+    input+  where+    cc' =+      reshape @hxShape+        . expand+          @'[batchSize, numLayers * NumberOfDirections directionality, hiddenSize]+          False -- TODO: What does the bool do?+        . toDependent+        $ cc+    hc' =+      reshape @hxShape+        . expand+          @'[batchSize, numLayers * NumberOfDirections directionality, hiddenSize]+          False -- TODO: What does the bool do?+        . toDependent+        $ hc++lstmForwardWithDropout,+  lstmForwardWithoutDropout ::+    forall+      shapeOrder+      batchSize+      seqLen+      directionality+      initialization+      numLayers+      inputSize+      outputSize+      hiddenSize+      inputShape+      outputShape+      hxShape+      parameters+      tensorParameters+      dtype+      device.+    ( KnownNat (NumberOfDirections directionality),+      KnownNat numLayers,+      KnownNat batchSize,+      KnownNat hiddenSize,+      KnownRNNShapeOrder shapeOrder,+      KnownRNNDirectionality directionality,+      outputSize ~ (hiddenSize * NumberOfDirections directionality),+      inputShape ~ RNNShape shapeOrder seqLen batchSize inputSize,+      outputShape ~ RNNShape shapeOrder seqLen batchSize outputSize,+      hxShape ~ '[numLayers * NumberOfDirections directionality, batchSize, hiddenSize],+      parameters ~ Parameters (LSTM inputSize hiddenSize numLayers directionality dtype device),+      Parameterized (LSTM inputSize hiddenSize numLayers directionality dtype device),+      tensorParameters ~ LSTMR inputSize hiddenSize numLayers directionality dtype device,+      ATen.Castable (HList tensorParameters) [D.ATenTensor],+      HMap' ToDependent parameters tensorParameters+    ) =>+    LSTMWithInit+      inputSize+      hiddenSize+      numLayers+      directionality+      initialization+      dtype+      device ->+    Tensor device dtype inputShape ->+    ( Tensor device dtype outputShape,+      Tensor device dtype hxShape,+      Tensor device dtype hxShape+    )+-- ^ Forward propagate the `LSTM` module and apply dropout on the outputs of each layer.+--+-- >>> input :: CPUTensor 'D.Float '[5,16,10] <- randn+-- >>> spec = LSTMWithZerosInitSpec @10 @30 @3 @'Bidirectional @'D.Float @'(D.CPU, 0) (LSTMSpec (DropoutSpec 0.5))+-- >>> model <- A.sample spec+-- >>> :t lstmForwardWithDropout @'BatchFirst model input+-- lstmForwardWithDropout @'BatchFirst model input+--   :: (Tensor '(D.CPU, 0) 'D.Float [5, 16, 60],+--       Tensor '(D.CPU, 0) 'D.Float [6, 5, 30],+--       Tensor '(D.CPU, 0) 'D.Float [6, 5, 30])+-- >>> (a,b,c) = lstmForwardWithDropout @'BatchFirst model input+-- >>> ((dtype a, shape a), (dtype b, shape b), (dtype c, shape c))+-- ((Float,[5,16,60]),(Float,[6,5,30]),(Float,[6,5,30]))+lstmForwardWithDropout =+  lstmForward+    @shapeOrder+    @batchSize+    @seqLen+    @directionality+    @initialization+    @numLayers+    @inputSize+    @outputSize+    @hiddenSize+    @inputShape+    @outputShape+    @hxShape+    @parameters+    @tensorParameters+    @dtype+    @device+    True+-- ^ Forward propagate the `LSTM` module (without applying dropout on the outputs of each layer).+--+-- >>> input :: CPUTensor 'D.Float '[5,16,10] <- randn+-- >>> spec = LSTMWithZerosInitSpec @10 @30 @3 @'Bidirectional @'D.Float @'(D.CPU, 0) (LSTMSpec (DropoutSpec 0.5))+-- >>> model <- A.sample spec+-- >>> :t lstmForwardWithoutDropout @'BatchFirst model input+-- lstmForwardWithoutDropout @'BatchFirst model input+--   :: (Tensor '(D.CPU, 0) 'D.Float [5, 16, 60],+--       Tensor '(D.CPU, 0) 'D.Float [6, 5, 30],+--       Tensor '(D.CPU, 0) 'D.Float [6, 5, 30])+-- >>> (a,b,c) = lstmForwardWithoutDropout @'BatchFirst model input+-- >>> ((dtype a, shape a), (dtype b, shape b), (dtype c, shape c))+-- ((Float,[5,16,60]),(Float,[6,5,30]),(Float,[6,5,30]))+lstmForwardWithoutDropout =+  lstmForward+    @shapeOrder+    @batchSize+    @seqLen+    @directionality+    @initialization+    @numLayers+    @inputSize+    @outputSize+    @hiddenSize+    @inputShape+    @outputShape+    @hxShape+    @parameters+    @tensorParameters+    @dtype+    @device+    False
+ src/Torch/Typed/NN/Sparse.hs view
@@ -0,0 +1,190 @@+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}++module Torch.Typed.NN.Sparse where++import Data.Proxy+import GHC.Generics+import GHC.TypeLits+import qualified Torch.DType as D+import qualified Torch.Device as D+import Torch.HList+import Torch.NN (HasForward (..), Randomizable (..))+import Torch.Typed.Auxiliary+import Torch.Typed.Factories+import Torch.Typed.Functional+import Torch.Typed.Parameter+import Torch.Typed.Tensor++data EmbeddingType = Constant | Learned deriving (Show, Generic)++data+  EmbeddingSpec+    (paddingIdx :: Maybe Nat)+    (numEmbeds :: Nat)+    (embedSize :: Nat)+    (embeddingType :: EmbeddingType)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  where+  ConstEmbeddingSpec ::+    forall paddingIdx numEmbeds embedSize dtype device.+    Tensor device dtype '[numEmbeds, embedSize] ->+    EmbeddingSpec paddingIdx numEmbeds embedSize 'Constant dtype device+  LearnedEmbeddingWithRandomInitSpec ::+    forall paddingIdx numEmbeds embedSize dtype device.+    EmbeddingSpec+      paddingIdx+      numEmbeds+      embedSize+      'Learned+      dtype+      device+  LearnedEmbeddingWithCustomInitSpec ::+    forall paddingIdx numEmbeds embedSize dtype device.+    Tensor device dtype '[numEmbeds, embedSize] ->+    EmbeddingSpec paddingIdx numEmbeds embedSize 'Learned dtype device++deriving instance Show (EmbeddingSpec paddingIdx numEmbeds embedSize embeddingType dtype device)++data+  Embedding+    (paddingIdx :: Maybe Nat)+    (numEmbeds :: Nat)+    (embedSize :: Nat)+    (embeddingType :: EmbeddingType)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  where+  ConstEmbedding ::+    forall paddingIdx numEmbeds embedSize dtype device.+    --  . (PaddingIdxCheck paddingIdx numEmbeds)+    {constEmbedWeights :: Tensor device dtype '[numEmbeds, embedSize]} ->+    Embedding+      paddingIdx+      numEmbeds+      embedSize+      'Constant+      dtype+      device+  LearnedEmbedding ::+    forall paddingIdx numEmbeds embedSize dtype device.+    --  . (PaddingIdxCheck paddingIdx numEmbeds)+    {learnedEmbedWeights :: Parameter device dtype '[numEmbeds, embedSize]} ->+    Embedding+      paddingIdx+      numEmbeds+      embedSize+      'Learned+      dtype+      device++deriving instance Show (Embedding paddingIdx numEmbeds embedSize embeddingType dtype device)++instance Generic (Embedding paddingIdx numEmbeds embedSize 'Constant dtype device) where+  type+    Rep (Embedding paddingIdx numEmbeds embedSize 'Constant dtype device) =+      Rec0 (Tensor device dtype '[numEmbeds, embedSize])+  from (ConstEmbedding {..}) = K1 constEmbedWeights+  to = ConstEmbedding . unK1++instance Generic (Embedding paddingIdx numEmbeds embedSize 'Learned dtype device) where+  type+    Rep (Embedding paddingIdx numEmbeds embedSize 'Learned dtype device) =+      Rec0 (Parameter device dtype '[numEmbeds, embedSize])+  from (LearnedEmbedding {..}) = K1 learnedEmbedWeights+  to = LearnedEmbedding . unK1++instance Parameterized (Embedding paddingIdx numEmbeds embedSize 'Constant dtype device)++instance Parameterized (Embedding paddingIdx numEmbeds embedSize 'Learned dtype device)++embed ::+  forall paddingIdx shape numEmbeds embedSize embeddingType dtype device shape'.+  ( KnownMaybeNat paddingIdx,+    PaddingIdxCheck paddingIdx numEmbeds,+    shape' ~ Reverse (embedSize ': (Reverse shape))+  ) =>+  Embedding paddingIdx numEmbeds embedSize embeddingType dtype device ->+  Tensor device 'D.Int64 shape ->+  Tensor device dtype shape'+embed ConstEmbedding {..} input =+  embedding @paddingIdx+    False+    False+    constEmbedWeights+    input+embed LearnedEmbedding {..} input =+  embedding @paddingIdx+    False+    False+    (toDependent learnedEmbedWeights)+    input++instance+  ( KnownMaybeNat paddingIdx,+    PaddingIdxCheck paddingIdx numEmbeds,+    shape' ~ Reverse (embedSize ': (Reverse shape))+  ) =>+  HasForward (Embedding paddingIdx numEmbeds embedSize embeddingType dtype device) (Tensor device 'D.Int64 shape) (Tensor device dtype shape')+  where+  forward = embed+  forwardStoch = (pure .) . forward++instance+  Randomizable+    (EmbeddingSpec paddingIdx numEmbeds embedSize 'Constant dtype device)+    (Embedding paddingIdx numEmbeds embedSize 'Constant dtype device)+  where+  sample (ConstEmbeddingSpec tensor) = pure (ConstEmbedding tensor)++instance+  ( KnownNat numEmbeds,+    KnownNat embedSize,+    KnownDType dtype,+    KnownDevice device,+    RandDTypeIsValid device dtype+  ) =>+  Randomizable+    (EmbeddingSpec 'Nothing numEmbeds embedSize 'Learned dtype device)+    (Embedding 'Nothing numEmbeds embedSize 'Learned dtype device)+  where+  sample LearnedEmbeddingWithRandomInitSpec = LearnedEmbedding <$> (makeIndependent =<< randn)+  sample (LearnedEmbeddingWithCustomInitSpec tensor) = LearnedEmbedding <$> (makeIndependent =<< (pure tensor))++instance+  ( paddingIdx <= numEmbeds,+    1 <= numEmbeds - paddingIdx,+    (((numEmbeds - paddingIdx) - 1) + (1 + paddingIdx)) ~ numEmbeds,+    KnownNat paddingIdx,+    KnownNat numEmbeds,+    KnownNat embedSize,+    KnownDType dtype,+    KnownDevice device,+    RandDTypeIsValid device dtype+  ) =>+  Randomizable+    (EmbeddingSpec ('Just paddingIdx) numEmbeds embedSize 'Learned dtype device)+    (Embedding ('Just paddingIdx) numEmbeds embedSize 'Learned dtype device)+  where+  sample LearnedEmbeddingWithRandomInitSpec =+    let mask =+          cat @0+            ( zeros @'[paddingIdx, embedSize] @'D.Bool @device+                :. ones @'[1, embedSize] @'D.Bool @device+                :. zeros @'[numEmbeds - paddingIdx - 1, embedSize] @'D.Bool @device+                :. HNil+            )+     in LearnedEmbedding <$> (makeIndependent =<< (maskedFill mask (0 :: Int) <$> (randn @'[numEmbeds, embedSize] @dtype @device)))+  sample (LearnedEmbeddingWithCustomInitSpec tensor) = LearnedEmbedding <$> (makeIndependent =<< (pure tensor))
+ src/Torch/Typed/NN/Transformer.hs view
@@ -0,0 +1,641 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE NoStarIsType #-}+{-# OPTIONS_GHC -fconstraint-solver-iterations=0 #-}++module Torch.Typed.NN.Transformer where++import Control.Monad+import Data.Proxy+import GHC.Generics+import GHC.TypeLits+import System.IO.Unsafe (unsafePerformIO)+import qualified Torch.DType as D+import qualified Torch.Device as D+import Torch.HList+import Torch.NN (HasForward (..))+import qualified Torch.NN as A+import Torch.Typed.Auxiliary+import Torch.Typed.Factories+import Torch.Typed.Functional hiding (linear, log)+import Torch.Typed.NN.Dropout+import Torch.Typed.NN.Linear+import Torch.Typed.NN.Normalization+import Torch.Typed.NN.Sparse+import Torch.Typed.Parameter+import Torch.Typed.Tensor+import Prelude hiding (cos, exp, sin)++residual f g x = f x >>= (\x' -> g (x `add` x'))++--------------------------------------------------------------------------------+-- Relation-Aware Multi-Headed Attention Layer+--------------------------------------------------------------------------------++data+  MultiheadAttentionSpec+    (embedDim :: Nat)+    (kEmbedDim :: Nat)+    (vEmbedDim :: Nat)+    (numHeads :: Nat)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  where+  MultiheadAttentionSpec ::+    -- | spec for dropout+    DropoutSpec ->+    MultiheadAttentionSpec embedDim kEmbedDim vEmbedDim numHeads dtype device+  deriving (Show, Eq)++data+  MultiheadAttention+    (embedDim :: Nat)+    (kEmbedDim :: Nat)+    (vEmbedDim :: Nat)+    (numHeads :: Nat)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  where+  MultiheadAttention ::+    { -- | in-projection for query+      mhaQInProj :: Linear embedDim embedDim dtype device,+      -- | in-projection for key+      mhaKInProj :: Linear kEmbedDim embedDim dtype device,+      -- | in-projection for value+      mhaVInProj :: Linear vEmbedDim embedDim dtype device,+      -- | out-projection+      mhaOutProj :: Linear embedDim embedDim dtype device,+      -- | dropout+      mhaDropout :: Dropout+    } ->+    MultiheadAttention embedDim kEmbedDim vEmbedDim numHeads dtype device+  deriving (Show, Generic, Parameterized)++multiheadAttention ::+  forall embedDim kEmbedDim vEmbedDim numHeads seqLen seqLen' batchSize headDim dtype device.+  ( 1 <= numHeads,+    embedDim ~ (headDim * numHeads),+    All KnownNat '[embedDim, kEmbedDim, vEmbedDim, numHeads, seqLen, seqLen', batchSize, headDim],+    KnownDType dtype,+    StandardFloatingPointDTypeValidation device dtype,+    MatMulDTypeIsValid device dtype,+    BasicArithmeticDTypeIsValid device dtype,+    dtype ~ SumDType dtype,+    SumDTypeIsValid device dtype,+    KnownDevice device+  ) =>+  -- | multi-head attention model ADT+  MultiheadAttention embedDim kEmbedDim vEmbedDim numHeads dtype device ->+  -- | switch between training mode and evaluation mode (turns random dropout on and off)+  Bool ->+  -- | optional attention mask+  Maybe (Tensor device dtype '[batchSize, seqLen', seqLen]) ->+  -- | optional key padding mask+  Maybe (Tensor device 'D.Bool '[batchSize, seqLen]) ->+  -- | optional key relations+  Maybe (Tensor device dtype '[batchSize, seqLen', seqLen, headDim]) ->+  -- | optional value relations+  Maybe (Tensor device dtype '[batchSize, seqLen', seqLen, headDim]) ->+  -- | query representation+  Tensor device dtype '[batchSize, seqLen', embedDim] ->+  -- | key representation+  Tensor device dtype '[batchSize, seqLen, kEmbedDim] ->+  -- | value representation+  Tensor device dtype '[batchSize, seqLen, vEmbedDim] ->+  -- | attention and attention averaged over heads+  IO+    ( Tensor device dtype '[batchSize, seqLen', embedDim],+      Tensor device dtype '[batchSize, seqLen', seqLen]+    )+multiheadAttention MultiheadAttention {..} train attentionMask keyPaddingMask keyRelations valueRelations query key value = do+  weights <-+    dropoutForward mhaDropout train+      . softmax @3+      . _maskKeyPaddings+      . _maskAttention+      $ _attentionWeights+  pure (_attention weights, averageOverHeads weights)+  where+    _attentionWeights =+      let scaling = Prelude.sqrt . fromIntegral $ natValI @headDim :: Double+          q = reshape' . divScalar scaling . forward mhaQInProj $ query+          k = reshape' . forward mhaKInProj $ key+          weights = matmul q (transpose @2 @3 k)+          weights' = case keyRelations of+            Nothing -> weights+            Just kr -> weights `add` transpose @1 @2 ((transpose @1 @2 q) `matmul` (transpose @2 @3 kr))+       in weights'+    _maskAttention attentionWeights =+      case attentionMask of+        Nothing -> attentionWeights+        Just am -> attentionWeights `add` unsqueeze @1 am+    _maskKeyPaddings attentionWeights =+      case keyPaddingMask of+        Nothing -> attentionWeights+        Just kpm ->+          let keyPaddingMask' = unsqueeze @2 . unsqueeze @1 $ kpm+           in maskedFill keyPaddingMask' (-1 / 0 :: Double) attentionWeights+    _attention attentionWeights =+      let v = reshape' . forward mhaVInProj $ value+          attention = transpose @1 @2 $ matmul attentionWeights v+          attention' = case valueRelations of+            Nothing -> attention+            Just vr -> attention `add` (matmul (transpose @1 @2 attentionWeights) vr)+       in forward mhaOutProj . reshape @'[batchSize, seqLen', embedDim] $ attention'+    averageOverHeads =+      let numHeads' = natValI @numHeads+       in divScalar numHeads' . sumDim @1+    reshape' ::+      forall seqLen''.+      KnownNat seqLen'' =>+      Tensor device dtype '[batchSize, seqLen'', embedDim] ->+      Tensor device dtype '[batchSize, numHeads, seqLen'', headDim]+    reshape' = transpose @1 @2 . reshape @'[batchSize, seqLen'', numHeads, headDim]++instance+  ( All KnownNat '[embedDim, kEmbedDim, vEmbedDim, numHeads],+    KnownDType dtype,+    KnownDevice device,+    RandDTypeIsValid device dtype+  ) =>+  A.Randomizable+    (MultiheadAttentionSpec embedDim kEmbedDim vEmbedDim numHeads dtype device)+    (MultiheadAttention embedDim kEmbedDim vEmbedDim numHeads dtype device)+  where+  sample (MultiheadAttentionSpec mhaDropoutSpec) =+    MultiheadAttention+      <$> A.sample LinearSpec+      <*> A.sample LinearSpec+      <*> A.sample LinearSpec+      <*> A.sample LinearSpec+      <*> A.sample mhaDropoutSpec++--------------------------------------------------------------------------------+-- Transformer MLP Layer+--------------------------------------------------------------------------------++data+  TransformerMLPSpec+    (embedDim :: Nat)+    (ffnDim :: Nat)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  where+  TransformerMLPSpec ::+    forall embedDim ffnDim dtype device.+    { -- | spec for relu dropout+      dropout0Spec :: DropoutSpec,+      -- | spec for other dropout+      dropout1Spec :: DropoutSpec,+      -- | epsilon for layer norm+      epsSpec :: Double+    } ->+    TransformerMLPSpec embedDim ffnDim dtype device+  deriving (Show, Eq)++data+  TransformerMLP+    (embedDim :: Nat)+    (ffnDim :: Nat)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  where+  TransformerMLP ::+    forall embedDim ffnDim dtype device.+    { -- | first fully connected layer+      linear0 :: Linear embedDim ffnDim dtype device,+      -- | second fully connected layer+      linear1 :: Linear ffnDim embedDim dtype device,+      -- | relu dropout+      dropout0 :: Dropout,+      -- | other dropout+      dropout1 :: Dropout,+      -- | layer norm+      ln :: LayerNorm '[embedDim] dtype device+    } ->+    TransformerMLP embedDim ffnDim dtype device+  deriving (Show, Generic, Parameterized)++transformerMLP ::+  forall embedDim ffnDim seqLen batchSize dtype device.+  ( BasicArithmeticDTypeIsValid device dtype,+    StandardFloatingPointDTypeValidation device dtype,+    KnownNat embedDim,+    IsSuffixOf '[embedDim] '[seqLen, batchSize, embedDim]+  ) =>+  -- | MLP model ADT for transformer+  TransformerMLP embedDim ffnDim dtype device ->+  -- | switch between training mode and evaluation mode (turns random dropout on and off)+  Bool ->+  Tensor device dtype '[seqLen, batchSize, embedDim] -> -- input+  IO (Tensor device dtype '[seqLen, batchSize, embedDim]) -- output+transformerMLP TransformerMLP {..} train input =+  residual f (pure . forward ln) input+  where+    f x =+      dropoutForward dropout1 train+        . forward linear1+        =<< dropoutForward dropout0 train+          . relu+          . forward linear0+        =<< pure x++instance+  ( All KnownNat '[embedDim, ffnDim],+    KnownDType dtype,+    KnownDevice device,+    RandDTypeIsValid device dtype+  ) =>+  A.Randomizable+    (TransformerMLPSpec embedDim ffnDim dtype device)+    (TransformerMLP embedDim ffnDim dtype device)+  where+  sample TransformerMLPSpec {..} =+    TransformerMLP+      <$> A.sample LinearSpec+      <*> A.sample LinearSpec+      <*> A.sample dropout0Spec+      <*> A.sample dropout1Spec+      <*> A.sample (LayerNormSpec epsSpec)++--------------------------------------------------------------------------------+-- Relation-Aware Transformer Layer+--------------------------------------------------------------------------------++data+  TransformerLayerSpec+    (embedDim :: Nat)+    (kEmbedDim :: Nat)+    (vEmbedDim :: Nat)+    (numHeads :: Nat)+    (ffnDim :: Nat)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  where+  TransformerLayerSpec ::+    forall embedDim kEmbedDim vEmbedDim numHeads ffnDim dtype device.+    { mhaSpec :: MultiheadAttentionSpec embedDim kEmbedDim vEmbedDim numHeads dtype device,+      attnDropoutSpec :: DropoutSpec,+      epsSpec' :: Double,+      mlpSpec :: TransformerMLPSpec embedDim ffnDim dtype device+    } ->+    TransformerLayerSpec embedDim kEmbedDim vEmbedDim numHeads ffnDim dtype device+  deriving (Show, Eq)++data+  TransformerLayer+    (embedDim :: Nat)+    (kEmbedDim :: Nat)+    (vEmbedDim :: Nat)+    (numHeads :: Nat)+    (ffnDim :: Nat)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  where+  TransformerLayer ::+    forall embedDim kEmbedDim vEmbedDim numHeads ffnDim dtype device.+    { -- | multi-head attention+      transformerLayer_mha :: MultiheadAttention embedDim kEmbedDim vEmbedDim numHeads dtype device,+      -- | dropout+      transformerLayer_attnDropout :: Dropout,+      -- | layer norm+      transformerLayer_ln :: LayerNorm '[embedDim] dtype device,+      -- | MLP+      transformerLayer_mlp :: TransformerMLP embedDim ffnDim dtype device+    } ->+    TransformerLayer embedDim kEmbedDim vEmbedDim numHeads ffnDim dtype device+  deriving (Show, Generic, Parameterized)++transformerLayer ::+  forall (numHeads :: Nat) (ffnDim :: Nat) (embedDim :: Nat) (kEmbedDim :: Nat) (vEmbedDim :: Nat) (headDim :: Nat) (seqLen :: Nat) (seqLen' :: Nat) (batchSize :: Nat) dtype device.+  ( 1 <= numHeads,+    embedDim ~ (headDim * numHeads),+    All KnownNat '[embedDim, kEmbedDim, vEmbedDim, numHeads, seqLen, seqLen', batchSize, headDim],+    IsSuffixOf '[embedDim] '[batchSize, seqLen', embedDim],+    KnownDType dtype,+    dtype ~ SumDType dtype,+    StandardFloatingPointDTypeValidation device dtype,+    MatMulDTypeIsValid device dtype,+    BasicArithmeticDTypeIsValid device dtype,+    SumDTypeIsValid device dtype,+    KnownDevice device+  ) =>+  -- | transformer layer model ADT+  TransformerLayer embedDim kEmbedDim vEmbedDim numHeads ffnDim dtype device ->+  -- | switch between training mode and evaluation mode (turns random dropout on and off)+  Bool ->+  -- | optional attention mask+  Maybe (Tensor device dtype '[batchSize, seqLen', seqLen]) ->+  -- | optional key padding mask+  Maybe (Tensor device 'D.Bool '[batchSize, seqLen]) ->+  -- | optional key relations+  Maybe (Tensor device dtype '[batchSize, seqLen', seqLen, headDim]) ->+  -- | optional value relations+  Maybe (Tensor device dtype '[batchSize, seqLen', seqLen, headDim]) ->+  -- | query representation+  Tensor device dtype '[batchSize, seqLen', embedDim] ->+  -- | key representation+  Tensor device dtype '[batchSize, seqLen, kEmbedDim] ->+  -- | value representation+  Tensor device dtype '[batchSize, seqLen, vEmbedDim] ->+  -- | transformer layer output representation+  IO (Tensor device dtype '[batchSize, seqLen', embedDim])+transformerLayer TransformerLayer {..} train attentionMask keyPaddingMask keyRelations valueRelations query key value =+  let f query' =+        multiheadAttention transformerLayer_mha train attentionMask keyPaddingMask keyRelations valueRelations query' key value+          >>= dropoutForward transformerLayer_attnDropout train . fst+   in residual f (pure . forward transformerLayer_ln) query >>= transformerMLP transformerLayer_mlp train++instance+  ( All KnownNat '[embedDim, kEmbedDim, vEmbedDim, numHeads, ffnDim],+    KnownDType dtype,+    KnownDevice device,+    RandDTypeIsValid device dtype+  ) =>+  A.Randomizable+    (TransformerLayerSpec embedDim kEmbedDim vEmbedDim numHeads ffnDim dtype device)+    (TransformerLayer embedDim kEmbedDim vEmbedDim numHeads ffnDim dtype device)+  where+  sample TransformerLayerSpec {..} =+    TransformerLayer+      <$> A.sample mhaSpec+      <*> A.sample attnDropoutSpec+      <*> A.sample (LayerNormSpec epsSpec')+      <*> A.sample mlpSpec++--------------------------------------------------------------------------------+-- Transformer Language Model (GPT-2)+--------------------------------------------------------------------------------++data+  TransformerLMSpec+    (numAttnLayers :: Nat)+    (numHeads :: Nat)+    (ffnDim :: Nat)+    (paddingIdx :: Nat)+    (numEmbeds :: Nat)+    (embedDim :: Nat)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  where+  TransformerLMSpec ::+    forall numAttnLayers numHeads ffnDim paddingIdx numEmbeds embedDim dtype device.+    { -- | dropout spec+      lmDropoutSpec :: DropoutSpec,+      -- | spec for each and every transformer layer+      lmLayerSpec :: TransformerLayerSpec embedDim embedDim embedDim numHeads ffnDim dtype device+    } ->+    TransformerLMSpec numAttnLayers numHeads ffnDim paddingIdx numEmbeds embedDim dtype device+  deriving (Show, Eq)++data+  TransformerLM+    (numAttnLayers :: Nat)+    (numHeads :: Nat)+    (ffnDim :: Nat)+    (paddingIdx :: Nat)+    (numEmbeds :: Nat)+    (embedDim :: Nat)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat))+  where+  TransformerLM ::+    forall numAttnLayers numHeads ffnDim paddingIdx numEmbeds embedDim dtype device.+    { -- | token embedding+      tEmbedding :: Embedding ('Just paddingIdx) numEmbeds embedDim 'Learned dtype device,+      -- | positional embedding+      tPosEmbedding :: Embedding 'Nothing 2048 embedDim 'Constant dtype device,+      -- | transformer dropout+      tDropout :: Dropout,+      -- | transformer layers+      tLayers :: HList (HReplicateR numAttnLayers (TransformerLayer embedDim embedDim embedDim numHeads ffnDim dtype device)),+      -- | final output projection+      tProj :: Linear embedDim numEmbeds dtype device+    } ->+    TransformerLM numAttnLayers numHeads ffnDim paddingIdx numEmbeds embedDim dtype device+  deriving (Generic)++deriving instance+  ( Show+      ( HList+          ( HReplicateR+              numAttnLayers+              ( TransformerLayer+                  embedDim+                  embedDim+                  embedDim+                  numHeads+                  ffnDim+                  dtype+                  device+              )+          )+      )+  ) =>+  Show (TransformerLM numAttnLayers numHeads ffnDim paddingIdx numEmbeds embedDim dtype device)++instance+  ( layers+      ~ ( HReplicateR+            numAttnLayers+            ( TransformerLayer+                embedDim+                embedDim+                embedDim+                numHeads+                ffnDim+                dtype+                device+            )+        ),+    Parameterized+      ( HList+          layers+      ),+    HAppendFD+      (Parameters (HList layers))+      '[ Parameter device dtype '[numEmbeds, embedDim],+         Parameter device dtype '[numEmbeds]+       ]+      ( Parameters (HList layers)+          ++ '[ Parameter device dtype '[numEmbeds, embedDim],+                Parameter device dtype '[numEmbeds]+              ]+      )+  ) =>+  Parameterized (TransformerLM numAttnLayers numHeads ffnDim paddingIdx numEmbeds embedDim dtype device)++data+  FoldLayers+    (batchSize :: Nat)+    (seqLen :: Nat)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat)) = FoldLayers+  { -- | switch between training mode and evaluation mode (turns random dropout on and off)+    flTrain :: Bool,+    -- | optional attention mask+    flAttentionMask :: Maybe (Tensor device dtype '[batchSize, seqLen, seqLen]),+    -- | optional key padding mask+    flKeyPaddingMask :: Maybe (Tensor device 'D.Bool '[batchSize, seqLen])+  }++instance+  ( 1 <= numHeads,+    embedDim ~ (headDim * numHeads),+    All KnownNat '[embedDim, numHeads, seqLen, batchSize, headDim],+    IsSuffixOf '[embedDim] '[batchSize, seqLen, embedDim],+    KnownDType dtype,+    StandardFloatingPointDTypeValidation device dtype,+    MatMulDTypeIsValid device dtype,+    BasicArithmeticDTypeIsValid device dtype,+    dtype ~ SumDType dtype,+    SumDTypeIsValid device dtype,+    KnownDevice device+  ) =>+  Apply'+    (FoldLayers batchSize seqLen dtype device)+    ( TransformerLayer embedDim embedDim embedDim numHeads ffnDim dtype device,+      IO (Tensor device dtype '[batchSize, seqLen, embedDim])+    )+    (IO (Tensor device dtype '[batchSize, seqLen, embedDim]))+  where+  apply' FoldLayers {..} (layer, mx) = mx >>= \x -> transformerLayer layer flTrain flAttentionMask flKeyPaddingMask Nothing Nothing x x x++transformerLM ::+  forall+    numAttnLayers+    numHeads+    ffnDim+    paddingIdx+    numEmbeds+    embedDim+    seqLen+    batchSize+    dtype+    device.+  ( All KnownNat '[paddingIdx, embedDim, seqLen, batchSize],+    paddingIdx + 1 <= numEmbeds,+    1 <= seqLen,+    HFoldrM+      IO+      (FoldLayers batchSize seqLen dtype device)+      (Tensor device dtype '[batchSize, seqLen, embedDim])+      (HReplicateR numAttnLayers (TransformerLayer embedDim embedDim embedDim numHeads ffnDim dtype device))+      (Tensor device dtype '[batchSize, seqLen, embedDim]),+    BasicArithmeticDTypeIsValid device dtype,+    ComparisonDTypeIsValid device dtype,+    ComparisonDTypeIsValid device 'D.Int64,+    KnownDType dtype,+    KnownDevice device+  ) =>+  TransformerLM numAttnLayers numHeads ffnDim paddingIdx numEmbeds embedDim dtype device ->+  Bool ->+  Tensor device 'D.Int64 '[batchSize, seqLen] ->+  IO (Tensor device dtype '[batchSize, seqLen, numEmbeds])+transformerLM TransformerLM {..} train xTokens = do+  let x = embed tEmbedding xTokens+      positions =+        expand @'[batchSize, seqLen, embedDim] True+          . embed tPosEmbedding+          . Torch.Typed.Tensor.toDType @D.Int64+          . linspace @seqLen (0 :: Int)+          $ natValI @(seqLen - 1)+  x' <- dropoutForward tDropout train (x `add` positions)+  let attentionMask =+        unsqueeze @0+          . Torch.Typed.Tensor.toDType @D.Bool+          . triu 1+          $ ones @'[seqLen, seqLen] @D.Int8 @device+      attentionMask' =+        pure . maskedFill attentionMask (-1 / 0 :: Double) $+          zeros @'[batchSize, seqLen, seqLen] @dtype @device+  let keyPaddingMask = pure $ xTokens ==. (fromInteger . natVal $ Proxy @paddingIdx :: Tensor device 'D.Int64 '[])+  y <- hfoldrM (FoldLayers train attentionMask' keyPaddingMask) x' tLayers+  return $ forward tProj y++instance+  ( All KnownNat '[paddingIdx, embedDim, seqLen, batchSize],+    paddingIdx + 1 <= numEmbeds,+    1 <= seqLen,+    HFoldrM+      IO+      (FoldLayers batchSize seqLen dtype device)+      (Tensor device dtype '[batchSize, seqLen, embedDim])+      (HReplicateR numAttnLayers (TransformerLayer embedDim embedDim embedDim numHeads ffnDim dtype device))+      (Tensor device dtype '[batchSize, seqLen, embedDim]),+    BasicArithmeticDTypeIsValid device dtype,+    ComparisonDTypeIsValid device dtype,+    ComparisonDTypeIsValid device 'D.Int64,+    KnownDType dtype,+    KnownDevice device+  ) =>+  HasForward (TransformerLM numAttnLayers numHeads ffnDim paddingIdx numEmbeds embedDim dtype device) (Tensor device 'D.Int64 '[batchSize, seqLen]) (Tensor device dtype '[batchSize, seqLen, numEmbeds])+  where+  forward model input = unsafePerformIO $ transformerLM model False input+  forwardStoch model input = transformerLM model True input++sinusoidal ::+  forall numEmbeds embedDim device.+  ( All KnownNat '[numEmbeds, embedDim],+    1 <= numEmbeds,+    1 <= Div embedDim 2,+    (Div embedDim 2 * 2) ~ embedDim,+    StandardFloatingPointDTypeValidation device 'D.Float,+    BasicArithmeticDTypeIsValid device 'D.Float,+    KnownDevice device+  ) =>+  Tensor device 'D.Float '[numEmbeds, embedDim]+sinusoidal =+  let positions =+        unsqueeze @1+          . linspace @numEmbeds (0 :: Int)+          $ natValI @(numEmbeds - 1)+      scalingFactors =+        exp+          . mulScalar (- log (10000 :: Double) / (fromInteger . natVal $ Proxy @(Div embedDim 2)))+          . linspace @(Div embedDim 2) (0 :: Int)+          $ natValI @((Div embedDim 2) - 1)+      radians = mul positions scalingFactors+      weights = stack @2 (sin radians :. cos radians :. HNil)+   in reshape weights++instance+  ( paddingIdx <= numEmbeds,+    1 <= numEmbeds - paddingIdx,+    1 <= Div embedDim 2,+    (((numEmbeds - paddingIdx) - 1) + (1 + paddingIdx)) ~ numEmbeds,+    (Div embedDim 2 * 2) ~ embedDim,+    All KnownNat '[ffnDim, paddingIdx, numEmbeds, embedDim],+    HReplicate numAttnLayers (TransformerLayerSpec embedDim embedDim embedDim numHeads ffnDim dtype device),+    A.Randomizable+      (HList (HReplicateR numAttnLayers (TransformerLayerSpec embedDim embedDim embedDim numHeads ffnDim dtype device)))+      (HList (HReplicateR numAttnLayers (TransformerLayer embedDim embedDim embedDim numHeads ffnDim dtype device))),+    KnownDType dtype,+    RandDTypeIsValid device dtype,+    StandardFloatingPointDTypeValidation device 'D.Float,+    BasicArithmeticDTypeIsValid device 'D.Float,+    KnownDevice device+  ) =>+  A.Randomizable+    (TransformerLMSpec numAttnLayers numHeads ffnDim paddingIdx numEmbeds embedDim dtype device)+    (TransformerLM numAttnLayers numHeads ffnDim paddingIdx numEmbeds embedDim dtype device)+  where+  sample TransformerLMSpec {..} =+    TransformerLM+      <$> A.sample (LearnedEmbeddingWithRandomInitSpec @('Just paddingIdx))+      <*> A.sample (ConstEmbeddingSpec @'Nothing (Torch.Typed.Tensor.toDType sinusoidal))+      <*> A.sample lmDropoutSpec+      <*> A.sample (hreplicate @numAttnLayers lmLayerSpec)+      <*> A.sample LinearSpec
+ src/Torch/Typed/NamedTensor.hs view
@@ -0,0 +1,94 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE UndecidableSuperClasses #-}+{-# LANGUAGE NoStarIsType #-}++module Torch.Typed.NamedTensor where++import Data.Default.Class+import Data.Kind+import Data.Maybe (fromJust)+import Data.Vector.Sized (Vector)+import qualified Data.Vector.Sized as V+import GHC.Exts+import GHC.Generics+import GHC.TypeLits+import qualified Torch.DType as D+import qualified Torch.Device as D+import Torch.Lens+import qualified Torch.Tensor as D+import Torch.Typed.Factories+import Torch.Typed.Functional+import Torch.Typed.Tensor++class NamedTensorLike a where+  type ToNestedList a :: Type+  toNestedList :: a -> ToNestedList a+  asNamedTensor :: a -> NamedTensor '( 'D.CPU, 0) (ToDType a) (ToShape a)+  fromNestedList :: ToNestedList a -> a+  fromNamedTensor :: NamedTensor '( 'D.CPU, 0) (ToDType a) (ToShape a) -> a++instance NamedTensorLike Bool where+  type ToNestedList Bool = Bool+  toNestedList = id+  asNamedTensor = fromUnnamed . UnsafeMkTensor . D.asTensor+  fromNestedList = id+  fromNamedTensor = D.asValue . toDynamic++instance NamedTensorLike Int where+  type ToNestedList Int = Int+  toNestedList = id+  asNamedTensor = fromUnnamed . UnsafeMkTensor . D.asTensor+  fromNestedList = id+  fromNamedTensor = D.asValue . toDynamic++instance NamedTensorLike Float where+  type ToNestedList Float = Float+  toNestedList = id+  asNamedTensor = fromUnnamed . UnsafeMkTensor . D.asTensor+  fromNestedList = id+  fromNamedTensor = D.asValue . toDynamic++instance NamedTensorLike Double where+  type ToNestedList Double = Double+  toNestedList = id+  asNamedTensor = fromUnnamed . UnsafeMkTensor . D.asTensor+  fromNestedList = id+  fromNamedTensor = D.asValue . toDynamic++instance (KnownNat n, D.TensorLike (ToNestedList a), NamedTensorLike a) => NamedTensorLike (Vector n a) where+  type ToNestedList (Vector n a) = [ToNestedList a]+  toNestedList v = fmap toNestedList (V.toList v)+  asNamedTensor v = fromUnnamed . UnsafeMkTensor . D.asTensor $ toNestedList v+  fromNestedList = fmap fromNestedList . fromJust . V.fromList+  fromNamedTensor = fromNestedList . D.asValue . toDynamic++instance {-# OVERLAPS #-} (Coercible (vec n a) (Vector n a), KnownNat n, D.TensorLike (ToNestedList a), NamedTensorLike a) => NamedTensorLike (vec n a) where+  type ToNestedList (vec n a) = [ToNestedList a]+  toNestedList v = map (toNestedList @a) (V.toList (coerce v :: Vector n a))+  asNamedTensor v = fromUnnamed . UnsafeMkTensor . D.asTensor $ toNestedList v+  fromNestedList v = coerce (fmap fromNestedList . fromJust . V.fromList $ v :: Vector n a)+  fromNamedTensor = fromNestedList . D.asValue . toDynamic++instance {-# OVERLAPS #-} (Generic (g a), Default (g a), HasTypes (g a) a, KnownNat (ToNat g), D.TensorLike (ToNestedList a), NamedTensorLike a) => NamedTensorLike (g a) where+  type ToNestedList (g a) = [ToNestedList a]+  toNestedList v = map (toNestedList @a) (flattenValues (types @a) v)+  asNamedTensor v = fromUnnamed . UnsafeMkTensor . D.asTensor $ toNestedList v+  fromNestedList v = replaceValues (types @a) def (fmap fromNestedList v)+  fromNamedTensor = fromNestedList . D.asValue . toDynamic
+ src/Torch/Typed/Optim.hs view
@@ -0,0 +1,377 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE NoStarIsType #-}++module Torch.Typed.Optim where++import Control.Monad.State+import Data.Kind+import System.Mem (performGC)+import qualified Torch.DType as D+import qualified Torch.Device as D+import Torch.HList+import qualified Torch.Internal.Cast as ATen+import qualified Torch.Internal.Class as ATen+import Torch.Internal.GC (mallocTrim)+import qualified Torch.Tensor as D+import Torch.Typed.Autograd+import Torch.Typed.Auxiliary+import Torch.Typed.Factories+import Torch.Typed.Functional+import Torch.Typed.Parameter+import Torch.Typed.Tensor+import Prelude hiding (div, sqrt)++type LearningRate device dtype = Tensor device dtype '[]++type Loss device dtype = Tensor device dtype '[]++data ZerosLike = ZerosLike++instance+  ( parameter ~ Parameter device dtype shape,+    momentum ~ Tensor device dtype shape,+    TensorOptions shape dtype device+  ) =>+  Apply' ZerosLike parameter momentum+  where+  apply' _ _ = zeros++class Optimizer optim gradients tensors dtype device where+  step ::+    LearningRate device dtype ->+    HList gradients ->+    HList tensors ->+    optim ->+    (HList tensors, optim)++runStep ::+  forall model optim parameters gradients tensors dtype device.+  ( Parameterized model,+    parameters ~ Parameters model,+    HasGrad (HList parameters) (HList gradients),+    tensors ~ gradients,+    HMap' ToDependent parameters tensors,+    ATen.Castable (HList gradients) [D.ATenTensor],+    Optimizer optim gradients tensors dtype device,+    HMapM' IO MakeIndependent tensors parameters+  ) =>+  model ->+  optim ->+  Loss device dtype ->+  LearningRate device dtype ->+  IO (model, optim)+runStep model optim loss learningRate = do+  performGC+  mallocTrim 0+  let parameters = flattenParameters model+      gradients = grad loss parameters+      tensors = hmap' ToDependent parameters+      (tensors', optim') = step learningRate gradients tensors optim+  parameters' <- hmapM' MakeIndependent tensors'+  let model' = replaceParameters model parameters'+  return (model', optim')++runStep' ::+  forall model optim parameters gradients tensors dtype device.+  ( Parameterized model,+    parameters ~ Parameters model,+    tensors ~ gradients,+    HMap' ToDependent parameters tensors,+    Optimizer optim gradients tensors dtype device,+    HMapM' IO MakeIndependent tensors parameters+  ) =>+  model ->+  optim ->+  LearningRate device dtype ->+  HList gradients ->+  IO (model, optim)+runStep' model optim learningRate gradients = do+  performGC+  mallocTrim 0+  let parameters = flattenParameters model+      tensors = hmap' ToDependent parameters+      (tensors', optim') = step learningRate gradients tensors optim+  parameters' <- hmapM' MakeIndependent tensors'+  let model' = replaceParameters model parameters'+  return (model', optim')++--+-- Gradient Descent (GD)+--++-- | Dummy state representation for GD Optimizer+data GD = GD++mkGD :: GD+mkGD = GD++newtype GDStep device dtype = GDStep (LearningRate device dtype)++instance+  ( parameter ~ Tensor device dtype shape,+    gradient ~ Tensor device dtype shape,+    shape ~ Broadcast '[] shape,+    BasicArithmeticDTypeIsValid device dtype,+    KnownDevice device+  ) =>+  Apply' (GDStep device dtype) (parameter, gradient) parameter+  where+  apply' (GDStep learningRate) (parameter, gradient) =+    parameter - mul learningRate gradient++-- | Gradient descent step with a dummy state variable+gd ::+  forall gradients tensors dtype device.+  HZipWith (GDStep device dtype) tensors gradients tensors =>+  LearningRate device dtype ->+  HList gradients ->+  HList tensors ->+  GD ->+  (HList tensors, GD)+gd learningRate gradients parameters gd =+  let step = hzipWith (GDStep learningRate) parameters gradients in (step, gd)++instance+  ( HZipWith (GDStep device dtype) tensors gradients tensors+  ) =>+  Optimizer GD gradients tensors dtype device+  where+  step = gd++instance Parameterized GD where+  type Parameters GD = '[]+  flattenParameters _ = HNil+  replaceParameters = const++--+-- Gradient Descent with Momentum (GDM)+--++-- | State representation for GDM Optimizer+data GDM (momenta :: [Type]) = GDM+  { beta :: Float, -- moment forgetting factor+    momenta :: HList momenta -- momenta+  }++mkGDM ::+  forall parameters momenta.+  (HMap' ZerosLike parameters momenta) =>+  Float ->+  HList parameters ->+  GDM momenta+mkGDM beta parameters = GDM beta (hmap' ZerosLike parameters)++data GDMStep device dtype = GDMStep Float (LearningRate device dtype)++instance+  ( parameter ~ Tensor device dtype shape,+    gradient ~ Tensor device dtype shape,+    momentum ~ Tensor device dtype shape,+    shape ~ Broadcast '[] shape,+    KnownDevice device,+    BasicArithmeticDTypeIsValid device dtype+  ) =>+  Apply' (GDMStep device dtype) (parameter, gradient, momentum) (parameter, momentum)+  where+  apply' (GDMStep beta learningRate) (parameter, gradient, momentum) =+    let momentum' = mulScalar beta momentum + gradient+        parameter' = parameter - mul learningRate momentum'+     in (parameter', momentum')++-- | gradient descent with momentum step+gdm ::+  forall gradients tensors momenta gdmStep dtype device.+  ( HZipWith3 (GDMStep device dtype) tensors gradients momenta gdmStep,+    HMap' AFst gdmStep tensors,+    HMap' ASnd gdmStep momenta+  ) =>+  -- | learning rate+  LearningRate device dtype ->+  -- | model parameter gradient tensors+  HList gradients ->+  -- | model parameter tensors+  HList tensors ->+  -- | beta and model parameter momentum tensors+  GDM momenta ->+  -- | returns updated parameters and momenta+  (HList tensors, GDM momenta)+gdm learningRate gradients parameters (GDM beta momenta) =+  let step = hzipWith3 (GDMStep beta learningRate) parameters gradients momenta+   in (hmap' AFst step, GDM beta (hmap' ASnd step))++instance+  ( HZipWith3 (GDMStep device dtype) tensors gradients momenta gdmStep,+    HMap' AFst gdmStep tensors,+    HMap' ASnd gdmStep momenta+  ) =>+  Optimizer (GDM momenta) gradients tensors dtype device+  where+  step = gdm++instance Parameterized (GDM momenta) where+  type Parameters (GDM momenta) = momenta+  flattenParameters GDM {..} = momenta+  replaceParameters gdm momenta = gdm {momenta = momenta}++--+-- Adam+-- https://arxiv.org/pdf/1412.6980.pdf+--++type AdamIter = Tensor '( 'D.CPU, 0) 'D.Int64 '[]++-- | State representation for Adam Optimizer+data Adam (momenta :: [Type]) = Adam+  { iter :: AdamIter, -- iteration+    beta1 :: Float, -- 1st moment forgetting factor+    beta2 :: Float, -- 2nd moment forgetting factor+    momenta1 :: HList momenta, -- 1st momenta+    momenta2 :: HList momenta -- 2nd momenta+  }++mkAdam ::+  forall parameters momenta.+  (HMap' ZerosLike parameters momenta) =>+  AdamIter ->+  Float ->+  Float ->+  HList parameters ->+  Adam momenta+mkAdam iter beta1 beta2 parameters =+  Adam+    iter+    beta1+    beta2+    (hmap' ZerosLike parameters)+    (hmap' ZerosLike parameters)++newtype AdamMomentum1Update = AdamMomentum1Update Float++-- | decaying average of the first momenta+instance+  ( gradient ~ Tensor device dtype shape,+    momentum1 ~ Tensor device dtype shape,+    KnownDevice device+  ) =>+  Apply' AdamMomentum1Update (momentum1, gradient) momentum1+  where+  apply' (AdamMomentum1Update beta1) (momentum1, gradient) =+    mulScalar beta1 momentum1 + mulScalar (1 - beta1) gradient++newtype AdamMomentum2Update = AdamMomentum2Update Float++-- | decaying average of the second momenta+instance+  ( gradient ~ Tensor device dtype shape,+    momentum2 ~ Tensor device dtype shape,+    shape ~ Broadcast shape shape,+    KnownDevice device,+    BasicArithmeticDTypeIsValid device dtype+  ) =>+  Apply' AdamMomentum2Update (momentum2, gradient) momentum2+  where+  apply' (AdamMomentum2Update beta2) (momentum2, gradient) =+    mulScalar beta2 momentum2 + mulScalar (1 - beta2) (mul gradient gradient)++data AdamBiasAdjustment = AdamBiasAdjustment AdamIter Float++-- | bias adjustment+instance+  ( momentum ~ Tensor device dtype shape,+    KnownDevice device,+    KnownDType dtype,+    shape ~ Reverse (Reverse shape),+    BasicArithmeticDTypeIsValid device dtype+  ) =>+  Apply' AdamBiasAdjustment momentum momentum+  where+  apply' (AdamBiasAdjustment iter beta) momentum =+    let iter' = toDevice @device @'( 'D.CPU, 0) . toDType @dtype @'D.Int64 $ iter + 1+        beta' = full @'[] @dtype @device beta+     in momentum `div` (1 - pow iter' beta')++data AdamParameterUpdate device dtype = AdamParameterUpdate Float (LearningRate device dtype)++-- | parameter update+instance+  ( parameter ~ Tensor device dtype shape,+    momentum ~ Tensor device dtype shape,+    shape ~ Broadcast '[] shape,+    KnownDevice device,+    BasicArithmeticDTypeIsValid device dtype,+    StandardFloatingPointDTypeValidation device dtype+  ) =>+  Apply'+    (AdamParameterUpdate device dtype)+    (parameter, momentum, momentum)+    parameter+  where+  apply'+    (AdamParameterUpdate eps learningRate)+    (parameter, biasAdjustedMomentum1, biasAdjustedMomentum2) =+      parameter - mul learningRate biasAdjustedMomentum1+        / addScalar eps (sqrt biasAdjustedMomentum2)++-- | Adam step+adam ::+  forall gradients tensors momenta adamStep dtype device.+  ( HZipWith AdamMomentum1Update momenta gradients momenta,+    HZipWith AdamMomentum2Update momenta gradients momenta,+    HMap' AdamBiasAdjustment momenta momenta,+    HZipWith3 (AdamParameterUpdate device dtype) tensors momenta momenta tensors+  ) =>+  -- | learning rate+  LearningRate device dtype ->+  -- | model parameter gradient tensors+  HList gradients ->+  -- | model parameter tensors+  HList tensors ->+  -- | adam parameters - beta1, beta2, momenta1, momenta2, iteration+  Adam momenta ->+  -- | returns new parameters + updated adam parameters+  (HList tensors, Adam momenta)+adam learningRate gradients parameters Adam {..} =+  (parameters', Adam (iter + 1) beta1 beta2 momenta1' momenta2')+  where+    momenta1' = hzipWith (AdamMomentum1Update beta1) momenta1 gradients+    momenta2' = hzipWith (AdamMomentum2Update beta2) momenta2 gradients+    biasAdjustedMomenta1 = hmap' (AdamBiasAdjustment iter beta1) momenta1'+    biasAdjustedMomenta2 = hmap' (AdamBiasAdjustment iter beta2) momenta2'+    parameters' =+      hzipWith3+        (AdamParameterUpdate 1e-37 learningRate)+        parameters+        biasAdjustedMomenta1+        biasAdjustedMomenta2++instance+  ( HZipWith AdamMomentum1Update momenta gradients momenta,+    HZipWith AdamMomentum2Update momenta gradients momenta,+    HMap' AdamBiasAdjustment momenta momenta,+    HZipWith3 (AdamParameterUpdate device dtype) tensors momenta momenta tensors+  ) =>+  Optimizer (Adam momenta) gradients tensors dtype device+  where+  step = adam++instance+  HAppendFD momenta momenta (momenta ++ momenta) =>+  Parameterized (Adam momenta)+  where+  type Parameters (Adam momenta) = AdamIter ': (momenta ++ momenta)+  flattenParameters Adam {..} = iter :. (momenta1 `happendFD` momenta2)+  replaceParameters adam (iter :. momenta) =+    let (momenta1, momenta2) = hunappendFD momenta+     in adam {iter = iter, momenta1 = momenta1, momenta2 = momenta2}
+ src/Torch/Typed/Optim/CppOptim.hs view
@@ -0,0 +1,158 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PartialTypeSignatures #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-}++module Torch.Typed.Optim.CppOptim+  ( module Torch.Typed.Optim.CppOptim,+    AdagradOptions (..),+    AdamOptions (..),+    AdamwOptions (..),+    LbfgsOptions (..),+    RmspropOptions (..),+    SGDOptions (..),+  )+where++import Data.Default.Class+import Data.Foldable (for_)+import Data.Kind (Type)+import qualified Debug.Trace as Debug+import Foreign.ForeignPtr+import System.Mem (performGC)+import qualified Torch as TD+import Torch.HList+import Torch.Internal.Cast+import Torch.Internal.Class (Castable (..), CppObject (..), CppTuple2 (..), CppTuple3 (..), CppTuple4 (..))+import Torch.Internal.GC (mallocTrim)+import qualified Torch.Internal.Managed.Optim as LibTorch+import qualified Torch.Internal.Type as ATen+import Torch.Optim.CppOptim+  ( AdagradOptions (..),+    AdamOptions (..),+    AdamwOptions (..),+    LbfgsOptions (..),+    RmspropOptions (..),+    SGDOptions (..),+  )+import Torch.Typed.Autograd+import Torch.Typed.NN+import qualified Torch.Typed.Optim as Optim+import Torch.Typed.Parameter+import Torch.Typed.Tensor++type CppOptimizerRef = ForeignPtr ATen.Optimizer++data CppOptimizerState option (params :: [Type])+  = CppOptimizerState option CppOptimizerRef++data ToParameter = ToParameter++instance Apply' ToParameter (Tensor dev dtype shape) (Parameter dev dtype shape) where+  apply' _ (UnsafeMkTensor tensor) = UnsafeMkParameter . TD.IndependentTensor $ tensor++class CppOptimizer option where+  initOptimizer ::+    forall model tensors.+    ( Parameterized model,+      HMap' ToDependent (Parameters model) tensors,+      Castable (HList tensors) [TD.ATenTensor]+    ) =>+    option ->+    model ->+    IO (CppOptimizerState option (Parameters model))++  unsafeStep ::+    forall model dev dtype lossShape tensors res.+    ( Parameterized model,+      HMap' ToDependent (Parameters model) tensors,+      HMap' ToParameter tensors (Parameters model),+      Castable (HList tensors) [TD.ATenTensor]+    ) =>+    model ->+    CppOptimizerState option (Parameters model) ->+    Tensor dev dtype lossShape ->+    IO (model, CppOptimizerState option (Parameters model))+  unsafeStep model o@(CppOptimizerState _ optimizer) loss = do+    -- let deps :: HList tensors+    --    deps = hmap' ToDependent $ flattenParameters model++    -- Debug.traceIO $ "Tensors in: "+    -- cast deps (Debug.traceIO . show . map (TD.shape . TD.Unsafe))+    v :: [TD.ATenTensor] <- cast2 LibTorch.unsafeStep optimizer loss+    -- Debug.traceIO $ "Params returned by unsafeStep: "<>show (length v)++    newParamTensors :: HList tensors <- uncast v pure+    -- Debug.traceIO $ "Tensors out: "+    -- cast newParamTensors (Debug.traceIO . show . map (TD.shape . TD.Unsafe))+    let newParams = hmap' ToParameter newParamTensors+    let newModel = replaceParameters model newParams+    return (newModel, o)++instance CppOptimizer AdamOptions where+  initOptimizer opt@AdamOptions {..} model = do+    v <-+      cast7+        LibTorch.adam+        adamLr+        (fst adamBetas)+        (snd adamBetas)+        adamEps+        adamWeightDecay+        adamAmsgrad+        initParams'+    return $ CppOptimizerState opt v+    where+      initParams' = hmap' ToDependent $ flattenParameters model++instance CppOptimizer AdamwOptions where+  initOptimizer opt@AdamwOptions {..} model = do+    v <- cast7 LibTorch.adamw adamwLr (fst adamwBetas) (snd adamwBetas) adamwEps adamwWeightDecay adamwAmsgrad initParams'+    return $ CppOptimizerState opt v+    where+      initParams' = hmap' ToDependent $ flattenParameters model++instance CppOptimizer LbfgsOptions where+  initOptimizer opt@LbfgsOptions {..} model = do+    v <- cast8 LibTorch.lbfgs lbfgsLr lbfgsMaxIter lbfgsMaxEval lbfgsToleranceGrad lbfgsToleranceChange lbfgsHistorySize lbfgsLineSearchFn initParams'+    return $ CppOptimizerState opt v+    where+      initParams' = hmap' ToDependent $ flattenParameters model++instance CppOptimizer RmspropOptions where+  initOptimizer opt@RmspropOptions {..} model = do+    v <- cast7 LibTorch.rmsprop rmspropLr rmspropAlpha rmspropEps rmspropWeightDecay rmspropMomentum rmspropCentered initParams'+    return $ CppOptimizerState opt v+    where+      initParams' = hmap' ToDependent $ flattenParameters model++instance CppOptimizer SGDOptions where+  initOptimizer opt@SGDOptions {..} model = do+    v <- cast6 LibTorch.sgd sgdLr sgdMomentum sgdDampening sgdWeightDecay sgdNesterov initParams'+    return $ CppOptimizerState opt v+    where+      initParams' = hmap' ToDependent $ flattenParameters model++runStep ::+  ( CppOptimizer option,+    Parameterized model,+    HMap' ToDependent (Parameters model) tensors,+    HMap' ToParameter tensors (Parameters model),+    Castable (HList tensors) [TD.ATenTensor]+  ) =>+  model ->+  CppOptimizerState option (Parameters model) ->+  Optim.Loss dev dtype ->+  IO (model, CppOptimizerState option (Parameters model))+runStep model optim loss = do+  performGC+  mallocTrim 0+  unsafeStep model optim loss
+ src/Torch/Typed/Parameter.hs view
@@ -0,0 +1,219 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PartialTypeSignatures #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}++module Torch.Typed.Parameter+  ( module Torch.Typed.Parameter,+    Torch.NN.Randomizable (..),+  )+where++import Control.Monad.State.Strict+import Data.Kind (Type)+import GHC.Generics+import GHC.TypeLits+import GHC.TypeLits.Extra+import qualified Torch.Autograd (IndependentTensor (..), makeIndependent)+import Torch.DType (DType)+import Torch.Device (DeviceType)+import Torch.HList+import qualified Torch.NN (Parameter, Randomizable (..), sample)+import qualified Torch.Tensor (toType, _toDevice)+import Torch.Typed.Auxiliary+import Torch.Typed.Factories+import Torch.Typed.Functional+import Torch.Typed.Tensor++newtype+  Parameter+    (device :: (DeviceType, Nat))+    (dtype :: DType)+    (shape :: [Nat])+  = UnsafeMkParameter Torch.Autograd.IndependentTensor+  deriving (Show)++untypeParam :: Parameter device dtype shape -> Torch.NN.Parameter+untypeParam (UnsafeMkParameter param) = param++toDependent ::+  forall shape dtype device.+  Parameter device dtype shape ->+  Tensor device dtype shape+toDependent (UnsafeMkParameter t) = UnsafeMkTensor $ Torch.Autograd.toDependent t++data ToDependent = ToDependent++instance Apply' ToDependent (Parameter device dtype shape) (Tensor device dtype shape) where+  apply' _ = toDependent++makeIndependent ::+  forall shape dtype device.+  Tensor device dtype shape ->+  IO (Parameter device dtype shape)+makeIndependent t = UnsafeMkParameter <$> Torch.Autograd.makeIndependent (toDynamic t)++data MakeIndependent = MakeIndependent++instance+  Apply'+    MakeIndependent+    (Tensor device dtype shape)+    (IO (Parameter device dtype shape))+  where+  apply' _ = makeIndependent++parameterToDevice ::+  forall device' device dtype shape.+  KnownDevice device' =>+  Parameter device dtype shape ->+  Parameter device' dtype shape+parameterToDevice (UnsafeMkParameter t) =+  UnsafeMkParameter+    . Torch.Autograd.IndependentTensor+    . Torch.Tensor._toDevice (deviceVal @device')+    . Torch.Autograd.toDependent+    $ t++parameterToDType ::+  forall dtype' dtype device shape.+  KnownDType dtype' =>+  Parameter device dtype shape ->+  Parameter device dtype' shape+parameterToDType (UnsafeMkParameter t) =+  UnsafeMkParameter+    . Torch.Autograd.IndependentTensor+    . Torch.Tensor.toType (dtypeVal @dtype')+    . Torch.Autograd.toDependent+    $ t++class Parameterized (f :: Type) where+  type Parameters f :: [Type]+  type Parameters f = GParameters (Rep f)+  flattenParameters :: f -> HList (Parameters f)+  default flattenParameters ::+    (Generic f, GParameterized (Rep f), Parameters f ~ GParameters (Rep f)) =>+    f ->+    HList (Parameters f)+  flattenParameters f = gFlattenParameters (from f)+  replaceParameters :: f -> HList (Parameters f) -> f+  default replaceParameters ::+    (Generic f, GParameterized (Rep f), Parameters f ~ GParameters (Rep f)) =>+    f ->+    HList (Parameters f) ->+    f+  replaceParameters f as = to (gReplaceParameters (from f) as)++class GParameterized (f :: Type -> Type) where+  type GParameters f :: [Type]+  gFlattenParameters :: forall a. f a -> HList (GParameters f)+  gReplaceParameters :: forall a. f a -> HList (GParameters f) -> f a++instance+  ( GParameterized l,+    GParameterized r,+    HAppendFD (GParameters l) (GParameters r) (GParameters l ++ GParameters r)+  ) =>+  GParameterized (l :*: r)+  where+  type GParameters (l :*: r) = (GParameters l) ++ (GParameters r)+  gFlattenParameters (l :*: r) =+    let as = gFlattenParameters l+        bs = gFlattenParameters r+     in as `happendFD` bs+  gReplaceParameters (l :*: r) cs =+    let (as, bs) = hunappendFD cs+        l' = gReplaceParameters l as+        r' = gReplaceParameters r bs+     in l' :*: r'++instance+  Parameterized f =>+  GParameterized (K1 i f)+  where+  type GParameters (K1 i f) = Parameters f+  gFlattenParameters = flattenParameters . unK1+  gReplaceParameters (K1 f) = K1 . replaceParameters f++instance GParameterized f => GParameterized (M1 i t f) where+  type GParameters (M1 i t f) = GParameters f+  gFlattenParameters = gFlattenParameters . unM1+  gReplaceParameters (M1 f) = M1 . gReplaceParameters f++instance GParameterized U1 where+  type GParameters U1 = '[]+  gFlattenParameters _ = HNil+  gReplaceParameters = const++instance Parameterized (Tensor device dtype shape) where+  type Parameters (Tensor device dtype shape) = '[]+  flattenParameters _ = HNil+  replaceParameters = const++instance Parameterized (Parameter device dtype shape) where+  type Parameters (Parameter device dtype shape) = '[Parameter device dtype shape]+  flattenParameters = (:. HNil)+  replaceParameters _ (parameter :. HNil) = parameter++instance Parameterized Int where+  type Parameters Int = '[]+  flattenParameters _ = HNil+  replaceParameters = const++instance Parameterized Float where+  type Parameters Float = '[]+  flattenParameters _ = HNil+  replaceParameters = const++instance Parameterized Double where+  type Parameters Double = '[]+  flattenParameters _ = HNil+  replaceParameters = const++instance Parameterized (HList '[]) where+  type Parameters (HList '[]) = '[]+  flattenParameters _ = HNil+  replaceParameters = const++instance+  ( Parameterized f,+    Parameterized (HList fs),+    HAppendFD (Parameters f) (Parameters (HList fs)) (Parameters f ++ Parameters (HList fs))+  ) =>+  Parameterized (HList (f ': fs))+  where+  type Parameters (HList (f ': fs)) = Parameters f ++ Parameters (HList fs)+  flattenParameters (f :. fs) = flattenParameters f `happendFD` flattenParameters fs+  replaceParameters (f :. fs) cs =+    let (as, bs) = hunappendFD cs+        f' = replaceParameters f as+        fs' = replaceParameters fs bs+     in f' :. fs'++instance Torch.NN.Randomizable (HList ('[] :: [Type])) (HList ('[] :: [Type])) where+  sample = return++instance+  ( Torch.NN.Randomizable xSpec x,+    Torch.NN.Randomizable (HList xsSpec) (HList xs)+  ) =>+  Torch.NN.Randomizable (HList (xSpec ': xsSpec)) (HList (x ': xs))+  where+  sample (xSpec :. xsSpec) = do+    x <- Torch.NN.sample xSpec+    xs <- Torch.NN.sample xsSpec+    return $ x :. xs
+ src/Torch/Typed/Serialize.hs view
@@ -0,0 +1,92 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}++module Torch.Typed.Serialize where++import Torch.HList+import qualified Torch.Internal.Cast as ATen+import qualified Torch.Internal.Class as ATen+import qualified Torch.Internal.Managed.Serialize as S+import qualified Torch.Internal.Type as ATen+import qualified Torch.Tensor as D+import Torch.Typed.Tensor+import Torch.Typed.Parameter+import Torch.Typed.NN+import Torch.Typed.Autograd++-- | save list of tensors to file+save ::+  forall tensors.+  ATen.Castable (HList tensors) [D.ATenTensor] =>+  -- | list of input tensors+  HList tensors ->+  -- | file+  FilePath ->+  IO ()+save = ATen.cast2 S.save++-- | load list of tensors from file+load ::+  forall tensors.+  ATen.Castable (HList tensors) [D.ATenTensor] =>+  -- | file+  FilePath ->+  IO (HList tensors)+load = ATen.cast1 S.load++saveParameters ::+  forall model parameters tensors dtype device.+  ( Parameterized model,+    parameters ~ Parameters model,+    HMap' ToDependent parameters tensors,+    HMapM' IO MakeIndependent tensors parameters,+    HFoldrM IO TensorListFold [D.ATenTensor] tensors [D.ATenTensor],+    Apply TensorListUnfold [D.ATenTensor] (HUnfoldMRes IO [D.ATenTensor] tensors),+    HUnfoldM IO TensorListUnfold (HUnfoldMRes IO [D.ATenTensor] tensors) tensors+  ) =>+  model ->+  FilePath ->+  IO ()+saveParameters model filePath = save (hmap' ToDependent . flattenParameters $ model) filePath++loadParameters ::+  forall model parameters tensors dtype device.+  ( Parameterized model,+    parameters ~ Parameters model,+    HMap' ToDependent parameters tensors,+    HMapM' IO MakeIndependent tensors parameters,+    HFoldrM IO TensorListFold [D.ATenTensor] tensors [D.ATenTensor],+    Apply TensorListUnfold [D.ATenTensor] (HUnfoldMRes IO [D.ATenTensor] tensors),+    HUnfoldM IO TensorListUnfold (HUnfoldMRes IO [D.ATenTensor] tensors) tensors+  ) =>+  model ->+  FilePath ->+  IO model+loadParameters model filePath = do+  tensors <- load @tensors filePath+  params <- hmapM' MakeIndependent tensors+  pure $ replaceParameters model params++loadParametersWithSpec ::+  forall spec model parameters tensors dtype device.+  ( Randomizable spec model,+    Parameterized model,+    parameters ~ Parameters model,+    HMap' ToDependent parameters tensors,+    HMapM' IO MakeIndependent tensors parameters,+    HFoldrM IO TensorListFold [D.ATenTensor] tensors [D.ATenTensor],+    Apply TensorListUnfold [D.ATenTensor] (HUnfoldMRes IO [D.ATenTensor] tensors),+    HUnfoldM IO TensorListUnfold (HUnfoldMRes IO [D.ATenTensor] tensors) tensors+  ) =>+  spec ->+  FilePath ->+  IO model+loadParametersWithSpec spec filePath = do+  model <- sample spec+  tensors <- load @tensors filePath+  params <- hmapM' MakeIndependent tensors+  pure $ replaceParameters model params
+ src/Torch/Typed/Tensor.hs view
@@ -0,0 +1,861 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE UndecidableSuperClasses #-}+{-# LANGUAGE NoStarIsType #-}++module Torch.Typed.Tensor where++import Control.Arrow+import Control.Category+import qualified Numeric.Half as N+import Data.Complex+import Data.Finite+import Data.Kind+  ( Constraint,+    Type,+  )+import Data.Maybe+import Data.Proxy+import Data.Reflection+import Data.Vector.Sized (Vector)+import qualified Data.Vector.Sized as V+import Foreign.ForeignPtr+import Foreign.Storable+import GHC.Exts+import GHC.Generics+import GHC.TypeLits+import qualified Torch.DType as D+import qualified Torch.Device as D+import qualified Torch.Functional as D hiding (select)+import Torch.HList+import Torch.Internal.Cast+import Torch.Internal.Class+  ( Castable (..),+    CppTuple2 (..),+    CppTuple3 (..),+    CppTuple4 (..),+  )+import qualified Torch.Internal.Type as ATen+import qualified Torch.Tensor as D+import qualified Torch.TensorFactories as D+import Torch.Typed.Auxiliary+import Prelude hiding (id, (.))++class KnownShape (shape :: [Nat]) where+  shapeVal :: [Int]++instance KnownShape '[] where+  shapeVal = []++instance (KnownNat h, KnownShape t) => KnownShape (h ': t) where+  shapeVal = natValI @h : shapeVal @t++getFiniteI :: Finite n -> Int+getFiniteI = fromIntegral . getFinite++class KnownDType (dtype :: D.DType) where+  dtypeVal :: D.DType++instance KnownDType 'D.Bool where+  dtypeVal = D.Bool++instance KnownDType 'D.UInt8 where+  dtypeVal = D.UInt8++instance KnownDType 'D.Int8 where+  dtypeVal = D.Int8++instance KnownDType 'D.Int16 where+  dtypeVal = D.Int16++instance KnownDType 'D.Int32 where+  dtypeVal = D.Int32++instance KnownDType 'D.Int64 where+  dtypeVal = D.Int64++instance KnownDType 'D.Half where+  dtypeVal = D.Half++instance KnownDType 'D.BFloat16 where+  dtypeVal = D.BFloat16++instance KnownDType 'D.Float where+  dtypeVal = D.Float++instance KnownDType 'D.Double where+  dtypeVal = D.Double++instance KnownDType 'D.ComplexHalf where+  dtypeVal = D.ComplexHalf++instance KnownDType 'D.ComplexFloat where+  dtypeVal = D.ComplexFloat++instance KnownDType 'D.ComplexDouble where+  dtypeVal = D.ComplexDouble++type family ComputeDType (dtype' :: dtype) :: D.DType where+  ComputeDType Bool = D.Bool+  ComputeDType D.Bool = D.Bool+  ComputeDType D.UInt8 = D.UInt8+  ComputeDType D.Int8 = D.Int8+  ComputeDType D.Int16 = D.Int16+  ComputeDType D.Int32 = D.Int32+  ComputeDType Int = D.Int64+  ComputeDType D.Int64 = D.Int64+  ComputeDType N.Half = D.Half+  ComputeDType D.Half = D.Half+  ComputeDType Float = D.Float+  ComputeDType D.Float = D.Float+  ComputeDType Double = D.Double+  ComputeDType D.Double = D.Double+  ComputeDType (Complex N.Half) = D.ComplexHalf+  ComputeDType D.ComplexHalf = D.ComplexHalf+  ComputeDType (Complex Float) = D.ComplexFloat+  ComputeDType D.ComplexFloat = D.ComplexFloat+  ComputeDType (Complex Double) = D.ComplexDouble+  ComputeDType D.ComplexDouble = D.ComplexDouble+  ComputeDType dtype' = TypeError (Text "Unsupported tensor type " :<>: ShowType dtype')++class KnownDevice (device :: (D.DeviceType, Nat)) where+  deviceVal :: D.Device++instance (KnownNat n) => KnownDevice '( 'D.CPU, n) where+  deviceVal = D.Device D.CPU (natValInt16 @n)++instance (KnownNat n) => KnownDevice '( 'D.CUDA, n) where+  deviceVal = D.Device D.CUDA (natValInt16 @n)++instance (KnownNat n) => KnownDevice '( 'D.MPS, n) where+  deviceVal = D.Device D.MPS (natValInt16 @n)++type Size = Type -> Type++type Shape = [Type -> Type]++type family ToNat (shape :: Size) :: Nat where+  ToNat (S1 ('MetaSel _ _ _ _) f) = ToNat f+  ToNat (D1 _ f) = ToNat f+  ToNat (C1 _ f) = ToNat f+  ToNat (l :*: r) = ToNat l + ToNat r+  ToNat (l :+: r) = If (ToNat l <=? ToNat r) (ToNat r) (ToNat l)+  ToNat (K1 R (Vector n _)) = n+  ToNat (K1 _ _) = 1+  ToNat U1 = 1+  ToNat (Vector n) = n+  ToNat a = ToNat (Rep (a ()))++type family ToNats (shape :: Shape) :: [Nat] where+  ToNats '[] = '[]+  ToNats (x ': xs) = ToNat x ': ToNats xs++type family FromNat (shape :: Nat) :: Size where+  FromNat n = Vector n++type family FromNats (shape :: [Nat]) :: Shape where+  FromNats '[] = '[]+  FromNats (x ': xs) = FromNat x ': FromNats xs++class Unnamed t where+  type UTShape t :: [Nat]+  type UTDevice t :: (D.DeviceType, Nat)+  type UTDType t :: D.DType+  toUnnamed ::+    forall device dtype shape.+    IsUnnamed t device dtype shape =>+    t ->+    Tensor device dtype shape+  fromUnnamed ::+    forall device dtype shape.+    IsUnnamed t device dtype shape =>+    Tensor device dtype shape ->+    t+  toDynamic ::+    t -> D.Tensor++type family IsUnnamed t (device :: (D.DeviceType, Nat)) (dtype :: D.DType) (shape :: [Nat]) :: Constraint where+  IsUnnamed t device dtype shape =+    ( Unnamed t,+      device ~ (UTDevice t),+      dtype ~ (UTDType t),+      shape ~ (UTShape t)+    )++instance Unnamed (Tensor device dtype shape) where+  type UTShape (Tensor device dtype shape) = shape+  type UTDevice (Tensor device dtype shape) = device+  type UTDType (Tensor device dtype shape) = dtype+  toUnnamed = id+  fromUnnamed = id+  toDynamic (UnsafeMkTensor t) = t++data Tensor (device :: (D.DeviceType, Nat)) (dtype :: D.DType) (shape :: [Nat]) where+  UnsafeMkTensor :: forall device dtype shape. D.Tensor -> Tensor device dtype shape++type CPUTensor = Tensor '( 'D.CPU, 0)++type CUDATensor deviceIndex = Tensor '( 'D.CUDA, deviceIndex)++type MPSTensor deviceIndex = Tensor '( 'D.MPS, 0)++data UnknownShapeTensor device dtype = forall shape. UnknownShapeTensor (Tensor device dtype shape)++type family ComputeHaskellType (dtype :: D.DType) :: Type where+  ComputeHaskellType D.Bool = Bool+  ComputeHaskellType D.Int64 = Int+  ComputeHaskellType D.Float = Float+  ComputeHaskellType D.Double = Double+  ComputeHaskellType dtype = TypeError (Text "Unsupported tensor type " :<>: ShowType dtype)++type family ComputeItemType (ty :: Type) (shape :: [Nat]) :: Type where+  ComputeItemType _ '[] = TypeError (Text "Scalars are not supported")+  ComputeItemType ty (_ ': '[]) = ty+  ComputeItemType ty (_ ': h ': t) = [ComputeItemType ty (h ': t)]++instance+  ( D.TensorLike [ComputeItemType (ComputeHaskellType dtype) shape],+    KnownDevice device,+    KnownShape shape+  ) =>+  IsList (Maybe (Tensor device dtype shape))+  where+  type Item (Maybe (Tensor device dtype shape)) = ComputeItemType (ComputeHaskellType dtype) shape+  fromList xs = do+    shapeXs <- D._deepDims xs+    if shapeVal @shape == shapeXs+      then return $ UnsafeMkTensor . D.toDevice (deviceVal @device) . D.asTensor $ xs+      else Nothing+  toList Nothing = []+  toList (Just t) = D.asValue . D.toDevice (D.Device D.CPU 0) . toDynamic $ t++instance KnownDevice device => Num (Tensor device dtype shape) where+  (+) a b = UnsafeMkTensor $ toDynamic a + toDynamic b+  (-) a b = UnsafeMkTensor $ toDynamic a - toDynamic b+  (*) a b = UnsafeMkTensor $ toDynamic a * toDynamic b+  negate t = UnsafeMkTensor $ negate $ toDynamic t+  abs t = UnsafeMkTensor $ abs $ toDynamic t+  signum t = UnsafeMkTensor $ signum $ toDynamic t+  fromInteger i = UnsafeMkTensor . D.toDevice (deviceVal @device) . D.asTensor @Int $ fromInteger @Int i++instance KnownDevice device => Fractional (Tensor device dtype shape) where+  a / b = UnsafeMkTensor $ toDynamic a / toDynamic b+  recip t = UnsafeMkTensor $ recip $ toDynamic t+  fromRational i = UnsafeMkTensor . D.toDevice (deviceVal @device) . D.asTensor @Float $ fromRational @Float i++instance Show (Tensor device dtype shape) where+  show (UnsafeMkTensor dynamic) = show dynamic++class TensorOptions (shape :: [Nat]) (dtype :: D.DType) (device :: (D.DeviceType, Nat)) where+  optionsRuntimeShape :: [Int]+  optionsRuntimeDType :: D.DType+  optionsRuntimeDevice :: D.Device++instance (KnownDType dtype, KnownDevice device) => TensorOptions '[] dtype device where+  optionsRuntimeShape = []+  optionsRuntimeDType = dtypeVal @dtype+  optionsRuntimeDevice = deviceVal @device++instance (KnownNat h, TensorOptions t dtype device) => TensorOptions (h ': t) dtype device where+  optionsRuntimeShape = natValI @h : optionsRuntimeShape @t @dtype @device+  optionsRuntimeDType = optionsRuntimeDType @t @dtype @device+  optionsRuntimeDevice = optionsRuntimeDevice @t @dtype @device++--------------------------------------------------------------------------------+-- Untyped -> Typed typecasts+--------------------------------------------------------------------------------++type family All (pred :: a -> Constraint) (l :: [a]) :: Constraint where+  All _ '[] = ()+  All pred (h ': t) = (pred h, All pred t)++data SomeShape where+  SomeShape :: forall (shape :: [Nat]). KnownShape shape => Proxy shape -> SomeShape++someShape :: [Int] -> SomeShape+someShape [] = SomeShape $ Proxy @'[]+someShape (h : t) = case someNatVal (fromIntegral h) of+  Nothing -> error "Negative dimension in someShape!"+  (Just (SomeNat (Proxy :: Proxy ht))) -> case someShape t of+    (SomeShape (Proxy :: Proxy tt)) -> SomeShape $ Proxy @(ht ': tt)++data SomeDType where+  SomeDType :: forall (dtype :: D.DType). KnownDType dtype => Proxy dtype -> SomeDType++someDType :: D.DType -> SomeDType+someDType D.Bool = SomeDType $ Proxy @D.Bool+someDType D.UInt8 = SomeDType $ Proxy @D.UInt8+someDType D.Int8 = SomeDType $ Proxy @D.Int8+someDType D.Int16 = SomeDType $ Proxy @D.Int16+someDType D.Int32 = SomeDType $ Proxy @D.Int32+someDType D.Int64 = SomeDType $ Proxy @D.Int64+someDType D.Half = SomeDType $ Proxy @D.Half+someDType D.Float = SomeDType $ Proxy @D.Float+someDType D.Double = SomeDType $ Proxy @D.Double++data SomeDevice where+  SomeDevice :: forall (device :: (D.DeviceType, Nat)). KnownDevice device => Proxy device -> SomeDevice++someDevice :: D.Device -> SomeDevice+someDevice D.Device {..} = case someNatVal (fromIntegral deviceIndex) of+  Nothing -> error "Negative device index in someDevice!"+  Just (SomeNat (Proxy :: Proxy n)) -> case deviceType of+    D.CPU -> SomeDevice $ Proxy @'( 'D.CPU, n)+    D.CUDA -> SomeDevice $ Proxy @'( 'D.CUDA, n)+    D.MPS -> SomeDevice $ Proxy @'( 'D.MPS, n)++withTensor ::+  D.Tensor ->+  ( forall shape dtype device.+    ( KnownDevice device,+      KnownDType dtype,+      KnownShape shape+    ) =>+    Tensor device dtype shape ->+    r+  ) ->+  r+withTensor untypedTensor f = case someShape (D.shape untypedTensor) of+  (SomeShape (Proxy :: Proxy shape)) -> case someDType (D.dtype untypedTensor) of+    (SomeDType (Proxy :: Proxy dtype)) -> case someDevice (D.device untypedTensor) of+      (SomeDevice (Proxy :: Proxy device)) -> f $ UnsafeMkTensor @device @dtype @shape untypedTensor++withTensorShape ::+  forall device dtype r.+  ( KnownDevice device,+    KnownDType dtype+  ) =>+  D.Tensor ->+  ( forall shape.+    KnownShape shape =>+    Tensor device dtype shape ->+    r+  ) ->+  r+withTensorShape untypedTensor f = case someShape (D.shape untypedTensor) of+  -- ToDo: check device/dtype of untyped tensor.+  (SomeShape (Proxy :: Proxy shape)) -> f $ UnsafeMkTensor @device @dtype @shape untypedTensor++--------------------------------------------------------------------------------+-- Broadcast type-level function+--------------------------------------------------------------------------------++type family ComputeBroadcast (reversedShape :: [Nat]) (reversedShape' :: [Nat]) :: Maybe [Nat] where+  ComputeBroadcast '[] reversedShape = Just reversedShape+  ComputeBroadcast reversedShape '[] = Just reversedShape+  ComputeBroadcast (h ': t) (h ': t2) = AppendToMaybe h (ComputeBroadcast t t2)+  ComputeBroadcast (h ': t) (1 ': t2) = AppendToMaybe h (ComputeBroadcast t t2)+  ComputeBroadcast (1 ': t) (h ': t2) = AppendToMaybe h (ComputeBroadcast t t2)+  ComputeBroadcast _ _ = Nothing++type family CheckBroadcast (shape :: [Nat]) (shape' :: [Nat]) (result :: Maybe [Nat]) :: [Nat] where+  CheckBroadcast shape shape' Nothing =+    TypeError+      ( Text "The shapes "+          :<>: ShowType shape+          :<>: Text " and "+          :<>: ShowType shape'+          :<>: Text " cannot be broadcast"+      )+  CheckBroadcast _ _ (Just result) = (Reverse result)++type Broadcast shape shape' =+  CheckBroadcast+    shape+    shape'+    ( ComputeBroadcast+        (Reverse shape)+        (Reverse shape')+    )++type family BasicArithmeticDTypeIsValid (device :: (D.DeviceType, Nat)) (dtype :: D.DType) :: Constraint where+  BasicArithmeticDTypeIsValid '( 'D.CPU, 0) dtype =+    ( DTypeIsNotBool '( 'D.CPU, 0) dtype,+      DTypeIsNotHalf '( 'D.CPU, 0) dtype+    )+  BasicArithmeticDTypeIsValid '( 'D.CUDA, _) dtype = ()+  BasicArithmeticDTypeIsValid '( 'D.MPS, 0) dtype = ()+  BasicArithmeticDTypeIsValid '(deviceType, _) dtype = UnsupportedDTypeForDevice deviceType dtype++add,+  sub,+  mul,+  div ::+    forall shape'' shape shape' dtype dtype' dtype'' device.+    ( dtype'' ~ DTypePromotion dtype dtype',+      shape'' ~ Broadcast shape shape',+      BasicArithmeticDTypeIsValid device dtype,+      BasicArithmeticDTypeIsValid device dtype',+      BasicArithmeticDTypeIsValid device dtype''+    ) =>+    Tensor device dtype shape ->+    Tensor device dtype' shape' ->+    Tensor device dtype'' shape''+add a b = UnsafeMkTensor $ D.add (toDynamic a) (toDynamic b)+sub a b = UnsafeMkTensor $ D.sub (toDynamic a) (toDynamic b)+mul a b = UnsafeMkTensor $ D.mul (toDynamic a) (toDynamic b)+div a b = UnsafeMkTensor $ D.div (toDynamic a) (toDynamic b)++type family ComparisonDTypeIsValid (device :: (D.DeviceType, Nat)) (dtype :: D.DType) :: Constraint where+  ComparisonDTypeIsValid '( 'D.CPU, 0) dtype =+    ( DTypeIsNotBool '( 'D.CPU, 0) dtype,+      DTypeIsNotHalf '( 'D.CPU, 0) dtype+    )+  ComparisonDTypeIsValid '( 'D.CUDA, _) dtype = ()+  ComparisonDTypeIsValid '( 'D.MPS, 0) dtype = ()+  ComparisonDTypeIsValid '(deviceType, _) dtype = UnsupportedDTypeForDevice deviceType dtype++gt,+  lt,+  ge,+  le,+  eq,+  ne,+  (>.),+  (<.),+  (>=.),+  (<=.),+  (==.),+  (/=.) ::+    forall shape'' shape shape' dtype dtype' device.+    ( shape'' ~ Broadcast shape shape',+      ComparisonDTypeIsValid device dtype,+      ComparisonDTypeIsValid device dtype'+    ) =>+    Tensor device dtype shape ->+    Tensor device dtype' shape' ->+    Tensor device 'D.Bool shape''+gt a b = UnsafeMkTensor $ D.gt (toDynamic a) (toDynamic b)+lt a b = UnsafeMkTensor $ D.lt (toDynamic a) (toDynamic b)+ge a b = UnsafeMkTensor $ D.ge (toDynamic a) (toDynamic b)+le a b = UnsafeMkTensor $ D.le (toDynamic a) (toDynamic b)+eq a b = UnsafeMkTensor $ D.eq (toDynamic a) (toDynamic b)+ne a b = UnsafeMkTensor $ D.ne (toDynamic a) (toDynamic b)+(>.) = gt+(<.) = lt+(>=.) = ge+(<=.) = le+(==.) = eq+(/=.) = ne++gtScalar,+  ltScalar,+  geScalar,+  leScalar,+  eqScalar,+  neScalar,+  (.>),+  (.<),+  (.>=),+  (.<=),+  (.==),+  (./=) ::+    forall shape dtype device.+    ( ComparisonDTypeIsValid device dtype,+      StandardFloatingPointDTypeValidation device dtype+    ) =>+    Tensor device dtype shape ->+    Float ->+    Tensor device 'D.Bool shape+gtScalar a s = UnsafeMkTensor $ D.gtScalar (toDynamic a) s+ltScalar a s = UnsafeMkTensor $ D.ltScalar (toDynamic a) s+geScalar a s = UnsafeMkTensor $ D.geScalar (toDynamic a) s+leScalar a s = UnsafeMkTensor $ D.leScalar (toDynamic a) s+eqScalar a s = UnsafeMkTensor $ D.eqScalar (toDynamic a) s+neScalar a s = UnsafeMkTensor $ D.neScalar (toDynamic a) s+(.>) = gtScalar+(.<) = ltScalar+(.>=) = geScalar+(.<=) = leScalar+(.==) = eqScalar+(./=) = neScalar++type family ComputeMatMul (reversedShape :: [Nat]) (reversedShape' :: [Nat]) :: Maybe [Nat] where+  ComputeMatMul (k ': '[]) (k ': '[]) = Just '[]+  ComputeMatMul (k ': '[]) (m ': k ': reversedBroadcastShape') = AppendToMaybe m (ComputeBroadcast '[] reversedBroadcastShape')+  ComputeMatMul (k ': n ': reversedBroadcastShape) (k ': '[]) = AppendToMaybe n (ComputeBroadcast '[] reversedBroadcastShape)+  ComputeMatMul (k ': n ': reversedBroadcastShape) (m ': k ': reversedBroadcastShape') = AppendToMaybe m (AppendToMaybe n (ComputeBroadcast reversedBroadcastShape reversedBroadcastShape'))++type family CheckMatMul (shape :: [Nat]) (shape' :: [Nat]) (result :: Maybe [Nat]) :: [Nat] where+  CheckMatMul shape shape' Nothing =+    TypeError+      ( Text "The shapes "+          :<>: ShowType shape+          :<>: Text " and "+          :<>: ShowType shape'+          :<>: Text " are not compatible with matrix multiplication"+      )+  CheckMatMul _ _ (Just result) = (Reverse result)++type MatMul shape shape' = CheckMatMul shape shape' (ComputeMatMul (Reverse shape) (Reverse shape'))++type family MatMulDTypeIsValid (device :: (D.DeviceType, Nat)) (dtype :: D.DType) :: Constraint where+  MatMulDTypeIsValid '( 'D.CPU, 0) dtype =+    ( DTypeIsNotBool '( 'D.CPU, 0) dtype,+      DTypeIsNotHalf '( 'D.CPU, 0) dtype+    )+  MatMulDTypeIsValid '( 'D.CUDA, deviceIndex) dtype = DTypeIsFloatingPoint '( 'D.CUDA, deviceIndex) dtype+  MatMulDTypeIsValid '( 'D.MPS, 0) dtype = DTypeIsFloatingPoint '( 'D.MPS, 0) dtype+  MatMulDTypeIsValid '(deviceType, _) dtype = UnsupportedDTypeForDevice deviceType dtype++-- | matrix multiplication+-- See https://pytorch.org/docs/stable/torch.html#torch.matmul.+matmul ::+  forall shape'' shape shape' dtype device.+  ( shape'' ~ MatMul shape shape',+    MatMulDTypeIsValid device dtype+  ) =>+  Tensor device dtype shape ->+  Tensor device dtype shape' ->+  Tensor device dtype shape''+matmul a b = UnsafeMkTensor $ D.matmul (toDynamic a) (toDynamic b)++select ::+  forall dim idx shape' shape dtype device.+  ( KnownNat dim,+    KnownNat idx,+    InRange shape dim idx,+    shape' ~ Remove shape dim+  ) =>+  Tensor device dtype shape ->+  Tensor device dtype shape'+select t = UnsafeMkTensor $ D.select (natValI @dim) (natValI @idx) (toDynamic t)++selectIdx ::+  forall dim n shape' shape dtype device.+  ( KnownNat dim,+    n ~ Index shape dim,+    shape' ~ Remove shape dim+  ) =>+  Tensor device dtype shape ->+  Finite n ->+  Tensor device dtype shape'+selectIdx t idx = UnsafeMkTensor $ D.select (natValI @dim) (getFiniteI idx) (toDynamic t)++type family CheckIndexSelectDim (dim :: Nat) (shape :: [Nat]) (result :: Maybe [Nat]) :: [Nat] where+  CheckIndexSelectDim dim shape 'Nothing = TypeError (Text "Dim " :<>: ShowType dim :<>: Text " not found in shape " :<>: ShowType shape)+  CheckIndexSelectDim dim shape ('Just shape') = shape'++type IndexSelectDim (dim :: Nat) (shape :: [Nat]) (numIndices :: Nat) = CheckIndexSelectDim dim shape (ReplaceDim dim shape numIndices)++-- | Returns a new tensor which indexes the input tensor along dimension dim using the entries in index which is a tensor of datatype Int64.+-- The returned tensor has the same number of dimensions as the original tensor (input).+-- The dimth dimension has the same size as the length of index; other dimensions have the same size as in the original tensor.+-- +-- See https://pytorch.org/docs/stable/generated/torch.index_select.html for more information.+indexSelectDim ::+  forall (dim :: Nat) (shape :: [Nat]) (shape' :: [Nat]) (indexLength :: Nat) dtype device.+  ( KnownNat dim,+    shape' ~ IndexSelectDim dim shape indexLength+  ) =>+  Tensor device D.Int64 '[indexLength]+  -> Tensor device dtype shape+  -> Tensor device dtype shape'+indexSelectDim index inputs = UnsafeMkTensor $ D.indexSelect (natValI @dim) (toDynamic index) (toDynamic inputs)++type family Numel (shape :: [Nat]) :: Nat where+  Numel '[] = 1+  Numel (h ': t) = h * (Numel t)++-- | reshape+-- >>> t :: CPUTensor 'D.Int64 '[2,3,4] = fromJust [[[111,112,113,114],[121,122,123,124],[131,132,133,134]],[[211,212,213,214],[221,222,223,224],[231,232,233,234]]]+-- >>> t' = reshape @'[24] t+-- >>> toList . Just $ t'+-- [111,112,113,114,121,122,123,124,131,132,133,134,211,212,213,214,221,222,223,224,231,232,233,234]+-- >>> toList . Just $ reshape @'[2,3,4] t'+-- [[[111,112,113,114],[121,122,123,124],[131,132,133,134]],[[211,212,213,214],[221,222,223,224],[231,232,233,234]]]+reshape ::+  forall shape' shape dtype device.+  ( KnownShape shape',+    Numel shape ~ Numel shape'+  ) =>+  Tensor device dtype shape ->+  Tensor device dtype shape'+reshape t = UnsafeMkTensor $ D.reshape (shapeVal @shape') (toDynamic t)++-- | To avoid overlapped instance for (Unnamed t => Castable t D.ATenTensor)+newtype Wrap a = Wrap {unWrap :: a}++instance {-# OVERLAPS #-} Unnamed t => Castable (Wrap t) D.ATenTensor where+  cast t f =+    let (D.Unsafe aten_tensor) = toDynamic (unWrap t)+     in f aten_tensor+  uncast aten_tensor f = f $ Wrap $ fromUnnamed $ UnsafeMkTensor (D.Unsafe aten_tensor)++instance Castable (NamedTensor device dtype shape) D.ATenTensor where+  cast (FromTensor (UnsafeMkTensor (D.Unsafe aten_tensor))) f = f aten_tensor+  uncast aten_tensor f = f . FromTensor . UnsafeMkTensor $ D.Unsafe aten_tensor++instance Castable (Tensor device dtype shape) D.ATenTensor where+  cast (UnsafeMkTensor (D.Unsafe aten_tensor)) f = f aten_tensor+  uncast aten_tensor f = f $ UnsafeMkTensor (D.Unsafe aten_tensor)++instance Castable [Tensor device dtype shape] (ForeignPtr ATen.TensorList) where+  cast xs f = do+    ptr_list <- mapM (\x -> (cast x return :: IO (ForeignPtr ATen.Tensor))) xs+    cast ptr_list f+  uncast xs f = uncast xs $ \ptr_list -> do+    tensor_list <- mapM (\(x :: ForeignPtr ATen.Tensor) -> uncast x return) ptr_list+    f tensor_list++instance KnownNat n => Castable (Vector n (Tensor device dtype shape)) (ForeignPtr ATen.TensorList) where+  cast xs f = do+    ptr_list <- V.toList <$> mapM (\x -> (cast x return :: IO (ForeignPtr ATen.Tensor))) xs+    cast ptr_list f+  uncast xs f = uncast xs $ \ptr_list -> do+    tensor_list <- mapM (\(x :: ForeignPtr ATen.Tensor) -> uncast x return) ptr_list+    Just xs <- pure $ V.fromListN tensor_list+    f xs++data TensorListFold = TensorListFold++instance (Castable x D.ATenTensor) => Apply' TensorListFold (x, IO [D.ATenTensor]) (IO [D.ATenTensor]) where+  apply' _ (x, mxs) = do+    xs <- mxs+    x' <- cast x return+    return (x' : xs)++data TensorListUnfold = TensorListUnfold++instance Apply TensorListUnfold [D.ATenTensor] (IO HNothing) where+  apply _ [] = pure HNothing++instance (Castable x D.ATenTensor) => Apply TensorListUnfold [D.ATenTensor] (IO (HJust (x, [D.ATenTensor]))) where+  apply _ (x : xs) = do+    x' <- uncast x return+    return $ HJust (x', xs)++instance+  ( HFoldrM IO TensorListFold [D.ATenTensor] l [D.ATenTensor],+    Apply TensorListUnfold [D.ATenTensor] res,+    HUnfoldM IO TensorListUnfold res l,+    res ~ (HUnfoldMRes IO [D.ATenTensor] l)+  ) =>+  Castable (HList l) [D.ATenTensor]+  where+  cast xs f = f =<< go xs+    where+      go :: HList l -> IO [D.ATenTensor]+      go xs = hfoldrM TensorListFold ([] :: [D.ATenTensor]) xs+  uncast xs f = f =<< go xs+    where+      go :: [D.ATenTensor] -> IO (HList l)+      go xs = hunfoldrM TensorListUnfold xs++instance Castable (HList l) [D.ATenTensor] => Castable (HList l) (ForeignPtr ATen.TensorList) where+  cast xs f = do+    ts <- cast xs return :: IO [ForeignPtr ATen.Tensor]+    cast ts f+  uncast xs f = uncast xs $ \(ptrList :: [ForeignPtr ATen.Tensor]) -> do+    ts <- uncast ptrList return :: IO (HList l)+    f ts++--------------------------------------------------------------------------------+-- Move tensors+--------------------------------------------------------------------------------++-- TODO: track sparsity in tensor type+toSparse :: Tensor device dtype shape -> Tensor device dtype shape+toSparse t = UnsafeMkTensor $ D.toSparse (toDynamic t)++-- TODO: track sparsity in tensor type+toDense :: Tensor device dtype shape -> Tensor device dtype shape+toDense t = UnsafeMkTensor $ D.toDense (toDynamic t)++-- -- TODO: is this a device?+-- toMKLDNN+--   :: forall device' device shape dtype+--    . Tensor device  dtype shape+--   -> Tensor device' dtype shape+-- toMKLDNN t = UnsafeMkTensor $ D.toMKLDNN (toDynamic t)++-- | move tensor to CPU+-- TODO: can this fail?+toCPU ::+  forall device shape dtype.+  Tensor device dtype shape ->+  CPUTensor dtype shape+toCPU input = UnsafeMkTensor $ D.toCPU (toDynamic input)++-- | move tensor to the first CUDA device+-- TODO: what if this fails?+toCUDA ::+  forall device' device shape dtype.+  Tensor device dtype shape ->+  CUDATensor 0 dtype shape+toCUDA t = UnsafeMkTensor $ D.toCUDA (toDynamic t)++-- | move tensor to the first MPS device+-- TODO: what if this fails?+toMPS ::+  forall device' device shape dtype.+  Tensor device dtype shape ->+  MPSTensor 0 dtype shape+toMPS t = UnsafeMkTensor $ D.toMPS (toDynamic t)++-- | move tensor to device+-- TODO: what if this fails?+toDevice ::+  forall device' device dtype shape t t'.+  ( KnownDevice device',+    IsUnnamed t device dtype shape,+    Unnamed t',+    t' ~ ReplaceDevice'' t device'+  ) =>+  t ->+  t'+toDevice = fromUnnamed . UnsafeMkTensor . D.toDevice (deviceVal @device') . toDynamic++-- | change tensor data type+toDType ::+  forall dtype' dtype device shape t t'.+  ( KnownDType dtype',+    IsUnnamed t device dtype shape,+    Unnamed t',+    t' ~ ReplaceDType'' t dtype'+  ) =>+  t ->+  t'+toDType = fromUnnamed . UnsafeMkTensor . D.toType (dtypeVal @dtype') . toDynamic++--------------------------------------------------------------------------------+-- Auxiliary functions for accessing tensor options as values+--------------------------------------------------------------------------------++-- | returns tensor dimension+--   uses compile-time information only+dim ::+  forall device dtype shape t.+  ( TensorOptions shape dtype device,+    IsUnnamed t device dtype shape+  ) =>+  t ->+  Int+dim t = length $ optionsRuntimeShape @shape @dtype @device++-- | returns tensor shape as list+--   uses compile-time information only+shape ::+  forall device dtype shape t.+  ( TensorOptions shape dtype device,+    IsUnnamed t device dtype shape+  ) =>+  t ->+  [Int]+shape _ = optionsRuntimeShape @shape @dtype @device++-- | returns tensor data type+--   uses compile-time information only+dtype ::+  forall device dtype shape t.+  ( TensorOptions shape dtype device,+    IsUnnamed t device dtype shape+  ) =>+  t ->+  D.DType+dtype _ = optionsRuntimeDType @shape @dtype @device++-- | returns tensor device+--   uses compile-time information only+device ::+  forall device dtype shape t.+  ( TensorOptions shape dtype device,+    IsUnnamed t device dtype shape+  ) =>+  t ->+  D.Device+device _ = optionsRuntimeDevice @shape @dtype @device++--------------------------------------------------------------------------------+-- Auxiliary functions for accessing tensors as values+--------------------------------------------------------------------------------++-- TODO: figure out what device, dtype, and shape we need for this+toInt ::+  Tensor device dtype shape ->+  Int+toInt t = D.toInt $ toDynamic t++toFloat :: forall device. Tensor device 'D.Float '[] -> Float+toFloat t = D.asValue . toDynamic . toCPU $ t++toDouble :: forall device. Tensor device 'D.Double '[] -> Double+toDouble t = D.asValue . toDynamic . toCPU $ t++toBool :: forall device. Tensor device 'D.Bool '[] -> Bool+toBool t = D.asValue . toDynamic . toCPU $ t++--------------------------------------------------------------------------------+-- NamedTensor+--------------------------------------------------------------------------------++type family ToDType a :: D.DType where+  ToDType Bool = 'D.Bool+  ToDType Int = 'D.Int64+  ToDType Float = 'D.Float+  ToDType Double = 'D.Double+  ToDType (f a) = ToDType a++type family ToShape a :: Shape where+  ToShape Bool = '[]+  ToShape Int = '[]+  ToShape Float = '[]+  ToShape Double = '[]+  ToShape (f a) = f ': ToShape a++type family FindDim (a :: Size) (shape :: Shape) :: Nat where+  FindDim a (a ': _) = 0+  FindDim a (b ': ax) = 1 + FindDim a ax+  FindDim a _ = TypeError (Text "Not find a type:" :<>: ShowType a :<>: Text " in the shape.")++data NamedTensor (device :: (D.DeviceType, Nat)) (dtype :: D.DType) (shape :: Shape) where+  FromTensor :: forall device dtype shape' shape. shape ~ ToNats shape' => Tensor device dtype shape -> NamedTensor device dtype shape'++instance Unnamed (NamedTensor device dtype shape) where+  type UTShape (NamedTensor device dtype shape) = ToNats shape+  type UTDevice (NamedTensor device dtype shape) = device+  type UTDType (NamedTensor device dtype shape) = dtype+  toUnnamed (FromTensor t) = t+  fromUnnamed = FromTensor+  toDynamic (FromTensor (UnsafeMkTensor t)) = t++instance (KnownDevice device) => Num (NamedTensor device dtype shape) where+  (+) a b = fromUnnamed $ toUnnamed a + toUnnamed b+  (-) a b = fromUnnamed $ toUnnamed a - toUnnamed b+  (*) a b = fromUnnamed $ toUnnamed a * toUnnamed b+  negate = fromUnnamed . negate . toUnnamed+  abs = fromUnnamed . abs . toUnnamed+  signum = fromUnnamed . signum . toUnnamed+  fromInteger = fromUnnamed . fromInteger++instance KnownDevice device => Fractional (NamedTensor device dtype shape) where+  a / b = fromUnnamed $ toUnnamed a / toUnnamed b+  recip = fromUnnamed . recip . toUnnamed+  fromRational = fromUnnamed . fromRational++instance Show (NamedTensor device dtype shape) where+  show = show . toUnnamed++type family ReplaceDevice'' (tensor :: t) (device :: (D.DeviceType, Nat)) :: t where+  ReplaceDevice'' (Tensor device0 dtype shape) device1 = Tensor device1 dtype shape+  ReplaceDevice'' (NamedTensor device0 dtype shape) device1 = NamedTensor device1 dtype shape++type family ReplaceDType'' (tensor :: t) (dtype :: D.DType) :: t where+  ReplaceDType'' (Tensor device dtype0 shape) dtype1 = Tensor device dtype1 shape+  ReplaceDType'' (NamedTensor device dtype0 shape) dtype1 = NamedTensor device dtype1 shape
+ src/Torch/Typed/VLTensor.hs view
@@ -0,0 +1,64 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeOperators #-}++module Torch.Typed.VLTensor where++import Data.Proxy+import GHC.TypeLits+import qualified Torch.DType as D+import qualified Torch.Device as D+import qualified Torch.Functional as Untyped+import qualified Torch.Functional.Internal as Internal+import qualified Torch.Tensor as Untyped+import Torch.Typed.Auxiliary+import Torch.Typed.Tensor+import Unsafe.Coerce (unsafeCoerce)++-- | A variable length tensor. The length cannot be determined in advance.+data VLTensor (device :: (D.DeviceType, Nat)) (dtype :: D.DType) (shape :: [Nat]) = forall n. KnownNat n => VLTensor (Tensor device dtype (n : shape))++instance Show (VLTensor device dtype shape) where+  show input =+    case input of+      VLTensor v -> show v++fromVLTensor ::+  forall n device dtype shape.+  ( KnownNat n,+    TensorOptions shape dtype device,+    KnownShape shape+  ) =>+  VLTensor device dtype shape ->+  Maybe (Tensor device dtype (n : shape))+fromVLTensor (VLTensor input) =+  if shape input == shapeVal @(n : shape)+    then Just (unsafeCoerce input)+    else Nothing++selectIndexes :: forall n device dtype shape. Tensor device dtype (n : shape) -> Tensor device 'D.Bool '[n] -> VLTensor device dtype shape+selectIndexes input boolTensor =+  let output = toDynamic input Untyped.! toDynamic boolTensor+   in withNat (head $ Untyped.shape output) $ \(Proxy :: Proxy b) ->+        VLTensor $ UnsafeMkTensor @device @dtype @(b : shape) output++pack :: forall device dtype shape. [Tensor device dtype shape] -> VLTensor device dtype shape+pack input =+  let output = Untyped.stack (Untyped.Dim 0) $ map toDynamic input+   in withNat (head $ Untyped.shape output) $ \(Proxy :: Proxy n) ->+        VLTensor $ UnsafeMkTensor @device @dtype @(n : shape) output++unpack :: forall device dtype shape. VLTensor device dtype shape -> [Tensor device dtype shape]+unpack input =+  case input of+    (VLTensor (input' :: Tensor device dtype (n : shape))) ->+      let output = Internal.unbind (toDynamic input') 0+       in map (UnsafeMkTensor @device @dtype @shape) output+
+ src/Torch/Typed/Vision.hs view
@@ -0,0 +1,144 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE NoStarIsType #-}++module Torch.Typed.Vision where++import qualified Codec.Compression.GZip as GZip+import Control.Monad (forM_)+import qualified Data.ByteString as BS+import qualified Data.ByteString.Internal as BSI+import Foreign.Marshal.Utils (copyBytes)+import qualified Data.ByteString.Lazy as BS.Lazy+import Data.Kind+import qualified Foreign.ForeignPtr as F+import qualified Foreign.Ptr as F+import GHC.Exts (IsList (fromList))+import GHC.TypeLits+import System.IO.Unsafe+import qualified Torch.DType as D+import Torch.Data.Pipeline+import qualified Torch.Device as D+import Torch.Internal.Cast+import qualified Torch.Internal.Managed.TensorFactories as LibTorch+import qualified Torch.Tensor as D+import qualified Torch.TensorOptions as D+import Torch.Typed.Auxiliary+import Torch.Typed.Functional+import Torch.Typed.Tensor++data MNIST (m :: Type -> Type) (device :: (D.DeviceType, Nat)) (batchSize :: Nat) = MNIST {mnistData :: MnistData}++instance+  (KnownNat batchSize, KnownDevice device, Applicative m) =>+  Dataset m (MNIST m device batchSize) Int (Tensor device 'D.Float '[batchSize, 784], Tensor device 'D.Int64 '[batchSize])+  where+  getItem MNIST {..} ix =+    let batchSize = natValI @batchSize+        indexes = [ix * batchSize .. (ix + 1) * batchSize - 1]+        imgs = getImages @batchSize mnistData indexes+        labels = getLabels @batchSize mnistData indexes+     in pure (toDevice @device imgs, toDevice @device labels)++  keys MNIST {..} = fromList [0 .. Torch.Typed.Vision.length mnistData `Prelude.div` (natValI @batchSize) - 1]++data MnistData = MnistData+  { images :: BS.ByteString,+    labels :: BS.ByteString+  }++type Rows = 28++type Cols = 28++type DataDim = Rows * Cols++type ClassDim = 10++getLabels ::+  forall n. KnownNat n => MnistData -> [Int] -> CPUTensor 'D.Int64 '[n]+getLabels mnist imageIdxs =+  UnsafeMkTensor . D.asTensor . map (getLabel mnist) . take (natValI @n) $ imageIdxs++getLabel :: MnistData -> Int -> Int+getLabel mnist imageIdx =+  fromIntegral $ BS.index (labels mnist) (fromIntegral imageIdx + 8)++getImage :: MnistData -> Int -> CPUTensor 'D.Float '[DataDim]+getImage mnist imageIdx =+  let imageBS =+        [ fromIntegral $+            BS.index+              (images mnist)+              (fromIntegral imageIdx * 28 ^ 2 + 16 + r)+          | r <- [0 .. 28 ^ 2 - 1]+        ] ::+          [Float]+      (tensor :: CPUTensor 'D.Float '[DataDim]) =+        UnsafeMkTensor $ D.asTensor imageBS+   in tensor++getImages' ::+  forall n.+  KnownNat n =>+  MnistData ->+  [Int] ->+  CPUTensor 'D.Float '[n, DataDim]+getImages' mnist imageIdxs =+  UnsafeMkTensor $+    D.asTensor $+      map image $+        take+          (natValI @n)+          imageIdxs+  where+    image idx =+      [ fromIntegral $+          BS.index (images mnist) (fromIntegral idx * 28 ^ 2 + 16 + r)+        | r <- [0 .. 28 ^ 2 - 1]+      ] ::+        [Float]++getImages ::+  forall n.+  KnownNat n =>+  MnistData ->+  [Int] ->+  CPUTensor 'D.Float '[n, DataDim]+getImages mnist imageIdxs = UnsafeMkTensor $+  unsafePerformIO $ do+    let (BSI.PS fptr off len) = images mnist+    t <-+      (cast2 LibTorch.empty_lo :: [Int] -> D.TensorOptions -> IO D.Tensor)+        [natValI @n, natValI @DataDim]+        (D.withDType D.UInt8 D.defaultOpts)+    D.withTensor t $ \ptr1 -> do+      F.withForeignPtr fptr $ \ptr2 -> do+        forM_ (zip [0 .. ((natValI @n) -1)] imageIdxs) $ \(i, idx) -> do+          copyBytes+            (F.plusPtr ptr1 ((natValI @DataDim) * i))+            (F.plusPtr ptr2 (off + 16 + (natValI @DataDim) * idx))+            (natValI @DataDim)+    return $ D.toType D.Float t++length :: MnistData -> Int+length mnist = fromIntegral $ BS.length (labels mnist) - 8++decompressFile :: String -> String -> IO BS.ByteString+decompressFile path file = decompress' <$> BS.readFile (path <> "/" <> file)+  where+    decompress' = BS.concat . BS.Lazy.toChunks . GZip.decompress . BS.Lazy.fromStrict++initMnist :: String -> IO (MnistData, MnistData)+initMnist path = do+  imagesBS <- decompressFile path "train-images-idx3-ubyte.gz"+  labelsBS <- decompressFile path "train-labels-idx1-ubyte.gz"+  testImagesBS <- decompressFile path "t10k-images-idx3-ubyte.gz"+  testLabelsBS <- decompressFile path "t10k-labels-idx1-ubyte.gz"+  return (MnistData imagesBS labelsBS, MnistData testImagesBS testLabelsBS)
+ src/Torch/Vision.hs view
@@ -0,0 +1,648 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TemplateHaskell #-}++module Torch.Vision where++import qualified Codec.Picture as I+import Control.Exception.Safe+  ( SomeException (..),+    throwIO,+    try,+  )+import Control.Monad+  ( MonadPlus,+    forM_,+    when,+  )+import qualified Data.ByteString as BS+import qualified Data.ByteString.Internal as BSI+import Foreign.Marshal.Utils (copyBytes)+import Data.Int+import Data.Kind (Type)+import qualified Data.Vector.Storable as V+import Data.Word+import qualified Foreign.ForeignPtr as F+import qualified Foreign.Ptr as F+import GHC.Exts (IsList (fromList))+import qualified Language.C.Inline as C+import Pipes+import System.IO.Unsafe+import System.Random (mkStdGen, randoms)+import qualified Torch.DType as D+import Torch.Data.Pipeline+import Torch.Data.StreamedPipeline+import Torch.Functional hiding (take)+import qualified Torch.Functional as D+import Torch.Internal.Cast+import qualified Torch.Internal.Managed.TensorFactories as LibTorch+import Torch.NN+import Torch.Tensor+import qualified Torch.Tensor as D+import qualified Torch.TensorOptions as D+import qualified Torch.Typed.Vision as I+import Prelude hiding (max, min)+import qualified Prelude as P++C.include "<stdint.h>"++data MNIST (m :: Type -> Type) = MNIST+  { batchSize :: Int,+    mnistData :: I.MnistData+  }++instance Monad m => Datastream m Int (MNIST m) (Tensor, Tensor) where+  streamSamples MNIST {..} seed = Select $+    for (each [1 .. numIters]) $+      \iter -> do+        let from = (iter -1) * batchSize+            to = (iter * batchSize) - 1+            indexes = [from .. to]+            target = getLabels' batchSize mnistData indexes+        let input = getImages' batchSize 784 mnistData indexes+        yield (input, target)+    where+      numIters = I.length mnistData `Prelude.div` batchSize++instance Applicative m => Dataset m (MNIST m) Int (Tensor, Tensor) where+  getItem MNIST {..} ix =+    let indexes = [ix * batchSize .. (ix + 1) * batchSize - 1]+        imgs = getImages' batchSize 784 mnistData indexes+        labels = getLabels' batchSize mnistData indexes+     in pure (imgs, labels)++  keys MNIST {..} = fromList [0 .. I.length mnistData `Prelude.div` batchSize - 1]++getLabels' :: Int -> I.MnistData -> [Int] -> Tensor+getLabels' n mnist imageIdxs =+  asTensor $ map (I.getLabel mnist) . take n $ imageIdxs++getImages' ::+  Int -> -- number of observations in minibatch+  Int -> -- dimensionality of the data+  I.MnistData -> -- mnist data representation+  [Int] -> -- indices of the dataset+  Tensor+getImages' n dataDim mnist imageIdxs = unsafePerformIO $ do+  let (BSI.PS fptr off len) = I.images mnist+  t <-+    (cast2 LibTorch.empty_lo :: [Int] -> D.TensorOptions -> IO D.Tensor)+      [n, dataDim]+      (D.withDType D.UInt8 D.defaultOpts)+  D.withTensor t $ \ptr1 -> do+    F.withForeignPtr fptr $ \ptr2 -> do+      forM_ (zip [0 .. (n -1)] imageIdxs) $ \(i, idx) -> do+        copyBytes+          (F.plusPtr ptr1 (dataDim * i))+          (F.plusPtr ptr2 (off + 16 + dataDim * idx))+          dataDim+  return $ D.toType D.Float t++-- http://paulbourke.net/dataformats/asciiart/+grayScale10 = " .:-=+*#%@"++grayScale70 = reverse "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\\|()1{}[]?-_+~<>i!lI;:,\"^`'. "++-- Display an MNIST image tensor as ascii text+dispImage :: Tensor -> IO ()+dispImage img = do+  mapM+    ( \row ->+        mapM+          ( \col ->+              putChar $ grayScale !! (P.floor $ scaled !! row !! col)+          )+          [0, downSamp .. 27]+          >> putStrLn ""+    )+    [0, downSamp .. 27]+  pure ()+  where+    downSamp = 2+    grayScale = grayScale10+    paletteMax = (fromIntegral $ length grayScale) - 1.0+    img' = reshape [28, 28] img+    scaled :: [[Float]] =+      let (mn, mx) = (min img', max img')+       in asValue $ (img' - mn) / (mx - mn) * paletteMax++data PixelFormat+  = Y8+  | YF+  | YA8+  | RGB8+  | RGBF+  | RGBA8+  | YCbCr8+  | CMYK8+  | CMYK16+  | RGBA16+  | RGB16+  | Y16+  | YA16+  | Y32+  deriving (Show, Eq)++readImage :: FilePath -> IO (Either String (D.Tensor, PixelFormat))+readImage file =+  I.readImage file >>= \case+    Left err -> return $ Left err+    Right img' -> return $ Right $ (fromDynImage img', pixelFormat img')++readImageAsRGB8 :: FilePath -> IO (Either String D.Tensor)+readImageAsRGB8 file =+  I.readImage file >>= \case+    Left err -> return $ Left err+    Right img' -> return . Right . fromDynImage . I.ImageRGB8 . I.convertRGB8 $ img'++readImageAsRGB8WithScaling :: FilePath -> Int -> Int -> Bool -> IO (Either String (I.Image I.PixelRGB8, D.Tensor))+readImageAsRGB8WithScaling file width height keepAspectRatio =+  I.readImage file >>= \case+    Left err -> return $ Left err+    Right img' -> do+      let img = (resizeRGB8 width height keepAspectRatio) . I.convertRGB8 $ img'+      return $ Right (img, fromDynImage . I.ImageRGB8 $ img)++centerCrop :: Int -> Int -> I.Image I.PixelRGB8 -> I.Image I.PixelRGB8+centerCrop width height input = unsafePerformIO $ do+  let channel = 3 :: Int+      (I.Image org_w org_h org_vec) = input+      img@(I.Image w h vec) = I.generateImage (\_ _ -> (I.PixelRGB8 0 0 0)) width height :: I.Image I.PixelRGB8+      (org_fptr, org_len) = V.unsafeToForeignPtr0 org_vec+      org_whc = fromIntegral $ org_w * org_h * channel+      (fptr, len) = V.unsafeToForeignPtr0 vec+      whc = fromIntegral $ w * h * channel+  F.withForeignPtr org_fptr $ \ptr1 -> F.withForeignPtr fptr $ \ptr2 -> do+    let src = F.castPtr ptr1+        dst = F.castPtr ptr2+        iw = fromIntegral w+        ih = fromIntegral h+        iorg_w = fromIntegral org_w+        iorg_h = fromIntegral org_h+        ichannel = fromIntegral channel+    [C.block| void {+        uint8_t* src = $(uint8_t* src);+        uint8_t* dst = $(uint8_t* dst);+        int w = $(int iw);+        int h = $(int ih);+        int channel = $(int ichannel);+        int ow = $(int iorg_w);+        int oh = $(int iorg_h);+        int offsetx = (ow - w)/2;+        int offsety = (oh - h)/2;+        for(int y=0;y<h;y++){+          for(int x=0;x<w;x++){+            for(int c=0;c<channel;c++){+              int sy = y + offsety;+              int sx = x + offsetx;+              if(sx >= 0 && sx < ow &&+                 sy >= 0 && sy < oh){+                 dst[(y*w+x)*channel+c] = src[(sy*ow+sx)*channel+c];+              }+            }+          }+        }+    } |]+    return img++drawLine :: Int -> Int -> Int -> Int -> (Int, Int, Int) -> I.Image I.PixelRGB8 -> IO ()+drawLine x0 y0 x1 y1 (r, g, b) input = do+  let img@(I.Image w h vec) = input+      (fptr, len) = V.unsafeToForeignPtr0 vec+  F.withForeignPtr fptr $ \ptr2 -> do+    let iw = fromIntegral w+        ih = fromIntegral h+        ix0 = fromIntegral x0+        iy0 = fromIntegral y0+        ix1 = fromIntegral x1+        iy1 = fromIntegral y1+        ir = fromIntegral r+        ig = fromIntegral g+        ib = fromIntegral b+        dst = F.castPtr ptr2+    [C.block| void {+        uint8_t* dst = $(uint8_t* dst);+        int w = $(int iw);+        int h = $(int ih);+        int x0 = $(int ix0);+        int y0 = $(int iy0);+        int x1 = $(int ix1);+        int y1 = $(int iy1);+        int r = $(int ir);+        int g = $(int ig);+        int b = $(int ib);+        int channel = 3;+        int sign_x =  x1 - x0 >= 0 ? 1 : -1;+        int sign_y =  y1 - y0 >= 0 ? 1 : -1;+        int abs_x =  x1 - x0 >= 0 ? x1 - x0 : x0 - x1;+        int abs_y =  y1 - y0 >= 0 ? y1 - y0 : y0 - y1;+        if(abs_x>=abs_y){+          for(int x=x0;x!=x1;x+=sign_x){+            int y = (x-x0) * (y1-y0) / (x1-x0) + y0;+            if(y >=0 && y < h &&+               x >=0 && x < w) {+              dst[(y*w+x)*channel+0] = r;+              dst[(y*w+x)*channel+1] = g;+              dst[(y*w+x)*channel+2] = b;+            }+          }+        } else {+          for(int y=y0;y!=y1;y+=sign_y){+            int x = (y-y0) * (x1-x0) / (y1-y0) + x0;+            if(y >=0 && y < h &&+               x >=0 && x < w) {+              dst[(y*w+x)*channel+0] = r;+              dst[(y*w+x)*channel+1] = g;+              dst[(y*w+x)*channel+2] = b;+            }+          }+        }+    } |]++drawRect :: Int -> Int -> Int -> Int -> (Int, Int, Int) -> I.Image I.PixelRGB8 -> IO ()+drawRect x0 y0 x1 y1 (r, g, b) input = do+  drawLine x0 y0 (x1 + 1) y0 (r, g, b) input+  drawLine x0 y0 x0 (y1 + 1) (r, g, b) input+  drawLine x0 y1 (x1 + 1) y1 (r, g, b) input+  drawLine x1 y0 x1 (y1 + 1) (r, g, b) input++drawString :: String -> Int -> Int -> (Int, Int, Int) -> (Int, Int, Int) -> I.Image I.PixelRGB8 -> IO ()+drawString text x0 y0 (r, g, b) (br, bg, bb) input = do+  forM_ (zip [0 ..] text) $ \(i, ch) -> do+    drawChar (fromEnum ch) (x0 + i * 8) y0 (r, g, b) (br, bg, bb) input++drawChar :: Int -> Int -> Int -> (Int, Int, Int) -> (Int, Int, Int) -> I.Image I.PixelRGB8 -> IO ()+drawChar ascii_code x0 y0 (r, g, b) (br, bg, bb) input = do+  let img@(I.Image w h vec) = input+      (fptr, len) = V.unsafeToForeignPtr0 vec+  F.withForeignPtr fptr $ \ptr2 -> do+    let iw = fromIntegral w+        ih = fromIntegral h+        ix0 = fromIntegral x0+        iy0 = fromIntegral y0+        ir = fromIntegral r+        ig = fromIntegral g+        ib = fromIntegral b+        ibr = fromIntegral br+        ibg = fromIntegral bg+        ibb = fromIntegral bb+        dst = F.castPtr ptr2+        iascii_code = fromIntegral ascii_code+    [C.block| void {+        uint8_t* dst = $(uint8_t* dst);+        int w = $(int iw);+        int h = $(int ih);+        int x0 = $(int ix0);+        int y0 = $(int iy0);+        int r = $(int ir);+        int g = $(int ig);+        int b = $(int ib);+        int br = $(int ibr);+        int bg = $(int ibg);+        int bb = $(int ibb);+        int ascii_code = $(int iascii_code);+        int channel = 3;+        int char_width = 8;+        int char_height = 8;+        char fonts[95][8] = { // 0x20 to 0x7e+            { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},+            { 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00},+            { 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},+            { 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00},+            { 0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00},+            { 0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00},+            { 0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00},+            { 0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00},+            { 0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00},+            { 0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00},+            { 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00},+            { 0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00},+            { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06},+            { 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00},+            { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00},+            { 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00},+            { 0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00},+            { 0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00},+            { 0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00},+            { 0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00},+            { 0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00},+            { 0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00},+            { 0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00},+            { 0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00},+            { 0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00},+            { 0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00},+            { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00},+            { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06},+            { 0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00},+            { 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00},+            { 0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00},+            { 0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00},+            { 0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00},+            { 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00},+            { 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00},+            { 0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00},+            { 0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00},+            { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00},+            { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00},+            { 0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00},+            { 0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00},+            { 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},+            { 0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00},+            { 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00},+            { 0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00},+            { 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00},+            { 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00},+            { 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00},+            { 0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00},+            { 0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00},+            { 0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00},+            { 0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00},+            { 0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},+            { 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00},+            { 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00},+            { 0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00},+            { 0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00},+            { 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00},+            { 0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00},+            { 0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00},+            { 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00},+            { 0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00},+            { 0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00},+            { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF},+            { 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00},+            { 0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00},+            { 0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00},+            { 0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00},+            { 0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00},+            { 0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00},+            { 0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00},+            { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F},+            { 0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00},+            { 0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},+            { 0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E},+            { 0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00},+            { 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},+            { 0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00},+            { 0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00},+            { 0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00},+            { 0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F},+            { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78},+            { 0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00},+            { 0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00},+            { 0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00},+            { 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00},+            { 0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00},+            { 0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00},+            { 0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00},+            { 0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F},+            { 0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00},+            { 0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00},+            { 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00},+            { 0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00},+            { 0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} +          };+        for(int y=y0;y<y0+char_height;y++){+          for(int x=x0;x<x0+char_width;x++){+            if(y >=0 && y < h &&+               x >=0 && x < w) {+              int dx = x-x0;+              int dy = y-y0;+              int bit = +                ascii_code > 0x20 && ascii_code < 0x7f ?+                fonts[ascii_code-0x20][dy] & (0x1 << dx) :+                0;+              if (bit) {+                dst[(y*w+x)*channel+0] = r;+                dst[(y*w+x)*channel+1] = g;+                dst[(y*w+x)*channel+2] = b;+              } else {+                dst[(y*w+x)*channel+0] = br;+                dst[(y*w+x)*channel+1] = bg;+                dst[(y*w+x)*channel+2] = bb;+              }+            }+          }+        }+    } |]++resizeRGB8 :: Int -> Int -> Bool -> I.Image I.PixelRGB8 -> I.Image I.PixelRGB8+resizeRGB8 width height keepAspectRatio input = unsafePerformIO $ do+  let channel = 3 :: Int+      (I.Image org_w org_h org_vec) = input+      img@(I.Image w h vec) = I.generateImage (\_ _ -> (I.PixelRGB8 0 0 0)) width height :: I.Image I.PixelRGB8+      (org_fptr, org_len) = V.unsafeToForeignPtr0 org_vec+      org_whc = fromIntegral $ org_w * org_h * channel+      (fptr, len) = V.unsafeToForeignPtr0 vec+      whc = fromIntegral $ w * h * channel+  F.withForeignPtr org_fptr $ \ptr1 -> F.withForeignPtr fptr $ \ptr2 -> do+    let src = F.castPtr ptr1+        dst = F.castPtr ptr2+        iw = fromIntegral w+        ih = fromIntegral h+        iorg_w = fromIntegral org_w+        iorg_h = fromIntegral org_h+        ichannel = fromIntegral channel+        ckeepAspectRatio = if keepAspectRatio then 1 else 0+    [C.block| void {+        uint8_t* src = $(uint8_t* src);+        uint8_t* dst = $(uint8_t* dst);+        int w = $(int iw);+        int h = $(int ih);+        int channel = $(int ichannel);+        int ow = $(int iorg_w);+        int oh = $(int iorg_h);+        int keepAspectRatio = $(int ckeepAspectRatio);+        if(keepAspectRatio){+          int t0h = h;+          int t0w = ow * h / oh;+          int t1h = oh * w / ow;+          int t1w = w;+          if (t0w > w) {+            int offset = (h - (oh * w / ow))/2;+            for(int y=offset;y<h-offset;y++){+              for(int x=0;x<w;x++){+                for(int c=0;c<channel;c++){+                  int sy = (y-offset) * ow / w;+                  int sx = x * ow / w;+                  if(sy >= 0 && sy < oh){+                    dst[(y*w+x)*channel+c] = src[(sy*ow+sx)*channel+c];+                  }+                }+              }+            }+          } else {+            int offset = (w - (ow * h / oh))/2;+            for(int y=0;y<h;y++){+              for(int x=offset;x<w-offset;x++){+                for(int c=0;c<channel;c++){+                  int sy = y * oh / h;+                  int sx = (x-offset) * oh / h;+                  if(sx >= 0 && sx < ow){+                    dst[(y*w+x)*channel+c] = src[(sy*ow+sx)*channel+c];+                  }+                }+              }+            }+          }+        } else {+          for(int y=0;y<h;y++){+            for(int x=0;x<w;x++){+              for(int c=0;c<channel;c++){+                int sy = y * oh / h;+                int sx = x * ow / w;+                dst[(y*w+x)*channel+c] = src[(sy*ow+sx)*channel+c];+              }+            }+          }+        }+    } |]+    return img++pixelFormat :: I.DynamicImage -> PixelFormat+pixelFormat image = case image of+  I.ImageY8 _ -> Y8+  I.ImageYF _ -> YF+  I.ImageYA8 _ -> YA8+  I.ImageRGB8 _ -> RGB8+  I.ImageRGBF _ -> RGBF+  I.ImageRGBA8 _ -> RGBA8+  I.ImageYCbCr8 _ -> YCbCr8+  I.ImageCMYK8 _ -> CMYK8+  I.ImageCMYK16 _ -> CMYK16+  I.ImageRGBA16 _ -> RGBA16+  I.ImageRGB16 _ -> RGB16+  I.ImageY16 _ -> Y16+  I.ImageYA16 _ -> YA16+  I.ImageY32 _ -> Y32++fromDynImage :: I.DynamicImage -> D.Tensor+fromDynImage image = unsafePerformIO $ case image of+  I.ImageY8 (I.Image width height vec) -> createTensor width height 1 D.UInt8 1 vec+  I.ImageYF (I.Image width height vec) -> createTensor width height 1 D.Float 4 vec+  I.ImageYA8 (I.Image width height vec) -> createTensor width height 2 D.UInt8 1 vec+  I.ImageRGB8 (I.Image width height vec) -> createTensor width height 3 D.UInt8 1 vec+  I.ImageRGBF (I.Image width height vec) -> createTensor width height 3 D.Float 4 vec+  I.ImageRGBA8 (I.Image width height vec) -> createTensor width height 4 D.UInt8 1 vec+  I.ImageYCbCr8 (I.Image width height vec) -> createTensor width height 3 D.UInt8 1 vec+  I.ImageCMYK8 (I.Image width height vec) -> createTensor width height 4 D.UInt8 1 vec+  I.ImageCMYK16 (I.Image width height vec) -> createTensorU16to32 width height 4 D.Int32 vec+  I.ImageRGBA16 (I.Image width height vec) -> createTensorU16to32 width height 4 D.Int32 vec+  I.ImageRGB16 (I.Image width height vec) -> createTensorU16to32 width height 3 D.Int32 vec+  I.ImageY16 (I.Image width height vec) -> createTensorU16to32 width height 1 D.Int32 vec+  I.ImageYA16 (I.Image width height vec) -> createTensorU16to32 width height 2 D.Int32 vec+  I.ImageY32 (I.Image width height vec) -> createTensorU32to64 width height 1 D.Int64 vec+  where+    createTensor width height channel dtype dtype_size vec = do+      t <- ((cast2 LibTorch.empty_lo) :: [Int] -> D.TensorOptions -> IO D.Tensor) [1, height, width, channel] $ D.withDType dtype D.defaultOpts+      D.withTensor t $ \ptr1 -> do+        let (fptr, len) = V.unsafeToForeignPtr0 vec+            whc = width * height * channel * dtype_size+        F.withForeignPtr fptr $ \ptr2 -> do+          copyBytes (F.castPtr ptr1) (F.castPtr ptr2) whc+          return t+    createTensorU16to32 width height channel dtype vec = do+      t <- ((cast2 LibTorch.empty_lo) :: [Int] -> D.TensorOptions -> IO D.Tensor) [1, height, width, channel] $ D.withDType dtype D.defaultOpts+      D.withTensor t $ \ptr1 -> do+        let (fptr, len) = V.unsafeToForeignPtr0 vec+            whc = fromIntegral $ width * height * channel+        F.withForeignPtr fptr $ \ptr2 -> do+          let src = F.castPtr ptr2+              dst = F.castPtr ptr1+          [C.block| void {+              uint16_t* src = $(uint16_t* src);+              int32_t* dst = $(int32_t* dst);+              for(int i=0;i<$(int whc);i++){+                 dst[i] = src[i];+              }+          } |]+          return t+    createTensorU32to64 width height channel dtype vec = do+      t <- ((cast2 LibTorch.empty_lo) :: [Int] -> D.TensorOptions -> IO D.Tensor) [1, height, width, channel] $ D.withDType dtype D.defaultOpts+      D.withTensor t $ \ptr1 -> do+        let (fptr, len) = V.unsafeToForeignPtr0 vec+            whc = fromIntegral $ width * height * channel+        F.withForeignPtr fptr $ \ptr2 -> do+          let src = F.castPtr ptr2+              dst = F.castPtr ptr1+          [C.block| void {+              uint32_t* src = $(uint32_t* src);+              int64_t* dst = $(int64_t* dst);+              for(int i=0;i<$(int whc);i++){+                 dst[i] = src[i];+              }+          } |]+          return t++fromImages :: [I.Image I.PixelRGB8] -> IO D.Tensor+fromImages imgs = do+  let num_imgs = length imgs+      channel = 3+      (I.Image width height _) = head imgs+  when (num_imgs == 0) $ do+    throwIO $ userError "The number of images should be greater than 0."+  t <- ((cast2 LibTorch.empty_lo) :: [Int] -> D.TensorOptions -> IO D.Tensor) [num_imgs, height, width, channel] $ D.withDType D.UInt8 D.defaultOpts+  D.withTensor t $ \ptr1 -> do+    forM_ (zip [0 ..] imgs) $ \(idx, (I.Image width' height' vec)) -> do+      let (fptr, len) = V.unsafeToForeignPtr0 vec+          whc = width * height * channel+      when (len /= whc) $ do+        throwIO $ userError "vector's length is not the same as tensor' one."+      when (width /= width') $ do+        throwIO $ userError "image's width is not the same as first image's one"+      when (height /= height') $ do+        throwIO $ userError "image's height is not the same as first image's one"+      F.withForeignPtr fptr $ \ptr2 -> do+        copyBytes (F.plusPtr (F.castPtr ptr1) (whc * idx)) ptr2 len+  return t++writeImage :: forall p. I.Pixel p => Int -> Int -> Int -> p -> D.Tensor -> IO (I.Image p)+writeImage width height channel pixel tensor = do+  let img@(I.Image w h vec) = I.generateImage (\_ _ -> pixel) width height :: I.Image p+  D.withTensor tensor $ \ptr1 -> do+    let (fptr, len) = V.unsafeToForeignPtr0 vec+        whc = width * height * channel+    if (len /= whc)+      then throwIO $ userError $ "vector's length(" ++ show len ++ ") is not the same as tensor' one."+      else do+        F.withForeignPtr fptr $ \ptr2 -> do+          copyBytes (F.castPtr ptr2) (F.castPtr ptr1) len+          return img++writeBitmap :: FilePath -> D.Tensor -> IO ()+writeBitmap file tensor = do+  case (D.shape tensor, D.dtype tensor) of+    ([1, height, width, 1], D.UInt8) -> writeImage width height 1 (0 :: I.Pixel8) tensor >>= I.writeBitmap file+    ([1, height, width], D.UInt8) -> writeImage width height 1 (0 :: I.Pixel8) tensor >>= I.writeBitmap file+    ([1, height, width, 3], D.UInt8) -> writeImage width height 3 (I.PixelRGB8 0 0 0) tensor >>= I.writeBitmap file+    ([height, width, 1], D.UInt8) -> writeImage width height 1 (0 :: I.Pixel8) tensor >>= I.writeBitmap file+    ([height, width], D.UInt8) -> writeImage width height 1 (0 :: I.Pixel8) tensor >>= I.writeBitmap file+    ([height, width, 3], D.UInt8) -> writeImage width height 3 (I.PixelRGB8 0 0 0) tensor >>= I.writeBitmap file+    format -> throwIO $ userError $ "Can not write a image. " ++ show format ++ " is unsupported format."++writePng :: FilePath -> D.Tensor -> IO ()+writePng file tensor = do+  case (D.shape tensor, D.dtype tensor) of+    ([1, height, width, 1], D.UInt8) -> writeImage width height 1 (0 :: I.Pixel8) tensor >>= I.writePng file+    ([1, height, width], D.UInt8) -> writeImage width height 1 (0 :: I.Pixel8) tensor >>= I.writePng file+    ([1, height, width, 3], D.UInt8) -> writeImage width height 3 (I.PixelRGB8 0 0 0) tensor >>= I.writePng file+    ([height, width, 1], D.UInt8) -> writeImage width height 1 (0 :: I.Pixel8) tensor >>= I.writePng file+    ([height, width], D.UInt8) -> writeImage width height 1 (0 :: I.Pixel8) tensor >>= I.writePng file+    ([height, width, 3], D.UInt8) -> writeImage width height 3 (I.PixelRGB8 0 0 0) tensor >>= I.writePng file+    format -> throwIO $ userError $ "Can not write a image. " ++ show format ++ " is unsupported format."++-- [batch, height, width, channel] -> [batch, channel, height, width]+hwc2chw :: D.Tensor -> D.Tensor+hwc2chw = D.permute [0, 3, 1, 2]++-- [batch, channel, height, width] -> [batch, height, width, channel]+chw2hwc :: D.Tensor -> D.Tensor+chw2hwc = D.permute [0, 2, 3, 1]++randomIndexes :: Int -> [Int]+randomIndexes size = (`mod` size) <$> randoms seed where seed = mkStdGen 123
+ test/DimnameSpec.hs view
@@ -0,0 +1,23 @@+{-# LANGUAGE OverloadedStrings #-}++module DimnameSpec (spec) where++import Control.Exception.Safe+import Test.Hspec+import Torch.Autograd+import Torch.DType+import Torch.Dimname+import Torch.Functional+import Torch.Tensor+import Torch.TensorFactories+import Torch.TensorOptions++spec :: Spec+spec = do+  it "named tensor with ones" $ do+    let v = onesWithDimnames' [(3, "batch")]+        s = sumWithDimnames v ["batch"] False Float+    -- ToDo:+    -- onesWithDimnames' does not work.+    -- When v is evaluated, cpu is running full speed!!+    True `shouldBe` True
+ test/FactorySpec.hs view
@@ -0,0 +1,58 @@+module FactorySpec (spec) where++import Control.Exception.Safe+import Test.Hspec+import Torch.DType+import Torch.Functional+import Torch.Tensor+import Torch.TensorFactories+import Torch.TensorOptions++spec :: Spec+spec = do+  it "ones factory" $ do+    let x = ones' [50]+    shape x `shouldBe` [50]+  it "zeros factory" $ do+    let x = zeros' [50]+    shape x `shouldBe` [50]+  it "onesLike factory" $ do+    let x = onesLike $ zeros' [50]+    shape x `shouldBe` [50]+  it "zerosLike factory" $ do+    let x = zerosLike $ ones' [50]+    shape x `shouldBe` [50]+  it "randIO factory" $ do+    x <- randIO' [50]+    shape x `shouldBe` [50]+  it "randnIO factory" $ do+    x <- randnIO' [50]+    shape x `shouldBe` [50]+  it "linspace factory" $ do+    let start = 5.0 :: Double+    let end = 25.0 :: Double+    let x = linspace start end 50 defaultOpts+    (toDouble $ select 0 49 x) `shouldBe` 25.0+  it "logspace factory" $ do+    let start = 5.0 :: Double+    let end = 25.0 :: Double+    let x = logspace start end 50 2.0 defaultOpts+    (toDouble $ select 0 0 x) `shouldBe` 32.0+  it "eyeSquare factory" $ do+    let x = eyeSquare' 7+    shape x `shouldBe` [7, 7]+    (toDouble $ select 0 0 (select 0 0 x)) `shouldBe` 1.0+    (toDouble $ select 0 1 (select 0 0 x)) `shouldBe` 0.0+  it "eye factory" $ do+    let x = eye' 7 3+    shape x `shouldBe` [7, 3]+    (toDouble $ select 0 0 (select 0 0 x)) `shouldBe` 1.0+    (toDouble $ select 0 1 (select 0 0 x)) `shouldBe` 0.0+  it "full factory" $ do+    let x = full' [5, 2] (15.0 :: Double)+    shape x `shouldBe` [5, 2]+    (toDouble $ select 0 0 (select 0 0 x)) `shouldBe` 15.0+  it "arange factory" $ do+    let x = arange' 0 10 2+    shape x `shouldBe` [5]+    asValue x `shouldBe` [0 :: Float, 2, 4, 6, 8]
+ test/FunctionalSpec.hs view
@@ -0,0 +1,315 @@+{-# LANGUAGE NoMonomorphismRestriction #-}++module FunctionalSpec (spec) where++import Control.Exception.Safe+import Test.Hspec+--import Torch.Tensor+--import Torch.DType+--import Torch.TensorFactories+--import Torch.Functional+--import Torch.TensorOptions+import Torch+import Prelude hiding (abs, all, div, exp, floor, log, max, min)++spec :: Spec+spec = do+  it "scales and adds" $ do+    let x = 2 * ones' [10] + 3 * ones' [10]+    (toDouble $ select 0 4 x) `shouldBe` 5.0+  it "sumAll" $ do+    let x = sumAll (2 * ones' [5])+    toDouble x `shouldBe` 10.0+  it "abs" $ do+    let x = abs $ (-2) * ones' [5]+    (toDouble $ select 0 0 x) `shouldBe` 2.0+  it "add" $ do+    let x = (-2) * ones' [5]+    let y = abs x+    let z = add x y+    (toDouble $ select 0 0 z) `shouldBe` 0.0+  it "sub" $ do+    let x = (-2) * ones' [5]+    let y = abs x+    let z = sub x y+    (toDouble $ select 0 0 z) `shouldBe` -4.0+  it "mul" $ do+    let x = (-5) * ones' [5]+    let y = 2 * ones' [5]+    let z = mul x y+    (toDouble $ select 0 0 z) `shouldBe` -10.0+  it "div" $ do+    let x = (-5) * ones' [5]+    let y = 2 * ones' [5]+    let z = div x y+    (toDouble $ select 0 0 z) `shouldBe` -2.5+  it "ceil" $ do+    x <- randIO' [5]+    let y = ceil x+    (toDouble $ select 0 0 y) `shouldBe` 1.0+  it "floor" $ do+    x <- randIO' [5]+    let y = floor x+    (toDouble $ select 0 0 y) `shouldBe` 0.0+  it "takes the minimum of a linspace" $ do+    let x = linspace (5.0 :: Double) (25.0 :: Double) 50 defaultOpts+    let m = min x+    toDouble m `shouldBe` 5.0+  it "takes the maximum of a linspace" $ do+    let x = linspace (5.0 :: Double) (25.0 :: Double) 50 defaultOpts+    let m = max x+    toDouble m `shouldBe` 25.0+  it "takes the median of a linspace" $ do+    let x = linspace (5.0 :: Double) (10.0 :: Double) 5 defaultOpts+    let m = median x+    toDouble m `shouldBe` 7.5+  it "performs matrix vector multiplication" $ do+    let m = 3 * ones' [5, 5]+    let v = 2 * ones' [5, 1]+    let x = matmul m v+    (toDouble $ select 0 0 x) `shouldBe` 30.0+  it "erf" $ do+    let x = erf $ zeros' [4]+    (toDouble $ select 0 0 x) `shouldBe` 0.0+  it "exp" $ do+    let x = exp $ zeros' [4]+    (toDouble $ select 0 0 x) `shouldBe` 1.0+  it "log1p" $ do+    let x = log1p $ zeros' [4]+    (toDouble $ select 0 0 x) `shouldBe` 0.0+  it "log2" $ do+    let x = log2 $ 4 * ones' [4]+    (toDouble $ select 0 0 x) `shouldBe` 2.0+  it "log10" $ do+    let x = log10 $ 1000 * ones' [4]+    (toDouble $ select 0 0 x) `shouldBe` 3.0+  it "relu (pos)" $ do+    let x = relu $ 5 * ones' [4]+    (toDouble $ select 0 0 x) `shouldBe` 5.0+  it "relu (neg)" $ do+    let x = relu $ -5 * ones' [4]+    (toDouble $ select 0 0 x) `shouldBe` 0.0+  {-+   gels is deprecated. use lstsq.+   -- deps/pytorch/torch/functional.py --+    .. warning::+        :func:`torch.gels` is deprecated in favour of :func:`torch.lstsq` and will be removed in the+        next release. Please use :func:`torch.lstsq` instead.+  -}+  it "lstsq" $ do+    let x = lstsq (ones' [5, 2]) (ones' [5, 3])+    shape x `shouldBe` [3, 2]+  it "diag" $ do+    let x = ones' [3]+    let y = diag (Diag 2) x+    shape y `shouldBe` [5, 5]+  it "diagEmbed" $ do+    let t = ones' [2, 3]+    shape (diagEmbed (Diag 0) (Dim (-2)) (Dim (-1)) t) `shouldBe` [2, 3, 3]+    shape (diagEmbed (Diag 1) (Dim 0) (Dim 2) t) `shouldBe` [4, 2, 4]+  it "diagflat" $ do+    let t1 = ones' [3]+    shape (diagflat (Diag 0) t1) `shouldBe` [3, 3]+    shape (diagflat (Diag 1) t1) `shouldBe` [4, 4]+    let t2 = ones' [2, 2]+    shape (diagflat (Diag 0) t2) `shouldBe` [4, 4]+  it "diagonal" $ do+    let t1 = ones' [3, 3]+    shape (diagonal (Diag 0) (Dim 0) (Dim 1) t1) `shouldBe` [3]+    shape (diagonal (Diag 1) (Dim 0) (Dim 1) t1) `shouldBe` [2]+    let t2 = ones' [2, 5, 4, 2]+    shape (diagonal (Diag (-1)) (Dim 1) (Dim 2) t2) `shouldBe` [2, 2, 4]+  it "expand" $ do+    let t = asTensor [[1], [2], [3 :: Int]]+    shape (expand t False [3, 4]) `shouldBe` [3, 4]+  it "flattenAll" $ do+    let t = asTensor [[1, 2], [3, 4 :: Int]]+    shape (flattenAll t) `shouldBe` [4]++  -- decomposition / solvers+  it "solve" $ do+    a <- randIO' [10, 10]+    b <- randIO' [10, 3]+    let x = solve b a+    shape x `shouldBe` [10, 3]++  it "cholesky decomposes" $ do+    let x = asTensor ([[4.0, 12.0, -16.0], [12.0, 37.0, -43.0], [-16.0, -43.0, 98.0]] :: [[Double]])+        c = cholesky Upper x+        c' = asTensor ([[2.0, 6.0, -8.0], [0.0, 1.0, 5.0], [0.0, 0.0, 3.0]] :: [[Double]])+    all (c ==. c') `shouldBe` True+  it "inverse of an identity matrix is an identity matrix" $ do+    let soln = eq (inverse $ eye' 3 3) (eye' 3 3)+    all soln `shouldBe` True+  it "conv1d" $ do+    let batch = 10+        in_channel = 3+        out_channel = 10+        kernel = 1+        input = 5+        x =+          conv1d'+            (ones' [out_channel, in_channel, kernel])+            (ones' [out_channel])+            1+            0+            (ones' [batch, in_channel, input])+    shape x `shouldBe` [batch, out_channel, input]+  it "conv2d" $ do+    let batch = 10+        in_channel = 3+        out_channel = 10+        kernel0 = 1+        kernel1 = 1+        input0 = 5+        input1 = 6+        x =+          conv2d'+            (ones' [out_channel, in_channel, kernel0, kernel1])+            (ones' [out_channel])+            (1, 1)+            (0, 0)+            (ones' [batch, in_channel, input0, input1])+    shape x `shouldBe` [batch, out_channel, input0, input1]+  it "conv3d" $ do+    let batch = 10+        in_channel = 3+        out_channel = 10+        kernel0 = 1+        kernel1 = 1+        kernel2 = 1+        input0 = 5+        input1 = 6+        input2 = 7+        x =+          conv3d'+            (ones' [out_channel, in_channel, kernel0, kernel1, kernel2])+            (ones' [out_channel])+            (1, 1, 1)+            (0, 0, 0)+            (ones' [batch, in_channel, input0, input1, input2])+    shape x `shouldBe` [batch, out_channel, input0, input1, input2]+  it "convTranspose1d" $ do+    let batch = 10+        in_channel = 3+        out_channel = 10+        kernel = 1+        input = 5+        x =+          convTranspose1d'+            (ones' [in_channel, out_channel, kernel])+            (ones' [out_channel])+            1+            0+            (ones' [batch, in_channel, input])+    shape x `shouldBe` [batch, out_channel, input]+  it "convTranspose2d" $ do+    let batch = 10+        in_channel = 3+        out_channel = 10+        kernel0 = 1+        kernel1 = 1+        input0 = 5+        input1 = 6+        x =+          convTranspose2d'+            (ones' [in_channel, out_channel, kernel0, kernel1])+            (ones' [out_channel])+            (1, 1)+            (0, 0)+            (ones' [batch, in_channel, input0, input1])+    shape x `shouldBe` [batch, out_channel, input0, input1]+  it "convTranspose3d" $ do+    let batch = 10+        in_channel = 3+        out_channel = 10+        kernel0 = 1+        kernel1 = 1+        kernel2 = 1+        input0 = 5+        input1 = 6+        input2 = 7+        x =+          convTranspose3d'+            (ones' [in_channel, out_channel, kernel0, kernel1, kernel2])+            (ones' [out_channel])+            (1, 1, 1)+            (0, 0, 0)+            (ones' [batch, in_channel, input0, input1, input2])+    shape x `shouldBe` [batch, out_channel, input0, input1, input2]+  it "elu (pos)" $ do+    let x = elu (0.5 :: Float) $ 5 * ones' [4]+    (toDouble $ select 0 0 x) `shouldBe` 5.0+  it "elu (neg)" $ do+    let x = elu (0.5 :: Float) $ -5 * ones' [4]+    (toDouble $ select 0 0 x) `shouldBe` (-0.49663102626800537)+  it "elu' (pos)" $ do+    let x = elu' $ 5 * ones' [4]+    (toDouble $ select 0 0 x) `shouldBe` 5.0+  it "elu' (neg)" $ do+    let x = elu' $ -5 * ones' [4]+    (toDouble $ select 0 0 x) `shouldBe` (-0.9932620525360107)+  it "embedding" $ do+    let dic = asTensor ([[1, 2, 3], [4, 5, 6]] :: [[Float]])+        indices = asTensor ([0, 1, 1] :: [Int])+        x = embedding' dic indices+        value = asTensor ([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [4.0, 5.0, 6.0]] :: [[Float]])+    Torch.all (x `eq` value) `shouldBe` True+  it "smoothL1Loss" $ do+    let input = ones' [3]+        target = 3 * input+        output = smoothL1Loss ReduceNone input target+    (toDouble $ select 0 0 output) `shouldBe` (1.5)+  it "softMarginLoss" $ do+    let input = ones' [3]+        target = 3 * input+        output = softMarginLoss ReduceSum input target+    (toInt $ output * 1000) `shouldBe` (145)+  it "softShrink" $ do+    let input = 3 * ones' [3]+        output = softShrink 1 input+    (toDouble $ select 0 0 output) `shouldBe` (2.0)+  it "stack" $ do+    let x = ones' [4, 3]+        y = ones' [4, 3]+        output = stack (Dim 1) [x, y]+    (shape output) `shouldBe` ([4, 2, 3])+  it "sumDim" $ do+    let x = asTensor ([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]] :: [[Float]])+        output = sumDim (Dim 0) KeepDim Float x+    (toDouble $ select 1 1 output) `shouldBe` (26.0)+  it "topK" $ do+    let x = asTensor ([1, 2, 3] :: [Float])+        output = fst $ topK 2 (Dim 0) True True x+    (toDouble $ select 0 0 output) `shouldBe` (3.0)+  it "triu" $ do+    let x = asTensor ([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]] :: [[Float]])+    (toDouble $ sumAll $ triu (Diag 0) x) `shouldBe` (26.0)+  it "tril" $ do+    let x = asTensor ([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]] :: [[Float]])+    (toDouble $ sumAll $ tril (Diag 0) x) `shouldBe` (67.0)+  it "unsqueeze" $ do+    let x = asTensor ([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]] :: [[Float]])+        output = unsqueeze (Dim 0) x+    (shape output) `shouldBe` ([1, 4, 3])+  it "ctcLoss" $ do+    ctcLoss'+      ReduceMean+      [1]+      [1]+      (asTensor ([[[0.1, 0.2, 0.7]]] :: [[[Float]]]))+      (asTensor ([2] :: [Int]))+      `shouldBe` asTensor (-0.7 :: Float)+  it "scaled_dot_product_attention with Nothing mask" $ do+    let query = ones' [2, 4, 8]+        key = ones' [2, 4, 8]+        value = ones' [2, 4, 8]+        result = scaled_dot_product_attention query key value Nothing 0.0 True 1.0 False+    shape result `shouldBe` [2, 4, 8]+  it "scaled_dot_product_attention with Just mask" $ do+    let query = ones' [2, 4, 8]+        key = ones' [2, 4, 8]+        value = ones' [2, 4, 8]+        attn_mask = ones' [2, 4, 4]+        result = scaled_dot_product_attention query key value (Just attn_mask) 0.0 False 1.0 False+    shape result `shouldBe` [2, 4, 8]
+ test/GradSpec.hs view
@@ -0,0 +1,26 @@+module GradSpec (spec) where++import Control.Exception.Safe+import Test.Hspec+import Torch.Autograd+import Torch.DType+import Torch.Functional+import Torch.Tensor+import Torch.TensorFactories+import Torch.TensorOptions++spec :: Spec+spec = do+  it "grad with ones" $ do+    xi <- makeIndependent $ ones' []+    let x = toDependent xi+        y = x * x + 5 * x + 3+    fmap toDouble (grad y [xi]) `shouldBe` [7.0]+  it "grad with ones" $ do+    xi <- makeIndependent $ ones' []+    yi <- makeIndependent $ ones' []+    let x = toDependent xi+        y = toDependent yi+        z = x * x * y+    fmap toDouble (grad z [xi]) `shouldBe` [2.0]+    fmap toDouble (grad z [yi]) `shouldBe` [1.0]
+ test/IndexSpec.hs view
@@ -0,0 +1,89 @@+{-# LANGUAGE ExtendedDefaultRules #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TemplateHaskell #-}++module IndexSpec (spec) where++import Control.Arrow ((&&&))+import Lens.Family+import Test.Hspec+import Test.QuickCheck+import Torch.DType+import Torch.Index+import Torch.Lens+import Torch.Tensor+import Torch.TensorFactories++spec :: Spec+spec = do+  describe "slice" $ do+    it "None" $ do+      [slice|None|] `shouldBe` None+    it "Ellipsis" $ do+      [slice|Ellipsis|] `shouldBe` Ellipsis+    it "..." $ do+      [slice|...|] `shouldBe` Ellipsis+    it "123" $ do+      [slice|123|] `shouldBe` 123+    it "-123" $ do+      [slice|-123|] `shouldBe` -123+    it "True" $ do+      [slice|True|] `shouldBe` True+    it "False" $ do+      [slice|False|] `shouldBe` False+    it ":" $ do+      [slice|:|] `shouldBe` Slice ()+    it "::" $ do+      [slice|::|] `shouldBe` Slice ()+    it "1:" $ do+      [slice|1:|] `shouldBe` Slice (1, None)+    it "1::" $ do+      [slice|1::|] `shouldBe` Slice (1, None)+    it ":3" $ do+      [slice|:3|] `shouldBe` Slice (None, 3)+    it ":3:" $ do+      [slice|:3:|] `shouldBe` Slice (None, 3)+    it "::2" $ do+      [slice|::2|] `shouldBe` Slice (None, None, 2)+    it "1:3" $ do+      [slice|1:3|] `shouldBe` Slice (1, 3)+    it "1::2" $ do+      [slice|1::2|] `shouldBe` Slice (1, None, 2)+    it ":3:2" $ do+      [slice|:3:2|] `shouldBe` Slice (None, 3, 2)+    it "1:3:2" $ do+      [slice|1:3:2|] `shouldBe` Slice (1, 3, 2)+    it "1,2,3" $ do+      [slice|1,2,3|] `shouldBe` (1, 2, 3)+    it "1 , 2, 3" $ do+      [slice|1 , 2, 3|] `shouldBe` (1, 2, 3)+    it "1 , 2, 3" $ do+      let i = 1+      [slice|{i} , 2, 3|] `shouldBe` (1, 2, 3)+  describe "indexing" $ do+    it "pick up a value" $ do+      let x = asTensor ([[[0, 1, 2], [3, 4, 5]], [[6, 7, 8], [9, 10, 11]]] :: [[[Int]]])+          r = x ! [slice|1,0,2|]+      (dtype &&& shape &&& asValue) r `shouldBe` (Int64, ([], 8 :: Int))+    it "intercalate" $ do+      let x = zeros' [6]+          i = [slice|0::2|]+      (dtype &&& shape &&& asValue) (maskedFill x i (arange' 1 4 1)) `shouldBe` (Float, ([6], [1, 0, 2, 0, 3, 0] :: [Float]))+    it "negative index" $ do+      let x = arange' 1 5 1+          i = [slice|-1|]+      (dtype &&& shape &&& asValue) (x ! i) `shouldBe` (Float, ([], 4 :: Float))+  describe "indexing with lens" $ do+    it "pick up a value" $ do+      let x = asTensor ([[[0, 1, 2], [3, 4, 5]], [[6, 7, 8], [9, 10, 11]]] :: [[[Int]]])+          r = x ^. [lslice|1,0,2|]+      (dtype &&& shape &&& asValue) r `shouldBe` (Int64, ([], 8 :: Int))+    it "intercalate" $ do+      let x = zeros' [6]+          i = [lslice|0::2|] :: Lens' Tensor Tensor+      (dtype &&& shape &&& asValue) (x & i .~ arange' 1 4 1) `shouldBe` (Float, ([6], [1, 0, 2, 0, 3, 0] :: [Float]))+    it "negative index" $ do+      let x = arange' 1 5 1+          i = [lslice|-1|]+      (dtype &&& shape &&& asValue) (x ^. i) `shouldBe` (Float, ([], 4 :: Float))
+ test/InitializerSpec.hs view
@@ -0,0 +1,23 @@+module InitializerSpec where++import Test.Hspec+import Torch.Functional+import Torch.Initializers+import Torch.Tensor (asValue)+import Prelude hiding (abs, mean, var)++spec :: Spec+spec = do+  describe "Check initializers" $ do+    it "kaiming uniform is 0-centered" $ do+      x <- kaimingUniform' [50, 500]+      (asValue (abs . mean $ x) :: Float) < 0.01 `shouldBe` True+    it "kaiming normal is 0-centered" $ do+      x <- kaimingNormal' [50, 500]+      (asValue (abs . mean $ x) :: Float) < 0.01 `shouldBe` True+    it "xavier uniform is 0-centered" $ do+      x <- xavierUniform' [50, 500]+      (asValue (abs . mean $ x) :: Float) < 0.01 `shouldBe` True+    it "xavier normal is 0-centered" $ do+      x <- xavierNormal' [50, 500]+      (asValue (abs . mean $ x) :: Float) < 0.01 `shouldBe` True
+ test/LensSpec.hs view
@@ -0,0 +1,32 @@+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE NoMonomorphismRestriction #-}++module LensSpec (spec) where++import Control.Exception.Safe (catch, throwIO)+import GHC.Generics+import Language.C.Inline.Cpp.Exceptions (CppException (..))+import Test.Hspec+import Torch.Lens++data WTree a w+  = Leaf a+  | Fork (WTree a w) (WTree a w)+  | WithWeight (WTree a w) w+  deriving (Generic, Show, Eq)++myTree = WithWeight (Fork (Leaf (Just "hello")) (Leaf Nothing)) "world"++instance {-# OVERLAPS #-} HasTypes String String where+  types_ = id++spec :: Spec+spec = describe "lens" $ do+  it "over for list" $ do+    over (types @String) (++ "!") ["hello"] `shouldBe` ["hello!"]+  it "over for tree" $ do+    over (types @String) (++ "!") myTree `shouldBe` WithWeight (Fork (Leaf (Just "hello!")) (Leaf Nothing)) "world!"
+ test/NNSpec.hs view
@@ -0,0 +1,40 @@+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE NoMonomorphismRestriction #-}++module NNSpec (spec) where++import Control.Exception.Safe+import Control.Monad.State.Strict+import GHC.Generics+import Test.Hspec+import Torch.Autograd+import Torch.NN+import Torch.Tensor+import Torch.TensorFactories++spec :: Spec+spec = do+  it "create flatten-parameters of Linear" $ do+    init <- sample $ LinearSpec {in_features = 3, out_features = 1}+    init2 <- sample $ LinearSpec {in_features = 3, out_features = 1}+    length (flattenParameters init) `shouldBe` 2+    length (flattenParameters (fst (flip runState (flattenParameters init2) (_replaceParameters init)))) `shouldBe` 2+  it "create flatten-parameters of [Linear]" $ do+    i0 <- sample $ LinearSpec {in_features = 3, out_features = 1}+    i1 <- sample $ LinearSpec {in_features = 3, out_features = 1}+    i2 <- sample $ LinearSpec {in_features = 3, out_features = 1}+    i3 <- sample $ LinearSpec {in_features = 3, out_features = 1}+    let init = [i0, i1]+        init2 = [i2, i3]+    length (flattenParameters init) `shouldBe` 4+    length (flattenParameters (fst (flip runState (flattenParameters init2) (_replaceParameters init)))) `shouldBe` 4+  it "create flatten-parameters of (Parameter,Parameter)" $ do+    i0 <- makeIndependent $ zeros' [2, 2]+    i1 <- makeIndependent $ zeros' [2, 2]+    i2 <- makeIndependent $ zeros' [2, 2]+    let init = (i0, i1)+        init2 = (i0, i1, i2)+    length (flattenParameters init) `shouldBe` 2+    length (flattenParameters init2) `shouldBe` 3
+ test/OptimSpec.hs view
@@ -0,0 +1,273 @@+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RecordWildCards #-}++module OptimSpec where++import Control.Monad (when)+import GHC.Generics+import Test.Hspec+import Text.Printf (printf)+import Torch.Autograd+import Torch.Functional+import Torch.NN+import Torch.Optim+import Torch.Tensor+import Torch.TensorFactories (eye', ones', randIO', randnIO', zeros')+import Prelude hiding (cos, exp, sqrt)+import qualified Prelude as P++-- Convex Quadratic++data ConvQuadSpec = ConvQuadSpec {n :: Int}++data ConvQuad = ConvQuad {w :: Parameter} deriving (Show, Generic)++instance Randomizable ConvQuadSpec ConvQuad where+  sample (ConvQuadSpec n) = do+    w <- makeIndependent =<< randnIO' [n]+    pure $ ConvQuad w++instance Parameterized ConvQuad++convexQuadratic :: Tensor -> Tensor -> Tensor -> Tensor+convexQuadratic a b w =+  mulScalar (0.5 :: Float) (dot (mv a w) w) - dot w b++lossConvQuad :: Tensor -> Tensor -> ConvQuad -> Tensor+lossConvQuad a b (ConvQuad w) = convexQuadratic a b w'+  where+    w' = toDependent w++-- 2D Rosenbrock++data RosenSpec = RosenSpec deriving (Show, Eq)++data Rosen = Rosen {x :: Parameter, y :: Parameter} deriving (Generic)++instance Show Rosen where+  show (Rosen x y) = show (extract x :: Float, extract y :: Float)+    where+      extract :: TensorLike a => Parameter -> a+      extract p = asValue $ toDependent p++instance Randomizable RosenSpec Rosen where+  sample RosenSpec = do+    x <- makeIndependent =<< randnIO' [1]+    y <- makeIndependent =<< randnIO' [1]+    pure $ Rosen x y++-- instance Parameterized Rosen++instance Parameterized Rosen where+  -- flattenParameters :: f -> [Parameter]+  flattenParameters (Rosen x y) = [x, y]++rosenbrock2d :: Float -> Float -> Tensor -> Tensor -> Tensor+rosenbrock2d a b x y = square (addScalar a $ (-1.0) * x) + mulScalar b (square (y - x * x))+  where+    square = pow (2 :: Int)++rosenbrock' :: Tensor -> Tensor -> Tensor+rosenbrock' = rosenbrock2d 1.0 100.0++lossRosen :: Rosen -> Tensor+lossRosen Rosen {..} = rosenbrock' (toDependent x) (toDependent y)++-- Ackley function++data AckleySpec = AckleySpec deriving (Show, Eq)++data Ackley = Ackley {pos :: Parameter} deriving (Show, Generic)++instance Randomizable AckleySpec Ackley where+  sample AckleySpec = do+    pos <- makeIndependent =<< randnIO' [2]+    pure $ Ackley pos++instance Parameterized Ackley++ackley :: Float -> Float -> Float -> Tensor -> Tensor+ackley a b c x =+  mulScalar (- a) (exp (- b' * (sqrt $ (sumAll (x * x)) / d)))+    - exp (1.0 / d * sumAll (cos (mulScalar c x)))+    + (asTensor $ a + P.exp 1.0)+  where+    b' = asTensor b+    c' = asTensor c+    d = asTensor . product $ shape x++ackley' = ackley 20.0 0.2 (2 * pi :: Float)++lossAckley :: Ackley -> Tensor+lossAckley (Ackley x) = ackley' x'+  where+    x' = toDependent x++-- | show output after n iterations (not used for tests)+showLog :: (Show a) => Int -> Int -> Int -> Tensor -> a -> IO ()+showLog n i maxIter lossValue state =+  when (i == 0 || mod i n == 0 || i == maxIter -1) $ do+    putStrLn+      ( "Iter: " ++ printf "%6d" i+          ++ " | Loss:"+          ++ printf "%05.4f" (asValue lossValue :: Float)+          ++ " | Parameters: "+          ++ show state+      )++-- | Optimize convex quadratic with specified optimizer+optConvQuad :: (Optimizer o) => Int -> o -> IO ()+optConvQuad numIter optInit = do+  let dim = 2+      a = eye' dim dim+      b = zeros' [dim]+  paramInit <- sample $ ConvQuadSpec dim+  trained <- foldLoop (paramInit, optInit) numIter $ \(paramState, optState) i -> do+    let lossValue = (lossConvQuad a b) paramState+    runStep paramState optState lossValue 5e-4+  pure ()++-- | Optimize Rosenbrock function with specified optimizer+optRosen :: (Optimizer o) => Int -> o -> IO ()+optRosen numIter optInit = do+  paramInit <- sample RosenSpec+  trained <- foldLoop (paramInit, optInit) numIter $ \(paramState, optState) i -> do+    let lossValue = lossRosen paramState+    runStep paramState optState lossValue 5e-4+  pure ()++-- | Optimize Ackley function with specified optimizer+optAckley :: (Optimizer o) => Int -> o -> IO ()+optAckley numIter optInit = do+  paramInit <- sample AckleySpec+  trained <- foldLoop (paramInit, optInit) numIter $ \(paramState, optState) i -> do+    let lossValue = lossAckley paramState+    runStep paramState optState lossValue 5e-4+  pure ()++-- | Check global minimum point for Rosenbrock+checkGlobalMinRosen :: IO ()+checkGlobalMinRosen = do+  putStrLn "\nCheck Actual Global Minimum (at 1, 1):"+  print $ rosenbrock' (asTensor (1.0 :: Float)) (asTensor (1.0 :: Float))++-- | Check global minimum point for Convex Quadratic+checkGlobalMinConvQuad :: IO ()+checkGlobalMinConvQuad = do+  putStrLn "\nCheck Actual Global Minimum (at 0, 0):"+  let dim = 2+      a = eye' dim dim+      b = zeros' [dim]+  print $ convexQuadratic a b (zeros' [dim])++-- | Check global minimum point for Ackley+checkGlobalMinAckley :: IO ()+checkGlobalMinAckley = do+  putStrLn "\nCheck Actual Global Minimum (at 0, 0):"+  print $ ackley' (zeros' [2])++main :: IO ()+main = do+  let numIter = 20000++  -- Convex Quadratic w/ GD, GD+Momentum, Adam+  putStrLn "\nConvex Quadratic\n================"+  putStrLn "\nGD"+  optConvQuad numIter GD+  putStrLn "\nGD + Momentum"+  optConvQuad numIter (GDM 0.9 [zeros' [2]])+  putStrLn "\nAdam"+  optConvQuad+    numIter+    Adam+      { beta1 = 0.9,+        beta2 = 0.999,+        m1 = [zeros' [1], zeros' [1]],+        m2 = [zeros' [1], zeros' [1]],+        iter = 0+      }+  checkGlobalMinConvQuad++  -- 2D Rosenbrock w/ GD, GD+Momentum, Adam+  putStrLn "\n2D Rosenbrock\n================"+  putStrLn "\nGD"+  optRosen numIter GD+  putStrLn "\nGD + Momentum"+  optRosen numIter (GDM 0.9 [zeros' [1], zeros' [1]])+  putStrLn "\nAdam"+  optRosen+    numIter+    Adam+      { beta1 = 0.9,+        beta2 = 0.999,+        m1 = [zeros' [1], zeros' [1]],+        m2 = [zeros' [1], zeros' [1]],+        iter = 0+      }+  checkGlobalMinRosen++  -- Ackley w/ GD, GD+Momentum, Adam+  putStrLn "\nAckley (Gradient methods fail)\n================"+  putStrLn "\nGD"+  optAckley numIter GD+  putStrLn "\nGD + Momentum"+  optAckley numIter (GDM 0.9 [zeros' [1], zeros' [1]])+  putStrLn "\nAdam"+  optAckley+    numIter+    Adam+      { beta1 = 0.9,+        beta2 = 0.999,+        m1 = [zeros' [1], zeros' [1]],+        m2 = [zeros' [1], zeros' [1]],+        iter = 0+      }+  checkGlobalMinAckley++spec :: Spec+spec = do+  it "ConvQuad GD" $ do+    optConvQuad numIter GD+  it "ConvQuad GDM" $ do+    optConvQuad numIter (GDM 0.9 [zeros' [2]])+  it "ConvQuad Adam" $ do+    optConvQuad+      numIter+      Adam+        { beta1 = 0.9,+          beta2 = 0.999,+          m1 = [zeros' [1], zeros' [1]],+          m2 = [zeros' [1], zeros' [1]],+          iter = 0+        }+  it "Rosen GD" $ do+    optRosen numIter GD+  it "Rosen GDM" $ do+    optRosen numIter (GDM 0.9 [zeros' [1], zeros' [1]])+  it "Rosen Adam" $ do+    optRosen+      numIter+      Adam+        { beta1 = 0.9,+          beta2 = 0.999,+          m1 = [zeros' [1], zeros' [1]],+          m2 = [zeros' [1], zeros' [1]],+          iter = 0+        }+  it "Ackley GD" $ do+    optAckley numIter GD+  it "Ackley GDM" $ do+    optAckley numIter (GDM 0.9 [zeros' [1], zeros' [1]])+  it "Ackley Adam" $ do+    optAckley+      numIter+      Adam+        { beta1 = 0.9,+          beta2 = 0.999,+          m1 = [zeros' [1], zeros' [1]],+          m2 = [zeros' [1], zeros' [1]],+          iter = 0+        }+  where+    numIter = 100
+ test/PipelineSpec.hs view
@@ -0,0 +1,108 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}++module PipelineSpec where++import Control.Concurrent+import Control.Concurrent.Async+import Control.Monad+import Control.Monad.Cont (ContT (runContT))+import GHC.Exts (IsList (fromList))+import GHC.IO (unsafePerformIO)+import Pipes+import Pipes.Prelude (drain)+import qualified Pipes.Prelude as P+import System.Exit+import System.IO+import System.Random+import System.Timeout+import Test.Hspec+import Torch.Data.Pipeline+import Torch.Data.Utils++streamAheadTimeout = 25000++timeoutConcurrent = 85000++data MockData = MockData++data ConcurrentData = ConcurrentData++data ShuffleSet = ShuffleSet++-- | Yields 4 items, each item taking 10000 milliseconds to compute+instance Dataset IO ConcurrentData Int Int where+  getItem ConcurrentData k = threadDelay 10000 >> pure k+  keys ConcurrentData = fromList [0 .. 7]++-- | Yields 2 items, each taking 5000 milliseconds to compute+instance Dataset IO MockData Int Int where+  getItem MockData _ = threadDelay 10000 >> pure 0+  keys (MockData) = fromList [0 .. 1]++instance Dataset IO ShuffleSet Int Int where+  getItem ShuffleSet k = pure k+  keys _ = fromList [0 .. 100]++testFoldTimeout :: MockData -> IO ()+testFoldTimeout dataset = do+  runContT (streamFromMap (datasetOpts 1) dataset) $+    (\l -> runEffect $ enumerateData l >-> takeThenTimeout) . fst+  where+    takeThenTimeout = forever $ do+      (_, iter) <- await+      lift $ when (iter == 0) $ threadDelay 5000++testConcurrentFoldTimeout :: ConcurrentData -> Int -> IO ()+testConcurrentFoldTimeout dataset numWorkers = do+  runContT (streamFromMap (datasetOpts numWorkers) dataset) $+    (\l -> runEffect $ enumerateData l >-> takeThenTimeout) . fst+  where+    takeThenTimeout = forever $ do+      (_, iter) <- await+      -- don't timeout on the last two iterations since data shouldn't be+      -- getting yielded anymore+      lift $ when (iter < 7) $ threadDelay 5000++testShuffle :: IO ()+testShuffle = do+  let options = (datasetOpts 4) {shuffle = Shuffle $ mkStdGen 123}+  let optionsDiff = (datasetOpts 4) {shuffle = Shuffle $ mkStdGen 50}++  datasets <- replicateM 100 $ runContT (streamFromMap options ShuffleSet) $ P.toListM . enumerate . fst+  differentOrder <- runContT (streamFromMap optionsDiff ShuffleSet) $ P.toListM . enumerate . fst++  all (\elems -> elems == head datasets) datasets `shouldBe` True+  head datasets == differentOrder `shouldBe` False++-- | This function returns Nothing if the IO action takes longer than the given+-- | time, otherwise it returns Just ()+runTest :: Int -> IO () -> IO (Maybe ())+runTest time test = do+  hFlush stdout+  result <- timeout time test+  pure result++-- | The first test tests if batches are being streamed ahead of+-- | the fold function for consumption. A new batch should be processed as soon as+-- | the fold consumes a batch.+-- |+-- | The second test tests that with 2 workers and fold processing batches twice as fast+-- | as they are yielded that workers are never idling. If they are the test must fail.+-- | Diagrammatically, this is how things should work out:+-- |+-- | working = -, idle = .+-- | Worker 1: |-----|-----|-----|+-- | Worker 2: |-----|-----|-----|+-- | Fold:     |.....|--|--|--|--|--|--|+spec :: Spec+spec = do+#ifndef darwin_HOST_OS+  it "Test data is flowing" $+    (runTest streamAheadTimeout (testFoldTimeout MockData)) `shouldReturn` (Just ())+  it "Test concurrent datasets yield concurrently" $+    (runTest timeoutConcurrent (testConcurrentFoldTimeout ConcurrentData 2) `shouldReturn` (Just ()))+#endif+  it "Test shuffle is deterministic with seed" $ testShuffle
+ test/RandomSpec.hs view
@@ -0,0 +1,21 @@+{-# LANGUAGE ScopedTypeVariables #-}++module RandomSpec (spec) where++import Control.Exception.Safe+import Test.Hspec+import Torch.Device+import Torch.Random+import Torch.Tensor+import Torch.TensorOptions++spec :: Spec+spec = do+  it "pure functional random with seed" $ do+    generator <- mkGenerator (Device CPU 0) 0+    let (t, next) = randn' [4] generator+        (_, next') = randn' [4] next+        (t2, next'') = randn' [4] next'+        (t3, _) = randn' [5] generator+    shape t2 `shouldBe` [4]+    ((asValue t) :: [Float]) `shouldBe` take 4 (asValue t3)
+ test/ScriptSpec.hs view
@@ -0,0 +1,137 @@+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE NoMonomorphismRestriction #-}++module ScriptSpec (spec) where++import Control.Exception.Safe (catch, throwIO)+import GHC.Generics+import Test.Hspec+import Torch hiding (forward)+import Torch.Autograd+import Torch.NN+import Torch.Script+import Prelude hiding (abs, exp, floor, log, max, min)++data MLPSpec = MLPSpec+  { inputFeatures :: Int,+    hiddenFeatures0 :: Int,+    hiddenFeatures1 :: Int,+    outputFeatures :: Int+  }+  deriving (Show, Eq)++data MLP = MLP+  { l0 :: Linear,+    l1 :: Linear,+    l2 :: Linear+  }+  deriving (Generic, Show)++instance Parameterized MLP++instance Randomizable MLPSpec MLP where+  sample MLPSpec {..} =+    MLP+      <$> sample (LinearSpec inputFeatures hiddenFeatures0)+      <*> sample (LinearSpec hiddenFeatures0 hiddenFeatures1)+      <*> sample (LinearSpec hiddenFeatures1 outputFeatures)++mlp :: MLP -> Tensor -> Tensor+mlp MLP {..} input =+  logSoftmax (Dim 1)+    . linear l2+    . relu+    . linear l1+    . relu+    . linear l0+    $ input++data MonoSpec = MonoSpec deriving (Show, Eq)++data MonoP = MonoP+  { m :: Parameter+  }+  deriving (Generic, Show)++instance Parameterized MonoP++instance Randomizable MonoSpec MonoP where+  sample MonoSpec = do+    m <- makeIndependent (ones' [])+    return $ MonoP {..}++monop :: MonoP -> Tensor -> Tensor+monop MonoP {..} input = input * (toDependent m)++spec :: Spec+spec = describe "torchscript" $ do+  it "define and run" $ do+    let v00 = asTensor (4 :: Float)+    m <- newModule "m"+    v00' <- makeIndependent v00+    registerParameter m "p0" (toDependent v00') False+    define m $+      "def foo(self, x):\n"+        ++ "    return (1, 2, x + 3 + 2 * self.p0)\n"+        ++ "\n"+        ++ "def forward(self, x):\n"+        ++ "    tuple = self.foo(x)\n"+        ++ "    return tuple\n"+    sm <- toScriptModule m+    let IVTuple [IVInt a, IVInt b, IVTensor c] = runMethod1 sm "forward" (IVTensor (ones' []))+    a `shouldBe` 1+    b `shouldBe` 2+    (asValue c :: Float) `shouldBe` 12.0+    saveScript sm "self.pt"+    sm2 <- loadScript WithRequiredGrad "self.pt"+    let IVTuple [IVInt a, IVInt b, IVTensor c] = runMethod1 sm2 "forward" (IVTensor (ones' []))+    let [g] = grad c (flattenParameters sm2)+    (asValue g :: Float) `shouldBe` 2.0+    return ()++  it "trace" $ do+    let v00 = asTensor (4 :: Float)+        v01 = asTensor (8 :: Float)+    m <- trace "MyModule" "forward" (\[x, y] -> return [x + y]) [v00, v01]+    sm <- toScriptModule m+    saveScript sm "self2.pt"+    let (IVTensor r0) = forward sm (map IVTensor [v00, v01])+    (asValue r0 :: Float) `shouldBe` 12+    graph <- traceAsGraph (\[x, y] -> return [x + y]) [v00, v01]+    graph' <- graphToJitGraph graph+    print graph'+  --    prettyException $ printGraph m2 >>= putStr+  --    prettyException $ printOnnx m2 >>= print+  it "trace mlp with parameters" $ do+    v00 <- randnIO' [3, 784]+    init' <- sample (MLPSpec 784 64 32 10)+    m <- traceWithParameters "MyModule" (\p [x] -> return [(mlp p x)]) init' [v00]+    sm <- toScriptModule m+    saveScript sm "mlp.pt"+    let (IVTensor r0) = forward sm (map IVTensor [v00])+    (shape r0) `shouldBe` [3, 10]+  it "trace monop with parameters" $ do+    let v00 = asTensor (4 :: Float)+    init' <- sample MonoSpec+    m <- traceWithParameters "MyModule" (\p [x] -> return [(monop p x)]) init' [v00]+    sm <- toScriptModule m+    saveScript sm "monop.pt"+    let (IVTensor r0) = forward sm (map IVTensor [v00])+    (asValue r0 :: Float) `shouldBe` 4.0+    (shape r0) `shouldBe` []+    let p0 = asTensor (2 :: Float)+    rm <- toRawModule sm+    setParameters rm [p0]+    ps <- getParametersIO rm+    sm2 <- toScriptModule rm+    let (IVTensor r2) = forward sm2 (map IVTensor [v00])+    (asValue r2 :: Float) `shouldBe` 8.0+    (shape r2) `shouldBe` []+  it "run" $ do+    m2 <- loadScript WithoutRequiredGrad "self2.pt"+    let v10 = asTensor (40 :: Float)+        v11 = asTensor (80 :: Float)+    let (IVTensor r1) = forward m2 (map IVTensor [v10, v11])+    (asValue r1 :: Float) `shouldBe` 120
+ test/SerializeSpec.hs view
@@ -0,0 +1,42 @@+module SerializeSpec (spec) where++import System.Directory (removeFile)+import System.IO+import Test.Hspec+import Torch.Serialize+import Torch.Tensor+import Torch.TensorFactories++spec :: Spec+spec = do+  it "save and load tensor" $ do+    let i =+          [ [0, 1, 1],+            [2, 0, 2]+          ] ::+            [[Int]]+        v = [3, 4, 5] :: [Float]+    save [(asTensor i), (asTensor v)] "test.pt"+    tensors <- load "test.pt"+    removeFile "test.pt"+    length tensors `shouldBe` 2+    let [ii, vv] = tensors+    (asValue ii :: [[Int]]) `shouldBe` i+    (asValue vv :: [Float]) `shouldBe` v+  it "save and load a raw data of numpy" $ do+    let org = zeros' [4]+    -- Following python script generates 'test/data/numpy_rawfile' file+    --+    -- #!/usr/bin/env python+    -- import torch+    -- f = open("test/data/numpy_rawfile","wb")+    -- torch.tensor([1,2,3,4], dtype=torch.float32).numpy().tofile(f)+    --+    new <- System.IO.withFile "test/data/numpy_rawfile" System.IO.ReadMode $+      \h -> loadBinary h org+    (asValue new :: [Float]) `shouldBe` [1, 2, 3, 4]+    System.IO.withFile "numpy_rawfile" System.IO.WriteMode $+      \h -> saveBinary h new+    new' <- System.IO.withFile "numpy_rawfile" System.IO.ReadMode $+      \h -> loadBinary h org+    (asValue new' :: [Float]) `shouldBe` [1, 2, 3, 4]
+ test/SparseSpec.hs view
@@ -0,0 +1,39 @@+{-# LANGUAGE NoMonomorphismRestriction #-}++module SparseSpec (spec) where++import Control.Exception.Safe+import Test.Hspec+import Torch.DType+import Torch.Functional+import Torch.Layout+import Torch.Tensor+import Torch.TensorFactories+import Torch.TensorOptions+import Prelude hiding (abs, exp, floor, log, max, min)++spec :: Spec+spec = do+  it "create sparse tensor" $ do+    let i =+          [ [0, 1, 1],+            [2, 0, 2]+          ] ::+            [[Int]]+        v = [3, 4, 5] :: [Float]+    let x = sparseCooTensor' (asTensor i) (asTensor v) [2, 3]+    (shape (asTensor i)) `shouldBe` [2, 3]+    (shape (asTensor v)) `shouldBe` [3]+    print (toDense x)+    -- When we call print for sparse tensor, it throws a exception.+    print x -- `shouldThrow` anyException+    (asValue (toDense x) :: [[Float]]) `shouldBe` [[0.0, 0.0, 3.0], [4.0, 0.0, 5.0]]+    (asValue (toDense (x + x)) :: [[Float]]) `shouldBe` [[0.0, 0.0, 6.0], [8.0, 0.0, 10.0]]+    (asValue (toDense (toSparse (toDense (x + x)))) :: [[Float]]) `shouldBe` [[0.0, 0.0, 6.0], [8.0, 0.0, 10.0]]+  it "zeros sparse tensor" $ do+    let x = zeros [2, 3] $ withLayout Sparse defaultOpts+    print x -- `shouldThrow` anyException+    (asValue (toDense x) :: [[Float]]) `shouldBe` [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]+  it "large sparse tensor" $ do+    let x = zeros [1000, 1000, 1000] $ withLayout Sparse defaultOpts+    shape x `shouldBe` [1000, 1000, 1000]
+ test/Spec.hs view
@@ -0,0 +1,81 @@+module Main where++import Test.Hspec (hspec)+import qualified DimnameSpec+import qualified FactorySpec+import qualified FunctionalSpec+import qualified GradSpec+import qualified IndexSpec+import qualified InitializerSpec+import qualified LensSpec+import qualified NNSpec+import qualified OptimSpec+import qualified PipelineSpec+import qualified RandomSpec+import qualified ScriptSpec+import qualified SerializeSpec+import qualified SparseSpec+import qualified TensorSpec+import qualified VisionSpec+import qualified Torch.Distributions.BernoulliSpec+import qualified Torch.Distributions.CategoricalSpec+import qualified Torch.Distributions.ConstraintsSpec+import qualified Torch.Typed.AutogradSpec+import qualified Torch.Typed.AuxiliarySpec+import qualified Torch.Typed.FactoriesSpec+import qualified Torch.Typed.FunctionalSpec0+import qualified Torch.Typed.FunctionalSpec1+import qualified Torch.Typed.FunctionalSpec2+import qualified Torch.Typed.NN.Recurrent.Cell.GRUSpec+import qualified Torch.Typed.NN.Recurrent.Cell.LSTMSpec+import qualified Torch.Typed.NN.Recurrent.GRUSpec+import qualified Torch.Typed.NN.Recurrent.LSTMSpec+import qualified Torch.Typed.NN.TransformerSpec+import qualified Torch.Typed.NNSpec+import qualified Torch.Typed.NamedTensorSpec+import qualified Torch.Typed.OptimSpec+import qualified Torch.Typed.TensorSpec0+import qualified Torch.Typed.TensorSpec1+import qualified Torch.Typed.VisionSpec+import qualified Torch.Typed.SerializeSpec++main :: IO ()+main = hspec $ do+  DimnameSpec.spec+  FactorySpec.spec+  FunctionalSpec.spec+  GradSpec.spec+  IndexSpec.spec+  InitializerSpec.spec+  LensSpec.spec+  NNSpec.spec+  OptimSpec.spec+  PipelineSpec.spec+  RandomSpec.spec+  ScriptSpec.spec+  SerializeSpec.spec+  SparseSpec.spec+  TensorSpec.spec+  VisionSpec.spec+  Torch.Distributions.BernoulliSpec.spec+  Torch.Distributions.CategoricalSpec.spec+  Torch.Distributions.ConstraintsSpec.spec+  Torch.Typed.AutogradSpec.spec+  Torch.Typed.AuxiliarySpec.spec+  Torch.Typed.FactoriesSpec.spec+  Torch.Typed.FunctionalSpec0.spec+  Torch.Typed.FunctionalSpec1.spec+  Torch.Typed.FunctionalSpec2.spec+  Torch.Typed.NN.Recurrent.Cell.GRUSpec.spec+  Torch.Typed.NN.Recurrent.Cell.LSTMSpec.spec+  Torch.Typed.NN.Recurrent.GRUSpec.spec+  Torch.Typed.NN.Recurrent.LSTMSpec.spec+  Torch.Typed.NN.TransformerSpec.spec+  Torch.Typed.NNSpec.spec+  Torch.Typed.NamedTensorSpec.spec+  Torch.Typed.OptimSpec.spec+  Torch.Typed.TensorSpec0.spec+  Torch.Typed.TensorSpec1.spec+  Torch.Typed.VisionSpec.spec+  Torch.Typed.SerializeSpec.spec+
+ test/TensorSpec.hs view
@@ -0,0 +1,307 @@+{-# LANGUAGE ExtendedDefaultRules #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE UndecidableInstances #-}++module TensorSpec (spec) where++import Control.Arrow ((&&&))+import Control.Exception.Safe+import Numeric.Half+import Data.Complex+import Data.Int+import Data.Word+import Test.Hspec+import Test.QuickCheck+import Torch.DType+import Torch.Functional+import Torch.Tensor+import Torch.TensorFactories+import Torch.TensorOptions+import Test.QuickCheck.Arbitrary+import qualified Data.Vector.Storable as VS+import qualified Data.Vector.Unboxed as VU+import qualified Data.Vector.Generic as VG++instance Arbitrary Half where+  arbitrary = arbitrarySizedFractional+  shrink    = shrinkDecimal++instance (Arbitrary a, VS.Storable a) => Arbitrary (VS.Vector a) where+  arbitrary = do+    n  <- choose (0, 20)           -- limit length to at most 20+    xs <- vectorOf n arbitrary    -- exactly n randomly generated `a`s+    return (VS.fromList xs)++  shrink v = [ VS.fromList xs+             | xs <- shrink (VS.toList v) ]++instance (Arbitrary a, VS.Storable a, VG.Vector VU.Vector a) => Arbitrary (VU.Vector a) where+  arbitrary = do+    n  <- choose (0, 20)           -- limit length to at most 20+    xs <- vectorOf n arbitrary    -- exactly n randomly generated `a`s+    return (VG.fromList xs)++  shrink v = [ VG.fromList xs+             | xs <- shrink (VG.toList v) ]++spec :: Spec+spec = do+  describe "TensorLike" $ do+    it "TensorLike Bool" $+      property $+        \x -> asValue (asTensor x) `shouldBe` (x :: Bool)+    it "TensorLike Word8" $+      property $+        \x -> asValue (asTensor x) `shouldBe` (x :: Word8)+    it "TensorLike Int8" $+      property $+        \x -> asValue (asTensor x) `shouldBe` (x :: Int8)+    it "TensorLike Int16" $+      property $+        \x -> asValue (asTensor x) `shouldBe` (x :: Int16)+    it "TensorLike Int32" $+      property $+        \x -> asValue (asTensor x) `shouldBe` (x :: Int32)+    it "TensorLike Int" $+      property $+        \x -> asValue (asTensor x) `shouldBe` (x :: Int)+    it "TensorLike Int64" $+      property $+        \x -> asValue (asTensor x) `shouldBe` (x :: Int64)+    it "TensorLike Half" $+      property $+        \x -> asValue (asTensor x) `shouldBe` (x :: Half)+    it "TensorLike Float" $+      property $+        \x -> asValue (asTensor x) `shouldBe` (x :: Float)+    it "TensorLike Double" $+      property $+        \x -> asValue (asTensor x) `shouldBe` (x :: Double)+    it "TensorLike ComplexHalf" $+      property $+        \x -> asValue (asTensor x) `shouldBe` (x :: Complex Half)+    it "TensorLike Complex Float" $+      property $+        \x -> asValue (asTensor x) `shouldBe` (x :: Complex Float)+    it "TensorLike Complex Double" $+      property $+        \x -> asValue (asTensor x) `shouldBe` (x :: Complex Double)+    it "TensorLike Storable Vector Float" $+      property $+        \x -> asValue (asTensor x) `shouldBe` (x :: VS.Vector Float)+    it "TensorLike Storable Vector Double" $+      property $+        \x -> asValue (asTensor x) `shouldBe` (x :: VS.Vector Double)+    it "TensorLike Unboxed Vector Double" $+      property $+        \x -> asValue (asTensor x) `shouldBe` (x :: VU.Vector Double)++    it "Compare internal expression of c++ with Storable expression of haskell" $ do+      show (asTensor [True, False, True, False])+        `shouldBe` "Tensor Bool [4] [ 1,  0,  1,  0]"+      show (asTensor ([1, 0, 1, 0] :: [Word8]))+        `shouldBe` "Tensor UInt8 [4] [ 1,  0,  1,  0]"+      show (asTensor ([1, 0, 1, 0] :: [Int8]))+        `shouldBe` "Tensor Int8 [4] [ 1,  0,  1,  0]"+      show (asTensor ([1, 0, 1, 0] :: [Int16]))+        `shouldBe` "Tensor Int16 [4] [ 1,  0,  1,  0]"+      show (asTensor ([1, 0, 1, 0] :: [Int32]))+        `shouldBe` "Tensor Int32 [4] [ 1,  0,  1,  0]"+      show (asTensor ([1, 0, 1, 0] :: [Int]))+        `shouldBe` "Tensor Int64 [4] [ 1,  0,  1,  0]"+      show (asTensor ([1, 0, 1, 0] :: [Int64]))+        `shouldBe` "Tensor Int64 [4] [ 1,  0,  1,  0]"+      show (asTensor ([1, 0, 1, 0] :: [Float]))+        `shouldBe` "Tensor Float [4] [ 1.0000   ,  0.0000,  1.0000   ,  0.0000]"+      show (asTensor ([1, 0, 1, 0] :: [Double]))+        `shouldBe` "Tensor Double [4] [ 1.0000   ,  0.0000,  1.0000   ,  0.0000]"+      show (asTensor ([[]] :: [[Int]]))+        `shouldBe` "Tensor Int64 [1,0] [[]]"+      show (asTensor ([[1]] :: [[Int]]))+        `shouldBe` "Tensor Int64 [1,1] [[ 1]]"++    it "TensorLike [Bool]" $+      property $+        \(NonEmpty (x :: [Bool])) -> do+          asValue (asTensor x) `shouldBe` x+          toDouble (select 0 0 (asTensor x)) `shouldBe` (if (head x) then 1 else 0)+          shape (asTensor x) `shouldBe` [length x]+          let xx = replicate 5 x+          asValue (asTensor xx) `shouldBe` xx+          let xxx = replicate 3 xx+          asValue (asTensor xxx) `shouldBe` xxx+    it "TensorLike [Word8]" $+      property $+        \(NonEmpty (x :: [Word8])) -> do+          asValue (asTensor x) `shouldBe` x+          toDouble (select 0 0 (asTensor x)) `shouldBe` fromIntegral (head x)+          shape (asTensor x) `shouldBe` [length x]+          let xx = replicate 5 x+          asValue (asTensor xx) `shouldBe` xx+          let xxx = replicate 3 xx+          asValue (asTensor xxx) `shouldBe` xxx+    it "TensorLike [Int8]" $+      property $+        \(NonEmpty (x :: [Int8])) -> do+          asValue (asTensor x) `shouldBe` x+          toDouble (select 0 0 (asTensor x)) `shouldBe` fromIntegral (head x)+          shape (asTensor x) `shouldBe` [length x]+          let xx = replicate 5 x+          asValue (asTensor xx) `shouldBe` xx+          let xxx = replicate 3 xx+          asValue (asTensor xxx) `shouldBe` xxx+    it "TensorLike [Int16]" $+      property $+        \(NonEmpty (x :: [Int16])) -> do+          asValue (asTensor x) `shouldBe` x+          toDouble (select 0 0 (asTensor x)) `shouldBe` fromIntegral (head x)+          shape (asTensor x) `shouldBe` [length x]+          let xx = replicate 5 x+          asValue (asTensor xx) `shouldBe` xx+          let xxx = replicate 3 xx+          asValue (asTensor xxx) `shouldBe` xxx+    it "TensorLike [Int32]" $+      property $+        \(NonEmpty (x :: [Int32])) -> do+          asValue (asTensor x) `shouldBe` x+          toDouble (select 0 0 (asTensor x)) `shouldBe` fromIntegral (head x)+          shape (asTensor x) `shouldBe` [length x]+          let xx = replicate 5 x+          asValue (asTensor xx) `shouldBe` xx+          let xxx = replicate 3 xx+          asValue (asTensor xxx) `shouldBe` xxx+    it "TensorLike [Int]" $+      property $+        \(NonEmpty (x :: [Int])) -> do+          asValue (asTensor x) `shouldBe` x+          toDouble (select 0 0 (asTensor x)) `shouldBe` fromIntegral (head x)+          shape (asTensor x) `shouldBe` [length x]+          let xx = replicate 5 x+          asValue (asTensor xx) `shouldBe` xx+          let xxx = replicate 3 xx+          asValue (asTensor xxx) `shouldBe` xxx+    it "TensorLike [Int64]" $+      property $+        \(NonEmpty (x :: [Int64])) -> do+          asValue (asTensor x) `shouldBe` x+          toDouble (select 0 0 (asTensor x)) `shouldBe` fromIntegral (head x)+          shape (asTensor x) `shouldBe` [length x]+          let xx = replicate 5 x+          asValue (asTensor xx) `shouldBe` xx+          let xxx = replicate 3 xx+          asValue (asTensor xxx) `shouldBe` xxx+    it "TensorLike [Half]" $+      property $+        \(NonEmpty (x :: [Half])) -> do+          asValue (asTensor x) `shouldBe` x+          toDouble (select 0 0 (asTensor x)) `shouldBe` realToFrac (head x)+          shape (asTensor x) `shouldBe` [length x]+          let xx = replicate 5 x+          asValue (asTensor xx) `shouldBe` xx+          let xxx = replicate 3 xx+          asValue (asTensor xxx) `shouldBe` xxx+    it "TensorLike [Float]" $+      property $+        \(NonEmpty (x :: [Float])) -> do+          asValue (asTensor x) `shouldBe` x+          toDouble (select 0 0 (asTensor x)) `shouldBe` realToFrac (head x)+          shape (asTensor x) `shouldBe` [length x]+          let xx = replicate 5 x+          asValue (asTensor xx) `shouldBe` xx+          let xxx = replicate 3 xx+          asValue (asTensor xxx) `shouldBe` xxx+    it "TensorLike [Double]" $+      property $+        \(NonEmpty (x :: [Double])) -> do+          asValue (asTensor x) `shouldBe` x+          toDouble (select 0 0 (asTensor x)) `shouldBe` realToFrac (head x)+          shape (asTensor x) `shouldBe` [length x]+          let xx = replicate 5 x+          asValue (asTensor xx) `shouldBe` xx+          let xxx = replicate 3 xx+          asValue (asTensor xxx) `shouldBe` xxx+    it "TensorLike [Complex Half]" $+      property $+        \(NonEmpty (x :: [Complex Half])) -> do+          asValue (asTensor x) `shouldBe` x+          asValue (select 0 0 (asTensor x)) `shouldBe` (head x)+          shape (asTensor x) `shouldBe` [length x]+          let xx = replicate 5 x+          asValue (asTensor xx) `shouldBe` xx+          let xxx = replicate 3 xx+          asValue (asTensor xxx) `shouldBe` xxx+    it "TensorLike [Complex Float]" $+      property $+        \(NonEmpty (x :: [Complex Float])) -> do+          asValue (asTensor x) `shouldBe` x+          asValue (select 0 0 (asTensor x)) `shouldBe` (head x)+          shape (asTensor x) `shouldBe` [length x]+          let xx = replicate 5 x+          asValue (asTensor xx) `shouldBe` xx+          let xxx = replicate 3 xx+          asValue (asTensor xxx) `shouldBe` xxx+    it "TensorLike [Complex Double]" $+      property $+        \(NonEmpty (x :: [Complex Double])) -> do+          asValue (asTensor x) `shouldBe` x+          asValue (select 0 0 (asTensor x)) `shouldBe` (head x)+          shape (asTensor x) `shouldBe` [length x]+          let xx = replicate 5 x+          asValue (asTensor xx) `shouldBe` xx+          let xxx = replicate 3 xx+          asValue (asTensor xxx) `shouldBe` xxx++    it "invalid cast of TensorLike a" $ do+      let x = asTensor (10 :: Int)+      (dtype x) `shouldBe` Int64+      (print (asValue x :: Double)) `shouldThrow` anyException+    it "invalid cast of TensorLike [a]" $ do+      let x = asTensor ([0 .. 10] :: [Int])+      (print (asValue x :: [Double])) `shouldThrow` anyException++    it "lists having different length" $ do+      (print (asTensor ([[1], [1, 2]] :: [[Double]]))) `shouldThrow` anyException+    it "cast of Tensor" $ do+      let x = asTensor ([0 .. 10] :: [Int])+      (dtype (toType Float x)) `shouldBe` Float++  describe "indexing" $ do+    it "pick up a value" $ do+      let x = asTensor ([[[0, 1, 2], [3, 4, 5]], [[6, 7, 8], [9, 10, 11]]] :: [[[Int]]])+          r = x ! (1, 0, 2)+      (dtype &&& shape &&& asValue) r `shouldBe` (Int64, ([], 8 :: Int))+    it "pick up a bottom tensor" $ do+      let x = asTensor ([[[0, 1, 2], [3, 4, 5]], [[6, 7, 8], [9, 10, 11]]] :: [[[Int]]])+          r = x ! (1, 0)+      (dtype &&& shape &&& asValue) r `shouldBe` (Int64, ([3], [6 :: Int, 7, 8]))+    it "make a slice of bottom values" $ do+      let x = asTensor ([[[0, 1, 2], [3, 4, 5]], [[6, 7, 8], [9, 10, 11]]] :: [[[Int]]])+          r = x ! ((), (), 1)+      (dtype &&& shape &&& asValue) r `shouldBe` (Int64, ([2, 2], [[1 :: Int, 4], [7, 10]]))+    it "ellipsis" $ do+      let x = asTensor ([[[0, 1, 2], [3, 4, 5]], [[6, 7, 8], [9, 10, 11]]] :: [[[Int]]])+          r = x ! (Ellipsis, 1)+      (dtype &&& shape &&& asValue) r `shouldBe` (Int64, ([2, 2], [[1 :: Int, 4], [7, 10]]))+    it "make a slice via muliple slices" $ do+      let x = asTensor ([[[0, 1, 2], [3, 4, 5]], [[6, 7, 8], [9, 10, 11]]] :: [[[Int]]])+          r = x ! ((), (Slice (1, None)))+      (dtype &&& shape &&& asValue) r `shouldBe` (Int64, ([2, 1, 3], [[[3 :: Int, 4, 5]], [[9, 10, 11]]]))+    it "make a slice via muliple slices" $ do+      let x = asTensor ([[[0, 1, 2], [3, 4, 5]], [[6, 7, 8], [9, 10, 11]]] :: [[[Int]]])+          r = x ! ((), (Slice (1, None)), (Slice (0, 1)))+      (dtype &&& shape &&& asValue) r `shouldBe` (Int64, ([2, 1, 1], [[[3 :: Int]], [[9]]]))+  describe "masked fill" $ do+    it "Fill a value" $ do+      let x = asTensor ([[[0, 1, 2], [3, 4, 5]], [[6, 7, 8], [9, 10, 11]]] :: [[[Int]]])+          r = maskedFill x (1, 0, 2) (9 :: Int)+      (dtype &&& shape &&& asValue) r `shouldBe` (Int64, ([2, 2, 3], [[[0, 1, 2], [3, 4, 5]], [[6, 7, 9], [9, 10, 11]]] :: [[[Int]]]))+    it "Fill a bottom tensor" $ do+      let x = asTensor ([[[0, 1, 2], [3, 4, 5]], [[6, 7, 8], [9, 10, 11]]] :: [[[Int]]])+          r = maskedFill x (1, 0) [8 :: Int, 8, 8]+      (dtype &&& shape &&& asValue) r `shouldBe` (Int64, ([2, 2, 3], [[[0, 1, 2], [3, 4, 5]], [[8, 8, 8], [9, 10, 11]]] :: [[[Int]]]))+    it "masked fill by boolean" $ do+      let m = asTensor ([[[True, True, False], [False, False, False]], [[True, False, False], [False, False, False]]] :: [[[Bool]]])+          x = asTensor ([[[0, 1, 2], [3, 4, 5]], [[6, 7, 8], [9, 10, 11]]] :: [[[Int]]])+          r = maskedFill x m [8 :: Int, 8, 8]+      (dtype &&& shape &&& asValue) r `shouldBe` (Int64, ([2, 2, 3], [[[8, 8, 2], [3, 4, 5]], [[8, 7, 8], [9, 10, 11]]] :: [[[Int]]]))
+ test/Torch/Distributions/BernoulliSpec.hs view
@@ -0,0 +1,77 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE ScopedTypeVariables #-}++module Torch.Distributions.BernoulliSpec (spec) where++import GHC.Exts+import Test.Hspec+import qualified Torch.DType as D+import qualified Torch.Device as D+import Torch.Distributions.Bernoulli+import qualified Torch.Distributions.Constraints as Constraints+import Torch.Distributions.Distribution+import qualified Torch.Functional as F+import qualified Torch.Tensor as D+import Torch.Typed.Tensor++type Tnsr dtype shape = Tensor '( 'D.CPU, 0) dtype shape++spec :: Spec+spec = do+  let ps = [0.8, 0.2 :: Float]+  let p = D.asTensor ps+  let d = fromProbs p++  it "batchShape" $ do+    batchShape d `shouldBe` []++  it "eventShape" $ do+    eventShape d `shouldBe` []++  it "probs" $ do+    -- putStrLn . show $ probs d+    let t :: Tnsr 'D.Float '[2] = UnsafeMkTensor $ probs d+    toList (Just t) `shouldBe` ps++  it "expand" $ do+    -- putStrLn . show $ expand d [2]+    let t :: Tnsr 'D.Float '[2] = UnsafeMkTensor $ probs $ expand d [2]+    toList (Just t) `shouldBe` ps++  it "support" $ do+    -- putStrLn . show $ support d $ D.asTensor [0.0, 0.5, 1.0, 2.0 :: Float]+    let t :: Tnsr 'D.Bool '[4] =+          UnsafeMkTensor+            . support d+            $ D.asTensor [0.0, 0.5, 1.0, 2.0 :: Float]+    toList (Just t) `shouldBe` [True, False, True, False]++  it "mean" $ do+    -- putStrLn . show $ mean d+    let t :: Tnsr 'D.Float '[2] = UnsafeMkTensor $ mean d+    toList (Just t) `shouldBe` ps++  it "variance" $ do+    -- putStrLn . show $ variance d+    F.allclose (variance d) (D.asTensor [0.16, 0.16 :: Float]) 0.01 0.01 False `shouldBe` True++  it "sample" $ do+    -- t <- sample d [2]+    -- putStrLn . show $ t+    t :: Tnsr 'D.Bool '[2] <- UnsafeMkTensor . Constraints.boolean <$> sample d [2]+    toList (Just t) `shouldBe` [True, True]++  it "logProb" $ do+    -- putStrLn . show $ logProb d $ D.asTensor [0.3, 0.5 :: Float]+    let t :: Tnsr 'D.Float '[2] = UnsafeMkTensor $ logProb d $ D.asTensor [0.3, 0.5 :: Float]+    F.allclose (toDynamic t) (D.asTensor [-0.6749387, -0.7530129 :: Float]) 0.001 0.001 False `shouldBe` True++  it "entropy" $ do+    -- putStrLn . show $ entropy d+    let t :: Tnsr 'D.Float '[2] = UnsafeMkTensor $ entropy d+    F.allclose (toDynamic t) (D.asTensor [0.7233937, 0.5433219 :: Float]) 0.0001 0.0001 False `shouldBe` True++  it "enumerateSupport" $ do+    -- putStrLn . show $ enumerateSupport d False+    let t :: Tnsr 'D.Float '[2] = UnsafeMkTensor $ enumerateSupport d False+    toList (Just t) `shouldBe` [0.0, 1.0]
+ test/Torch/Distributions/CategoricalSpec.hs view
@@ -0,0 +1,85 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE ScopedTypeVariables #-}++module Torch.Distributions.CategoricalSpec (spec) where++import GHC.Exts+import Test.Hspec+import qualified Torch.DType as D+import qualified Torch.Device as D+import Torch.Distributions.Categorical+import qualified Torch.Distributions.Constraints as Constraints+import Torch.Distributions.Distribution+import qualified Torch.Functional as F+import qualified Torch.Tensor as D+import Torch.Typed.Tensor++type Tnsr dtype shape = Tensor '( 'D.CPU, 0) dtype shape++spec :: Spec+spec = do+  let ps = [0.8, 0.2 :: Float]+  let p = D.asTensor ps+  let d = fromProbs p++  it "batchShape" $ do+    batchShape d `shouldBe` []++  it "eventShape" $ do+    eventShape d `shouldBe` []++  it "probs" $ do+    -- putStrLn . show $ probs d+    let t :: Tnsr 'D.Float '[2] = UnsafeMkTensor $ probs d+    toList (Just t) `shouldBe` ps++  it "expand" $ do+    -- putStrLn . show $ expand d [2]+    let t :: Tnsr 'D.Float '[2] = UnsafeMkTensor $ probs $ expand d [2]+    toList (Just t) !! 0 `shouldBe` 0.8 -- ps+  it "support" $ do+    -- putStrLn . show $ support d $ D.asTensor [0.0, 0.5, 1.0, 2.0 :: Float]+    let t :: Tnsr 'D.Bool '[4] =+          UnsafeMkTensor+            . support d+            $ D.asTensor [0.0, 0.5, 1.0, 2.0 :: Float]+    toList (Just t) `shouldBe` [True, True, True, False]++  it "mean" $ do+    -- putStrLn . show $ mean d+    let t :: Tnsr 'D.Float '[] = UnsafeMkTensor $ mean d+    isInfinite (toFloat t) `shouldBe` True++  it "variance" $ do+    -- putStrLn . show $ variance d+    let t :: Tnsr 'D.Float '[] = UnsafeMkTensor $ variance d+    isInfinite (toFloat t) `shouldBe` True++  it "sample" $ do+    t <- sample d [2]+    -- putStrLn . show $ t+    D.shape t `shouldBe` [2]+    let t' :: Tnsr 'D.Bool '[2] = UnsafeMkTensor . Constraints.boolean $ t+    toList (Just t') `shouldBe` [True, True]++  it "sample: multi-dimensional" $ do+    let d = fromProbs . D.asTensor $ [[0.3, 0.2], [0.4, 0.1 :: Float]]+    t <- sample d [3]+    -- putStrLn . show $ t+    D.shape t `shouldBe` [3, 2]++  it "logProb" $ do+    -- putStrLn . show $ logProb d $ D.asTensor [0.3, 0.5 :: Float]+    let t :: Tnsr 'D.Float '[2] = UnsafeMkTensor $ logProb d $ D.asTensor [0.3, 0.5 :: Float]+    F.allclose (toDynamic t) (D.asTensor [-9.691001e-2, -9.691001e-2 :: Float]) 0.0001 0.0001 False `shouldBe` True++  it "entropy" $ do+    -- putStrLn . show $ entropy d+    let t :: Tnsr 'D.Float '[] = UnsafeMkTensor $ entropy d+    abs (toFloat t - 0.2173) < 0.01 `shouldBe` True+    F.allclose (toDynamic t) (D.asTensor [0.2173 :: Float]) 0.001 0.001 False `shouldBe` True++  it "enumerateSupport" $ do+    -- putStrLn . show $ enumerateSupport d False+    let t :: Tnsr 'D.Float '[2] = UnsafeMkTensor $ enumerateSupport d False+    toList (Just t) `shouldBe` [0.0, 1.0]
+ test/Torch/Distributions/ConstraintsSpec.hs view
@@ -0,0 +1,141 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}++module Torch.Distributions.ConstraintsSpec (spec) where++import GHC.Exts+import Test.Hspec+import qualified Torch.DType as D+import qualified Torch.Device as D+import Torch.Distributions.Constraints as Constraints+import qualified Torch.Functional as F+import qualified Torch.Tensor as D+import Torch.Typed.Tensor++spec :: Spec+spec = do+  it "boolean" $ do+    let t :: Tensor '( 'D.CPU, 0) 'D.Bool '[3] =+          toDevice @'( 'D.CPU, 0) . UnsafeMkTensor+            . Constraints.boolean+            . D.asTensor+            $ [0.0, 1.0, 2.0 :: Float]+    toList (Just t) `shouldBe` [True, True, False]++  it "integerInterval" $ do+    let t :: Tensor '( 'D.CPU, 0) 'D.Bool '[4] =+          toDevice @'( 'D.CPU, 0) . UnsafeMkTensor+            . Constraints.integerInterval 1 2+            . D.asTensor+            $ [0, 1, 2, 3 :: Int]+    toList (Just t) `shouldBe` [False, True, True, False]++  it "integerGreaterThan" $ do+    let t :: Tensor '( 'D.CPU, 0) 'D.Bool '[4] =+          toDevice @'( 'D.CPU, 0) . UnsafeMkTensor+            . Constraints.integerGreaterThan 1+            . D.asTensor+            $ [0, 1, 2, 3 :: Int]+    toList (Just t) `shouldBe` [False, False, True, True]++  it "real" $ do+    let t :: Tensor '( 'D.CPU, 0) 'D.Bool '[3] =+          toDevice @'( 'D.CPU, 0) . UnsafeMkTensor+            . Constraints.real+            $ D.asTensor $ [0.0, 1.0, 2.0 :: Float]+    toList (Just t) `shouldBe` [True, True, True]+    let nans = F.divScalar (0.0 :: Float) $ D.asTensor [0.0, 1.0, 2.0 :: Float]+    let t :: Tensor '( 'D.CPU, 0) 'D.Bool '[3] =+          toDevice @'( 'D.CPU, 0) . UnsafeMkTensor+            . Constraints.real+            $ nans+    toList (Just t) `shouldBe` [False, False, False]++  it "greaterThan" $ do+    let t :: Tensor '( 'D.CPU, 0) 'D.Bool '[3] =+          toDevice @'( 'D.CPU, 0) . UnsafeMkTensor+            . Constraints.greaterThan 0.0+            . D.asTensor+            $ [0.0, 1.0, 2.0 :: Float]+    toList (Just t) `shouldBe` [False, True, True]++  it "greaterThanEq" $ do+    let t :: Tensor '( 'D.CPU, 0) 'D.Bool '[3] =+          toDevice @'( 'D.CPU, 0) . UnsafeMkTensor+            . Constraints.greaterThanEq 1.0+            . D.asTensor+            $ [0.0, 1.0, 2.0 :: Float]+    toList (Just t) `shouldBe` [False, True, True]++  it "lessThan" $ do+    let t :: Tensor '( 'D.CPU, 0) 'D.Bool '[3] =+          toDevice @'( 'D.CPU, 0) . UnsafeMkTensor+            . Constraints.lessThan 1.0+            . D.asTensor+            $ [0.0, 1.0, 2.0 :: Float]+    toList (Just t) `shouldBe` [True, False, False]++  it "lessThanEq" $ do+    let t :: Tensor '( 'D.CPU, 0) 'D.Bool '[3] =+          toDevice @'( 'D.CPU, 0) . UnsafeMkTensor+            . Constraints.lessThanEq 1.0+            . D.asTensor+            $ [0.0, 1.0, 2.0 :: Float]+    toList (Just t) `shouldBe` [True, True, False]++  it "interval" $ do+    let t :: Tensor '( 'D.CPU, 0) 'D.Bool '[4] =+          toDevice @'( 'D.CPU, 0) . UnsafeMkTensor+            . Constraints.interval 1.0 2.0+            . D.asTensor+            $ [0.0, 1.0, 2.0, 3.0 :: Float]+    toList (Just t) `shouldBe` [False, True, True, False]++  it "halfOpenInterval" $ do+    let t :: Tensor '( 'D.CPU, 0) 'D.Bool '[3] =+          toDevice @'( 'D.CPU, 0) . UnsafeMkTensor+            . Constraints.halfOpenInterval 1.0 2.0+            . D.asTensor+            $ [0.0, 1.0, 2.0 :: Float]+    toList (Just t) `shouldBe` [False, True, False]++  it "nonNegativeInteger" $ do+    let t :: Tensor '( 'D.CPU, 0) 'D.Bool '[3] =+          toDevice @'( 'D.CPU, 0) . UnsafeMkTensor+            . Constraints.nonNegativeInteger+            . D.asTensor+            $ [-1, 0, 1 :: Int]+    toList (Just t) `shouldBe` [False, True, True]++  it "positiveInteger" $ do+    let t :: Tensor '( 'D.CPU, 0) 'D.Bool '[3] =+          toDevice @'( 'D.CPU, 0) . UnsafeMkTensor+            . Constraints.positiveInteger+            . D.asTensor+            $ [0, 1, 2 :: Int]+    toList (Just t) `shouldBe` [False, True, True]++  it "integerInterval" $ do+    let t :: Tensor '( 'D.CPU, 0) 'D.Bool '[4] =+          toDevice @'( 'D.CPU, 0) . UnsafeMkTensor+            . Constraints.integerInterval 1 2+            . D.asTensor+            $ [0, 1, 2, 3 :: Int]+    toList (Just t) `shouldBe` [False, True, True, False]++  it "positive" $ do+    let t :: Tensor '( 'D.CPU, 0) 'D.Bool '[3] =+          toDevice @'( 'D.CPU, 0) . UnsafeMkTensor+            . Constraints.positive+            . D.asTensor+            $ [0.0, 1.0, 2.0 :: Float]+    toList (Just t) `shouldBe` [False, True, True]++  it "unitInterval" $ do+    let t :: Tensor '( 'D.CPU, 0) 'D.Bool '[4] =+          toDevice @'( 'D.CPU, 0) . UnsafeMkTensor+            . Constraints.unitInterval+            . D.asTensor+            $ [-1.0, 0.0, 1.0, 2.0 :: Float]+    toList (Just t) `shouldBe` [False, True, True, False]
+ test/Torch/Typed/AutogradSpec.hs view
@@ -0,0 +1,485 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PartialTypeSignatures #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE NoStarIsType #-}+{-# OPTIONS_GHC -Wno-partial-type-signatures #-}+{-# OPTIONS_GHC -fplugin GHC.TypeLits.Extra.Solver #-}+{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-}+{-# OPTIONS_GHC -fplugin GHC.TypeLits.Normalise #-}++module Torch.Typed.AutogradSpec+  ( Torch.Typed.AutogradSpec.spec,+  )+where++import Control.Monad (when)+import Data.Kind+import Data.Maybe ()+import Data.Proxy+import Data.Reflection ()+import GHC.Exts (toList)+import GHC.Generics+import GHC.TypeLits+import System.IO.Unsafe ()+import Test.Hspec (Spec, describe, it, shouldBe)+import Test.QuickCheck ()+import Torch (ATenTensor)+import Torch.Internal.Class (Castable)+import Torch.Typed+import Torch.Typed.AuxiliarySpec+import Prelude hiding+  ( all,+    cos,+    sin,+  )++data+  RastriginLayerSpec+    (n :: Nat)+    (dtype :: DType)+    (device :: (DeviceType, Nat))+  = RastriginLayerSpec+  deriving (Show, Eq)++data+  RastriginLayer+    (n :: Nat)+    (dtype :: DType)+    (device :: (DeviceType, Nat))+  where+  RastriginLayer ::+    forall n dtype device.+    {x :: Parameter device dtype '[n]} ->+    RastriginLayer n dtype device+  deriving (Show, Generic, Parameterized)++instance+  ( RandDTypeIsValid device dtype,+    KnownNat n,+    KnownDType dtype,+    KnownDevice device+  ) =>+  Randomizable+    (RastriginLayerSpec n dtype device)+    (RastriginLayer n dtype device)+  where+  sample _ = RastriginLayer <$> (makeIndependent =<< randn)++rastriginLayer' ::+  forall device dtype a n shape.+  ( SumDTypeIsValid device dtype,+    StandardFloatingPointDTypeValidation device dtype,+    All Scalar '[a, n],+    KnownDType (SumDType dtype),+    KnownDevice device+  ) =>+  Tensor device dtype shape ->+  a ->+  n ->+  Tensor device (SumDType dtype) '[]+rastriginLayer' x a n =+  (mulScalar a . mulScalar n $ ones)+    + sumAll (x * x - (mulScalar a . cos . mulScalar (2 * pi :: Double)) x)++gradientsRastriginLayer' ::+  forall device dtype a shape.+  (KnownDevice device, StandardFloatingPointDTypeValidation device dtype, Scalar a) =>+  Tensor device dtype shape ->+  a ->+  Tensor device dtype shape+gradientsRastriginLayer' x a =+  mulScalar+    (2 :: Int)+    ( x+        + ( mulScalar a . mulScalar (pi :: Double)+              . sin+              . mulScalar (2 * pi :: Double)+          )+          x+    )++data+  RastriginStackSpec+    (num :: Nat)+    (ns :: [Nat])+    (dtypes :: [DType])+    (devices :: [(DeviceType, Nat)])+  = RastriginStackSpec+  deriving (Show, Eq)++data+  RastriginStack+    (num :: Nat)+    (ns :: [Nat])+    (dtypes :: [DType])+    (devices :: [(DeviceType, Nat)])+  where+  Rastrigin1 ::+    forall n dtype device.+    RastriginLayer n dtype device ->+    RastriginStack 1 '[n] '[dtype] '[device]+  RastriginK ::+    forall num n ns dtype dtypes device devices.+    RastriginLayer n dtype device ->+    RastriginStack num ns dtypes devices ->+    RastriginStack (num + 1) (n ': ns) (dtype ': dtypes) (device ': devices)++deriving instance Show (RastriginStack num ns dtypes devices)++class RastriginStackParameterized (flag :: Bool) num ns dtypes devices where+  type RastriginStackParameters flag num ns dtypes devices :: [Type]+  rastriginStackFlattenParameters ::+    Proxy flag ->+    RastriginStack num ns dtypes devices ->+    HList (RastriginStackParameters flag num ns dtypes devices)+  rastriginStackReplaceParameters ::+    Proxy flag ->+    RastriginStack num ns dtypes devices ->+    HList (RastriginStackParameters flag num ns dtypes devices) ->+    RastriginStack num ns dtypes devices++instance+  Parameterized (RastriginLayer n dtype device) =>+  RastriginStackParameterized 'False 1 '[n] '[dtype] '[device]+  where+  type+    RastriginStackParameters 'False 1 '[n] '[dtype] '[device] =+      Parameters (RastriginLayer n dtype device)+  rastriginStackFlattenParameters _ (Rastrigin1 rastriginLayer) = flattenParameters rastriginLayer+  rastriginStackReplaceParameters _ (Rastrigin1 rastriginLayer) parameters =+    Rastrigin1 $ replaceParameters rastriginLayer parameters++instance+  ( Parameterized (RastriginLayer n dtype device),+    Parameterized (RastriginStack (num - 1) ns dtypes devices),+    HAppendFD+      (Parameters (RastriginLayer n dtype device))+      (Parameters (RastriginStack (num - 1) ns dtypes devices))+      ( Parameters (RastriginLayer n dtype device)+          ++ Parameters (RastriginStack (num - 1) ns dtypes devices)+      ),+    1 <= num,+    numM1 ~ num - 1,+    0 <= numM1+  ) =>+  RastriginStackParameterized 'True num (n ': ns) (dtype ': dtypes) (device ': devices)+  where+  type+    RastriginStackParameters 'True num (n ': ns) (dtype ': dtypes) (device ': devices) =+      (Parameters (RastriginLayer n dtype device) ++ Parameters (RastriginStack (num - 1) ns dtypes devices))+  rastriginStackFlattenParameters _ (RastriginK rastriginLayer rastriginStack) =+    let parameters = flattenParameters rastriginLayer+        parameters' = flattenParameters @(RastriginStack numM1 ns dtypes devices) rastriginStack+     in parameters `happendFD` parameters'+  rastriginStackReplaceParameters _ (RastriginK rastriginLayer rastriginStack) parameters'' =+    let (parameters, parameters') = hunappendFD parameters''+        rastriginLayer' = replaceParameters rastriginLayer parameters+        rastriginStack' =+          replaceParameters @(RastriginStack (num - 1) ns dtypes devices)+            rastriginStack+            parameters'+     in RastriginK rastriginLayer' rastriginStack'++instance+  ( 1 <= num,+    (2 <=? num) ~ flag,+    RastriginStackParameterized flag num ns dtypes devices+  ) =>+  Parameterized (RastriginStack num ns dtypes devices)+  where+  type+    Parameters (RastriginStack num ns dtypes devices) =+      RastriginStackParameters (2 <=? num) num ns dtypes devices+  flattenParameters = rastriginStackFlattenParameters (Proxy :: Proxy flag)+  replaceParameters = rastriginStackReplaceParameters (Proxy :: Proxy flag)++class RastriginStackRandomizable (flag :: Bool) num ns dtypes devices where+  rastriginStackSample ::+    Proxy flag ->+    RastriginStackSpec num ns dtypes devices ->+    IO (RastriginStack num ns dtypes devices)++instance+  ( KnownNat n,+    KnownDType dtype,+    KnownDevice device,+    RandDTypeIsValid device dtype+  ) =>+  RastriginStackRandomizable 'False 1 '[n] '[dtype] '[device]+  where+  rastriginStackSample _ _ = Rastrigin1 <$> (sample $ RastriginLayerSpec @n @dtype @device)++instance+  ( KnownNat n,+    KnownDType dtype,+    KnownDevice device,+    RandDTypeIsValid device dtype,+    Randomizable+      (RastriginStackSpec (num - 1) ns dtypes devices)+      (RastriginStack (num - 1) ns dtypes devices),+    1 <= num+  ) =>+  RastriginStackRandomizable 'True num (n ': ns) (dtype ': dtypes) (device ': devices)+  where+  rastriginStackSample _ _ =+    RastriginK+      <$> (sample $ RastriginLayerSpec @n @dtype @device)+      <*> ( sample+              @(RastriginStackSpec (num - 1) ns dtypes devices)+              @(RastriginStack (num - 1) ns dtypes devices)+              $ RastriginStackSpec+          )++instance+  ( 1 <= num,+    (2 <=? num) ~ flag,+    RandDTypeIsValid device dtype,+    KnownDType dtype,+    KnownDevice device,+    RastriginStackRandomizable flag num (n ': ns) (dtype ': dtypes) (device ': devices)+  ) =>+  Randomizable+    (RastriginStackSpec num (n ': ns) (dtype ': dtypes) (device ': devices))+    (RastriginStack num (n ': ns) (dtype ': dtypes) (device ': devices))+  where+  sample = rastriginStackSample (Proxy :: Proxy flag)++data+  RastriginSpec+    (num :: Nat)+    (ns :: [Nat])+    (dtypes :: [DType])+    (devices :: [(DeviceType, Nat)])+  = RastriginSpec+  deriving (Show, Eq)++data+  Rastrigin+    (num :: Nat)+    (ns :: [Nat])+    (dtypes :: [DType])+    (devices :: [(DeviceType, Nat)]) = Rastrigin+  { rastriginStack :: RastriginStack num ns dtypes devices+  }+  deriving (Show, Generic)++deriving instance+  ( 1 <= num,+    Parameterized (RastriginStack num ns dtypes devices)+  ) =>+  Parameterized (Rastrigin num ns dtypes devices)++instance+  ( Randomizable+      (RastriginStackSpec num ns dtypes devices)+      (RastriginStack num ns dtypes devices)+  ) =>+  Randomizable+    (RastriginSpec num ns dtypes devices)+    (Rastrigin num ns dtypes devices)+  where+  sample _ =+    Rastrigin <$> (sample $ RastriginStackSpec @num @ns @dtypes @devices)++data RastriginA a dv dt = RastriginA a dv dt++instance+  ( Scalar a,+    KnownNat n,+    All KnownDType [SumDType dtype, dtype'],+    All KnownDevice [device, device'],+    SumDTypeIsValid device dtype,+    StandardFloatingPointDTypeValidation device dtype+  ) =>+  Apply'+    (RastriginA a (Proxy device') (Proxy dtype'))+    (Parameter device dtype '[n])+    (Tensor device' dtype' '[])+  where+  apply' (RastriginA a _ _) parameter =+    toDevice @device'+      . toDType @dtype' @(SumDType dtype)+      . rastriginLayer' (toDependent parameter) a+      $ natValI @n++rastrigin ::+  forall a dtype device tensors parameters num ns dtypes devices shape.+  ( SumDType dtype ~ dtype,+    SumDTypeIsValid device dtype,+    parameters ~ Parameters (Rastrigin num ns dtypes devices),+    Parameterized (Rastrigin num ns dtypes devices),+    HMap' (RastriginA a (Proxy device) (Proxy dtype)) parameters tensors,+    Castable (HList tensors) [ATenTensor],+    '(shape, dtype, device) ~ Stack 0 tensors,+    DropValue shape 0 ~ '[]+  ) =>+  Rastrigin num ns dtypes devices ->+  a ->+  Tensor device dtype '[]+rastrigin model a =+  sumDim @0+    . stack @0+    . hmap' (RastriginA a (Proxy @device) (Proxy @dtype))+    . flattenParameters+    $ model++data GradientsRastriginA a = GradientsRastriginA a++instance+  ( KnownDevice device,+    StandardFloatingPointDTypeValidation device dtype,+    Scalar a+  ) =>+  Apply' (GradientsRastriginA a) (Parameter device dtype '[n]) (Tensor device dtype '[n])+  where+  apply' (GradientsRastriginA a) parameter = gradientsRastriginLayer' (toDependent parameter) $ a++gradientsRastrigin ::+  forall gradients a num ns dtypes devices parameters.+  ( HMap' (GradientsRastriginA a) parameters gradients,+    parameters ~ Parameters (Rastrigin num ns dtypes devices),+    Parameterized (Rastrigin num ns dtypes devices)+  ) =>+  Rastrigin num ns dtypes devices ->+  a ->+  HList gradients+gradientsRastrigin model a =+  hmap'+    (GradientsRastriginA a)+    . flattenParameters+    $ model++data GradientsTestInner = GradientsTestInner++instance+  ( TensorOptions shape dtype device+  ) =>+  Apply'+    GradientsTestInner+    ((Tensor device dtype shape, Tensor device dtype shape), IO ())+    (IO ())+  where+  apply' _ ((a, b), agg) =+    agg >> do+      checkDynamicTensorAttributes a+      checkDynamicTensorAttributes b+      (toList . Just . toDevice @'( 'CPU, 0) @device . unsqueeze @0 . all)+        (isclose 1e-05 1e-08 False a b)+        `shouldBe` [True]++data GradientsTestOuter a = GradientsTestOuter a++instance+  ( Randomizable+      (RastriginStackSpec num ns dtypes devices)+      (RastriginStack num ns dtypes devices),+    HasGrad (HList parameters) (HList gradients),+    SumDType dtype ~ dtype,+    SumDTypeIsValid device dtype,+    parameters ~ Parameters (Rastrigin num ns dtypes devices),+    Parameterized (Rastrigin num ns dtypes devices),+    HMap' (RastriginA a (Proxy device) (Proxy dtype)) parameters tensors,+    Castable (HList tensors) [ATenTensor],+    '(shape, dtype, device) ~ Stack 0 tensors,+    DropValue shape 0 ~ '[],+    HMap' (GradientsRastriginA a) parameters gradients',+    HZip gradients gradients' zs,+    HFoldrM IO GradientsTestInner () zs ()+  ) =>+  Apply'+    (GradientsTestOuter a)+    ( ( (Proxy device, Proxy dtype),+        RastriginSpec num ns dtypes devices+      ),+      IO ()+    )+    (IO ())+  where+  apply' (GradientsTestOuter a) ((_, rastriginSpec), agg) =+    agg >> do+      model <- sample rastriginSpec+      let zipped =+            hzip+              ( grad+                  (rastrigin @a @dtype @device @tensors @parameters model a)+                  (flattenParameters model)+              )+              (gradientsRastrigin @gradients' model a)+      hfoldrM @IO GradientsTestInner () zipped++data LinearForward = LinearForward++instance+  Apply'+    LinearForward+    ( Linear inputFeatures outputFeatures dtype device,+      Tensor device dtype '[batchSize, inputFeatures]+    )+    (Tensor device dtype '[batchSize, outputFeatures])+  where+  apply' _ (model, input) = forward model input++spec :: Spec+spec = describe "grad" $ do+  it "works if everything has identical device and dtype" $ do+    hfoldrM @IO (GradientsTestOuter (10 :: Int)) () $+      hattach+        (Proxy @'( 'CPU, 0), Proxy @'Float)+        ( RastriginSpec @1 @'[2] @'[ 'Float] @'[ '( 'CPU, 0)]+            :. RastriginSpec @2 @'[2, 3] @'[ 'Float, 'Float] @'[ '( 'CPU, 0), '( 'CPU, 0)]+            :. HNil+        )+  it "works if model and loss have different dtypes but live on the same device" $ do+    hfoldrM @IO (GradientsTestOuter (10 :: Int)) () $+      hproduct+        ( (Proxy @'( 'CPU, 0), Proxy @'Double)+            :. (Proxy @'( 'CPU, 0), Proxy @'Float)+            :. HNil+        )+        ( RastriginSpec @2 @'[0, 1] @'[ 'Float, 'Double] @'[ '( 'CPU, 0), '( 'CPU, 0)]+            :. RastriginSpec @4 @'[2, 3, 1, 13] @'[ 'Float, 'Double, 'Float, 'Double] @'[ '( 'CPU, 0), '( 'CPU, 0), '( 'CPU, 0), '( 'CPU, 0)]+            :. HNil+        )+  when+    ( elem (Device {deviceType = CPU, deviceIndex = 0}) availableDevices+        && elem (Device {deviceType = CUDA, deviceIndex = 0}) availableDevices+    )+    $ do+      it "works if individual model layers and loss have different dtypes and live on different devices" $ do+        hfoldrM @IO (GradientsTestOuter (10 :: Int)) () $+          hproduct+            ( (Proxy @'( 'CPU, 0), Proxy @'Double)+                :. (Proxy @'( 'CUDA, 0), Proxy @'Double)+                :. HNil+            )+            ( RastriginSpec @2 @'[1, 5] @'[ 'Float, 'Double] @'[ '( 'CUDA, 0), '( 'CPU, 0)]+                :. RastriginSpec @4 @'[2, 3, 1, 13] @'[ 'Float, 'Double, 'Float, 'Double] @'[ '( 'CPU, 0), '( 'CUDA, 0), '( 'CPU, 0), '( 'CUDA, 0)]+                :. HNil+            )+-- ToDo: The error in the lower digits is very large as if using half precision.+--       it "works in a data-parallel setting" $ do+--         let spec = LinearSpec @10 @5 @'Float @'( 'CPU, 0)+--         model <- sample spec+--         input <- randn @'[20, 10] @'Float @'( 'CPU, 0)+--         output <- forwardConcurrently' @'[ '( 'CPU, 0), '( 'CUDA, 0)] @'( 'CPU, 0) model input+--         let loss = mseLoss @ReduceMean output zeros+--             gradientWeight :. gradientBias :. HNil = grad loss (flattenParameters model)+--             output' = forward model input+--             loss' = mseLoss @ReduceMean output' zeros+--             gradientWeight' :. gradientBias' :. HNil = grad loss' (flattenParameters model)+--         print (gradientWeight,gradientWeight')+-- +--        (toInt . all) (isclose 1e-08 1e-05 False gradientWeight gradientWeight') `shouldBe` 1+--        (toInt . all) (isclose 1e-08 1e-05 False gradientBias gradientBias') `shouldBe` 1
+ test/Torch/Typed/AuxiliarySpec.hs view
@@ -0,0 +1,104 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE PartialTypeSignatures #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# OPTIONS_GHC -Wno-partial-type-signatures #-}++module Torch.Typed.AuxiliarySpec where++import Data.Proxy+import System.IO.Unsafe+import System.Environment (lookupEnv)+import Test.Hspec (Spec, shouldBe)+import Test.QuickCheck ()+import qualified Torch as Torch (device, dtype, shape)+import Torch.Internal.Cast (cast0)+import Torch.Internal.Managed.Type.Context (hasCUDA, hasMPS)+import Torch.Typed++instance Semigroup Spec where+  (<>) a b = a >> b++instance Monoid Spec where+  mempty = pure ()++checkDynamicTensorAttributes ::+  forall device dtype shape.+  (TensorOptions shape dtype device) =>+  Tensor device dtype shape ->+  IO ()+checkDynamicTensorAttributes t = do+  Torch.device untyped `shouldBe` optionsRuntimeDevice @shape @dtype @device+  Torch.dtype untyped `shouldBe` optionsRuntimeDType @shape @dtype @device+  Torch.shape untyped `shouldBe` optionsRuntimeShape @shape @dtype @device+  where+    untyped = toDynamic t++allFloatingPointDTypes :: _+allFloatingPointDTypes = withHalf standardFloatingPointDTypes++mpsFloatingPointDTypes :: _+mpsFloatingPointDTypes = Proxy @'Float :. HNil++standardFloatingPointDTypes :: _+standardFloatingPointDTypes = Proxy @'Float :. Proxy @'Double :. HNil++allDTypes :: _+allDTypes = withHalf almostAllDTypes++withHalf :: _ -> _+withHalf dtypes = Proxy @'Half :. dtypes++almostAllDTypes :: _+almostAllDTypes = withBool standardDTypes++withBool :: _ -> _+withBool dtypes = Proxy @'Bool :. dtypes++standardDTypes :: _+standardDTypes =+  Proxy @'UInt8+    :. Proxy @'Int8+    :. Proxy @'Int16+    :. Proxy @'Int32+    :. Proxy @'Int64+    :. standardFloatingPointDTypes++mpsDTypes :: _+mpsDTypes =+  Proxy @'UInt8+    :. Proxy @'Int8+    :. Proxy @'Int16+    :. Proxy @'Int32+    :. Proxy @'Int64+    :. mpsFloatingPointDTypes++cpu :: _+cpu = Proxy @'( 'CPU, 0)++cuda0 :: _+cuda0 = Proxy @'( 'CUDA, 0)++mps :: _+mps = Proxy @'( 'MPS, 0)++availableDevices :: [Device]+availableDevices =+  let hasCuda = unsafePerformIO $ cast0 hasCUDA+      hasMps = unsafePerformIO $ cast0 hasMPS+      hasMpsFallback = unsafePerformIO $ do+        env <- lookupEnv "PYTORCH_ENABLE_MPS_FALLBACK"+        return $ env == Just "1"+   in [Device {deviceType = CPU, deviceIndex = 0}]+        <> ( if hasCuda+               then [Device {deviceType = CUDA, deviceIndex = 0}]+               else mempty+           )+        <> ( if hasMps && hasMpsFallback+               then [Device {deviceType = MPS, deviceIndex = 0}]+               else mempty+           )++spec :: Spec+spec = return ()
+ test/Torch/Typed/FactoriesSpec.hs view
@@ -0,0 +1,107 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE UndecidableInstances #-}++module Torch.Typed.FactoriesSpec+  ( Torch.Typed.FactoriesSpec.spec,+  )+where++import Data.Proxy+import Test.Hspec (Spec, describe, it)+import Test.QuickCheck ()+import Torch.Typed+import Torch.Typed.AuxiliarySpec++data SimpleFactoriesSpec = ZerosSpec | OnesSpec | FullSpec++instance+  ( TensorOptions shape dtype device+  ) =>+  Apply' SimpleFactoriesSpec ((Proxy device, (Proxy dtype, Proxy shape)), IO ()) (IO ())+  where+  apply' ZerosSpec (_, agg) =+    agg >> do+      let t = zeros :: Tensor device dtype shape+      checkDynamicTensorAttributes t+  apply' OnesSpec (_, agg) =+    agg >> do+      let t = ones :: Tensor device dtype shape+      checkDynamicTensorAttributes t+  apply' FullSpec (_, agg) =+    agg >> do+      let t = full (2.0 :: Float) :: Tensor device dtype shape+      checkDynamicTensorAttributes t++data RandomFactoriesSpec = RandSpec | RandnSpec++instance+  ( TensorOptions shape dtype device,+    RandDTypeIsValid device dtype+  ) =>+  Apply' RandomFactoriesSpec ((Proxy device, (Proxy dtype, Proxy shape)), IO ()) (IO ())+  where+  apply' RandSpec (_, agg) =+    agg >> do+      t <- rand :: IO (Tensor device dtype shape)+      checkDynamicTensorAttributes t+  apply' RandnSpec (_, agg) =+    agg >> do+      t <- randn :: IO (Tensor device dtype shape)+      checkDynamicTensorAttributes t++spec :: Spec+spec = foldMap spec' availableDevices++spec' :: Device -> Spec+spec' device =+  describe ("for " <> show device) $ do+    let standardShapes = Proxy @'[2, 3] :. HNil -- (Proxy :: Proxy ('[] :: [Nat])) :. Proxy @'[0]  :. Proxy @'[0, 1] :. Proxy @'[1, 0] :. Proxy @'[2, 3] :. HNil+    describe "simple factories" $ do+      let dispatch simpleFactoriesSpec =+            case device of+              Device {deviceType = CPU, deviceIndex = 0} ->+                hfoldrM @IO simpleFactoriesSpec () (hattach cpu (hproduct allDTypes standardShapes))+              Device {deviceType = CUDA, deviceIndex = 0} ->+                hfoldrM @IO simpleFactoriesSpec () (hattach cuda0 (hproduct allDTypes standardShapes))+              Device {deviceType = MPS, deviceIndex = 0} ->+                hfoldrM @IO simpleFactoriesSpec () (hattach mps (hproduct mpsDTypes standardShapes))+      it "ones" $ dispatch ZerosSpec+      it "zeros" $ dispatch OnesSpec+      it "full" $ dispatch FullSpec+    describe "random factories" $ do+      let dispatch randomFactoriesSpec =+            case device of+              Device {deviceType = CPU, deviceIndex = 0} ->+                hfoldrM @IO randomFactoriesSpec () (hattach cpu (hproduct standardFloatingPointDTypes standardShapes))+              Device {deviceType = CUDA, deviceIndex = 0} ->+                hfoldrM @IO randomFactoriesSpec () (hattach cuda0 (hproduct allFloatingPointDTypes standardShapes))+              Device {deviceType = MPS, deviceIndex = 0} ->+                hfoldrM @IO randomFactoriesSpec () (hattach mps (hproduct mpsFloatingPointDTypes standardShapes))+      it "rand" $ dispatch RandSpec+      it "randn" $ dispatch RandnSpec+    describe "advanced factories" $ do+      it "linspace" $ case device of+        Device {deviceType = CPU, deviceIndex = 0} -> do+          let t = linspace @3 @'( 'CPU, 0) (1 :: Int) (3 :: Int)+          checkDynamicTensorAttributes t+        Device {deviceType = CUDA, deviceIndex = 0} -> do+          let t = linspace @3 @'( 'CUDA, 0) (1 :: Int) (3 :: Int)+          checkDynamicTensorAttributes t+        Device {deviceType = MPS, deviceIndex = 0} -> do+          let t = linspace @3 @'( 'MPS, 0) (1 :: Int) (3 :: Int)+          checkDynamicTensorAttributes t+      it "eyeSquare" $ case device of+        Device {deviceType = CPU, deviceIndex = 0} -> do+          let t = eyeSquare @10 @'Float @'( 'CPU, 0)+          checkDynamicTensorAttributes t+        Device {deviceType = CUDA, deviceIndex = 0} -> do+          let t = eyeSquare @10 @'Float @'( 'CUDA, 0)+          checkDynamicTensorAttributes t+        Device {deviceType = MPS, deviceIndex = 0} -> do+          let t = eyeSquare @10 @'Float @'( 'MPS, 0)+          checkDynamicTensorAttributes t
+ test/Torch/Typed/FunctionalSpec0.hs view
@@ -0,0 +1,753 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE NoStarIsType #-}+{-# LANGUAGE FlexibleContexts #-}+{-# OPTIONS_GHC -freduction-depth=0 #-}++module Torch.Typed.FunctionalSpec0+  ( Torch.Typed.FunctionalSpec0.spec,+  )+where++import Data.Proxy+import GHC.TypeLits+import Test.Hspec (Spec, before_, describe, it)+import Test.QuickCheck ()+import Torch.Internal.Managed.Type.Context (get_manual_seed)+import Torch.Typed+import Torch.Typed.AuxiliarySpec+import Prelude hiding+  ( abs,+    acos,+    acosh,+    all,+    any,+    asin,+    asinh,+    atan,+    atanh,+    cos,+    cosh,+    exp,+    floor,+    log,+    max,+    min,+    round,+    sin,+    sinh,+    sqrt,+    tan,+    tanh,+  )++data UnaryAllDTypesSpec+  = SignSpec+  | OnesLikeSpec+  | ZerosLikeSpec++instance+  ( TensorOptions shape dtype device+  ) =>+  Apply' UnaryAllDTypesSpec ((Proxy device, (Proxy dtype, Proxy shape)), IO ()) (IO ())+  where+  apply' SignSpec (_, agg) =+    agg >> do+      let t = sign (ones @shape @dtype @device)+      checkDynamicTensorAttributes t+  apply' OnesLikeSpec (_, agg) =+    agg >> do+      let t = onesLike (ones @shape @dtype @device)+      checkDynamicTensorAttributes t+  apply' ZerosLikeSpec (_, agg) =+    agg >> do+      let t = zerosLike (ones @shape @dtype @device)+      checkDynamicTensorAttributes t++data UnaryStandardDTypesSpec+  = AbsSpec++instance+  ( TensorOptions shape dtype device,+    StandardDTypeValidation device dtype+  ) =>+  Apply' UnaryStandardDTypesSpec ((Proxy device, (Proxy dtype, Proxy shape)), IO ()) (IO ())+  where+  apply' AbsSpec (_, agg) =+    agg >> do+      let t = abs (ones @shape @dtype @device)+      checkDynamicTensorAttributes t++data UnaryStandardFloatingPointDTypesSpec+  = FracSpec+  | CeilSpec+  | FloorSpec+  | RoundSpec+  | TruncSpec+  | ErfSpec+  | ErfcSpec+  | ErfinvSpec+  | ExpSpec+  | Expm1Spec+  | LogSpec+  | Log1pSpec+  | Log2Spec+  | Log10Spec+  | LgammaSpec+  | DigammaSpec+  | ReluSpec+  | SeluSpec+  | SigmoidSpec+  | LogSigmoidSpec+  | SinSpec+  | SinhSpec+  | AsinSpec+  | CosSpec+  | CoshSpec+  | AcosSpec+  | TanSpec+  | TanhSpec+  | AtanSpec+  | SqrtSpec+  | RsqrtSpec+  | RandLikeSpec+  | RandnLikeSpec++instance+  ( TensorOptions shape dtype device,+    StandardFloatingPointDTypeValidation device dtype+  ) =>+  Apply' UnaryStandardFloatingPointDTypesSpec ((Proxy device, (Proxy dtype, Proxy shape)), IO ()) (IO ())+  where+  apply' FracSpec (_, agg) =+    agg >> do+      let t = frac (ones @shape @dtype @device)+      checkDynamicTensorAttributes t+  apply' CeilSpec (_, agg) =+    agg >> do+      let t = ceil (ones @shape @dtype @device)+      checkDynamicTensorAttributes t+  apply' FloorSpec (_, agg) =+    agg >> do+      let t = floor (ones @shape @dtype @device)+      checkDynamicTensorAttributes t+  apply' TruncSpec (_, agg) =+    agg >> do+      let t = trunc (ones @shape @dtype @device)+      checkDynamicTensorAttributes t+  apply' ErfSpec (_, agg) =+    agg >> do+      let t = erf (ones @shape @dtype @device)+      checkDynamicTensorAttributes t+  apply' ErfcSpec (_, agg) =+    agg >> do+      let t = erfc (ones @shape @dtype @device)+      checkDynamicTensorAttributes t+  apply' ErfinvSpec (_, agg) =+    agg >> do+      let t = erfinv (ones @shape @dtype @device)+      checkDynamicTensorAttributes t+  apply' ExpSpec (_, agg) =+    agg >> do+      let t = exp (ones @shape @dtype @device)+      checkDynamicTensorAttributes t+  apply' Expm1Spec (_, agg) =+    agg >> do+      let t = expm1 (ones @shape @dtype @device)+      checkDynamicTensorAttributes t+  apply' LogSpec (_, agg) =+    agg >> do+      let t = log (ones @shape @dtype @device)+      checkDynamicTensorAttributes t+  apply' Log1pSpec (_, agg) =+    agg >> do+      let t = log1p (ones @shape @dtype @device)+      checkDynamicTensorAttributes t+  apply' Log2Spec (_, agg) =+    agg >> do+      let t = log2 (ones @shape @dtype @device)+      checkDynamicTensorAttributes t+  apply' Log10Spec (_, agg) =+    agg >> do+      let t = log10 (ones @shape @dtype @device)+      checkDynamicTensorAttributes t+  apply' LgammaSpec (_, agg) =+    agg >> do+      let t = lgamma (ones @shape @dtype @device)+      checkDynamicTensorAttributes t+  apply' DigammaSpec (_, agg) =+    agg >> do+      let t = digamma (ones @shape @dtype @device)+      checkDynamicTensorAttributes t+  apply' ReluSpec (_, agg) =+    agg >> do+      let t = relu (ones @shape @dtype @device)+      checkDynamicTensorAttributes t+  apply' SeluSpec (_, agg) =+    agg >> do+      let t = selu (ones @shape @dtype @device)+      checkDynamicTensorAttributes t+  apply' SigmoidSpec (_, agg) =+    agg >> do+      let t = sigmoid (ones @shape @dtype @device)+      checkDynamicTensorAttributes t+  apply' LogSigmoidSpec (_, agg) =+    agg >> do+      let t = logSigmoid (ones @shape @dtype @device)+      checkDynamicTensorAttributes t+  apply' SinSpec (_, agg) =+    agg >> do+      let t = sin (ones @shape @dtype @device)+      checkDynamicTensorAttributes t+  apply' SinhSpec (_, agg) =+    agg >> do+      let t = sinh (ones @shape @dtype @device)+      checkDynamicTensorAttributes t+  apply' AsinSpec (_, agg) =+    agg >> do+      let t = asin (ones @shape @dtype @device)+      checkDynamicTensorAttributes t+  apply' CosSpec (_, agg) =+    agg >> do+      let t = cos (ones @shape @dtype @device)+      checkDynamicTensorAttributes t+  apply' CoshSpec (_, agg) =+    agg >> do+      let t = cosh (ones @shape @dtype @device)+      checkDynamicTensorAttributes t+  apply' AcosSpec (_, agg) =+    agg >> do+      let t = acos (ones @shape @dtype @device)+      checkDynamicTensorAttributes t+  apply' TanSpec (_, agg) =+    agg >> do+      let t = tan (ones @shape @dtype @device)+      checkDynamicTensorAttributes t+  apply' TanhSpec (_, agg) =+    agg >> do+      let t = tanh (ones @shape @dtype @device)+      checkDynamicTensorAttributes t+  apply' AtanSpec (_, agg) =+    agg >> do+      let t = atan (ones @shape @dtype @device)+      checkDynamicTensorAttributes t+  apply' SqrtSpec (_, agg) =+    agg >> do+      let t = sqrt (ones @shape @dtype @device)+      checkDynamicTensorAttributes t+  apply' RsqrtSpec (_, agg) =+    agg >> do+      let t = rsqrt (ones @shape @dtype @device)+      checkDynamicTensorAttributes t+  apply' RandLikeSpec (_, agg) =+    agg >> do+      t <- randLike (ones @shape @dtype @device)+      checkDynamicTensorAttributes t+  apply' RandnLikeSpec (_, agg) =+    agg >> do+      t <- randnLike (ones @shape @dtype @device)+      checkDynamicTensorAttributes t++data MishSpec = MishSpec++instance+  ( TensorOptions shape dtype device,+    StandardFloatingPointDTypeValidation device dtype,+    BasicArithmeticDTypeIsValid device dtype,+    shape ~ Broadcast shape shape+  ) =>+  Apply' MishSpec ((Proxy device, (Proxy dtype, Proxy shape)), IO ()) (IO ())+  where+  apply' MishSpec (_, agg) =+    agg >> do+      let t = mish (ones @shape @dtype @device)+      checkDynamicTensorAttributes t++data GeluSpec = GeluSpec++instance+  ( TensorOptions shape dtype device,+    GeluDTypeIsValid device dtype+  ) =>+  Apply' GeluSpec ((Proxy device, (Proxy dtype, Proxy shape)), IO ()) (IO ())+  where+  apply' GeluSpec (_, agg) =+    agg >> do+      let t = gelu (ones @shape @dtype @device)+      checkDynamicTensorAttributes t++data LeakyReluSpec = LeakyReluSpec++instance+  ( TensorOptions shape dtype device,+    Scalar a,+    StandardFloatingPointDTypeValidation device dtype+  ) =>+  Apply' LeakyReluSpec ((Proxy device, (a, (Proxy dtype, Proxy shape))), IO ()) (IO ())+  where+  apply' LeakyReluSpec ((_, (negativeSlope, _)), agg) =+    agg >> do+      let t = leakyRelu negativeSlope (ones @shape @dtype @device)+      checkDynamicTensorAttributes t++data ELUSpec = ELUSpec++instance+  ( TensorOptions shape dtype device,+    Scalar a,+    StandardFloatingPointDTypeValidation device dtype+  ) =>+  Apply' ELUSpec ((Proxy device, ((a, (a, a)), (Proxy dtype, Proxy shape))), IO ()) (IO ())+  where+  apply' ELUSpec ((_, ((alpha, (scale, inputScale)), _)), agg) =+    agg >> do+      let t = elu alpha scale inputScale (ones @shape @dtype @device)+      checkDynamicTensorAttributes t++data ToDTypeSpec = ToDTypeSpec++instance+  ( TensorOptions shape dtype device,+    TensorOptions shape dtype' device,+    KnownDType dtype'+  ) =>+  Apply' ToDTypeSpec ((Proxy device, ((Proxy dtype, Proxy dtype'), Proxy shape)), IO ()) (IO ())+  where+  apply' ToDTypeSpec (_, agg) =+    agg >> do+      let t = ones @shape @dtype @device+          t' = toDType @dtype' @dtype t+      checkDynamicTensorAttributes t'++data SumAllSpec = SumAllSpec++instance+  ( TensorOptions shape dtype device,+    SumDTypeIsValid device dtype,+    KnownDType (SumDType dtype),+    KnownDevice device+  ) =>+  Apply' SumAllSpec ((Proxy device, (Proxy dtype, Proxy shape)), IO ()) (IO ())+  where+  apply' SumAllSpec (_, agg) =+    agg >> do+      let t = ones @shape @dtype @device+          t' = sumAll t+      checkDynamicTensorAttributes t'++data SumDimSpec = SumDimSpec++instance+  ( TensorOptions shape dtype device,+    TensorOptions shape' dtype' device,+    KnownNat d,+    shape' ~ DropValue shape d,+    dtype' ~ SumDType dtype,+    SumDTypeIsValid device dtype+  ) =>+  Apply' SumDimSpec ((Proxy d, (Proxy device, (Proxy dtype, Proxy shape))), IO ()) (IO ())+  where+  apply' SumDimSpec (_, agg) =+    agg >> do+      let t = ones @shape @dtype @device+          t' = sumDim @d t+      checkDynamicTensorAttributes t'++data MinMaxSpec+  = MinSpec+  | MaxSpec++instance+  ( TensorOptions shape dtype device,+    KnownDType dtype,+    KnownDevice device,+    MinMaxDTypeIsValid device dtype,+    AllDimsPositive shape+  ) =>+  Apply' MinMaxSpec ((Proxy device, (Proxy dtype, Proxy shape)), IO ()) (IO ())+  where+  apply' MinSpec (_, agg) =+    agg >> do+      let t = ones @shape @dtype @device+          t' = min t+      checkDynamicTensorAttributes t'+  apply' MaxSpec (_, agg) =+    agg >> do+      let t = ones @shape @dtype @device+          t' = max t+      checkDynamicTensorAttributes t'++data MeanAllSpec = MeanAllSpec++instance+  ( TensorOptions shape dtype device,+    KnownDType dtype,+    KnownDevice device,+    MeanDTypeValidation device dtype,+    AllDimsPositive shape+  ) =>+  Apply' MeanAllSpec ((Proxy device, (Proxy dtype, Proxy shape)), IO ()) (IO ())+  where+  apply' MeanAllSpec (_, agg) =+    agg >> do+      let t = ones @shape @dtype @device+          t' = meanAll t+      checkDynamicTensorAttributes t'++data MeanDimSpec = MeanDimSpec++instance+  ( TensorOptions shape dtype device,+    TensorOptions shape' dtype device,+    KnownNat dim,+    shape' ~ DropValue shape dim,+    MeanDTypeValidation device dtype,+    AllDimsPositive shape+  ) =>+  Apply' MeanDimSpec ((Proxy dim, (Proxy device, (Proxy dtype, Proxy shape))), IO ()) (IO ())+  where+  apply' MeanDimSpec (_, agg) =+    agg >> do+      let t = ones @shape @dtype @device+          t' = meanDim @dim t+      checkDynamicTensorAttributes t'++data MeanSpec = MeanSpec++instance+  ( TensorOptions shape dtype device,+    TensorOptions shape' dtype device,+    KnownNat dim,+    KnownKeepOrDropDim keepOrDropDim,+    shape' ~ ConditionalDropDimension shape dim keepOrDropDim,+    MeanDTypeValidation device dtype,+    AllDimsPositive shape+  ) =>+  Apply' MeanSpec (((Proxy dim, Proxy keepOrDropDim), (Proxy device, (Proxy dtype, Proxy shape))), IO ()) (IO ())+  where+  apply' MeanSpec (_, agg) =+    agg >> do+      let t = ones @shape @dtype @device+          t' = mean @dim @keepOrDropDim t+      checkDynamicTensorAttributes t'++data MedianAllSpec = MedianAllSpec++instance+  ( TensorOptions shape dtype device,+    KnownDType dtype,+    KnownDevice device,+    StandardDTypeValidation device dtype,+    AllDimsPositive shape+  ) =>+  Apply' MedianAllSpec ((Proxy device, (Proxy dtype, Proxy shape)), IO ()) (IO ())+  where+  apply' MedianAllSpec (_, agg) =+    agg >> do+      let t = ones @shape @dtype @device+          t' = medianAll t+      checkDynamicTensorAttributes t'++data MedianDimSpec = MedianDimSpec++instance+  ( TensorOptions shape dtype device,+    TensorOptions shape' dtype device,+    TensorOptions shape' 'Int64 device,+    KnownNat dim,+    shape' ~ DropValue shape dim,+    StandardDTypeValidation device dtype,+    AllDimsPositive shape+  ) =>+  Apply' MedianDimSpec ((Proxy dim, (Proxy device, (Proxy dtype, Proxy shape))), IO ()) (IO ())+  where+  apply' MedianDimSpec (_, agg) =+    agg >> do+      let t = ones @shape @dtype @device+          (t', t'') = medianDim @dim t+      checkDynamicTensorAttributes t'+      checkDynamicTensorAttributes t''++data MedianSpec = MedianSpec++instance+  ( TensorOptions shape dtype device,+    TensorOptions shape' dtype device,+    TensorOptions shape' 'Int64 device,+    KnownNat dim,+    KnownKeepOrDropDim keepOrDropDim,+    shape' ~ ConditionalDropDimension shape dim keepOrDropDim,+    StandardDTypeValidation device dtype,+    AllDimsPositive shape+  ) =>+  Apply' MedianSpec (((Proxy dim, Proxy keepOrDropDim), (Proxy device, (Proxy dtype, Proxy shape))), IO ()) (IO ())+  where+  apply' MedianSpec (_, agg) =+    agg >> do+      let t = ones @shape @dtype @device+          (t', t'') = median @dim @keepOrDropDim t+      checkDynamicTensorAttributes t'+      checkDynamicTensorAttributes t''++data ModeSpec = ModeSpec++instance+  ( TensorOptions shape dtype device,+    TensorOptions shape' dtype device,+    TensorOptions shape' 'Int64 device,+    KnownNat dim,+    KnownKeepOrDropDim keepOrDropDim,+    shape' ~ ConditionalDropDimension shape dim keepOrDropDim,+    StandardDTypeValidation device dtype,+    AllDimsPositive shape+  ) =>+  Apply' ModeSpec (((Proxy dim, Proxy keepOrDropDim), (Proxy device, (Proxy dtype, Proxy shape))), IO ()) (IO ())+  where+  apply' ModeSpec (_, agg) =+    agg >> do+      let t = ones @shape @dtype @device+          (t', t'') = mode @dim @keepOrDropDim t+      checkDynamicTensorAttributes t'+      checkDynamicTensorAttributes t''++spec :: Spec+spec = before_ printSeed $ do+  foldMap spec' availableDevices+  where+    printSeed = do+      putStr "      seed:"+      get_manual_seed >>= print++spec' :: Device -> Spec+spec' device =+  describe ("for " <> show device) $ do+    let standardShapes = Proxy @'[2, 3] :. HNil -- (Proxy :: Proxy ('[] :: [Nat])) :. Proxy @'[0]  :. Proxy @'[0, 1] :. Proxy @'[1, 0] :. Proxy @'[2, 3] :. HNil+        squareShapes = Proxy @'[0, 0] :. Proxy @'[1, 1] :. Proxy @'[2, 2] :. Proxy @'[0, 0, 0] :. Proxy @'[0, 1, 1] :. Proxy @'[1, 0, 0] :. Proxy @'[3, 2, 2] :. HNil+        reductions = Proxy @ReduceNone :. Proxy @ReduceMean :. Proxy @ReduceSum :. HNil++    describe "unary ops" $ do+      let dispatch unaryAllDTypesSpec = case device of+            Device {deviceType = CPU, deviceIndex = 0} ->+              hfoldrM @IO unaryAllDTypesSpec () (hattach cpu (hproduct allDTypes standardShapes))+            Device {deviceType = CUDA, deviceIndex = 0} ->+              hfoldrM @IO unaryAllDTypesSpec () (hattach cuda0 (hproduct allDTypes standardShapes))+            Device {deviceType = MPS, deviceIndex = 0} ->+              hfoldrM @IO unaryAllDTypesSpec () (hattach mps (hproduct mpsDTypes standardShapes))++      it "abs" $ case device of+        Device {deviceType = CPU, deviceIndex = 0} ->+          hfoldrM @IO AbsSpec () (hattach cpu (hproduct standardDTypes standardShapes))+        Device {deviceType = CUDA, deviceIndex = 0} ->+          hfoldrM @IO AbsSpec () (hattach cuda0 (hproduct standardDTypes standardShapes))+        Device {deviceType = MPS, deviceIndex = 0} ->+          hfoldrM @IO AbsSpec () (hattach mps (hproduct mpsDTypes standardShapes))+      it "sign" $ dispatch SignSpec+      it "onesLike" $ dispatch OnesLikeSpec+      it "zerosLike" $ dispatch ZerosLikeSpec++    describe "unary floating-point ops" $ do+      let scalarParams = (0.01 :: Double) :. (0.01 :: Float) :. (1 :: Int) :. HNil+          dispatch unaryStandardFloatingPointDTypesSpec = case device of+            Device {deviceType = CPU, deviceIndex = 0} ->+              hfoldrM @IO unaryStandardFloatingPointDTypesSpec () (hattach cpu (hproduct standardFloatingPointDTypes standardShapes))+            Device {deviceType = CUDA, deviceIndex = 0} ->+              hfoldrM @IO unaryStandardFloatingPointDTypesSpec () (hattach cuda0 (hproduct allFloatingPointDTypes standardShapes))+            Device {deviceType = MPS, deviceIndex = 0} ->+              hfoldrM @IO unaryStandardFloatingPointDTypesSpec () (hattach mps (hproduct mpsFloatingPointDTypes standardShapes))++      it "frac" $ dispatch FracSpec+      it "ceil" $ dispatch CeilSpec+      it "floor" $ dispatch FloorSpec+      it "trunc" $ dispatch TruncSpec++      it "erf" $ dispatch ErfSpec+      it "erfc" $ dispatch ErfcSpec+      it "erfinv" $ dispatch ErfinvSpec+      it "exp" $ dispatch ExpSpec+      it "expm1" $ dispatch Expm1Spec+      it "log" $ dispatch LogSpec+      it "log1p" $ dispatch Log1pSpec+      it "log2" $ dispatch Log2Spec+      it "log10" $ dispatch Log10Spec+      it "lgamma" $ dispatch LgammaSpec+      it "digamma" $ dispatch DigammaSpec++      it "relu" $ dispatch ReluSpec+      it "selu" $ dispatch SeluSpec+      it "mish" $ case device of+        Device {deviceType = CPU, deviceIndex = 0} ->+          hfoldrM @IO MishSpec () (hattach cpu (hproduct standardFloatingPointDTypes standardShapes))+        Device {deviceType = CUDA, deviceIndex = 0} ->+          hfoldrM @IO MishSpec () (hattach cuda0 (hproduct allFloatingPointDTypes standardShapes))+        Device {deviceType = MPS, deviceIndex = 0} ->+          hfoldrM @IO MishSpec () (hattach mps (hproduct mpsFloatingPointDTypes standardShapes))+      it "gelu" $ case device of+        Device {deviceType = CPU, deviceIndex = 0} ->+          hfoldrM @IO GeluSpec () (hattach cpu (hproduct standardFloatingPointDTypes standardShapes))+        Device {deviceType = CUDA, deviceIndex = 0} ->+          hfoldrM @IO GeluSpec () (hattach cuda0 (hproduct standardFloatingPointDTypes standardShapes))+        Device {deviceType = MPS, deviceIndex = 0} ->+          hfoldrM @IO GeluSpec () (hattach mps (hproduct mpsFloatingPointDTypes standardShapes))+      it "leakyRelu" $ case device of+        Device {deviceType = CPU, deviceIndex = 0} ->+          hfoldrM @IO+            LeakyReluSpec+            ()+            (hattach cpu (hproduct scalarParams (hproduct standardFloatingPointDTypes standardShapes)))+        Device {deviceType = CUDA, deviceIndex = 0} ->+          hfoldrM @IO+            LeakyReluSpec+            ()+            (hattach cuda0 (hproduct scalarParams (hproduct standardFloatingPointDTypes standardShapes)))+        Device {deviceType = MPS, deviceIndex = 0} ->+          hfoldrM @IO+            LeakyReluSpec+            ()+            (hattach mps (hproduct scalarParams (hproduct mpsFloatingPointDTypes standardShapes)))+      it "elu" $ case device of+        Device {deviceType = CPU, deviceIndex = 0} ->+          hfoldrM @IO+            ELUSpec+            ()+            (hattach cpu (hproduct (hzip scalarParams (hzip scalarParams scalarParams)) (hproduct standardFloatingPointDTypes standardShapes)))+        Device {deviceType = CUDA, deviceIndex = 0} ->+          hfoldrM @IO+            ELUSpec+            ()+            (hattach cuda0 (hproduct (hzip scalarParams (hzip scalarParams scalarParams)) (hproduct standardFloatingPointDTypes standardShapes)))+        Device {deviceType = MPS, deviceIndex = 0} ->+          hfoldrM @IO+            ELUSpec+            ()+            (hattach mps (hproduct (hzip scalarParams (hzip scalarParams scalarParams)) (hproduct mpsFloatingPointDTypes standardShapes)))+      it "sigmoid" $ dispatch SigmoidSpec+      it "logSigmoid" $ dispatch LogSigmoidSpec++      it "sin" $ dispatch SinSpec+      it "sinh" $ dispatch SinhSpec+      it "asin" $ dispatch AsinSpec+      it "cos" $ dispatch CosSpec+      it "cosh" $ dispatch CoshSpec+      it "acos" $ dispatch AcosSpec+      it "tan" $ dispatch TanSpec+      it "tanh" $ dispatch TanhSpec+      it "atan" $ dispatch AtanSpec+      it "sqrt" $ dispatch SqrtSpec+      it "rsqrt" $ dispatch RsqrtSpec++      it "randLike" $ dispatch RandLikeSpec+      it "randnLike" $ dispatch RandnLikeSpec++      it "toDType" $ case device of+        Device {deviceType = CPU, deviceIndex = 0} ->+          hfoldrM @IO ToDTypeSpec () (hattach cpu (hproduct (hproduct allDTypes allDTypes) standardShapes))+        Device {deviceType = CUDA, deviceIndex = 0} ->+          hfoldrM @IO ToDTypeSpec () (hattach cuda0 (hproduct (hproduct allDTypes allDTypes) standardShapes))+        Device {deviceType = MPS, deviceIndex = 0} ->+          hfoldrM @IO ToDTypeSpec () (hattach mps (hproduct (hproduct mpsDTypes mpsDTypes) standardShapes))++    describe "aggregation" $ do+      it "sumAll" $ case device of+        Device {deviceType = CPU, deviceIndex = 0} ->+          hfoldrM @IO SumAllSpec () (hattach cpu (hproduct almostAllDTypes standardShapes))+        Device {deviceType = CUDA, deviceIndex = 0} ->+          hfoldrM @IO SumAllSpec () (hattach cuda0 (hproduct allDTypes standardShapes))+        Device {deviceType = MPS, deviceIndex = 0} ->+          hfoldrM @IO SumAllSpec () (hattach mps (hproduct mpsDTypes standardShapes))+      it "sumDim" $ do+        let sumDimDims = Proxy @0 :. Proxy @1 :. HNil+            sumDimShapes = Proxy @'[1, 0] :. Proxy @'[2, 3] :. HNil+        case device of+          Device {deviceType = CPU, deviceIndex = 0} ->+            hfoldrM @IO SumDimSpec () (hproduct sumDimDims (hattach cpu (hproduct almostAllDTypes sumDimShapes)))+          Device {deviceType = CUDA, deviceIndex = 0} ->+            hfoldrM @IO SumDimSpec () (hproduct sumDimDims (hattach cuda0 (hproduct allDTypes sumDimShapes)))+          Device {deviceType = MPS, deviceIndex = 0} ->+            hfoldrM @IO SumDimSpec () (hproduct sumDimDims (hattach mps (hproduct mpsDTypes sumDimShapes)))+      do+        let shapes = (Proxy :: Proxy ('[] :: [Nat])) :. Proxy @'[1] :. Proxy @'[2, 3] :. HNil+            dispatch spec = case device of+              Device {deviceType = CPU, deviceIndex = 0} ->+                hfoldrM @IO spec () (hattach cpu (hproduct almostAllDTypes shapes))+              Device {deviceType = CUDA, deviceIndex = 0} ->+                hfoldrM @IO spec () (hattach cuda0 (hproduct allDTypes shapes))+              Device {deviceType = MPS, deviceIndex = 0} ->+                hfoldrM @IO spec () (hattach mps (hproduct mpsDTypes shapes))+        it "min" $ dispatch MinSpec+        it "max" $ dispatch MaxSpec+      it "meanAll" $ do+        let shapes = (Proxy :: Proxy ('[] :: [Nat])) :. Proxy @'[1] :. Proxy @'[2, 3] :. HNil+        case device of+          Device {deviceType = CPU, deviceIndex = 0} ->+            hfoldrM @IO MeanAllSpec () (hattach cpu (hproduct standardFloatingPointDTypes shapes))+          Device {deviceType = CUDA, deviceIndex = 0} ->+            hfoldrM @IO MeanAllSpec () (hattach cuda0 (hproduct standardFloatingPointDTypes shapes))+          Device {deviceType = MPS, deviceIndex = 0} ->+            hfoldrM @IO MeanAllSpec () (hattach mps (hproduct mpsFloatingPointDTypes shapes))+      it "meanDim" $ do+        let dims = Proxy @0 :. Proxy @1 :. HNil+            shapes = Proxy @'[1, 3] :. Proxy @'[2, 3] :. HNil+        case device of+          Device {deviceType = CPU, deviceIndex = 0} ->+            hfoldrM @IO MeanDimSpec () (hproduct dims (hattach cpu (hproduct standardFloatingPointDTypes shapes)))+          Device {deviceType = CUDA, deviceIndex = 0} ->+            hfoldrM @IO MeanDimSpec () (hproduct dims (hattach cuda0 (hproduct standardFloatingPointDTypes shapes)))+          Device {deviceType = MPS, deviceIndex = 0} ->+            hfoldrM @IO MeanDimSpec () (hproduct dims (hattach mps (hproduct mpsFloatingPointDTypes shapes)))+      it "mean" $ do+        let dims = Proxy @0 :. Proxy @1 :. HNil+            keepOrDropDims = Proxy @KeepDim :. Proxy @DropDim :. HNil+            shapes = Proxy @'[1, 12] :. Proxy @'[2, 3] :. HNil+        case device of+          Device {deviceType = CPU, deviceIndex = 0} ->+            hfoldrM @IO MeanSpec () (hproduct (hproduct dims keepOrDropDims) (hattach cpu (hproduct standardFloatingPointDTypes shapes)))+          Device {deviceType = CUDA, deviceIndex = 0} ->+            hfoldrM @IO MeanSpec () (hproduct (hproduct dims keepOrDropDims) (hattach cpu (hproduct standardFloatingPointDTypes shapes)))+          Device {deviceType = MPS, deviceIndex = 0} ->+            hfoldrM @IO MeanSpec () (hproduct (hproduct dims keepOrDropDims) (hattach cpu (hproduct mpsFloatingPointDTypes shapes)))+      it "medianAll" $ do+        let shapes = (Proxy :: Proxy ('[] :: [Nat])) :. Proxy @'[1] :. Proxy @'[2, 3] :. HNil+        case device of+          Device {deviceType = CPU, deviceIndex = 0} ->+            hfoldrM @IO MedianAllSpec () (hattach cpu (hproduct standardDTypes shapes))+          Device {deviceType = CUDA, deviceIndex = 0} ->+            hfoldrM @IO MedianAllSpec () (hattach cuda0 (hproduct (withHalf standardDTypes) shapes))+          Device {deviceType = MPS, deviceIndex = 0} ->+            hfoldrM @IO MedianAllSpec () (hattach mps (hproduct (withHalf mpsDTypes) shapes))+      it "medianDim" $ do+        let dims = Proxy @0 :. Proxy @1 :. HNil+            shapes = Proxy @'[1, 17, 1] :. Proxy @'[2, 3] :. HNil+        case device of+          Device {deviceType = CPU, deviceIndex = 0} ->+            hfoldrM @IO MedianDimSpec () (hproduct dims (hattach cpu (hproduct standardDTypes shapes)))+          Device {deviceType = CUDA, deviceIndex = 0} ->+            hfoldrM @IO MedianDimSpec () (hproduct dims (hattach cuda0 (hproduct (withHalf standardDTypes) shapes)))+          Device {deviceType = MPS, deviceIndex = 0} ->+            hfoldrM @IO MedianDimSpec () (hproduct dims (hattach mps (hproduct (withHalf mpsDTypes) shapes)))+      it "median" $ do+        let dims = Proxy @0 :. Proxy @1 :. HNil+            keepOrDropDims = Proxy @KeepDim :. Proxy @DropDim :. HNil+            shapes = Proxy @'[2, 13] :. Proxy @'[2, 3] :. Proxy @'[1, 3, 7] :. HNil+        case device of+          Device {deviceType = CPU, deviceIndex = 0} ->+            hfoldrM @IO MedianSpec () (hproduct (hproduct dims keepOrDropDims) (hattach cpu (hproduct standardDTypes shapes)))+          Device {deviceType = CUDA, deviceIndex = 0} ->+            hfoldrM @IO MedianSpec () (hproduct (hproduct dims keepOrDropDims) (hattach cuda0 (hproduct (withHalf standardDTypes) shapes)))+          Device {deviceType = MPS, deviceIndex = 0} ->+            hfoldrM @IO MedianSpec () (hproduct (hproduct dims keepOrDropDims) (hattach mps (hproduct (withHalf mpsDTypes) shapes)))+      it "mode" $ do+        let dims = Proxy @0 :. Proxy @1 :. HNil+            keepOrDropDims = Proxy @KeepDim :. Proxy @DropDim :. HNil+            shapes = Proxy @'[2, 13] :. Proxy @'[2, 3] :. Proxy @'[1, 3, 7] :. HNil+        case device of+          Device {deviceType = CPU, deviceIndex = 0} ->+            hfoldrM @IO ModeSpec () (hproduct (hproduct dims keepOrDropDims) (hattach cpu (hproduct standardDTypes shapes)))+          Device {deviceType = CUDA, deviceIndex = 0} ->+            hfoldrM @IO ModeSpec () (hproduct (hproduct dims keepOrDropDims) (hattach cuda0 (hproduct (withHalf standardDTypes) shapes)))+          Device {deviceType = MPS, deviceIndex = 0} -> pure ()
+ test/Torch/Typed/FunctionalSpec1.hs view
@@ -0,0 +1,337 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE NoStarIsType #-}+{-# LANGUAGE FlexibleContexts #-}+{-# OPTIONS_GHC -freduction-depth=0 #-}++module Torch.Typed.FunctionalSpec1+  ( Torch.Typed.FunctionalSpec1.spec,+  )+where++import Data.Proxy+import GHC.TypeLits+import Test.Hspec (Spec, before_, describe, it)+import Test.QuickCheck ()+import Torch.Internal.Managed.Type.Context (get_manual_seed)+import Torch.Typed+import Torch.Typed.AuxiliarySpec+import Prelude hiding+  ( abs,+    acos,+    acosh,+    all,+    any,+    asin,+    asinh,+    atan,+    atanh,+    cos,+    cosh,+    exp,+    floor,+    log,+    max,+    min,+    round,+    sin,+    sinh,+    sqrt,+    tan,+    tanh,+  )++data SqueezeAllSpec = SqueezeAllSpec++instance+  ( TensorOptions shape dtype device,+    TensorOptions shape' dtype device,+    shape' ~ SqueezeAll shape+  ) =>+  Apply' SqueezeAllSpec ((Proxy device, (Proxy dtype, Proxy shape)), IO ()) (IO ())+  where+  apply' SqueezeAllSpec (_, agg) =+    agg >> do+      let t = ones @shape @dtype @device+          t' = squeezeAll t+      checkDynamicTensorAttributes t'++data TransposeSpec = TransposeSpec++instance+  ( TensorOptions shape dtype device,+    TensorOptions shape' dtype device,+    shape' ~ Transpose shape n m,+    KnownNat n,+    KnownNat m+  ) =>+  Apply' TransposeSpec (((Proxy n, Proxy m), (Proxy device, (Proxy dtype, Proxy shape))), IO ()) (IO ())+  where+  apply' TransposeSpec (_, agg) =+    agg >> do+      let t = ones @shape @dtype @device+          t' = transpose @n @m t+      checkDynamicTensorAttributes t'++data Transpose2DSpec = Transpose2DSpec++instance+  ( TensorOptions '[i, j] dtype device,+    TensorOptions '[j, i] dtype device+  ) =>+  Apply' Transpose2DSpec ((Proxy device, (Proxy dtype, Proxy '[i, j])), IO ()) (IO ())+  where+  apply' Transpose2DSpec (_, agg) =+    agg >> do+      let t = ones @'[i, j] @dtype @device+          t' = transpose2D t+      checkDynamicTensorAttributes t'++data NarrowSpec = NarrowSpec++instance+  ( TensorOptions shape dtype device,+    TensorOptions+      ( NarrowCheck+          (ExtractDim dim shape)+          (Narrow' dim shape (ExtractDim dim shape) start length)+          shape+          dim+          start+          length+      )+      dtype+      device,+    All KnownNat shape,+    All KnownNat '[dim, start, length]+  ) =>+  Apply' NarrowSpec ((Proxy dim, (Proxy start, (Proxy length, (Proxy device, (Proxy dtype, Proxy shape))))), IO ()) (IO ())+  where+  apply' NarrowSpec (_, agg) =+    agg >> do+      let t = ones @shape @dtype @device+          t' = narrow @dim @start @length t+      checkDynamicTensorAttributes t'++data DiagSpec = DiagSpec++instance+  ( TensorOptions shape dtype device,+    TensorOptions shape' dtype device,+    KnownTri tri,+    KnownNat index,+    StandardDTypeValidation device dtype,+    shape' ~ DiagShape tri index shape+  ) =>+  Apply' DiagSpec (((Proxy tri, Proxy index), (Proxy device, (Proxy dtype, Proxy shape))), IO ()) (IO ())+  where+  apply' DiagSpec (_, agg) =+    agg >> do+      let t = ones @shape @dtype @device+      checkDynamicTensorAttributes $ diag @tri @index t++data DiagEmbedSpec = DiagEmbedSpec++instance+  ( TensorOptions shape dtype device,+    TensorOptions shape' dtype device,+    KnownNat index,+    KnownNat dim1,+    KnownNat dim2,+    DimsDistinctAscending dim1 dim2,+    shape' ~ DiagEmbedShape index dim1 dim2 shape,+    StandardDTypeValidation device dtype+  ) =>+  Apply' DiagEmbedSpec (((Proxy index, (Proxy dim1, Proxy dim2)), (Proxy device, (Proxy dtype, Proxy shape))), IO ()) (IO ())+  where+  apply' DiagEmbedSpec (_, agg) =+    agg >> do+      let t = ones @shape @dtype @device+      foldMap+        (\tri -> checkDynamicTensorAttributes $ diagEmbed @index @dim1 @dim2 tri t)+        [Upper, Lower]++data DiagflatSpec = DiagflatSpec++instance+  ( TensorOptions shape dtype device,+    TensorOptions shape' dtype device,+    KnownNat index,+    shape' ~ DiagflatShape index shape,+    StandardDTypeValidation device dtype+  ) =>+  Apply' DiagflatSpec ((Proxy index, (Proxy device, (Proxy dtype, Proxy shape))), IO ()) (IO ())+  where+  apply' DiagflatSpec (_, agg) =+    agg >> do+      let t = ones @shape @dtype @device+      foldMap+        (\tri -> checkDynamicTensorAttributes $ diagflat @index tri t)+        [Upper, Lower]++data DiagonalSpec = DiagonalSpec++instance+  ( TensorOptions shape dtype device,+    TensorOptions shape' dtype device,+    KnownTri tri,+    KnownNat index,+    KnownNat dim1,+    KnownNat dim2,+    NDimAtLeast 2 shape,+    DimsDistinctAscending dim1 dim2,+    shape' ~ DiagonalShape tri index dim1 dim2 shape,+    StandardDTypeValidation device dtype+  ) =>+  Apply' DiagonalSpec (((Proxy tri, (Proxy index, (Proxy dim1, Proxy dim2))), (Proxy device, (Proxy dtype, Proxy shape))), IO ()) (IO ())+  where+  apply' DiagonalSpec (_, agg) =+    agg >> do+      let t = ones @shape @dtype @device+      checkDynamicTensorAttributes $ diagonal @tri @index @dim1 @dim2 t++spec :: Spec+spec = before_ printSeed $ do+  foldMap spec' availableDevices+  where+    printSeed = do+      putStr "      seed:"+      get_manual_seed >>= print++spec' :: Device -> Spec+spec' device =+  describe ("for " <> show device) $ do+    let standardShapes = Proxy @'[2, 3] :. HNil -- (Proxy :: Proxy ('[] :: [Nat])) :. Proxy @'[0]  :. Proxy @'[0, 1] :. Proxy @'[1, 0] :. Proxy @'[2, 3] :. HNil+        squareShapes = Proxy @'[0, 0] :. Proxy @'[1, 1] :. Proxy @'[2, 2] :. Proxy @'[0, 0, 0] :. Proxy @'[0, 1, 1] :. Proxy @'[1, 0, 0] :. Proxy @'[3, 2, 2] :. HNil+        reductions = Proxy @ReduceNone :. Proxy @ReduceMean :. Proxy @ReduceSum :. HNil++    describe "shape ops" $ do+      it "narrow" $ do+        let dims = Proxy @0 :. Proxy @1 :. HNil+            narrowStarts = Proxy @0 :. Proxy @1 :. HNil+            narrowLengths = Proxy @1 :. Proxy @2 :. HNil+            narrowShapes = Proxy @'[3, 3, 2] :. Proxy @'[13, 5, 0] :. HNil+        case device of+          Device {deviceType = CPU, deviceIndex = 0} ->+            hfoldrM @IO NarrowSpec () (hproduct dims (hproduct narrowStarts (hproduct narrowLengths (hattach cpu (hproduct standardFloatingPointDTypes narrowShapes)))))+          Device {deviceType = CUDA, deviceIndex = 0} ->+            hfoldrM @IO NarrowSpec () (hproduct dims (hproduct narrowStarts (hproduct narrowLengths (hattach cuda0 (hproduct allFloatingPointDTypes narrowShapes)))))+          Device {deviceType = MPS, deviceIndex = 0} ->+            hfoldrM @IO NarrowSpec () (hproduct dims (hproduct narrowStarts (hproduct narrowLengths (hattach mps (hproduct mpsFloatingPointDTypes narrowShapes)))))+      it "squeezeAll" $ case device of+        Device {deviceType = CPU, deviceIndex = 0} ->+          hfoldrM @IO SqueezeAllSpec () (hattach cpu (hproduct allDTypes standardShapes))+        Device {deviceType = CUDA, deviceIndex = 0} ->+          hfoldrM @IO SqueezeAllSpec () (hattach cuda0 (hproduct allDTypes standardShapes))+        Device {deviceType = MPS, deviceIndex = 0} ->+          hfoldrM @IO SqueezeAllSpec () (hattach mps (hproduct mpsDTypes standardShapes))+      it "transpose" $ do+        let dims =+              hzip+                (Proxy @0 :. Proxy @0 :. Proxy @1 :. HNil)+                (Proxy @0 :. Proxy @1 :. Proxy @0 :. HNil)+            shapes = Proxy @'[0, 0] :. Proxy @'[0, 1] :. Proxy @'[1, 0] :. Proxy @'[2, 3] :. Proxy @'[0, 1, 1] :. Proxy @'[1, 0, 1] :. HNil+        case device of+          Device {deviceType = CPU, deviceIndex = 0} ->+            hfoldrM @IO TransposeSpec () (hproduct dims (hattach cpu (hproduct allDTypes shapes)))+          Device {deviceType = CUDA, deviceIndex = 0} ->+            hfoldrM @IO TransposeSpec () (hproduct dims (hattach cuda0 (hproduct allDTypes shapes)))+          Device {deviceType = MPS, deviceIndex = 0} ->+            hfoldrM @IO TransposeSpec () (hproduct dims (hattach mps (hproduct mpsDTypes shapes)))+      it "transpose2d" $ case device of+        Device {deviceType = CPU, deviceIndex = 0} ->+          hfoldrM @IO Transpose2DSpec () (hattach cpu (hproduct allDTypes (Proxy @'[2, 3] :. HNil)))+        Device {deviceType = CUDA, deviceIndex = 0} ->+          hfoldrM @IO Transpose2DSpec () (hattach cuda0 (hproduct allDTypes (Proxy @'[2, 3] :. HNil)))+        Device {deviceType = MPS, deviceIndex = 0} ->+          hfoldrM @IO Transpose2DSpec () (hattach mps (hproduct mpsDTypes (Proxy @'[2, 3] :. HNil)))+      it "diag" $ do+        let vectorShapes = Proxy @'[0] :. Proxy @'[1] :. Proxy @'[2] :. HNil+            emptyShapes = Proxy @'[0, 0] :. Proxy @'[0, 1] :. Proxy @'[1, 0] :. HNil+            tris = Proxy @'Upper :. Proxy @'Lower :. HNil+            indexes = Proxy @0 :. Proxy @1 :. HNil+            indexes' = Proxy @0 :. HNil+        case device of+          Device {deviceType = CPU, deviceIndex = 0} -> do+            hfoldrM @IO DiagSpec () (hproduct (hproduct tris indexes) (hattach cpu (hproduct standardDTypes standardShapes)))+            hfoldrM @IO DiagSpec () (hproduct (hproduct tris indexes) (hattach cpu (hproduct standardDTypes vectorShapes)))+            hfoldrM @IO DiagSpec () (hproduct (hproduct tris indexes') (hattach cpu (hproduct standardDTypes emptyShapes)))+          Device {deviceType = CUDA, deviceIndex = 0} -> do+            hfoldrM @IO DiagSpec () (hproduct (hproduct tris indexes) (hattach cuda0 (hproduct (withHalf standardDTypes) standardShapes)))+            hfoldrM @IO DiagSpec () (hproduct (hproduct tris indexes) (hattach cuda0 (hproduct (withHalf standardDTypes) vectorShapes)))+            hfoldrM @IO DiagSpec () (hproduct (hproduct tris indexes') (hattach cuda0 (hproduct (withHalf standardDTypes) emptyShapes)))+          Device {deviceType = MPS, deviceIndex = 0} -> do+            hfoldrM @IO DiagSpec () (hproduct (hproduct tris indexes) (hattach mps (hproduct (withHalf mpsDTypes) standardShapes)))+            hfoldrM @IO DiagSpec () (hproduct (hproduct tris indexes) (hattach mps (hproduct (withHalf mpsDTypes) vectorShapes)))+            hfoldrM @IO DiagSpec () (hproduct (hproduct tris indexes') (hattach mps (hproduct (withHalf mpsDTypes) emptyShapes)))+      it "diagEmbed" $ do+        let shapes =+              standardShapes+                `happend` ( Proxy @'[0]+                              :. Proxy @'[1]+                              :. Proxy @'[2]+                              :. Proxy @'[0, 0]+                              :. Proxy @'[0, 1]+                              :. Proxy @'[1, 0]+                              :. HNil+                          )+            indexes = Proxy @0 :. Proxy @1 :. HNil+            dims = (Proxy @0, Proxy @1) :. HNil+            allDims = (Proxy @0, Proxy @2) :. dims+        case device of+          Device {deviceType = CPU, deviceIndex = 0} -> do+            hfoldrM @IO DiagEmbedSpec () (hproduct (hproduct indexes dims) (hattach cpu (hproduct standardDTypes shapes)))+            hfoldrM @IO DiagEmbedSpec () (hproduct (hproduct indexes allDims) (hattach cpu (hproduct standardDTypes standardShapes)))+          Device {deviceType = CUDA, deviceIndex = 0} -> do+            hfoldrM @IO DiagEmbedSpec () (hproduct (hproduct indexes dims) (hattach cuda0 (hproduct (withHalf standardDTypes) shapes)))+            hfoldrM @IO DiagEmbedSpec () (hproduct (hproduct indexes allDims) (hattach cuda0 (hproduct (withHalf standardDTypes) standardShapes)))+          Device {deviceType = MPS, deviceIndex = 0} -> do+            hfoldrM @IO DiagEmbedSpec () (hproduct (hproduct indexes dims) (hattach mps (hproduct (withHalf mpsDTypes) shapes)))+            hfoldrM @IO DiagEmbedSpec () (hproduct (hproduct indexes allDims) (hattach mps (hproduct (withHalf mpsDTypes) standardShapes)))+      it "diagflat" $ do+        let shapes =+              standardShapes+                `happend` ( Proxy @'[0]+                              :. Proxy @'[1]+                              :. Proxy @'[2]+                              :. Proxy @'[0, 0]+                              :. Proxy @'[0, 1]+                              :. Proxy @'[1, 0]+                              :. HNil+                          )+            indexes = Proxy @0 :. Proxy @1 :. HNil+        case device of+          Device {deviceType = CPU, deviceIndex = 0} -> do+            hfoldrM @IO DiagflatSpec () (hproduct indexes (hattach cpu (hproduct standardDTypes shapes)))+          Device {deviceType = CUDA, deviceIndex = 0} -> do+            hfoldrM @IO DiagflatSpec () (hproduct indexes (hattach cuda0 (hproduct (withHalf standardDTypes) shapes)))+          Device {deviceType = MPS, deviceIndex = 0} -> do+            hfoldrM @IO DiagflatSpec () (hproduct indexes (hattach mps (hproduct (withHalf mpsDTypes) shapes)))+      it "diagonal" $ do+        let shapes1 = Proxy @'[2, 5, 4, 2] :. HNil+            shapes2 = Proxy @'[2, 3] :. shapes1+            allShapes = Proxy @'[1, 0] :. Proxy @'[0, 1] :. Proxy @'[1, 0] :. Proxy @'[2, 3] :. shapes2+            tris = Proxy @'Upper :. Proxy @'Lower :. HNil+            indexes = Proxy @0 :. HNil+            allIndexes = Proxy @1 :. indexes+            dims = (Proxy @0, Proxy @1) :. HNil+            allDims = (Proxy @0, Proxy @2) :. dims+        case device of+          Device {deviceType = CPU, deviceIndex = 0} -> do+            hfoldrM @IO DiagonalSpec () (hproduct (hproduct tris (hproduct indexes dims)) (hattach cpu (hproduct standardDTypes allShapes)))+            hfoldrM @IO DiagonalSpec () (hproduct (hproduct tris (hproduct allIndexes allDims)) (hattach cpu (hproduct standardDTypes shapes1)))+            hfoldrM @IO DiagonalSpec () (hproduct (hproduct tris (hproduct allIndexes dims)) (hattach cpu (hproduct standardDTypes shapes2)))+          Device {deviceType = CUDA, deviceIndex = 0} -> do+            hfoldrM @IO DiagonalSpec () (hproduct (hproduct tris (hproduct indexes dims)) (hattach cuda0 (hproduct (withHalf standardDTypes) allShapes)))+            hfoldrM @IO DiagonalSpec () (hproduct (hproduct tris (hproduct allIndexes allDims)) (hattach cuda0 (hproduct (withHalf standardDTypes) shapes1)))+            hfoldrM @IO DiagonalSpec () (hproduct (hproduct tris (hproduct allIndexes dims)) (hattach cuda0 (hproduct (withHalf standardDTypes) shapes2)))+          Device {deviceType = MPS, deviceIndex = 0} -> do+            hfoldrM @IO DiagonalSpec () (hproduct (hproduct tris (hproduct indexes dims)) (hattach mps (hproduct (withHalf mpsDTypes) allShapes)))+            hfoldrM @IO DiagonalSpec () (hproduct (hproduct tris (hproduct allIndexes allDims)) (hattach mps (hproduct (withHalf mpsDTypes) shapes1)))+            hfoldrM @IO DiagonalSpec () (hproduct (hproduct tris (hproduct allIndexes dims)) (hattach mps (hproduct (withHalf mpsDTypes) shapes2)))
+ test/Torch/Typed/FunctionalSpec2.hs view
@@ -0,0 +1,741 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE NoStarIsType #-}+{-# LANGUAGE FlexibleContexts #-}+{-# OPTIONS_GHC -freduction-depth=0 #-}++module Torch.Typed.FunctionalSpec2+  ( Torch.Typed.FunctionalSpec2.spec,+  )+where++import Data.Proxy+import GHC.TypeLits+import Test.Hspec (Spec, before_, describe, it)+import Test.QuickCheck ()+import Torch.Internal.Managed.Type.Context (get_manual_seed)+import Torch.Typed+import Torch.Typed.AuxiliarySpec+import Prelude hiding+  ( abs,+    acos,+    acosh,+    all,+    any,+    asin,+    asinh,+    atan,+    atanh,+    cos,+    cosh,+    exp,+    floor,+    log,+    max,+    min,+    round,+    sin,+    sinh,+    sqrt,+    tan,+    tanh,+  )++data LossSpec+  = BinaryCrossEntropySpec+  | MSELossSpec++instance+  ( TensorOptions shape dtype device,+    TensorOptions shape' dtype device,+    KnownReduction reduction,+    shape' ~ ConditionalReduction shape reduction,+    StandardFloatingPointDTypeValidation device dtype+  ) =>+  Apply' LossSpec ((Proxy reduction, (Proxy device, (Proxy dtype, Proxy shape))), IO ()) (IO ())+  where+  apply' BinaryCrossEntropySpec (_, agg) =+    agg >> do+      let weight = ones @shape @dtype @device+          prediction = ones @shape @dtype @device+          target = ones @shape @dtype @device+          t = binaryCrossEntropy @reduction weight prediction target+      checkDynamicTensorAttributes t+  apply' MSELossSpec (_, agg) =+    agg >> do+      let prediction = ones @shape @dtype @device+          target = ones @shape @dtype @device+          t = mseLoss @reduction prediction target+      checkDynamicTensorAttributes t++data SoftmaxSpec+  = SoftmaxSpec+  | LogSoftmaxSpec++instance+  ( TensorOptions shape dtype device,+    KnownNat dim,+    DimOutOfBoundCheck shape dim,+    KnownDType dtype,+    StandardFloatingPointDTypeValidation device dtype+  ) =>+  Apply' SoftmaxSpec ((Proxy dim, (Proxy device, (Proxy dtype, Proxy shape))), IO ()) (IO ())+  where+  apply' SoftmaxSpec (_, agg) =+    agg >> do+      let t = ones @shape @dtype @device+          t' = softmax @dim t+      checkDynamicTensorAttributes t'+  apply' LogSoftmaxSpec (_, agg) =+    agg >> do+      let t = ones @shape @dtype @device+          t' = logSoftmax @dim t+      checkDynamicTensorAttributes t'++data DotSpec = DotSpec++instance+  ( TensorOptions '[size] dtype device,+    DotDTypeIsValid device dtype,+    KnownDType dtype,+    KnownDevice device+  ) =>+  Apply' DotSpec ((Proxy device, (Proxy dtype, Proxy size)), IO ()) (IO ())+  where+  apply' DotSpec (_, agg) =+    agg >> do+      let a = ones @'[size] @dtype @device+          b = ones @'[size] @dtype @device+          t = dot a b+      checkDynamicTensorAttributes t++data InverseSpec = InverseSpec++instance+  ( TensorOptions shape dtype device,+    TensorOptions shape' dtype device,+    shape' ~ Square shape,+    InverseShapeIsValid device shape,+    InverseDTypeIsValid device dtype,+    RandDTypeIsValid device dtype+  ) =>+  Apply' InverseSpec ((Proxy device, (Proxy dtype, Proxy shape)), IO ()) (IO ())+  where+  apply' InverseSpec (_, agg) =+    agg >> do+      t <- rand @shape @dtype @device+      let t' = inverse t+      checkDynamicTensorAttributes t'++data SymeigSpec = SymeigSpec | SymeigvaluesSpec++instance+  ( TensorOptions shape dtype device,+    TensorOptions shape' dtype device,+    TensorOptions shape'' dtype device,+    shape' ~ VectorOfSquare shape,+    shape'' ~ Square shape,+    SymeigDTypeIsValid device dtype,+    RandDTypeIsValid device dtype+  ) =>+  Apply' SymeigSpec ((Proxy device, (Proxy dtype, Proxy shape)), IO ()) (IO ())+  where+  apply' SymeigSpec (_, agg) =+    agg >> do+      t <- rand @shape @dtype @device+      foldMap+        ( \upper -> do+            let (t', t'') = symeig upper t+            checkDynamicTensorAttributes t'+            checkDynamicTensorAttributes t''+        )+        [Upper, Lower]+  apply' SymeigvaluesSpec (_, agg) =+    agg >> do+      t <- rand @shape @dtype @device+      foldMap+        ( \upper -> do+            let t' = symeigvalues upper t+            checkDynamicTensorAttributes t'+        )+        [Upper, Lower]++data EigSpec = EigSpec++instance+  ( TensorOptions shape dtype device,+    TensorOptions shape' dtype device,+    shape ~ '[n, n],+    shape' ~ ConditionalEigenVectors eigenvectors n,+    KnownNat n,+    KnownEigenVectors eigenvectors,+    KnownDType dtype,+    KnownDevice device,+    EigDTypeIsValid device dtype,+    RandDTypeIsValid device dtype,+    KnownDType (ToComplexNumber dtype),+    TensorOptions shape (ToComplexNumber dtype) device,+    TensorOptions shape' (ToComplexNumber dtype) device+  ) =>+  Apply' EigSpec ((Proxy eigenvectors, (Proxy device, (Proxy dtype, Proxy n))), IO ()) (IO ())+  where+  apply' EigSpec (_, agg) =+    agg >> do+      t <- rand @shape @dtype @device+      let (t', t'') = eig @eigenvectors @n @shape' @dtype @device t+      checkDynamicTensorAttributes t'+      checkDynamicTensorAttributes t''++data SVDSpec = SVDSpec++instance+  ( TensorOptions shape dtype device,+    TensorOptions shapeU dtype device,+    TensorOptions shapeS dtype device,+    TensorOptions shapeV dtype device,+    KnownReducedSVD reduced,+    '(shapeU, shapeS, shapeV) ~ SVDShapes shape reduced,+    RandDTypeIsValid device dtype,+    SVDDTypeIsValid device dtype+  ) =>+  Apply' SVDSpec ((Proxy reduced, (Proxy device, (Proxy dtype, Proxy shape))), IO ()) (IO ())+  where+  apply' SVDSpec (_, agg) =+    agg >> do+      a <- randn @shape @dtype @device+      let (u, s, v) = svd @reduced a+      checkDynamicTensorAttributes u+      checkDynamicTensorAttributes s+      checkDynamicTensorAttributes v++data CholeskySpec = CholeskySpec++instance+  ( TensorOptions shape dtype device,+    TensorOptions shape' dtype device,+    TensorOptions shape'' dtype device,+    shape' ~ Square shape,+    shape'' ~ Square (MatMul shape (Transpose shape (LastDim shape) (LastDim shape - 1))),+    1 <= LastDim shape,+    KnownNat (LastDim shape),+    KnownNat (LastDim shape - 1),+    MatMulDTypeIsValid device dtype,+    CholeskyDTypeIsValid device dtype,+    RandDTypeIsValid device dtype+  ) =>+  Apply' CholeskySpec ((Proxy device, (Proxy dtype, Proxy shape)), IO ()) (IO ())+  where+  apply' CholeskySpec (_, agg) =+    agg >> do+      t <- rand @shape @dtype @device+      let t' = t `matmul` transpose @(Backwards shape 0) @(Backwards shape 1) t+      foldMap+        ( \tri -> do+            let t'' = cholesky tri t'+            checkDynamicTensorAttributes t''+        )+        [Upper, Lower]++data CholeskyInverseSpec = CholeskyInverseSpec++instance+  ( TensorOptions shape dtype device,+    shape ~ '[n, n],+    1 <= n,+    RandDTypeIsValid device dtype,+    MatMulDTypeIsValid device dtype,+    CholeskyDTypeIsValid device dtype+  ) =>+  Apply' CholeskyInverseSpec ((Proxy device, (Proxy dtype, Proxy shape)), IO ()) (IO ())+  where+  apply' CholeskyInverseSpec (_, agg) =+    agg >> do+      t <- rand @shape @dtype @device+      let t' = t `matmul` transpose @0 @1 t+      foldMap+        ( \tri -> do+            let t'' = cholesky tri t'+            let t''' = choleskyInverse tri t''+            checkDynamicTensorAttributes t'''+        )+        [Upper, Lower]++data CholeskySolveSpec = CholeskySolveSpec++instance+  ( TensorOptions m_k dtype device,+    TensorOptions m_m dtype device,+    Square m_m ~ m_m,+    MatMul m_m (Transpose m_m (LastDim m_m) (LastDim m_m - 1)) ~ m_m,+    FstSquareDim m_m ~ FstSquareDim m_k,+    1 <= FstSquareDim m_m,+    1 <= LastDim m_m,+    KnownNat (LastDim m_m),+    KnownNat (LastDim m_m - 1),+    MatMulDTypeIsValid device dtype,+    CholeskyDTypeIsValid device dtype,+    RandDTypeIsValid device dtype+  ) =>+  Apply' CholeskySolveSpec ((Proxy device, (Proxy dtype, (Proxy m_k, Proxy m_m))), IO ()) (IO ())+  where+  apply' CholeskySolveSpec (_, agg) =+    agg >> do+      t <- rand @m_m @dtype @device+      let a = t `matmul` transpose @(Backwards m_m 0) @(Backwards m_m 1) t+      b <- rand @m_k+      foldMap+        ( \tri -> do+            let u = cholesky tri a+            checkDynamicTensorAttributes u+            let c = choleskySolve tri b u+            checkDynamicTensorAttributes c+        )+        [Upper, Lower]++data SolveSpec = SolveSpec++instance+  ( TensorOptions m_k dtype device,+    TensorOptions m_m dtype device,+    Square m_m ~ m_m,+    FstSquareDim m_m ~ FstSquareDim m_k,+    1 <= FstSquareDim m_m,+    SolveDTypeIsValid device dtype,+    RandDTypeIsValid device dtype+  ) =>+  Apply' SolveSpec ((Proxy device, (Proxy dtype, (Proxy m_k, Proxy m_m))), IO ()) (IO ())+  where+  apply' SolveSpec (_, agg) =+    agg >> do+      b <- rand @m_k @dtype @device+      a <- rand @m_m+      let c = solve b a+      checkDynamicTensorAttributes c++data TransposeSpec = TransposeSpec++instance+  ( TensorOptions shape dtype device,+    TensorOptions shape' dtype device,+    shape' ~ Transpose shape n m,+    KnownNat n,+    KnownNat m+  ) =>+  Apply' TransposeSpec (((Proxy n, Proxy m), (Proxy device, (Proxy dtype, Proxy shape))), IO ()) (IO ())+  where+  apply' TransposeSpec (_, agg) =+    agg >> do+      let t = ones @shape @dtype @device+          t' = transpose @n @m t+      checkDynamicTensorAttributes t'++data Transpose2DSpec = Transpose2DSpec++instance+  ( TensorOptions '[i, j] dtype device,+    TensorOptions '[j, i] dtype device+  ) =>+  Apply' Transpose2DSpec ((Proxy device, (Proxy dtype, Proxy '[i, j])), IO ()) (IO ())+  where+  apply' Transpose2DSpec (_, agg) =+    agg >> do+      let t = ones @'[i, j] @dtype @device+          t' = transpose2D t+      checkDynamicTensorAttributes t'++data DiagSpec = DiagSpec++instance+  ( TensorOptions shape dtype device,+    TensorOptions shape' dtype device,+    KnownTri tri,+    KnownNat index,+    StandardDTypeValidation device dtype,+    shape' ~ DiagShape tri index shape+  ) =>+  Apply' DiagSpec (((Proxy tri, Proxy index), (Proxy device, (Proxy dtype, Proxy shape))), IO ()) (IO ())+  where+  apply' DiagSpec (_, agg) =+    agg >> do+      let t = ones @shape @dtype @device+      checkDynamicTensorAttributes $ diag @tri @index t++data DiagEmbedSpec = DiagEmbedSpec++instance+  ( TensorOptions shape dtype device,+    TensorOptions shape' dtype device,+    KnownNat index,+    KnownNat dim1,+    KnownNat dim2,+    DimsDistinctAscending dim1 dim2,+    shape' ~ DiagEmbedShape index dim1 dim2 shape,+    StandardDTypeValidation device dtype+  ) =>+  Apply' DiagEmbedSpec (((Proxy index, (Proxy dim1, Proxy dim2)), (Proxy device, (Proxy dtype, Proxy shape))), IO ()) (IO ())+  where+  apply' DiagEmbedSpec (_, agg) =+    agg >> do+      let t = ones @shape @dtype @device+      foldMap+        (\tri -> checkDynamicTensorAttributes $ diagEmbed @index @dim1 @dim2 tri t)+        [Upper, Lower]++data DiagflatSpec = DiagflatSpec++instance+  ( TensorOptions shape dtype device,+    TensorOptions shape' dtype device,+    KnownNat index,+    shape' ~ DiagflatShape index shape,+    StandardDTypeValidation device dtype+  ) =>+  Apply' DiagflatSpec ((Proxy index, (Proxy device, (Proxy dtype, Proxy shape))), IO ()) (IO ())+  where+  apply' DiagflatSpec (_, agg) =+    agg >> do+      let t = ones @shape @dtype @device+      foldMap+        (\tri -> checkDynamicTensorAttributes $ diagflat @index tri t)+        [Upper, Lower]++data DiagonalSpec = DiagonalSpec++instance+  ( TensorOptions shape dtype device,+    TensorOptions shape' dtype device,+    KnownTri tri,+    KnownNat index,+    KnownNat dim1,+    KnownNat dim2,+    NDimAtLeast 2 shape,+    DimsDistinctAscending dim1 dim2,+    shape' ~ DiagonalShape tri index dim1 dim2 shape,+    StandardDTypeValidation device dtype+  ) =>+  Apply' DiagonalSpec (((Proxy tri, (Proxy index, (Proxy dim1, Proxy dim2))), (Proxy device, (Proxy dtype, Proxy shape))), IO ()) (IO ())+  where+  apply' DiagonalSpec (_, agg) =+    agg >> do+      let t = ones @shape @dtype @device+      checkDynamicTensorAttributes $ diagonal @tri @index @dim1 @dim2 t++data AnyAllSpec = AnySpec | AllSpec++instance+  ( TensorOptions shape 'Bool device,+    KnownDevice device+  ) =>+  Apply' AnyAllSpec ((Proxy device, Proxy shape), IO ()) (IO ())+  where+  apply' AnySpec (_, agg) =+    agg >> do+      let t = ones @shape @'Bool @device+          t' = any t+      checkDynamicTensorAttributes t'+  apply' AllSpec (_, agg) =+    agg >> do+      let t = ones @shape @'Bool @device+          t' = all t+      checkDynamicTensorAttributes t'++data AnyPrimeAllPrimeSpec = AnyPrimeSpec | AllPrimeSpec++instance+  ( TensorOptions shape 'Bool device,+    TensorOptions shape' 'Bool device,+    KnownNat dim,+    KnownKeepOrDropDim keepOrDropDim,+    shape' ~ ConditionalDropDimension shape dim keepOrDropDim+  ) =>+  Apply' AnyPrimeAllPrimeSpec (((Proxy dim, Proxy keepOrDropDim), (Proxy device, Proxy shape)), IO ()) (IO ())+  where+  apply' AnyPrimeSpec (_, agg) =+    agg >> do+      let t = ones @shape @'Bool @device+          t' = anyDim @dim @keepOrDropDim t+      checkDynamicTensorAttributes t'+  apply' AllPrimeSpec (_, agg) =+    agg >> do+      let t = ones @shape @'Bool @device+          t' = allDim @dim @keepOrDropDim t+      checkDynamicTensorAttributes t'++data LstmCellSpec = LstmCellSpec++instance+  ( TensorOptions '[4 * hiddenSize, inputSize] dtype device,+    TensorOptions '[4 * hiddenSize, hiddenSize] dtype device,+    TensorOptions '[4 * hiddenSize] dtype device,+    TensorOptions '[batchSize, hiddenSize] dtype device,+    TensorOptions '[batchSize, inputSize] dtype device,+    KnownNat inputSize,+    KnownNat hiddenSize,+    KnownNat batchSize+  ) =>+  Apply' LstmCellSpec ((Proxy device, (Proxy dtype, (Proxy hiddenSize, Proxy inputSize, Proxy batchSize))), IO ()) (IO ())+  where+  apply' LstmCellSpec (_, agg) =+    agg >> do+      let wi = ones @'[4 * hiddenSize, inputSize] @dtype @device+          wh = ones @'[4 * hiddenSize, hiddenSize] @dtype @device+          bi = ones @'[4 * hiddenSize] @dtype @device+          bh = ones @'[4 * hiddenSize] @dtype @device+          cc = ones @'[batchSize, hiddenSize] @dtype @device+          hc = ones @'[batchSize, hiddenSize] @dtype @device+          input = ones @'[batchSize, inputSize] @dtype @device+          (ncc, nhc) = lstmCell wi wh bi bh (cc, hc) input+      checkDynamicTensorAttributes ncc+      checkDynamicTensorAttributes nhc++data GruCellSpec = GruCellSpec++instance+  ( TensorOptions '[3 * hiddenSize, inputSize] dtype device,+    TensorOptions '[3 * hiddenSize, hiddenSize] dtype device,+    TensorOptions '[3 * hiddenSize] dtype device,+    TensorOptions '[batchSize, hiddenSize] dtype device,+    TensorOptions '[batchSize, inputSize] dtype device,+    KnownNat inputSize,+    KnownNat hiddenSize,+    KnownNat batchSize+  ) =>+  Apply' GruCellSpec ((Proxy device, (Proxy dtype, (Proxy hiddenSize, Proxy inputSize, Proxy batchSize))), IO ()) (IO ())+  where+  apply' GruCellSpec (_, agg) =+    agg >> do+      let wi = ones @'[3 * hiddenSize, inputSize] @dtype @device+          wh = ones @'[3 * hiddenSize, hiddenSize] @dtype @device+          bi = ones @'[3 * hiddenSize] @dtype @device+          bh = ones @'[3 * hiddenSize] @dtype @device+          hx = ones @'[batchSize, hiddenSize] @dtype @device+          input = ones @'[batchSize, inputSize] @dtype @device+          nhx = gruCell wi wh bi bh hx input+      checkDynamicTensorAttributes nhx++spec :: Spec+spec = before_ printSeed $ do+  foldMap spec' availableDevices+  where+    printSeed = do+      putStr "      seed:"+      get_manual_seed >>= print++spec' :: Device -> Spec+spec' device =+  describe ("for " <> show device) $ do+    let standardShapes = Proxy @'[2, 3] :. HNil -- (Proxy :: Proxy ('[] :: [Nat])) :. Proxy @'[0]  :. Proxy @'[0, 1] :. Proxy @'[1, 0] :. Proxy @'[2, 3] :. HNil+        squareShapes = Proxy @'[0, 0] :. Proxy @'[1, 1] :. Proxy @'[2, 2] :. Proxy @'[0, 0, 0] :. Proxy @'[0, 1, 1] :. Proxy @'[1, 0, 0] :. Proxy @'[3, 2, 2] :. HNil+        reductions = Proxy @ReduceNone :. Proxy @ReduceMean :. Proxy @ReduceSum :. HNil++    describe "loss functions" $ do+      let dispatch lossSpec = case device of+            Device {deviceType = CPU, deviceIndex = 0} ->+              hfoldrM @IO lossSpec () (hproduct reductions (hattach cpu (hproduct standardFloatingPointDTypes standardShapes)))+            Device {deviceType = CUDA, deviceIndex = 0} ->+              hfoldrM @IO lossSpec () (hproduct reductions (hattach cuda0 (hproduct allFloatingPointDTypes standardShapes)))+            Device {deviceType = MPS, deviceIndex = 0} ->+              hfoldrM @IO lossSpec () (hproduct reductions (hattach mps (hproduct mpsFloatingPointDTypes standardShapes)))+      it "binaryCrossEntropy" $ dispatch BinaryCrossEntropySpec+      it "mseLoss" $ dispatch MSELossSpec++    describe "softmax" $ do+      let softmaxDims = Proxy @0 :. Proxy @1 :. HNil+          softmaxShapes = Proxy @'[1, 0] :. Proxy @'[2, 3] :. HNil+          dispatch softmaxSpec = case device of+            Device {deviceType = CPU, deviceIndex = 0} ->+              hfoldrM @IO softmaxSpec () (hproduct softmaxDims (hattach cpu (hproduct standardFloatingPointDTypes standardShapes)))+            Device {deviceType = CUDA, deviceIndex = 0} ->+              hfoldrM @IO softmaxSpec () (hproduct softmaxDims (hattach cuda0 (hproduct allFloatingPointDTypes standardShapes)))+            Device {deviceType = MPS, deviceIndex = 0} ->+              hfoldrM @IO softmaxSpec () (hproduct softmaxDims (hattach mps (hproduct mpsFloatingPointDTypes standardShapes)))+      it "softmax" $ dispatch SoftmaxSpec+      it "logSoftmax" $ dispatch LogSoftmaxSpec++    describe "linear algrebra" $ do+      it "dot" $ case device of+        Device {deviceType = CPU, deviceIndex = 0} ->+          hfoldrM @IO DotSpec () (hattach cpu (hproduct standardDTypes (Proxy @0 :. Proxy @1 :. Proxy @2 :. HNil)))+        Device {deviceType = CUDA, deviceIndex = 0} ->+          hfoldrM @IO DotSpec () (hattach cuda0 (hproduct allFloatingPointDTypes (Proxy @0 :. Proxy @1 :. Proxy @2 :. HNil)))+        Device {deviceType = MPS, deviceIndex = 0} ->+          hfoldrM @IO DotSpec () (hattach mps (hproduct mpsFloatingPointDTypes (Proxy @1 :. Proxy @2 :. HNil)))+      it "inverse" $ case device of+        Device {deviceType = CPU, deviceIndex = 0} ->+          hfoldrM @IO InverseSpec () (hattach cpu (hproduct standardFloatingPointDTypes squareShapes))+        Device {deviceType = CUDA, deviceIndex = 0} ->+          hfoldrM @IO InverseSpec () (hattach cuda0 (hproduct standardFloatingPointDTypes (Proxy @'[1, 1] :. Proxy @'[2, 2] :. Proxy @'[1, 1, 1] :. Proxy @'[2, 2, 2] :. HNil)))+        Device {deviceType = MPS, deviceIndex = 0} ->+          hfoldrM @IO InverseSpec () (hattach mps (hproduct mpsFloatingPointDTypes (Proxy @'[1, 1] :. Proxy @'[2, 2] :. Proxy @'[1, 1, 1] :. Proxy @'[2, 2, 2] :. HNil)))+      let dispatchSymeigSpec symeigSpec = case device of+            Device {deviceType = CPU, deviceIndex = 0} ->+              hfoldrM @IO symeigSpec () (hattach cpu (hproduct standardFloatingPointDTypes squareShapes))+            Device {deviceType = CUDA, deviceIndex = 0} ->+              hfoldrM @IO symeigSpec () (hattach cuda0 (hproduct standardFloatingPointDTypes squareShapes))+            Device {deviceType = MPS, deviceIndex = 0} ->+              hfoldrM @IO symeigSpec () (hattach mps (hproduct mpsFloatingPointDTypes squareShapes))+      it "symeig" $ do+        dispatchSymeigSpec SymeigSpec+      it "symeigvalues" $ do+        dispatchSymeigSpec SymeigvaluesSpec+      it "eig" $ do+        let eigenVectors = Proxy @'EnableEigenVectors :. Proxy @'DisableEigenVectors :. HNil+            ns = Proxy @0 :. Proxy @2 :. Proxy @10 :. HNil+        case device of+          Device {deviceType = CPU, deviceIndex = 0} ->+            hfoldrM @IO EigSpec () (hproduct eigenVectors (hattach cpu (hproduct standardFloatingPointDTypes ns)))+          Device {deviceType = CUDA, deviceIndex = 0} ->+            hfoldrM @IO EigSpec () (hproduct eigenVectors (hattach cuda0 (hproduct standardFloatingPointDTypes ns)))+          Device {deviceType = MPS, deviceIndex = 0} ->+            hfoldrM @IO EigSpec () (hproduct eigenVectors (hattach mps (hproduct mpsFloatingPointDTypes ns)))+      it "svd" $ do+        let svdShapes = Proxy @'[1, 1] :. Proxy @'[1, 2] :. Proxy @'[2, 1] :. Proxy @'[1, 1, 1] :. Proxy @'[3, 2, 3] :. Proxy @'[3, 3, 2] :. HNil+            reducedSVD = Proxy @'ThinSVD :. Proxy @'FullSVD :. HNil+        case device of+          Device {deviceType = CPU, deviceIndex = 0} ->+            hfoldrM @IO SVDSpec () (hproduct reducedSVD (hattach cpu (hproduct standardFloatingPointDTypes svdShapes)))+          Device {deviceType = CUDA, deviceIndex = 0} ->+            hfoldrM @IO SVDSpec () (hproduct reducedSVD (hattach cuda0 (hproduct standardFloatingPointDTypes svdShapes)))+          Device {deviceType = MPS, deviceIndex = 0} ->+            hfoldrM @IO SVDSpec () (hproduct reducedSVD (hattach mps (hproduct mpsFloatingPointDTypes svdShapes)))+      it "cholesky" $ case device of+        Device {deviceType = CPU, deviceIndex = 0} ->+          hfoldrM @IO CholeskySpec () (hattach cpu (hproduct standardFloatingPointDTypes squareShapes))+        Device {deviceType = CUDA, deviceIndex = 0} ->+          hfoldrM @IO CholeskySpec () (hattach cuda0 (hproduct standardFloatingPointDTypes squareShapes))+        Device {deviceType = MPS, deviceIndex = 0} ->+          hfoldrM @IO CholeskySpec () (hattach mps (hproduct mpsFloatingPointDTypes squareShapes))+      it "choleskyInverse" $ do+        let choleskyInverseShapes = Proxy @'[1, 1] :. Proxy @'[2, 2] :. HNil+        case device of+          Device {deviceType = CPU, deviceIndex = 0} ->+            hfoldrM @IO CholeskyInverseSpec () (hattach cpu (hproduct standardFloatingPointDTypes choleskyInverseShapes))+          Device {deviceType = CUDA, deviceIndex = 0} ->+            hfoldrM @IO CholeskyInverseSpec () (hattach cuda0 (hproduct standardFloatingPointDTypes choleskyInverseShapes))+          Device {deviceType = MPS, deviceIndex = 0} ->+            hfoldrM @IO CholeskyInverseSpec () (hattach mps (hproduct mpsFloatingPointDTypes choleskyInverseShapes))+      it "choleskySolve" $ do+        let choleskySolveShapes =+              hzip+                (Proxy @'[1, 0] :. Proxy @'[1, 2] :. Proxy @'[2, 1] :. Proxy @'[3, 1, 2] :. HNil)+                (Proxy @'[1, 1] :. Proxy @'[1, 1] :. Proxy @'[2, 2] :. Proxy @'[3, 1, 1] :. HNil)+        case device of+          Device {deviceType = CPU, deviceIndex = 0} ->+            hfoldrM @IO CholeskySolveSpec () (hattach cpu (hproduct standardFloatingPointDTypes choleskySolveShapes))+          Device {deviceType = CUDA, deviceIndex = 0} ->+            hfoldrM @IO CholeskySolveSpec () (hattach cuda0 (hproduct standardFloatingPointDTypes choleskySolveShapes))+          Device {deviceType = MPS, deviceIndex = 0} ->+            hfoldrM @IO CholeskySolveSpec () (hattach mps (hproduct mpsFloatingPointDTypes choleskySolveShapes))+      it "solve" $ do+        let solveShapes =+              hzip+                (Proxy @'[1, 2] :. Proxy @'[2, 1] :. Proxy @'[3, 1, 2] :. HNil)+                (Proxy @'[1, 1] :. Proxy @'[2, 2] :. Proxy @'[3, 1, 1] :. HNil)+        case device of+          Device {deviceType = CPU, deviceIndex = 0} ->+            hfoldrM @IO SolveSpec () (hattach cpu (hproduct standardFloatingPointDTypes solveShapes))+          Device {deviceType = CUDA, deviceIndex = 0} ->+            hfoldrM @IO SolveSpec () (hattach cuda0 (hproduct standardFloatingPointDTypes solveShapes))+          Device {deviceType = MPS, deviceIndex = 0} ->+            hfoldrM @IO SolveSpec () (hattach mps (hproduct mpsFloatingPointDTypes solveShapes))++    describe "boolean algebra" $ do+      do+        let dispatch anyAllSpec = case device of+              Device {deviceType = CPU, deviceIndex = 0} ->+                hfoldrM @IO anyAllSpec () (hattach cpu standardShapes)+              Device {deviceType = CUDA, deviceIndex = 0} ->+                hfoldrM @IO anyAllSpec () (hattach cuda0 standardShapes)+              Device {deviceType = MPS, deviceIndex = 0} ->+                hfoldrM @IO anyAllSpec () (hattach mps standardShapes)+        it "all" $ dispatch AllSpec+        it "any" $ dispatch AnySpec+      do+        let anyPrimeAllPrimeDims = Proxy @0 :. Proxy @1 :. HNil+            keepOrDropDims = Proxy @KeepDim :. Proxy @DropDim :. HNil+            anyPrimeAllPrimeShapes = Proxy @'[0, 0] :. Proxy @'[0, 1] :. Proxy @'[1, 0] :. Proxy @'[2, 3] :. Proxy @'[0, 1, 1] :. Proxy @'[1, 0, 1] :. HNil+            dispatch anyPrimeAllPrimeSpec = case device of+              Device {deviceType = CPU, deviceIndex = 0} ->+                hfoldrM @IO+                  anyPrimeAllPrimeSpec+                  ()+                  ( hproduct+                      (hproduct anyPrimeAllPrimeDims keepOrDropDims)+                      (hattach cpu anyPrimeAllPrimeShapes)+                  )+              Device {deviceType = CUDA, deviceIndex = 0} ->+                hfoldrM @IO+                  anyPrimeAllPrimeSpec+                  ()+                  ( hproduct+                      (hproduct anyPrimeAllPrimeDims keepOrDropDims)+                      (hattach cuda0 anyPrimeAllPrimeShapes)+                  )+              Device {deviceType = MPS, deviceIndex = 0} ->+                hfoldrM @IO+                  anyPrimeAllPrimeSpec+                  ()+                  ( hproduct+                      (hproduct anyPrimeAllPrimeDims keepOrDropDims)+                      (hattach mps anyPrimeAllPrimeShapes)+                  )+        it "allDim" $ dispatch AllPrimeSpec+        it "anyDim" $ dispatch AnyPrimeSpec++    describe "pooling" $+      it "maxPool2d" $ do+        let c = maxPool2d @'(1, 1) @'(1, 1) @'(0, 0) (ones :: CPUTensor 'Float '[1, 3, 4, 5])+        checkDynamicTensorAttributes c++    describe "sorting" $+      it "topk" $ do+        let (c, c') = topk @3 @1 True True (ones :: CPUTensor 'Float '[2, 3])+        checkDynamicTensorAttributes c+        checkDynamicTensorAttributes c'++    describe "upsampling" $ do+      it "upsample_nearest2d" $ do+        let c = upsample_nearest2d @5 @3 (ones :: CPUTensor 'Float '[2, 3, 2, 2])+        checkDynamicTensorAttributes c+      it "upsample_bicubic2d" $ do+        let c = upsample_bicubic2d @5 @3 False (ones :: CPUTensor 'Float '[2, 3, 2, 2])+        checkDynamicTensorAttributes c+      it "upsample_bilinear2d" $ do+        let c = upsample_bilinear2d @5 @3 False (ones :: CPUTensor 'Float '[2, 3, 2, 2])+        checkDynamicTensorAttributes c++    describe "binary native ops" $ return ()++    describe "RNNCells op" $ do+      it "lstmCell op" $ do+        let sizes =+              hzip3+                (Proxy @2 :. Proxy @4 :. Proxy @6 :. Proxy @7 :. HNil)+                (Proxy @7 :. Proxy @6 :. Proxy @5 :. Proxy @4 :. HNil)+                (Proxy @5 :. Proxy @10 :. Proxy @15 :. Proxy @20 :. HNil)+        case device of+          Device {deviceType = CPU, deviceIndex = 0} ->+            hfoldrM @IO LstmCellSpec () (hattach cpu (hproduct standardFloatingPointDTypes sizes))+          Device {deviceType = CUDA, deviceIndex = 0} ->+            hfoldrM @IO LstmCellSpec () (hattach cuda0 (hproduct standardFloatingPointDTypes sizes))+          Device {deviceType = MPS, deviceIndex = 0} ->+            hfoldrM @IO LstmCellSpec () (hattach mps (hproduct mpsFloatingPointDTypes sizes))+      it "gruCell op" $ do+        let sizes =+              hzip3+                (Proxy @2 :. Proxy @4 :. Proxy @6 :. Proxy @7 :. HNil)+                (Proxy @7 :. Proxy @6 :. Proxy @5 :. Proxy @4 :. HNil)+                (Proxy @5 :. Proxy @10 :. Proxy @15 :. Proxy @20 :. HNil)+        case device of+          Device {deviceType = CPU, deviceIndex = 0} ->+            hfoldrM @IO GruCellSpec () (hattach cpu (hproduct standardFloatingPointDTypes sizes))+          Device {deviceType = CUDA, deviceIndex = 0} ->+            hfoldrM @IO GruCellSpec () (hattach cuda0 (hproduct standardFloatingPointDTypes sizes))+          Device {deviceType = MPS, deviceIndex = 0} ->+            hfoldrM @IO GruCellSpec () (hattach mps (hproduct mpsFloatingPointDTypes sizes))
+ test/Torch/Typed/NN/Recurrent/Cell/GRUSpec.hs view
@@ -0,0 +1,33 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeApplications #-}++module Torch.Typed.NN.Recurrent.Cell.GRUSpec+  ( Torch.Typed.NN.Recurrent.Cell.GRUSpec.spec,+  )+where++import Test.Hspec+import qualified Torch.DType as D+import qualified Torch.Device as D+import Torch.HList+import qualified Torch.NN as A+import Torch.Typed.Factories+import Torch.Typed.NN.Recurrent.Cell.GRU+import Torch.Typed.Parameter++spec :: Spec+spec = return ()++testGRUCell ::+  IO+    ( HList+        '[ Parameter '( 'D.CPU, 0) 'D.Float '[21, 5],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21]+         ]+    )+testGRUCell = do+  let spec = GRUCellSpec @5 @7 @'D.Float @'( 'D.CPU, 0)+  model <- A.sample spec+  pure . flattenParameters $ model
+ test/Torch/Typed/NN/Recurrent/Cell/LSTMSpec.hs view
@@ -0,0 +1,33 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeApplications #-}++module Torch.Typed.NN.Recurrent.Cell.LSTMSpec+  ( Torch.Typed.NN.Recurrent.Cell.LSTMSpec.spec,+  )+where++import Test.Hspec+import qualified Torch.DType as D+import qualified Torch.Device as D+import Torch.HList+import qualified Torch.NN as A+import Torch.Typed.Factories+import Torch.Typed.NN.Recurrent.Cell.LSTM+import Torch.Typed.Parameter++spec :: Spec+spec = return ()++testLSTMCell ::+  IO+    ( HList+        '[ Parameter '( 'D.CPU, 0) 'D.Float '[28, 5],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28]+         ]+    )+testLSTMCell = do+  let spec = LSTMCellSpec @5 @7 @'D.Float @'( 'D.CPU, 0)+  model <- A.sample spec+  pure . flattenParameters $ model
+ test/Torch/Typed/NN/Recurrent/GRUSpec.hs view
@@ -0,0 +1,127 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeApplications #-}++module Torch.Typed.NN.Recurrent.GRUSpec+  ( Torch.Typed.NN.Recurrent.GRUSpec.spec,+  )+where++import Test.Hspec+import qualified Torch.DType as D+import qualified Torch.Device as D+import Torch.HList+import qualified Torch.NN as A+import Torch.Typed.Factories+import Torch.Typed.Functional+import Torch.Typed.NN+import Torch.Typed.NN.Recurrent.Auxiliary+import Torch.Typed.NN.Recurrent.GRU+import Torch.Typed.Parameter++spec :: Spec+spec = return ()++testGRU ::+  IO+    ( HList+        '[ Parameter '( 'D.CPU, 0) 'D.Float '[21, 5],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 5],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 14],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 14],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 14],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 14],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21]+         ]+    )+testGRU = do+  let spec = GRUSpec @5 @7 @3 @'Bidirectional @'D.Float @'( 'D.CPU, 0) (DropoutSpec 0.1)+  model <- A.sample spec+  pure . flattenParameters $ model++testGRUWithConstInitSpec ::+  IO+    ( HList+        '[ Parameter '( 'D.CPU, 0) 'D.Float '[21, 5],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 5],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 14],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 14],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 14],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 14],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21]+         ]+    )+testGRUWithConstInitSpec = do+  let spec = GRUSpec @5 @7 @3 @'Bidirectional @'D.Float @'( 'D.CPU, 0) (DropoutSpec 0.1)+      spec' = GRUWithConstInitSpec spec Torch.Typed.Factories.zeros+  model <- A.sample spec'+  pure . flattenParameters $ model++testGRUWithLearnedInitSpec ::+  IO+    ( HList+        '[ Parameter '( 'D.CPU, 0) 'D.Float '[21, 5],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 5],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 14],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 14],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 14],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 14],+           Parameter '( 'D.CPU, 0) 'D.Float '[21, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[21],+           Parameter '( 'D.CPU, 0) 'D.Float '[6, 7]+         ]+    )+testGRUWithLearnedInitSpec = do+  let spec = GRUSpec @5 @7 @3 @'Bidirectional @'D.Float @'( 'D.CPU, 0) (DropoutSpec 0.1)+      spec' = GRUWithLearnedInitSpec spec Torch.Typed.Factories.zeros+  model <- A.sample spec'+  pure . flattenParameters $ model
+ test/Torch/Typed/NN/Recurrent/LSTMSpec.hs view
@@ -0,0 +1,128 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeApplications #-}++module Torch.Typed.NN.Recurrent.LSTMSpec+  ( Torch.Typed.NN.Recurrent.LSTMSpec.spec,+  )+where++import Test.Hspec+import qualified Torch.DType as D+import qualified Torch.Device as D+import Torch.HList+import qualified Torch.NN as A+import Torch.Typed.Factories+import Torch.Typed.Functional+import Torch.Typed.NN+import Torch.Typed.NN.Recurrent.Auxiliary+import Torch.Typed.NN.Recurrent.LSTM+import Torch.Typed.Parameter++spec :: Spec+spec = return ()++testLSTM ::+  IO+    ( HList+        '[ Parameter '( 'D.CPU, 0) 'D.Float '[28, 5],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 5],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 14],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 14],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 14],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 14],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28]+         ]+    )+testLSTM = do+  let spec = LSTMSpec @5 @7 @3 @'Bidirectional @'D.Float @'( 'D.CPU, 0) (DropoutSpec 0.1)+  model <- A.sample spec+  pure . flattenParameters $ model++testLSTMWithConstInitSpec ::+  IO+    ( HList+        '[ Parameter '( 'D.CPU, 0) 'D.Float '[28, 5],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 5],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 14],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 14],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 14],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 14],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28]+         ]+    )+testLSTMWithConstInitSpec = do+  let spec = LSTMSpec @5 @7 @3 @'Bidirectional @'D.Float @'( 'D.CPU, 0) (DropoutSpec 0.1)+      spec' = LSTMWithConstInitSpec spec Torch.Typed.Factories.zeros Torch.Typed.Factories.zeros+  model <- A.sample spec'+  pure . flattenParameters $ model++testLSTMWithLearnedInitSpec ::+  IO+    ( HList+        '[ Parameter '( 'D.CPU, 0) 'D.Float '[28, 5],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 5],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 14],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 14],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 14],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 14],+           Parameter '( 'D.CPU, 0) 'D.Float '[28, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[28],+           Parameter '( 'D.CPU, 0) 'D.Float '[6, 7],+           Parameter '( 'D.CPU, 0) 'D.Float '[6, 7]+         ]+    )+testLSTMWithLearnedInitSpec = do+  let spec = LSTMSpec @5 @7 @3 @'Bidirectional @'D.Float @'( 'D.CPU, 0) (DropoutSpec 0.1)+      spec' = LSTMWithLearnedInitSpec spec Torch.Typed.Factories.zeros Torch.Typed.Factories.zeros+  model <- A.sample spec'+  pure . flattenParameters $ model
+ test/Torch/Typed/NN/TransformerSpec.hs view
@@ -0,0 +1,80 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeApplications #-}++module Torch.Typed.NN.TransformerSpec+  ( Torch.Typed.NN.TransformerSpec.spec,+  )+where++import Test.Hspec+import qualified Torch.DType as D+import qualified Torch.Device as D+import Torch.HList+import qualified Torch.NN as A+import Torch.Typed.Factories+import Torch.Typed.Functional+import Torch.Typed.NN+import Torch.Typed.NN.Transformer+import Torch.Typed.Parameter++spec :: Spec+spec = return ()++testTransformerLM ::+  IO+    ( HList+        '[ Parameter '( 'D.CPU, 0) 'D.Float '[16, 32],+           Parameter '( 'D.CPU, 0) 'D.Float '[32, 32],+           Parameter '( 'D.CPU, 0) 'D.Float '[32],+           Parameter '( 'D.CPU, 0) 'D.Float '[32, 32],+           Parameter '( 'D.CPU, 0) 'D.Float '[32],+           Parameter '( 'D.CPU, 0) 'D.Float '[32, 32],+           Parameter '( 'D.CPU, 0) 'D.Float '[32],+           Parameter '( 'D.CPU, 0) 'D.Float '[32, 32],+           Parameter '( 'D.CPU, 0) 'D.Float '[32],+           Parameter '( 'D.CPU, 0) 'D.Float '[32],+           Parameter '( 'D.CPU, 0) 'D.Float '[32],+           Parameter '( 'D.CPU, 0) 'D.Float '[10, 32],+           Parameter '( 'D.CPU, 0) 'D.Float '[10],+           Parameter '( 'D.CPU, 0) 'D.Float '[32, 10],+           Parameter '( 'D.CPU, 0) 'D.Float '[32],+           Parameter '( 'D.CPU, 0) 'D.Float '[32],+           Parameter '( 'D.CPU, 0) 'D.Float '[32],+           Parameter '( 'D.CPU, 0) 'D.Float '[32, 32],+           Parameter '( 'D.CPU, 0) 'D.Float '[32],+           Parameter '( 'D.CPU, 0) 'D.Float '[32, 32],+           Parameter '( 'D.CPU, 0) 'D.Float '[32],+           Parameter '( 'D.CPU, 0) 'D.Float '[32, 32],+           Parameter '( 'D.CPU, 0) 'D.Float '[32],+           Parameter '( 'D.CPU, 0) 'D.Float '[32, 32],+           Parameter '( 'D.CPU, 0) 'D.Float '[32],+           Parameter '( 'D.CPU, 0) 'D.Float '[32],+           Parameter '( 'D.CPU, 0) 'D.Float '[32],+           Parameter '( 'D.CPU, 0) 'D.Float '[10, 32],+           Parameter '( 'D.CPU, 0) 'D.Float '[10],+           Parameter '( 'D.CPU, 0) 'D.Float '[32, 10],+           Parameter '( 'D.CPU, 0) 'D.Float '[32],+           Parameter '( 'D.CPU, 0) 'D.Float '[32],+           Parameter '( 'D.CPU, 0) 'D.Float '[32],+           Parameter '( 'D.CPU, 0) 'D.Float '[16, 32],+           Parameter '( 'D.CPU, 0) 'D.Float '[16]+         ]+    )+testTransformerLM = do+  let spec =+        TransformerLMSpec @2 @3 @10 @0 @16 @32 @'D.Float @'( 'D.CPU, 0)+          (DropoutSpec 0.2)+          ( TransformerLayerSpec+              ( MultiheadAttentionSpec+                  (DropoutSpec 0.2)+              )+              (DropoutSpec 0.2)+              0.001+              ( TransformerMLPSpec+                  (DropoutSpec 0.2)+                  (DropoutSpec 0.2)+                  0.001+              )+          )+  model <- A.sample spec+  pure . flattenParameters $ model
+ test/Torch/Typed/NNSpec.hs view
@@ -0,0 +1,97 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeApplications #-}++module Torch.Typed.NNSpec+  ( Torch.Typed.NNSpec.spec,+  )+where++import Test.Hspec+import Torch.Typed++spec :: Spec+spec = return ()++testLinear ::+  IO+    ( HList+        '[ Parameter '( 'CPU, 0) 'Float '[5, 10],+           Parameter '( 'CPU, 0) 'Float '[5]+         ]+    )+testLinear = do+  let spec = LinearSpec @10 @5 @'Float @'( 'CPU, 0)+  model <- sample spec+  pure . flattenParameters $ model++testDropout :: IO (HList '[])+testDropout = do+  let spec = DropoutSpec 0.1+  model <- sample spec+  pure . flattenParameters $ model++testConstEmbedding :: IO (HList '[])+testConstEmbedding = do+  let spec = ConstEmbeddingSpec @'Nothing @10 @8 @'Float @'( 'CPU, 0) zeros+  model <- sample spec+  pure . flattenParameters $ model++testLearnedEmbeddingWithRandomInit :: IO (HList '[Parameter '( 'CPU, 0) 'Float '[10, 8]])+testLearnedEmbeddingWithRandomInit = do+  let spec = LearnedEmbeddingWithRandomInitSpec @'Nothing @10 @8 @'Float @'( 'CPU, 0)+  model <- sample spec+  pure . flattenParameters $ model++testLearnedEmbeddingWithCustomInit :: IO (HList '[Parameter '( 'CPU, 0) 'Float '[10, 8]])+testLearnedEmbeddingWithCustomInit = do+  let spec = LearnedEmbeddingWithCustomInitSpec @'Nothing @10 @8 @'Float @'( 'CPU, 0) zeros+  model <- sample spec+  pure . flattenParameters $ model++testConv1d ::+  IO+    ( HList+        '[ Parameter '( 'CPU, 0) 'Float '[5, 10, 3],+           Parameter '( 'CPU, 0) 'Float '[5]+         ]+    )+testConv1d = do+  let spec = Conv1dSpec @10 @5 @3 @'Float @'( 'CPU, 0)+  model <- sample spec+  pure . flattenParameters $ model++testConv2d ::+  IO+    ( HList+        '[ Parameter '( 'CPU, 0) 'Float '[5, 10, 3, 2],+           Parameter '( 'CPU, 0) 'Float '[5]+         ]+    )+testConv2d = do+  let spec = Conv2dSpec @10 @5 @3 @2 @'Float @'( 'CPU, 0)+  model <- sample spec+  pure . flattenParameters $ model++testConv3d ::+  IO+    ( HList+        '[ Parameter '( 'CPU, 0) 'Float '[5, 10, 3, 2, 1],+           Parameter '( 'CPU, 0) 'Float '[5]+         ]+    )+testConv3d = do+  let spec = Conv3dSpec @10 @5 @3 @2 @1 @'Float @'( 'CPU, 0)+  model <- sample spec+  pure . flattenParameters $ model++testLayerNorm ::+  IO+    ( HList+        '[ Parameter '( 'CPU, 0) 'Float '[5],+           Parameter '( 'CPU, 0) 'Float '[5]+         ]+    )+testLayerNorm = do+  let spec = LayerNormSpec @'[5] @'Float @'( 'CPU, 0) 0.1+  model <- sample spec+  pure . flattenParameters $ model
+ test/Torch/Typed/NamedTensorSpec.hs view
@@ -0,0 +1,184 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedLists #-}+{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE UndecidableSuperClasses #-}+{-# LANGUAGE NoStarIsType #-}++module Torch.Typed.NamedTensorSpec (spec) where++import Data.Default.Class+import Data.Kind+import Data.Maybe (fromJust)+import Data.Proxy+import Data.Vector.Sized (Vector)+import qualified Data.Vector.Sized as V+import GHC.Exts+import GHC.Generics+import GHC.TypeLits+import Lens.Family+import Test.Hspec+import qualified Torch.DType as D+import qualified Torch.Device as D+import qualified Torch.Functional as F+import Torch.Lens+import qualified Torch.Tensor as D+import Torch.Typed.Factories+import Torch.Typed.Functional+import Torch.Typed.Lens+import Torch.Typed.NamedTensor+import Torch.Typed.Tensor++newtype Batch (n :: Nat) a = Batch (Vector n a) deriving (Show, Eq, Generic)++newtype Height (n :: Nat) a = Height (Vector n a) deriving (Show, Eq, Generic)++newtype Width (n :: Nat) a = Width (Vector n a) deriving (Show, Eq, Generic)++data RGB a = RGB+  { r :: a,+    g :: a,+    b :: a+  }+  deriving (Show, Eq, Generic, Default)++data YCoCg a = YCoCg+  { y :: a,+    co :: a,+    cg :: a+  }+  deriving (Show, Eq, Generic, Default)++data RGBA a = RGBA a a a a deriving (Show, Eq, Generic, Default)++testFieldLens :: HasField "r" shape => Lens' (NamedTensor '(D.CPU, 0) 'D.Float shape) (NamedTensor '(D.CPU, 0) 'D.Float (DropField "r" shape))+testFieldLens = field @"r"++testFieldLens2 :: Lens' (NamedTensor '(D.CPU, 0) 'D.Float '[Vector n, RGB]) (NamedTensor '(D.CPU, 0) 'D.Float '[Vector n])+testFieldLens2 = field @"r"++testNamedLens :: Traversal' (NamedTensor '(D.CPU, 0) 'D.Float '[Vector n, RGB]) (NamedTensor '(D.CPU, 0) 'D.Float '[Vector n])+testNamedLens = name @RGB++testNamedLens2 :: Traversal' (NamedTensor '(D.CPU, 0) 'D.Float '[Vector 3, RGB, Vector 4]) (NamedTensor '(D.CPU, 0) 'D.Float '[Vector 3, Vector 4])+testNamedLens2 = name @RGB++testDropField :: Proxy (DropField "r" '[Vector 2, RGB]) -> Proxy '[Vector 2]+testDropField = id++testDropField2 :: Proxy (DropField "y" '[Vector 2, YCoCg]) -> Proxy '[Vector 2]+testDropField2 = id++testCountField :: Proxy (ToNat YCoCg) -> Proxy 3+testCountField = id++testCountField2 :: Proxy (ToNat (Vector n)) -> Proxy n+testCountField2 = id++testCountField3 :: Proxy (ToNat RGBA) -> Proxy 4+testCountField3 = id++testCountField4 :: Proxy (ToNat (Batch n)) -> Proxy n+testCountField4 = id++toYCoCG :: (KnownNat n, KnownDType dtype, KnownDevice device) => NamedTensor device dtype [Vector n, RGB] -> NamedTensor device dtype [Vector n, YCoCg]+toYCoCG rgb =+  set (field @"y") ((r + g * 2 + b) / 4) $+    set (field @"co") ((r - b) / 2) $+      set (field @"cg") ((- r + g * 2 - b) / 4) $+        def+  where+    r = rgb ^. field @"r"+    g = rgb ^. field @"g"+    b = rgb ^. field @"b"++checkDynamicTensorAttributes' ::+  forall device dtype shape t.+  ( IsUnnamed t device dtype shape,+    TensorOptions shape dtype device+  ) =>+  t ->+  IO ()+checkDynamicTensorAttributes' t = do+  D.device untyped `shouldBe` optionsRuntimeDevice @shape @dtype @device+  D.dtype untyped `shouldBe` optionsRuntimeDType @shape @dtype @device+  D.shape untyped `shouldBe` optionsRuntimeShape @shape @dtype @device+  where+    untyped = toDynamic t++spec :: Spec+spec = do+  describe "NamedTensor" $ do+    it "create by Typed Tensor" $ do+      let t :: Tensor '(D.CPU, 0) 'D.Float '[2, 3]+          t = ones+          t2 :: NamedTensor '(D.CPU, 0) 'D.Float '[Vector 2, RGB]+          t2 = fromUnnamed t+          t3 :: NamedTensor '(D.CPU, 0) 'D.Float '[Batch 2, RGB]+          t3 = fromUnnamed t+      print t2+      checkDynamicTensorAttributes' t2+      checkDynamicTensorAttributes' t3+    it "create by default class" $ do+      let t :: NamedTensor '(D.CPU, 0) 'D.Float '[Batch 2, Height 3, Width 4, RGB]+          t = def+      checkDynamicTensorAttributes' t+    it "create by NamedTensorLike" $ do+      let t :: NamedTensor '(D.CPU, 0) 'D.Float '[Batch 1, Height 1, Width 1, RGB]+          t = asNamedTensor $ Batch (V.singleton (Height (V.singleton (Width (V.singleton (RGB {r = 0 :: Float, g = 1, b = 2}))))))+      checkDynamicTensorAttributes' t+    it "check a shape of lens" $ do+      let t :: NamedTensor '(D.CPU, 0) 'D.Float '[Vector 2, Vector 3, Vector 4, RGB]+          t = def+          t2 :: NamedTensor '(D.CPU, 0) 'D.Float '[Vector 2, Vector 3, Vector 4]+          t2 = t ^. field @"r"+      print $ shape t2+      checkDynamicTensorAttributes' t+      checkDynamicTensorAttributes' t2+    it "get fieldids" $ do+      let v = RGB () () ()+      fieldId @"r" (Proxy :: Proxy (RGB ())) `shouldBe` Just 0+      fieldId @"g" (Proxy :: Proxy (RGB ())) `shouldBe` Just 1+      fieldId @"b" (Proxy :: Proxy (RGB ())) `shouldBe` Just 2+      fieldId @"y" (Proxy :: Proxy (RGB ())) `shouldBe` Nothing+    it "sort" $ do+      let t :: NamedTensor '(D.CPU, 0) 'D.Float '[Vector 2, Vector 3, Vector 4, RGB]+          t = def+          (v, idx) = sortNamedDim @RGB True t+      checkDynamicTensorAttributes' v+      checkDynamicTensorAttributes' idx+    it "mean" $ do+      let t :: NamedTensor '(D.CPU, 0) 'D.Float '[Vector 2, Vector 3, Vector 4, RGB]+          t = def+          v0 = meanNamedDim @RGB t :: NamedTensor '(D.CPU, 0) 'D.Float '[Vector 2, Vector 3, Vector 4]+          v1 = meanNamedDim @(Vector 3) t :: NamedTensor '(D.CPU, 0) 'D.Float '[Vector 2, Vector 4, RGB]+      checkDynamicTensorAttributes' v0+      checkDynamicTensorAttributes' v1+    it "shape and dtype" $ do+      let t :: NamedTensor '(D.CPU, 0) 'D.Float '[Vector 2, Vector 3, Vector 4, RGB]+          t = def+      shape t `shouldBe` [2, 3, 4, 3]+      dtype t `shouldBe` D.Float+    it "named index" $ do+      let t :: NamedTensor '(D.CPU, 0) 'D.Float '[Vector 2, Vector 3, Vector 4, RGB]+          t = def+          t2 = flattenValues (name @(Vector 3)) t+      map shape t2 `shouldBe` [[2, 4, 3], [2, 4, 3], [2, 4, 3]]+      map dtype t2 `shouldBe` [D.Float, D.Float, D.Float]
+ test/Torch/Typed/OptimSpec.hs view
@@ -0,0 +1,463 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}++module Torch.Typed.OptimSpec+  ( Torch.Typed.OptimSpec.spec,+  )+where++import Control.Monad (foldM)+import Data.Kind+import Data.Maybe+import Data.Proxy+import GHC.Exts (toList)+import GHC.Generics+import GHC.TypeLits+import Test.Hspec (Spec, describe, it, shouldBe)+import Test.QuickCheck ()+import Torch (ATenTensor)+import Torch.Internal.Class (Castable)+import Torch.Internal.Managed.Type.Context (manual_seed_L)+import Torch.Typed+import Torch.Typed.AuxiliarySpec+import Prelude hiding+  ( cos,+    exp,+    sqrt,+  )++data+  ConvQuadSpec+    (features :: Nat)+    (dtype :: DType)+    (device :: (DeviceType, Nat))+  = ConvQuadSpec+  deriving (Show, Eq)++data+  ConvQuad+    (features :: Nat)+    (dtype :: DType)+    (device :: (DeviceType, Nat))+  where+  ConvQuad ::+    forall features dtype device.+    {w :: Parameter device dtype '[features]} ->+    ConvQuad features dtype device+  deriving (Show, Generic, Parameterized)++instance+  ( RandDTypeIsValid device dtype,+    KnownNat features,+    KnownDType dtype,+    KnownDevice device+  ) =>+  Randomizable+    (ConvQuadSpec features dtype device)+    (ConvQuad features dtype device)+  where+  sample _ = ConvQuad <$> (makeIndependent =<< randn)++convQuad ::+  forall features dtype device.+  (KnownDevice device, DotDTypeIsValid device dtype) =>+  ConvQuad features dtype device ->+  Tensor device dtype '[features, features] ->+  Tensor device dtype '[features] ->+  Tensor device dtype '[]+convQuad ConvQuad {..} a b =+  let w' = toDependent w in mulScalar (0.5 :: Float) (dot w' (mv a w')) - dot b w'++data+  RosenbrockSpec+    (dtype :: DType)+    (device :: (DeviceType, Nat))+  = RosenbrockSpec+  deriving (Show, Eq)++data+  Rosenbrock+    (dtype :: DType)+    (device :: (DeviceType, Nat))+  where+  Rosenbrock ::+    forall dtype device.+    { x :: Parameter device dtype '[1],+      y :: Parameter device dtype '[1]+    } ->+    Rosenbrock dtype device+  deriving (Show, Generic, Parameterized)++instance+  ( RandDTypeIsValid device dtype,+    KnownDType dtype,+    KnownDevice device+  ) =>+  Randomizable+    (RosenbrockSpec dtype device)+    (Rosenbrock dtype device)+  where+  sample _ = Rosenbrock <$> (makeIndependent =<< randn) <*> (makeIndependent =<< randn)++rosenbrock ::+  forall a dtype device.+  (KnownDevice device, Scalar a) =>+  Rosenbrock dtype device ->+  a ->+  a ->+  Tensor device dtype '[]+rosenbrock Rosenbrock {..} a b =+  let x' = toDependent x+      y' = toDependent y+      square c = powScalar (2 :: Int) c+   in reshape $ square (subScalar a x') + mulScalar b (square (y' - square x'))++data+  AckleySpec+    (features :: Nat)+    (dtype :: DType)+    (device :: (DeviceType, Nat))+  = AckleySpec+  deriving (Show, Eq)++data+  Ackley+    (features :: Nat)+    (dtype :: DType)+    (device :: (DeviceType, Nat))+  where+  Ackley ::+    forall features dtype device.+    {pos :: Parameter device dtype '[features]} ->+    Ackley features dtype device+  deriving (Show, Generic, Parameterized)++instance+  ( RandDTypeIsValid device dtype,+    KnownNat features,+    KnownDType dtype,+    KnownDevice device+  ) =>+  Randomizable+    (AckleySpec features dtype device)+    (Ackley features dtype device)+  where+  sample _ =+    Ackley <$> (makeIndependent =<< randn)++ackley ::+  forall features a dtype device.+  ( KnownNat features,+    Scalar a,+    Num a,+    dtype ~ SumDType dtype,+    KnownDType dtype,+    StandardFloatingPointDTypeValidation device dtype,+    SumDTypeIsValid device dtype,+    KnownDevice device+  ) =>+  Ackley features dtype device ->+  a ->+  a ->+  a ->+  Tensor device dtype '[]+ackley Ackley {..} a b c =+  mulScalar (- a) (exp . mulScalar (- b) . sqrt . divScalar d . sumAll $ pos' * pos')+    + addScalar a (exp ones)+    - exp (divScalar d . sumAll . cos . mulScalar c $ pos')+  where+    d = product . shape $ pos'+    pos' = toDependent pos++foldLoop ::+  forall a b m. (Num a, Enum a, Monad m) => b -> a -> (b -> a -> m b) -> m b+foldLoop x count block = foldM block x ([1 .. count] :: [a])++optimize ::+  forall model optim parameters tensors gradients dtype device.+  ( -- gradients ~ GradR parameters+    HasGrad (HList parameters) (HList gradients),+    tensors ~ gradients,+    HMap' ToDependent parameters tensors,+    Castable (HList gradients) [ATenTensor],+    parameters ~ Parameters model,+    Parameterized model,+    Optimizer optim gradients tensors dtype device,+    HMapM' IO MakeIndependent tensors parameters,+    Show model+  ) =>+  model ->+  optim ->+  (model -> Loss device dtype) ->+  LearningRate device dtype ->+  Int ->+  IO (model, optim)+optimize initModel initOptim loss learningRate numIters =+  foldLoop (initModel, initOptim) numIters $+    \(model, optim) _ -> runStep model optim (loss model) learningRate++-- optimize initModel initOptim loss learningRate numIters = do+--   print $ "initial model: " <> show initModel+--   print $ "initial loss:" <> show (loss initModel)+--   (finalModel, finalOptim) <- foldLoop (initModel, initOptim) numIters+--     $ \(model, optim) _ -> runStep model optim (loss model) learningRate+--   print $ "final model: " <> show finalModel+--   print $ "final loss:" <> show (loss finalModel)+--   pure (finalModel, finalOptim)++data OptimConvQuadSpec = GDConvQuadSpec | GDMConvQuadSpec | AdamConvQuadSpec++instance+  ( KnownNat features,+    KnownDType dtype,+    KnownDevice device,+    DotDTypeIsValid device dtype,+    BasicArithmeticDTypeIsValid device dtype,+    StandardFloatingPointDTypeValidation device dtype+  ) =>+  Apply' OptimConvQuadSpec ((Proxy device, (Proxy dtype, Proxy features)), IO ()) (IO ())+  where+  apply' GDConvQuadSpec (_, agg) =+    agg >> do+      manual_seed_L 123+      initModel <- sample (ConvQuadSpec @features @'Float @'( 'CPU, 0))+      let initModel' = toDevice @device @'( 'CPU, 0) . toDType @dtype @'Float $ initModel+          initOptim = mkGD+          a = eyeSquare @features @dtype @device+          b = zeros @'[features] @dtype @device+          loss model = convQuad model a b+          learningRate = 0.1+          numIter = 1000+      (model, _optim) <- optimize initModel' initOptim loss learningRate numIter+      isNonZero (isclose 1e-03 1e-04 False (loss model) zeros) `shouldBe` True+  apply' GDMConvQuadSpec (_, agg) =+    agg >> do+      manual_seed_L 123+      initModel <- sample (ConvQuadSpec @features @'Float @'( 'CPU, 0))+      let initModel' = toDevice @device @'( 'CPU, 0) . toDType @dtype @'Float $ initModel+          initOptim = mkGDM 0.9 (flattenParameters initModel')+          a = eyeSquare @features @dtype @device+          b = zeros @'[features] @dtype @device+          loss model = convQuad model a b+          learningRate = 0.1+          numIter = 1000+      (model, _optim) <- optimize initModel' initOptim loss learningRate numIter+      isNonZero (isclose 1e-03 1e-04 False (loss model) zeros) `shouldBe` True+  apply' AdamConvQuadSpec (_, agg) =+    agg >> do+      manual_seed_L 123+      initModel <- sample (ConvQuadSpec @features @'Float @'( 'CPU, 0))+      let initModel' = toDevice @device @'( 'CPU, 0) . toDType @dtype @'Float $ initModel+          initOptim = mkAdam 0 0.9 0.999 (flattenParameters initModel')+          a = eyeSquare @features @dtype @device+          b = zeros @'[features] @dtype @device+          loss model = convQuad model a b+          learningRate = 0.1+          numIter = 1000+      (model, _optim) <- optimize initModel' initOptim loss learningRate numIter+      isNonZero (isclose 1e-03 1e-04 False (loss model) zeros) `shouldBe` True++data OptimRosenbrockSpec = GDRosenbrockSpec | GDMRosenbrockSpec | AdamRosenbrockSpec++instance+  ( KnownDType dtype,+    KnownDevice device,+    BasicArithmeticDTypeIsValid device dtype,+    StandardFloatingPointDTypeValidation device dtype+  ) =>+  Apply' OptimRosenbrockSpec ((Proxy device, Proxy dtype), IO ()) (IO ())+  where+  apply' GDRosenbrockSpec (_, agg) =+    agg >> do+      manual_seed_L 123+      initModel <- sample (RosenbrockSpec @'Float @'( 'CPU, 0))+      let initModel' = toDevice @device @'( 'CPU, 0) . toDType @dtype @'Float $ initModel+          initOptim = mkGD+          a :: Float = 1.0+          b :: Float = 100.0+          loss model = rosenbrock model a b+          learningRate = 0.002+          numIter = 15000+      (model, _optim) <- optimize initModel' initOptim loss learningRate numIter+      let close = isclose 1e-01 1e-01 False (cat @0 . hmap' ToDependent . flattenParameters $ model) ones+      (toList . Just) close `shouldBe` [True, True]+      isNonZero (isclose 1e-04 1e-04 False (loss model) zeros) `shouldBe` True+  apply' GDMRosenbrockSpec (_, agg) =+    agg >> do+      manual_seed_L 123+      initModel <- sample (RosenbrockSpec @'Float @'( 'CPU, 0))+      let initModel' = toDevice @device @'( 'CPU, 0) . toDType @dtype @'Float $ initModel+          initOptim = mkGDM 0.9 (flattenParameters initModel')+          a :: Float = 1.0+          b :: Float = 100.0+          loss model = rosenbrock model a b+          learningRate = 0.001+          numIter = 10000+      (model, _optim) <- optimize initModel' initOptim loss learningRate numIter+      let close = (isclose 1e-01 1e-01 False (cat @0 . hmap' ToDependent . flattenParameters $ model) ones)+      (toList . Just) close `shouldBe` [True, True]+      isNonZero (isclose 1e-04 1e-04 False (loss model) zeros) `shouldBe` True+  apply' AdamRosenbrockSpec (_, agg) =+    agg >> do+      manual_seed_L 123+      initModel <- sample (RosenbrockSpec @'Float @'( 'CPU, 0))+      let initModel' = toDevice @device @'( 'CPU, 0) . toDType @dtype @'Float $ initModel+          initOptim = mkAdam 0 0.9 0.999 (flattenParameters initModel')+          a :: Float = 1.0+          b :: Float = 100.0+          loss model = rosenbrock model a b+          learningRate = 0.005+          numIter = 5000+      (model, _optim) <- optimize initModel' initOptim loss learningRate numIter+      let close = (isclose 1e-02 1e-02 False (cat @0 . hmap' ToDependent . flattenParameters $ model) ones)+      (toList . Just) close `shouldBe` [True, True]+      isNonZero (isclose 1e-04 1e-04 False (loss model) zeros) `shouldBe` True++data OptimAckleySpec = GDAckleySpec | GDMAckleySpec | AdamAckleySpec++instance+  ( KnownDType dtype,+    KnownDevice device,+    BasicArithmeticDTypeIsValid device dtype,+    StandardFloatingPointDTypeValidation device dtype,+    SumDTypeIsValid device dtype,+    dtype ~ SumDType dtype+  ) =>+  Apply' OptimAckleySpec ((Proxy device, Proxy dtype), IO ()) (IO ())+  where+  apply' GDAckleySpec (_, agg) =+    agg >> do+      manual_seed_L 123+      initModel <- sample (AckleySpec @2 @'Float @'( 'CPU, 0))+      let initModel' = toDevice @device @'( 'CPU, 0) . toDType @dtype @'Float $ initModel+          initOptim = mkGD+          a :: Float = 20.0+          b :: Float = 0.2+          c :: Float = 2 * pi+          loss model = ackley model a b c+          learningRate = 0.00001+          numIter = 5000+      (model, _optim) <- optimize initModel' initOptim loss learningRate numIter+      let finalLoss = loss model+      let close = isclose 1e-03 1e-03 False (cat @0 . hmap' ToDependent . flattenParameters $ model) zeros+      (toList . Just) close `shouldBe` [True, True]+      isNonZero (isclose 1e-04 1e-04 False (loss model) zeros) `shouldBe` True+  apply' GDMAckleySpec (_, agg) =+    agg >> do+      manual_seed_L 123+      initModel <- sample (AckleySpec @2 @'Float @'( 'CPU, 0))+      let initModel' = toDevice @device @'( 'CPU, 0) . toDType @dtype @'Float $ initModel+          initOptim = mkGDM 0.9 (flattenParameters initModel')+          a :: Float = 20.0+          b :: Float = 0.2+          c :: Float = 2 * pi+          loss model = ackley model a b c+          learningRate = 0.000005+          numIter = 5000+      (model, _optim) <- optimize initModel' initOptim loss learningRate numIter+      let finalLoss = loss model+      let close = isclose 1e-03 1e-03 False (cat @0 . hmap' ToDependent . flattenParameters $ model) zeros+      (toList . Just) close `shouldBe` [True, True]+      isNonZero (isclose 1e-04 1e-04 False (loss model) zeros) `shouldBe` True+  apply' AdamAckleySpec (_, agg) =+    agg >> do+      manual_seed_L 123+      initModel <- sample (AckleySpec @2 @'Float @'( 'CPU, 0))+      let initModel' = toDevice @device @'( 'CPU, 0) . toDType @dtype @'Float $ initModel+          initOptim = mkAdam 0 0.9 0.999 (flattenParameters initModel')+          a :: Float = 20.0+          b :: Float = 0.2+          c :: Float = 2 * pi+          loss model = ackley model a b c+          learningRate = 0.0001+          numIter = 2000+      (model, _optim) <- optimize initModel' initOptim loss learningRate numIter+      let finalLoss = loss model+      let close = isclose 1e-03 1e-03 False (cat @0 . hmap' ToDependent . flattenParameters $ model) zeros+      (toList . Just) close `shouldBe` [True, True]+      isNonZero (isclose 1e-04 1e-04 False (loss model) zeros) `shouldBe` True++spec = foldMap spec' availableDevices++spec' :: Device -> Spec+spec' device = describe ("for " <> show device) $ do+  describe "GD" $ do+    it "convex quadratic" $ case device of+      Device {deviceType = CPU, deviceIndex = 0} ->+        hfoldrM @IO GDConvQuadSpec () (hattach cpu (hproduct standardFloatingPointDTypes (Proxy @0 :. Proxy @1 :. Proxy @2 :. HNil)))+      Device {deviceType = CUDA, deviceIndex = 0} ->+        hfoldrM @IO GDConvQuadSpec () (hattach cuda0 (hproduct allFloatingPointDTypes (Proxy @0 :. Proxy @1 :. Proxy @2 :. HNil)))+      Device {deviceType = MPS, deviceIndex = 0} ->+        hfoldrM @IO GDConvQuadSpec () (hattach mps (hproduct mpsFloatingPointDTypes (Proxy @1 :. Proxy @2 :. HNil)))+    it "Rosenbrock" $ case device of+      Device {deviceType = CPU, deviceIndex = 0} ->+        hfoldrM @IO GDRosenbrockSpec () (hattach cpu standardFloatingPointDTypes)+      Device {deviceType = CUDA, deviceIndex = 0} ->+        hfoldrM @IO GDRosenbrockSpec () (hattach cuda0 standardFloatingPointDTypes)+      Device {deviceType = MPS, deviceIndex = 0} ->+        return ()+      -- ToDo: This test does not pass. --+      -- Device {deviceType = MPS, deviceIndex = 0} ->+      --   hfoldrM @IO GDRosenbrockSpec () (hattach mps mpsFloatingPointDTypes)+    it "Ackley" $ case device of+      Device {deviceType = CPU, deviceIndex = 0} ->+        hfoldrM @IO GDAckleySpec () (hattach cpu standardFloatingPointDTypes)+      Device {deviceType = CUDA, deviceIndex = 0} ->+        hfoldrM @IO GDAckleySpec () (hattach cuda0 standardFloatingPointDTypes)+      Device {deviceType = MPS, deviceIndex = 0} ->+        hfoldrM @IO GDAckleySpec () (hattach mps mpsFloatingPointDTypes)+  describe "GDM" $ do+    it "convex quadratic" $ case device of+      Device {deviceType = CPU, deviceIndex = 0} ->+        hfoldrM @IO GDMConvQuadSpec () (hattach cpu (hproduct standardFloatingPointDTypes (Proxy @0 :. Proxy @1 :. Proxy @2 :. HNil)))+      Device {deviceType = CUDA, deviceIndex = 0} ->+        hfoldrM @IO GDMConvQuadSpec () (hattach cuda0 (hproduct allFloatingPointDTypes (Proxy @0 :. Proxy @1 :. Proxy @2 :. HNil)))+      Device {deviceType = MPS, deviceIndex = 0} ->+        hfoldrM @IO GDMConvQuadSpec () (hattach mps (hproduct mpsFloatingPointDTypes (Proxy @1 :. Proxy @2 :. HNil)))+    it "Rosenbrock" $ case device of+      Device {deviceType = CPU, deviceIndex = 0} ->+        hfoldrM @IO GDMRosenbrockSpec () (hattach cpu standardFloatingPointDTypes)+      Device {deviceType = CUDA, deviceIndex = 0} ->+        hfoldrM @IO GDMRosenbrockSpec () (hattach cuda0 standardFloatingPointDTypes)+      Device {deviceType = MPS, deviceIndex = 0} ->+        hfoldrM @IO GDMRosenbrockSpec () (hattach mps mpsFloatingPointDTypes)+    it "Ackley" $ case device of+      Device {deviceType = CPU, deviceIndex = 0} ->+        hfoldrM @IO GDMAckleySpec () (hattach cpu standardFloatingPointDTypes)+      Device {deviceType = CUDA, deviceIndex = 0} ->+        hfoldrM @IO GDMAckleySpec () (hattach cuda0 standardFloatingPointDTypes)+      Device {deviceType = MPS, deviceIndex = 0} ->+        hfoldrM @IO GDMAckleySpec () (hattach mps mpsFloatingPointDTypes)+  describe "Adam" $ do+    it "convex quadratic" $ case device of+      Device {deviceType = CPU, deviceIndex = 0} ->+        hfoldrM @IO AdamConvQuadSpec () (hattach cpu (hproduct standardFloatingPointDTypes (Proxy @0 :. Proxy @1 :. Proxy @2 :. HNil)))+      Device {deviceType = CUDA, deviceIndex = 0} ->+        hfoldrM @IO AdamConvQuadSpec () (hattach cuda0 (hproduct allFloatingPointDTypes (Proxy @0 :. Proxy @1 :. Proxy @2 :. HNil)))+      Device {deviceType = MPS, deviceIndex = 0} ->+        hfoldrM @IO AdamConvQuadSpec () (hattach mps (hproduct mpsFloatingPointDTypes (Proxy @1 :. Proxy @2 :. HNil)))+    it "Rosenbrock" $ case device of+      Device {deviceType = CPU, deviceIndex = 0} ->+        hfoldrM @IO AdamRosenbrockSpec () (hattach cpu standardFloatingPointDTypes)+      Device {deviceType = CUDA, deviceIndex = 0} ->+        hfoldrM @IO AdamRosenbrockSpec () (hattach cuda0 standardFloatingPointDTypes)+      Device {deviceType = MPS, deviceIndex = 0} ->+        hfoldrM @IO AdamRosenbrockSpec () (hattach mps mpsFloatingPointDTypes)+    it "Ackley" $ case device of+      Device {deviceType = CPU, deviceIndex = 0} ->+        hfoldrM @IO AdamAckleySpec () (hattach cpu standardFloatingPointDTypes)+      Device {deviceType = CUDA, deviceIndex = 0} ->+        hfoldrM @IO AdamAckleySpec () (hattach cuda0 standardFloatingPointDTypes)+      Device {deviceType = MPS, deviceIndex = 0} ->+        hfoldrM @IO AdamAckleySpec () (hattach mps mpsFloatingPointDTypes)
+ test/Torch/Typed/SerializeSpec.hs view
@@ -0,0 +1,93 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}++module Torch.Typed.SerializeSpec+  ( Torch.Typed.SerializeSpec.spec,+  )+where++import Control.Monad (foldM)+import Data.Kind+import Data.Maybe+import Data.Proxy+import GHC.Exts (toList)+import GHC.Generics+import GHC.TypeLits+import Test.Hspec (Spec, describe, it, shouldBe)+import Test.QuickCheck ()+import Torch (ATenTensor)+import Torch.Internal.Class (Castable)+import Torch.Internal.Managed.Type.Context (manual_seed_L)+import Torch.Typed++import qualified Torch.DType as D+import qualified Torch.Device as D+++data+  MLPSpec+    (inputFeatures :: Nat)+    (outputFeatures :: Nat)+    (hiddenFeatures :: Nat)+    (dtype :: DType)+    (device :: (DeviceType, Nat))+  where+  MLPSpec ::+    forall inputFeatures outputFeatures hiddenFeatures dtype device.+    MLPSpec inputFeatures outputFeatures hiddenFeatures dtype device+  deriving (Show, Eq)++data+  MLP+    (inputFeatures :: Nat)+    (outputFeatures :: Nat)+    (hiddenFeatures :: Nat)+    (dtype :: D.DType)+    (device :: (D.DeviceType, Nat)) = MLP+  { layer0 :: Linear inputFeatures hiddenFeatures dtype device,+    layer1 :: Linear hiddenFeatures hiddenFeatures dtype device,+    layer2 :: Linear hiddenFeatures outputFeatures dtype device+  }+  deriving (Show, Generic, Parameterized)++instance+  ( KnownNat inputFeatures,+    KnownNat outputFeatures,+    KnownNat hiddenFeatures,+    KnownDType dtype,+    KnownDevice device,+    RandDTypeIsValid device dtype+  ) =>+  Randomizable+    (MLPSpec inputFeatures outputFeatures hiddenFeatures dtype device)+    (MLP inputFeatures outputFeatures hiddenFeatures dtype device)+  where+  sample _ =+    MLP+      <$> sample LinearSpec+      <*> sample LinearSpec+      <*> sample LinearSpec++saveMLP :: MLP 10 3 4 'D.Float '(D.CPU, 0) -> FilePath -> IO ()+saveMLP model filePath = saveParameters model filePath ++loadMLP :: MLP 10 3 4 'D.Float '(D.CPU, 0) -> FilePath -> IO (MLP 10 3 4 'D.Float '(D.CPU, 0))+loadMLP model filePath = loadParameters model filePath ++loadMLPWithSpec :: MLPSpec 10 3 4 'D.Float '(D.CPU, 0) -> FilePath -> IO (MLP 10 3 4 'D.Float '(D.CPU, 0))+loadMLPWithSpec spec filePath = loadParametersWithSpec spec filePath ++spec :: Spec+spec = pure ()+
+ test/Torch/Typed/TensorSpec0.hs view
@@ -0,0 +1,205 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}+{-# OPTIONS_GHC -freduction-depth=0 #-}++module Torch.Typed.TensorSpec0+  ( Torch.Typed.TensorSpec0.spec,+  )+where++import Data.Kind+import Data.Proxy+import GHC.TypeLits+import Test.Hspec (Spec, describe, it, shouldBe)+import Test.QuickCheck ()+import qualified Torch as Torch+import Torch.Internal.Class (Castable (cast), uncast)+import Torch.Typed+import Torch.Typed.AuxiliarySpec++data BinarySpec = AddSpec | SubSpec | MulSpec++instance+  ( TensorOptions shape dtype device,+    TensorOptions shape' dtype' device,+    TensorOptions shape'' dtype'' device,+    shape'' ~ Broadcast shape shape',+    dtype'' ~ DTypePromotion dtype dtype',+    BasicArithmeticDTypeIsValid device dtype,+    BasicArithmeticDTypeIsValid device dtype',+    BasicArithmeticDTypeIsValid device dtype''+  ) =>+  Apply' BinarySpec ((Proxy device, ((Proxy dtype, Proxy dtype'), (Proxy shape, Proxy shape'))), IO ()) (IO ())+  where+  apply' AddSpec (_, agg) =+    agg >> do+      let a = ones @shape @dtype @device+      let b = ones @shape' @dtype' @device+      let c = add a b+      checkDynamicTensorAttributes c+  apply' SubSpec (_, agg) =+    agg >> do+      let a = ones @shape @dtype @device+      let b = ones @shape' @dtype' @device+      let c = sub a b+      checkDynamicTensorAttributes c+  apply' MulSpec (_, agg) =+    agg >> do+      let a = ones @shape @dtype @device+      let b = ones @shape' @dtype' @device+      let c = mul a b+      checkDynamicTensorAttributes c++data MatMulSpec = MatMulSpec++instance+  ( TensorOptions shape dtype device,+    TensorOptions shape' dtype device,+    TensorOptions shape'' dtype device,+    shape'' ~ MatMul shape shape',+    MatMulDTypeIsValid device dtype+  ) =>+  Apply' MatMulSpec ((Proxy device, (Proxy dtype, (Proxy shape, Proxy shape'))), IO ()) (IO ())+  where+  apply' MatMulSpec (_, agg) =+    agg >> do+      let a = ones @shape @dtype @device+      let b = ones @shape' @dtype @device+      let c = matmul a b+      checkDynamicTensorAttributes c++spec = foldMap spec' availableDevices++spec' :: Device -> Spec+spec' device =+  describe ("for " <> show device) $ do+    let standardShapes = Proxy @'[2, 3] :. HNil -- (Proxy :: Proxy ('[] :: [Nat])) :. Proxy @'[0]  :. Proxy @'[0, 1] :. Proxy @'[1, 0] :. Proxy @'[2, 3] :. HNil+        broadcastableShapes0 = Proxy @'[3, 1, 4, 1] :. HNil+        broadcastableShapes1 = Proxy @'[2, 1, 1] :. HNil+        standardDTypes2 = hproduct standardDTypes standardDTypes+        almostAllDTypes2 = hproduct (withHalf standardDTypes) (withHalf standardDTypes)+        mpsDTypes2 = hproduct mpsDTypes mpsDTypes+        identicalShapes = hzip standardShapes standardShapes+        broadcastableShapes = hzip broadcastableShapes0 broadcastableShapes1++    describe "basic arithmetic" $ do+      let dispatch binarySpec = do+            it "works on tensors of identical shapes" $+              case device of+                Device {deviceType = CPU, deviceIndex = 0} ->+                  hfoldrM @IO binarySpec () (hattach cpu (hproduct standardDTypes2 identicalShapes))+                Device {deviceType = CUDA, deviceIndex = 0} ->+                  hfoldrM @IO binarySpec () (hattach cuda0 (hproduct almostAllDTypes2 identicalShapes))+                Device {deviceType = MPS, deviceIndex = 0} ->+                  hfoldrM @IO binarySpec () (hattach mps (hproduct mpsDTypes2 identicalShapes))+            it "works on broadcastable tensors of different shapes" $+              case device of+                Device {deviceType = CPU, deviceIndex = 0} ->+                  hfoldrM @IO binarySpec () (hattach cpu (hproduct standardDTypes2 broadcastableShapes))+                Device {deviceType = CUDA, deviceIndex = 0} ->+                  hfoldrM @IO binarySpec () (hattach cuda0 (hproduct almostAllDTypes2 broadcastableShapes))+                Device {deviceType = MPS, deviceIndex = 0} ->+                  hfoldrM @IO binarySpec () (hattach mps (hproduct mpsDTypes2 broadcastableShapes))+      describe "addition" $ dispatch AddSpec+      describe "subtraction" $ dispatch SubSpec+      describe "multiplication" $ dispatch MulSpec++    describe "matrix multiplication" $ do+      it "returns the dot product if both tensors are 1-dimensional" $ do+        let shapes = hzip (Proxy @'[3] :. HNil) (Proxy @'[3] :. HNil)+        case device of+          Device {deviceType = CPU, deviceIndex = 0} ->+            hfoldrM @IO MatMulSpec () (hattach cpu (hproduct standardDTypes shapes))+          Device {deviceType = CUDA, deviceIndex = 0} ->+            hfoldrM @IO MatMulSpec () (hattach cuda0 (hproduct allFloatingPointDTypes shapes))+          Device {deviceType = MPS, deviceIndex = 0} ->+            hfoldrM @IO MatMulSpec () (hattach mps (hproduct mpsFloatingPointDTypes shapes))+      it "returns the matrix-matrix product if both arguments are 2-dimensional" $ do+        let shapes = hzip (Proxy @'[3, 2] :. HNil) (Proxy @'[2, 4] :. HNil)+        case device of+          Device {deviceType = CPU, deviceIndex = 0} ->+            hfoldrM @IO MatMulSpec () (hattach cpu (hproduct standardDTypes shapes))+          Device {deviceType = CUDA, deviceIndex = 0} ->+            hfoldrM @IO MatMulSpec () (hattach cuda0 (hproduct allFloatingPointDTypes shapes))+          Device {deviceType = MPS, deviceIndex = 0} ->+            hfoldrM @IO MatMulSpec () (hattach mps (hproduct mpsFloatingPointDTypes shapes))+      it "returns the matrix-matrix product if the first argument is 1-dimensional and the second argument is 2-dimensional by temporarily adding a 1 to the dimension of the first argument" $ do+        let shapes = hzip (Proxy @'[3] :. HNil) (Proxy @'[3, 4] :. HNil)+        case device of+          Device {deviceType = CPU, deviceIndex = 0} ->+            hfoldrM @IO MatMulSpec () (hattach cpu (hproduct standardDTypes shapes))+          Device {deviceType = CUDA, deviceIndex = 0} ->+            hfoldrM @IO MatMulSpec () (hattach cuda0 (hproduct allFloatingPointDTypes shapes))+          Device {deviceType = MPS, deviceIndex = 0} ->+            hfoldrM @IO MatMulSpec () (hattach mps (hproduct mpsFloatingPointDTypes shapes))+      it "returns the matrix-vector product if the first argument is 2-dimensional and the second argument is 1-dimensional" $ do+        let shapes = hzip (Proxy @'[3, 4] :. HNil) (Proxy @'[4] :. HNil)+        case device of+          Device {deviceType = CPU, deviceIndex = 0} ->+            hfoldrM @IO MatMulSpec () (hattach cpu (hproduct standardDTypes shapes))+          Device {deviceType = CUDA, deviceIndex = 0} ->+            hfoldrM @IO MatMulSpec () (hattach cuda0 (hproduct allFloatingPointDTypes shapes))+          Device {deviceType = MPS, deviceIndex = 0} ->+            hfoldrM @IO MatMulSpec () (hattach mps (hproduct mpsFloatingPointDTypes shapes))+      it "returns a batched matrix-matrix product if both arguments are at least 2-dimensional and the batch (i.e. non-matrix) dimensions are broadcastable" $ do+        let shapes = hzip (Proxy @'[2, 1, 4, 3] :. HNil) (Proxy @'[3, 3, 2] :. HNil)+        case device of+          Device {deviceType = CPU, deviceIndex = 0} ->+            hfoldrM @IO MatMulSpec () (hattach cpu (hproduct standardDTypes shapes))+          Device {deviceType = CUDA, deviceIndex = 0} ->+            hfoldrM @IO MatMulSpec () (hattach cuda0 (hproduct allFloatingPointDTypes shapes))+          Device {deviceType = MPS, deviceIndex = 0} ->+            hfoldrM @IO MatMulSpec () (hattach mps (hproduct mpsFloatingPointDTypes shapes))+      it "returns a batched matrix-matrix product if the first argument is 1-dimensional and the second argument has more than 2 dimensions" $ do+        let shapes = hzip (Proxy @'[3] :. HNil) (Proxy @'[2, 3, 4] :. HNil)+        case device of+          Device {deviceType = CPU, deviceIndex = 0} ->+            hfoldrM @IO MatMulSpec () (hattach cpu (hproduct standardDTypes shapes))+          Device {deviceType = CUDA, deviceIndex = 0} ->+            hfoldrM @IO MatMulSpec () (hattach cuda0 (hproduct allFloatingPointDTypes shapes))+          Device {deviceType = MPS, deviceIndex = 0} ->+            hfoldrM @IO MatMulSpec () (hattach mps (hproduct mpsFloatingPointDTypes shapes))+      it "returns a batched matrix-vector product if the first argument has more than 2 dimensions and the second argument is 1-dimensional" $ do+        let shapes = hzip (Proxy @'[2, 3, 4] :. HNil) (Proxy @'[4] :. HNil)+        case device of+          Device {deviceType = CPU, deviceIndex = 0} ->+            hfoldrM @IO MatMulSpec () (hattach cpu (hproduct standardDTypes shapes))+          Device {deviceType = CUDA, deviceIndex = 0} ->+            hfoldrM @IO MatMulSpec () (hattach cuda0 (hproduct allFloatingPointDTypes shapes))+          Device {deviceType = MPS, deviceIndex = 0} ->+            hfoldrM @IO MatMulSpec () (hattach mps (hproduct mpsFloatingPointDTypes shapes))++testTensorListFold ::+  forall device dtype shape. Tensor device dtype shape -> IO [Torch.ATenTensor]+testTensorListFold t = hfoldrM TensorListFold ([] :: [Torch.ATenTensor]) (t :. HNil)++testTensorListUnfold ::+  forall device dtype shape device' dtype' shape'.+  [Torch.ATenTensor] ->+  IO (HList '[Tensor device dtype shape, Tensor device' dtype' shape'])+testTensorListUnfold = hunfoldrM TensorListUnfold++testCast ::+  forall device dtype shape.+  HList '[Tensor device dtype shape] ->+  IO [Torch.ATenTensor]+testCast xs = cast xs return++testUncast ::+  forall device dtype shape.+  [Torch.ATenTensor] ->+  IO (HList '[Tensor device dtype shape])+testUncast xs = uncast xs return++testReplicate ::+  forall device dtype shape.+  Tensor device dtype shape ->+  HList (HReplicateR 3 (Tensor device dtype shape))+testReplicate = hreplicate @3
+ test/Torch/Typed/TensorSpec1.hs view
@@ -0,0 +1,246 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# OPTIONS_GHC -freduction-depth=0 #-}++module Torch.Typed.TensorSpec1+  ( Torch.Typed.TensorSpec1.spec,+  )+where++import Data.Kind+import Data.Proxy+import GHC.TypeLits+import Test.Hspec (Spec, describe, it, shouldBe)+import Test.QuickCheck ()+import qualified Torch as Torch+import Torch.Internal.Class (Castable (cast), uncast)+import Torch.Typed+import Torch.Typed.AuxiliarySpec++data BinaryCmpSpec = GTSpec | LTSpec | GESpec | LESpec | EQSpec | NESpec++instance+  ( TensorOptions shape dtype device,+    TensorOptions shape' dtype' device,+    TensorOptions shape'' 'Bool device,+    shape'' ~ Broadcast shape shape',+    ComparisonDTypeIsValid device dtype,+    ComparisonDTypeIsValid device dtype'+  ) =>+  Apply' BinaryCmpSpec ((Proxy device, ((Proxy dtype, Proxy dtype'), (Proxy shape, Proxy shape'))), IO ()) (IO ())+  where+  apply' GTSpec (_, agg) =+    agg >> do+      let a = ones @shape @dtype @device+      let b = ones @shape' @dtype' @device+      let c = gt a b+      checkDynamicTensorAttributes c+  apply' LTSpec (_, agg) =+    agg >> do+      let a = ones @shape @dtype @device+      let b = ones @shape' @dtype' @device+      let c = lt a b+      checkDynamicTensorAttributes c+  apply' GESpec (_, agg) =+    agg >> do+      let a = ones @shape @dtype @device+      let b = ones @shape' @dtype' @device+      let c = ge a b+      checkDynamicTensorAttributes c+  apply' LESpec (_, agg) =+    agg >> do+      let a = ones @shape @dtype @device+      let b = ones @shape' @dtype' @device+      let c = le a b+      checkDynamicTensorAttributes c+  apply' EQSpec (_, agg) =+    agg >> do+      let a = ones @shape @dtype @device+      let b = ones @shape' @dtype' @device+      let c = eq a b+      checkDynamicTensorAttributes c+  apply' NESpec (_, agg) =+    agg >> do+      let a = ones @shape @dtype @device+      let b = ones @shape' @dtype' @device+      let c = ne a b+      checkDynamicTensorAttributes c++data ReshapeSpec = ReshapeSpec++instance+  ( TensorOptions fromShape dtype device,+    TensorOptions toShape dtype device,+    KnownShape fromShape,+    KnownShape toShape,+    Numel fromShape ~ Numel toShape+  ) =>+  Apply' ReshapeSpec ((Proxy device, (Proxy dtype, (Proxy fromShape, Proxy toShape))), IO ()) (IO ())+  where+  apply' ReshapeSpec (_, agg) =+    agg >> do+      let t = ones @fromShape @dtype @device+      let t' = reshape @toShape t+      checkDynamicTensorAttributes t'+      let t'' = reshape @fromShape t'+      checkDynamicTensorAttributes t''++data ToTypeSpec = ToTypeSpec++instance+  ( TensorOptions shape dtype device,+    TensorOptions shape dtype' device,+    KnownDType dtype'+  ) =>+  Apply' ToTypeSpec ((Proxy device, ((Proxy dtype, Proxy dtype'), Proxy shape)), IO ()) (IO ())+  where+  apply' ToTypeSpec (_, agg) =+    agg >> do+      let t = ones @shape @dtype @device+          t' = toDType @dtype' @dtype t+      checkDynamicTensorAttributes t'++data ToDeviceSpec = ToDeviceSpec++instance+  ( TensorOptions shape dtype device,+    KnownDevice device+  ) =>+  Apply' ToDeviceSpec ((Proxy device, (Proxy dtype, Proxy shape)), IO ()) (IO ())+  where+  apply' ToDeviceSpec (_, agg) =+    agg+      >> foldMap+        ( \device' -> case someDevice device' of+            (SomeDevice (Proxy :: Proxy device')) -> do+              let t = ones @shape @dtype @device+              checkDynamicTensorAttributes t+              let t' = toDevice @device' @device t+              Torch.device (toDynamic t') `shouldBe` deviceVal @device'+              let t'' = toDevice @device @device' t'+              Torch.device (toDynamic t'') `shouldBe` deviceVal @device+        )+        availableDevices++spec = foldMap spec' availableDevices++spec' :: Device -> Spec+spec' device =+  describe ("for " <> show device) $ do+    let standardShapes = Proxy @'[2, 3] :. HNil -- (Proxy :: Proxy ('[] :: [Nat])) :. Proxy @'[0]  :. Proxy @'[0, 1] :. Proxy @'[1, 0] :. Proxy @'[2, 3] :. HNil+        broadcastableShapes0 = Proxy @'[3, 1, 4, 1] :. HNil+        broadcastableShapes1 = Proxy @'[2, 1, 1] :. HNil+        standardDTypes2 = hproduct standardDTypes standardDTypes+        almostAllDTypes2 = hproduct (withHalf standardDTypes) (withHalf standardDTypes)+        mpsDTypes2 = hproduct mpsDTypes mpsDTypes+        identicalShapes = hzip standardShapes standardShapes+        broadcastableShapes = hzip broadcastableShapes0 broadcastableShapes1++    describe "binary comparison" $ do+      let dispatch binaryCmpSpec = do+            it "works on tensors of identical shapes" $+              case device of+                Device {deviceType = CPU, deviceIndex = 0} ->+                  hfoldrM @IO binaryCmpSpec () (hattach cpu (hproduct standardDTypes2 identicalShapes))+                Device {deviceType = CUDA, deviceIndex = 0} ->+                  hfoldrM @IO binaryCmpSpec () (hattach cuda0 (hproduct almostAllDTypes2 identicalShapes))+                Device {deviceType = MPS, deviceIndex = 0} ->+                  hfoldrM @IO binaryCmpSpec () (hattach mps (hproduct mpsDTypes2 identicalShapes))+            it "works on broadcastable tensors of different shapes" $+              case device of+                Device {deviceType = CPU, deviceIndex = 0} ->+                  hfoldrM @IO binaryCmpSpec () (hattach cpu (hproduct standardDTypes2 broadcastableShapes))+                Device {deviceType = CUDA, deviceIndex = 0} ->+                  hfoldrM @IO binaryCmpSpec () (hattach cuda0 (hproduct almostAllDTypes2 broadcastableShapes))+                Device {deviceType = MPS, deviceIndex = 0} ->+                  hfoldrM @IO binaryCmpSpec () (hattach mps (hproduct mpsDTypes2 broadcastableShapes))+      describe "greater than" $ dispatch GTSpec+      describe "lower than" $ dispatch LTSpec+      describe "greater or equal than" $ dispatch GESpec+      describe "lower or equal than" $ dispatch LESpec+      describe "equal to" $ dispatch EQSpec+      describe "not equal to" $ dispatch NESpec++    describe "tensor conversion" $ do+      it "reshape" $ do+        let fromShapes = Proxy @'[0] :. Proxy @'[0, 0] :. Proxy @'[0, 1] :. Proxy @'[1, 0] :. (Proxy :: Proxy ('[] :: [Nat])) :. Proxy @'[1] :. Proxy @'[1, 1] :. Proxy @'[1, 1, 1] :. Proxy @'[1, 2] :. Proxy @'[2, 1] :. Proxy @'[1, 4, 2] :. Proxy @'[1, 1, 8] :. Proxy @'[8] :. Proxy @'[2, 2, 2] :. HNil+            toShapes = Proxy @'[1, 0] :. Proxy @'[0, 1] :. Proxy @'[0] :. Proxy @'[0, 0] :. Proxy @'[1, 1] :. Proxy @'[1, 1, 1] :. Proxy @'[1] :. (Proxy :: Proxy ('[] :: [Nat])) :. Proxy @'[1, 2, 1] :. Proxy @'[2] :. Proxy @'[8] :. Proxy @'[1, 1, 8] :. Proxy @'[2, 2, 2] :. Proxy @'[1, 1, 8] :. HNil+            shapes = hzip fromShapes toShapes+        case device of+          Device {deviceType = CPU, deviceIndex = 0} ->+            hfoldrM @IO ReshapeSpec () (hattach cpu (hproduct allDTypes shapes))+          Device {deviceType = CUDA, deviceIndex = 0} ->+            hfoldrM @IO ReshapeSpec () (hattach cuda0 (hproduct allDTypes shapes))+          Device {deviceType = MPS, deviceIndex = 0} ->+            hfoldrM @IO ReshapeSpec () (hattach mps (hproduct mpsDTypes shapes))++      it "toDevice" $ case device of+        Device {deviceType = CPU, deviceIndex = 0} ->+#ifdef __APPLE__+          hfoldrM @IO ToDeviceSpec () (hattach cpu (hproduct mpsDTypes standardShapes))+#else+          hfoldrM @IO ToDeviceSpec () (hattach cpu (hproduct allDTypes standardShapes))+#endif+        Device {deviceType = CUDA, deviceIndex = 0} ->+          hfoldrM @IO ToDeviceSpec () (hattach cuda0 (hproduct allDTypes standardShapes))+        Device {deviceType = MPS, deviceIndex = 0} ->+          hfoldrM @IO ToDeviceSpec () (hattach mps (hproduct mpsDTypes standardShapes))+      it "toType" $ case device of+        Device {deviceType = CPU, deviceIndex = 0} ->+          hfoldrM @IO ToTypeSpec () (hattach cpu (hproduct (hproduct allDTypes allDTypes) standardShapes))+        Device {deviceType = CUDA, deviceIndex = 0} ->+          hfoldrM @IO ToTypeSpec () (hattach cuda0 (hproduct (hproduct allDTypes allDTypes) standardShapes))+        Device {deviceType = MPS, deviceIndex = 0} ->+          hfoldrM @IO ToTypeSpec () (hattach mps (hproduct (hproduct mpsDTypes mpsDTypes) standardShapes))++    describe "untyped to typed tensor" $ do+      it "withTensor" $ do+        withTensor (Torch.zeros' [2, 3, 4]) $ \t -> print t+      it "withTensorShape with matmul" $ do+        --    ToDo: withTensor does not work with matmul.+        --        withTensor (Torch.zeros' [3,4]) $ \(t0 :: Tensor device0 dtype0 shape0)->+        --          withTensor (Torch.zeros' [4,3]) $ \(t1 :: Tensor device1 dtype1 shape1)-> do+        --            print (matmul t0 t1)+        withTensorShape @'(CPU, 0) @'Float (Torch.zeros' [3, 4]) $ \t0 -> do+          withTensorShape @'(CPU, 0) @'Float (Torch.zeros' [4, 3]) $ \t1 -> do+            print (matmul t0 t1)+      it "withNat" $ do+        withNat 2 $ \(_ :: Proxy n) -> print $ (zeros :: Tensor '(CPU, 0) 'Float [n, 2, 3])++testTensorListFold ::+  forall device dtype shape. Tensor device dtype shape -> IO [Torch.ATenTensor]+testTensorListFold t = hfoldrM TensorListFold ([] :: [Torch.ATenTensor]) (t :. HNil)++testTensorListUnfold ::+  forall device dtype shape device' dtype' shape'.+  [Torch.ATenTensor] ->+  IO (HList '[Tensor device dtype shape, Tensor device' dtype' shape'])+testTensorListUnfold = hunfoldrM TensorListUnfold++testCast ::+  forall device dtype shape.+  HList '[Tensor device dtype shape] ->+  IO [Torch.ATenTensor]+testCast xs = cast xs return++testUncast ::+  forall device dtype shape.+  [Torch.ATenTensor] ->+  IO (HList '[Tensor device dtype shape])+testUncast xs = uncast xs return++testReplicate ::+  forall device dtype shape.+  Tensor device dtype shape ->+  HList (HReplicateR 3 (Tensor device dtype shape))+testReplicate = hreplicate @3
+ test/Torch/Typed/VisionSpec.hs view
@@ -0,0 +1,26 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeApplications #-}++module Torch.Typed.VisionSpec+  ( Torch.Typed.VisionSpec.spec,+  )+where++import Test.Hspec (Spec, describe, it, shouldBe)+import Torch (asValue)+import Torch.Typed+import Prelude hiding (length)++checkAsTensor :: IO ()+checkAsTensor = do+  imagesBS <- decompressFile "test/data" "mnist-sample-images-idx3-ubyte.gz"+  labelsBS <- decompressFile "test/data" "mnist-sample-labels-idx1-ubyte.gz"+  let mnist = MnistData imagesBS labelsBS+  length mnist `shouldBe` 16+  (asValue (toDynamic (getImages @16 mnist [0 ..])) :: [[Float]])+    `shouldBe` asValue (toDynamic (getImages' @16 mnist [0 ..]))++spec :: Spec+spec =+  describe "Load images" $+    it "Comparison of using asTensor and memcpy" checkAsTensor
+ test/VisionSpec.hs view
@@ -0,0 +1,74 @@+{-# LANGUAGE NoMonomorphismRestriction #-}++module VisionSpec (spec) where++import Codec.Picture+import Codec.Picture.Types (freezeImage, newMutableImage)+import Control.Exception.Safe+import Control.Monad.ST+import Data.Int+import Data.Word+import Test.Hspec+import Torch.DType+import Torch.Layout+import Torch.Tensor+import Torch.TensorFactories+import Torch.TensorOptions+import Torch.Vision++newImage :: Pixel a => Int -> Int -> [((Int, Int), a)] -> Image a+newImage width height ipixels = runST $ do+  mim <- newMutableImage height width+  mapM_ (\((x, y), rgb) -> writePixel mim x y rgb) ipixels+  freezeImage mim++spec :: Spec+spec = do+  describe "fromImage" $ do+    it "RGBA16" $ do+      let img = fromDynImage $ ImageRGBA16 $ newImage 1 3 (map (\i -> ((i, 0), PixelRGBA16 (fromIntegral i) 0 0 3)) [0 .. 2])+      (asValue img :: [[[[Int32]]]]) `shouldBe` [[[[0, 0, 0, 3], [1, 0, 0, 3], [2, 0, 0, 3]]]]+    it "RGB16" $ do+      let img = fromDynImage $ ImageRGB16 $ newImage 1 3 (map (\i -> ((i, 0), PixelRGB16 (fromIntegral i) 0 4)) [0 .. 2])+      (asValue img :: [[[[Int32]]]]) `shouldBe` [[[[0, 0, 4], [1, 0, 4], [2, 0, 4]]]]+    it "Y32" $ do+      let img = fromDynImage $ ImageY32 $ newImage 1 3 (map (\i -> ((i, 0), (fromIntegral i))) [0 .. 2])+      (asValue img :: [[[[Int64]]]]) `shouldBe` [[[[0], [1], [2]]]]+    it "Y16" $ do+      let img = fromDynImage $ ImageY16 $ newImage 1 3 (map (\i -> ((i, 0), (fromIntegral i))) [0 .. 2])+      (asValue img :: [[[[Int32]]]]) `shouldBe` [[[[0], [1], [2]]]]+    it "Y8" $ do+      let img = fromDynImage $ ImageY8 $ newImage 1 3 (map (\i -> ((i, 0), (fromIntegral i))) [0 .. 2])+      (asValue img :: [[[[Word8]]]]) `shouldBe` [[[[0], [1], [2]]]]+    it "YF" $ do+      let img = fromDynImage $ ImageYF $ newImage 1 3 (map (\i -> ((i, 0), (fromIntegral i))) [0 .. 2])+      (asValue img :: [[[[Float]]]]) `shouldBe` [[[[0], [1], [2]]]]+    it "YA8" $ do+      let img = fromDynImage $ ImageYA8 $ newImage 1 3 (map (\i -> ((i, 0), PixelYA8 (fromIntegral i) 0)) [0 .. 2])+      (asValue img :: [[[[Word8]]]]) `shouldBe` [[[[0, 0], [1, 0], [2, 0]]]]+    it "YA16" $ do+      let img = fromDynImage $ ImageYA16 $ newImage 1 3 (map (\i -> ((i, 0), PixelYA16 (fromIntegral i) 0)) [0 .. 2])+      (asValue img :: [[[[Int32]]]]) `shouldBe` [[[[0, 0], [1, 0], [2, 0]]]]+    it "RGB8" $ do+      let img = fromDynImage $ ImageRGB8 $ newImage 1 3 (map (\i -> ((i, 0), PixelRGB8 (fromIntegral i) 0 0)) [0 .. 2])+      (asValue img :: [[[[Word8]]]]) `shouldBe` [[[[0, 0, 0], [1, 0, 0], [2, 0, 0]]]]+    it "RGBF" $ do+      let img = fromDynImage $ ImageRGBF $ newImage 1 3 (map (\i -> ((i, 0), PixelRGBF (fromIntegral i) 0 0)) [0 .. 2])+      (asValue img :: [[[[Float]]]]) `shouldBe` [[[[0, 0, 0], [1, 0, 0], [2, 0, 0]]]]+    it "RGBA8" $ do+      let img = fromDynImage $ ImageRGBA8 $ newImage 1 3 (map (\i -> ((i, 0), PixelRGBA8 (fromIntegral i) 0 0 0)) [0 .. 2])+      (asValue img :: [[[[Word8]]]]) `shouldBe` [[[[0, 0, 0, 0], [1, 0, 0, 0], [2, 0, 0, 0]]]]+    it "YCbCr8" $ do+      let img = fromDynImage $ ImageYCbCr8 $ newImage 1 3 (map (\i -> ((i, 0), PixelYCbCr8 (fromIntegral i) 0 0)) [0 .. 2])+      (asValue img :: [[[[Word8]]]]) `shouldBe` [[[[0, 0, 0], [1, 0, 0], [2, 0, 0]]]]+    it "CMYK8" $ do+      let img = fromDynImage $ ImageCMYK8 $ newImage 1 3 (map (\i -> ((i, 0), PixelCMYK8 (fromIntegral i) 0 0 0)) [0 .. 2])+      (asValue img :: [[[[Word8]]]]) `shouldBe` [[[[0, 0, 0, 0], [1, 0, 0, 0], [2, 0, 0, 0]]]]+    it "CMYK16" $ do+      let img = fromDynImage $ ImageCMYK16 $ newImage 1 3 (map (\i -> ((i, 0), PixelCMYK16 (fromIntegral i) 0 0 0)) [0 .. 2])+      (asValue img :: [[[[Int32]]]]) `shouldBe` [[[[0, 0, 0, 0], [1, 0, 0, 0], [2, 0, 0, 0]]]]+  describe "fromImages" $ do+    it "RGB8" $ do+      let img = newImage 1 3 (map (\i -> ((i, 0), PixelRGB8 (fromIntegral i) 0 0)) [0 .. 2])+      imgs <- fromImages [img, img, img]+      (asValue imgs :: [[[[Word8]]]]) `shouldBe` [[[[0, 0, 0], [1, 0, 0], [2, 0, 0]]], [[[0, 0, 0], [1, 0, 0], [2, 0, 0]]], [[[0, 0, 0], [1, 0, 0], [2, 0, 0]]]]
+ test/data/mnist-sample-images-idx3-ubyte.gz view

binary file changed (absent → 2638 bytes)

+ test/data/mnist-sample-labels-idx1-ubyte.gz view

binary file changed (absent → 44 bytes)

+ test/data/numpy_rawfile view

binary file changed (absent → 16 bytes)

+ test/doctests.hs view
@@ -0,0 +1,33 @@+module Main where++import Build_doctests (flags, module_sources, pkgs)+import Data.Foldable (traverse_)+import System.Environment (lookupEnv)+import Test.DocTest (doctest)++main :: IO ()+main = do+  libDir <- lookupEnv "NIX_GHC_LIBDIR"++  let args =+        concat+          [ flags,+            pkgs,+            maybe [] (\x -> ["-package-db " <> x <> "/package.conf.d"]) libDir,+            [ "-XDataKinds",+              "-XScopedTypeVariables",+              "-XTypeApplications",+              "-XTypeFamilies",+              "-XQuasiQuotes",+              "-XTemplateHaskell",+              "-XHaskell2010",+              "-fplugin GHC.TypeLits.Normalise",+              "-fplugin GHC.TypeLits.KnownNat.Solver",+              "-fplugin GHC.TypeLits.Extra.Solver",+              "-fconstraint-solver-iterations=0"+            ],+            module_sources+          ]++  -- traverse_ putStrLn args+  doctest args
− tests/GarbageCollectionSpec.hs
@@ -1,118 +0,0 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE ScopedTypeVariables #-}-module GarbageCollectionSpec (spec) where--import Numeric.Dimensions-import Torch.Double.Dynamic as Math-import qualified Torch.Core.Random as R (newRNG)--import Torch.Prelude.Extras--main :: IO ()-main = hspec spec--spec :: Spec-spec = do-  -- it "runs scenario: testGCTensor" testGCTensor-  -- it "runs scenario: testOps" testOps-  it "runs scenario: rawTest" rawTest-  it "runs scenario: testCadd" testCadd-  it "runs scenario: testCopy" testCopy-  it "runs scenario: testLapack" testLapack-  it "runs scenario: matrixMultTest" matrixMultTest--{---- | basic test of garbage collected tensor-testGCTensor :: Property-testGCTensor = monadicIO . run $ do-  let t0 = _new (dims :: Dims '[8, 4])-      t1 = t0-  _fill 3 t1-  let t2 = _fill 6 t1-  print t0 -- should be matrix of 3.0-  print t1 -- should be matrix of 3.0-  print t2 -- should be matrix of 6.0--testOps :: IO ()-testOps = do-  print $ _neg $ _addConst (_new (dims :: Dims '[2, 2])) 3-  print $ _sigmoid $ _neg $ _addConst (_new (dims :: Dims '[2,2])) 3-  new (dims :: Dims '[2, 2]) >>= addConst () 3 >>= sigmoid >>= \(r::DoubleDynamic) -> print r--  foo :: DoubleDynamic <- constant (dims :: Dims '[5]) 3-  print (3.0 * 3.0 * 5 :: Double)-  dot foo foo >>= print--  new (dims :: Dims '[5]) >>= (`add` 2) >>= \(r::DoubleDynamic) -> print r-  new (dims :: Dims '[5]) >>= (`add` 2) >>= (`Math.div` 4) >>= \(r::DoubleDynamic) -> print r--}---- TODO : move raw test elsewhere?-rawTest = do-  let-    x :: DoubleDynamic-    x = constant (dims :: Dims '[5]) 2.0-    y = constant (dims :: Dims '[5]) 3.0-    z = constant (dims :: Dims '[5]) 4.0-  print x-  -- cadd = z <- y + scalar * x, z value discarded-  print (2.0 * 4.4 + 3.0 :: Double)-  cadd_ z 4.4 x-  cadd_ y 4.4 x-  print z-  print y--testCadd = do-  let foo :: DoubleDynamic = constant (dims :: Dims '[5]) 5-      bar :: DoubleDynamic = constant (dims :: Dims '[5]) 2-  print $ 5 + 3 * 2-  print $ cadd foo 3 bar--testCopy :: IO ()-testCopy = do-  let foo :: DoubleDynamic = new (dims :: Dims '[3, 3])-  fill_ foo 5-  bar <- newWithTensor foo-  print foo-  print bar-  let baz = foo `add` 2-  let fob = bar `sub` 2-  print foo-  print bar-  print baz-  print fob-  pure ()--matrixMultTest :: IO ()-matrixMultTest = do-  gen <- R.newRNG-  let Just o10 = ord2Tuple (-10, 10)-  mapM_ (\_ -> go gen o10) [1..10]-  where-    go gen o10 = do-      mat' :: DoubleDynamic <- uniform (dims :: Dims '[10, 7]) gen o10-      vec' :: DoubleDynamic <- uniform (dims :: Dims '[7])     gen o10-      print mat'-      print vec'-      -- print $ mat !* vec--testLapack :: IO ()-testLapack = do-  rng <- R.newRNG-  let Just o1 = ord2Tuple (-1.0, 1.0)-  t :: DoubleDynamic <- uniform (dims :: Dims '[2, 2]) rng o1--  let b  = constant (dims :: Dims '[2, 1]) 1.0-      x  = constant (dims :: Dims '[2, 1]) 0-      lu = constant (dims :: Dims '[2, 2]) 0--  gesv_ (x, lu) b t-  print x-  print lu--  let resQ = constant (dims :: Dims '[2, 2]) 0-      resR = constant (dims :: Dims '[2, 2]) 0-  qr_ (resQ,resR) t-  print resQ-  print resR-
− tests/MemorySpec.hs
@@ -1,100 +0,0 @@-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE BangPatterns #-}-{-# LANGUAGE DataKinds #-}-module MemorySpec (spec) where--import Test.Hspec-import Control.Exception (bracket)-import Control.Monad (forM_)-import Numeric.Dimensions--import Torch.Double.Dynamic as Dynamic--import System.Mem ()---- |Confirm that memory is deallocated (works)-main :: IO ()-main = hspec spec--spec :: Spec-spec = do-  it "scenario: memoryTestMinimal" memoryTestMinimal--headIdx :: Dims '[0, 0, 0, 0]-headIdx = dims--headIdx' :: SomeDims-headIdx' = SomeDims (dims :: Dims '[0, 0, 0, 0])--iterator :: SomeDims -> Int -> IO ()-iterator = iteratorBracket---- |Leaks memory-iteratorAssign :: SomeDims -> Int -> IO ()-iteratorAssign d niter = do-  putStrLn $ show (memSizeGB d) ++ " GB per allocation x " ++ show niter-  forM_ [1..niter] $ \iter -> do-    putStr ("Iteration : " ++ show iter ++ " / ")-    let x = (Dynamic.new' d :: DoubleDynamic) `getDim` headIdx-    putStrLn $ "Printing dummy value: " ++ show x-  putStrLn "Done"---- |Releases memory on OSX (but not consistently on linux)-iteratorMonadic :: SomeDims -> Int -> IO ()-iteratorMonadic d niter = do-  putStrLn $ show (memSizeGB d) ++ " GB per allocation x " ++ show niter-  forM_ [1..niter] $ \iter -> do-    putStr ("Iteration : " ++ show iter ++ " / ")-    let x = (Dynamic.new' d :: DoubleDynamic) `getDim` headIdx-    putStrLn $ "Printing dummy value: " ++ show x-  putStrLn "Done"---- |Releases memory-iteratorBracket :: SomeDims -> Int -> IO ()-iteratorBracket d niter = do-  putStrLn $ show (memSizeGB d) ++ " GB per allocation x " ++ show niter-  forM_ [1..niter] $ \iter ->-    bracket (pure iter)-    (\iter -> do-       putStr ("Iteration : " ++ show iter ++ " / ")-       let x = (Dynamic.new' d :: DoubleDynamic) `getDim` headIdx-       putStrLn $ "Printing dummy value: " ++ show x-    )-    (const (pure ()))-  putStrLn "Done"--manualAlloc1 :: IO ()-manualAlloc1 = do-  putStrLn   "Allocating"-  let !(t :: DoubleDynamic) = new (dims :: Dims '[200, 200, 200, 200])-  let x = getDim t headIdx-  putStrLn $ "Printing dummy value: " ++ show x--manualAlloc2 :: Double -> IO (DoubleDynamic)-manualAlloc2 v = do-  putStrLn "Allocating"-  let !(t :: DoubleDynamic) = constant (dims :: Dims '[200, 200, 100, 100]) v-  let x = getDim t headIdx-  putStrLn $ "Printing dummy value: " ++ show x-  pure t--pr :: DoubleDynamic -> IO ()-pr t = do-  let v = getDim t headIdx-  putStrLn $ "Printing dummy value: " ++ show v---- |getDim' size per allocation-memSizeGB :: SomeDims -> Double-memSizeGB (SomeDims d) = (fromIntegral (totalDim d) * 8) / 1000000000.0--memoryTestLarge :: IO ()-memoryTestLarge = iterator (SomeDims (dims :: Dims '[200, 200, 200, 200])) 1000000 -- 12.8 GB x 1M = 12M GB--memoryTestSmall :: IO ()-memoryTestSmall = iterator (SomeDims (dims :: Dims '[100, 100, 100, 7])) 300 -- 50 MB x 300 = 15 GB--memoryTestFast :: IO ()-memoryTestFast = iterator (SomeDims (dims :: Dims '[50, 50, 50, 5])) 10000 -- 5 MB x 1000 = 5 GB--memoryTestMinimal :: IO ()-memoryTestMinimal = iterator (SomeDims (dims :: Dims '[50, 50, 50, 5])) 100 -- 5 MB x 100 = 500 MB
− tests/Orphans.hs
@@ -1,18 +0,0 @@-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE FlexibleInstances #-}-module Orphans () where--import Data.Function (on)-import Test.QuickCheck--instance Num a => Num (Positive a) where-  (-)         = Positive .: ((-) `on` getPositive)-  (+)         = Positive .: ((+) `on` getPositive)-  (*)         = Positive .: ((*) `on` getPositive)-  abs         = Positive . abs . getPositive-  signum      = Positive . signum . getPositive-  fromInteger = Positive . fromInteger--(.:) = (.) . (.)--
− tests/RawLapackSVDSpec.hs
@@ -1,40 +0,0 @@-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE DataKinds #-}-module RawLapackSVDSpec where--import Foreign.C.Types--import Numeric.Dimensions-import Torch.Float.Dynamic--import Torch.Prelude.Extras--main :: IO ()-main = hspec spec--spec :: Spec-spec = do-  it "scenario: pcaRaw" pcaRaw--pcaRaw :: IO ()-pcaRaw = do--  let a :: FloatDynamic = constant (dims :: Dims '[2, 2]) 2-  print a--  let b                 = constant (dims :: Dims '[2]) 1-  print b--  set2d_ a 0 0 1.0-  set2d_ a 0 1 2.0-  set2d_ a 1 0 3.0-  set2d_ a 1 0 4.0-  print a-  print b--  let resA = constant (dims :: Dims '[2, 2]) 0-  let resB = constant (dims :: Dims '[2, 2]) 0-  gesv_ (resB,resA) b a-  print resA-  print resB-
− tests/Spec.hs
@@ -1,25 +0,0 @@-{- O-P-T-I-O-N-S_GHC -F -pgmF hspec-discover -}-module Main where--import Test.Hspec-import qualified MemorySpec as MS-import qualified RawLapackSVDSpec as SVDS-import qualified GarbageCollectionSpec as GS-import qualified Torch.Core.LogAddSpec as LS-import qualified Torch.Core.RandomSpec as RS-import qualified Torch.Static.NN.AbsSpec as AbsNN-import qualified Torch.Static.NN.LinearSpec as LinearNN-import qualified Torch.Static.NN.ReLUSpec as ReLUNN--main :: IO ()-main = hspec $ do-  describe "MemorySpec" MS.spec-  describe "RawLapackSVDSpec" SVDS.spec-  describe "GarbageCollectionSpec" GS.spec-  describe "Torch.Core.LogAddSpec" LS.spec-  describe "Torch.Core.RandomSpec" RS.spec-  describe "Torch.Static.NN.AbsSpec" AbsNN.spec-  describe "Torch.Static.NN.ReLUSpec" ReLUNN.spec-  describe "Torch.Static.NN.LinearSpec" LinearNN.spec--
− tests/Torch/Core/LogAddSpec.hs
@@ -1,37 +0,0 @@-{-# LANGUAGE ScopedTypeVariables #-}-module Torch.Core.LogAddSpec (spec) where--import Torch.Core.LogAdd-import Torch.Prelude.Extras--main :: IO ()-main = hspec spec---spec :: Spec-spec = do-  describe "logAdd" logAddSpec-  describe "logSub" logSubSpec-  describe "expMinusApprox" expMinusApproxSpec---logAddSpec :: Spec-logAddSpec = do-  it "returns a value" . property $ \((a, b)::(Double, Double)) ->-    a `logAdd` b >>= (`shouldSatisfy` doesn'tCrash)---logSubSpec :: Spec-logSubSpec =-  it "returns a value" . property $ \((a, b)::(Double, Double)) ->-    if a < b-    then a `logSub` b `shouldThrow` anyException-    else a `logSub` b >>= (`shouldSatisfy` doesn'tCrash)---expMinusApproxSpec :: Spec-expMinusApproxSpec =-  it "returns a value" . property $ \(a::Double) ->-    expMinusApprox a >>= (`shouldSatisfy` doesn'tCrash)--
− tests/Torch/Core/RandomSpec.hs
@@ -1,161 +0,0 @@-{-# LANGUAGE ScopedTypeVariables #-}-module Torch.Core.RandomSpec (spec) where--import Test.Hspec-import Test.QuickCheck-import Test.QuickCheck.Monadic--import Control.Monad (replicateM)-import Foreign (Ptr)--import qualified Control.Exception as E-import Torch.Core.Random as R-import Torch.Prelude.Extras (doesn'tCrash)-import Orphans ()---main :: IO ()-main = hspec spec--spec :: Spec-spec = do-  describe "newRNG" newRNGSpec-  describe "seed" seedSpec-  describe "manualSeed" manualSeedSpec-  describe "initialSeed" initialSeedSpec-  describe "random" randomSpec-  describe "uniform" uniformSpec-  describe "normal" normalSpec-  describe "exponential" exponentialSpec-  describe "cauchy" cauchySpec-  describe "logNormal" logNormalSpec-  describe "geometric" geometricSpec-  describe "bernoulli" bernoulliSpec-  describe "scenario" $ do-    it "runs this scenario as expected" $ testScenario--newRNGSpec :: Spec-newRNGSpec = do-  rngs <- runIO (replicateM 10 R.newRNG)-  it "always creates a new random number" $-    zipWith (==) (tail rngs) (init rngs) `shouldNotContain` [True]--seedSpec :: Spec-seedSpec = do-  beforeAll-    (do-        rngs <- (replicateM 10 R.newRNG)-        rng1 <- mapM seed rngs-        rng2 <- mapM seed rngs-        pure (rngs, rng1, rng2)-    )-    (describe "seedSpec" $ do-      it "generates different values, given the same starting generators" $-        \(rngs, rng1, rng2) -> do-          zipWith (==) rng1 rng2 `shouldNotContain` [True]-    )--manualSeedSpec :: Spec-manualSeedSpec = do-  rngs <- runIO (replicateM 10 R.newRNG)-  rng1 <- runIO $ mapM (`manualSeed` 1) rngs-  rng2 <- runIO $ mapM (`manualSeed` 1) rngs--  it "generates the same value, given the same seed values" $-    zipWith (==) rng1 rng2 `shouldNotContain` [False]--initialSeedSpec :: Spec-initialSeedSpec = do-  it "doesn't crash" $-    pending--randomSpec :: Spec-randomSpec = do-  rngs <- runIO (replicateM 10 R.newRNG)-  rs <- runIO $ mapM random rngs-  it "generates numbers and doesn't crash" $-    rs `shouldSatisfy` doesn'tCrash--uniformSpec :: Spec-uniformSpec = do-  rng <- runIO R.newRNG-  distributed2BoundsCheck rng uniform $ \a b x ->-    case compare a b of-      LT -> x <= b && x >= a-      _  -> x <= a && x >= b--normalSpec :: Spec-normalSpec = do-  rng <- runIO R.newRNG-  distributed2BoundsCheck rng (withStdv normal) (\a b x -> doesn'tCrash ())--exponentialSpec :: Spec-exponentialSpec = do-  rng <- runIO R.newRNG-  distributed1BoundsCheck rng exponential property (\a x -> doesn'tCrash ())--cauchySpec :: Spec-cauchySpec = do-  rng <- runIO R.newRNG-  distributed2BoundsCheck rng cauchy (\a b x -> doesn'tCrash ())--logNormalSpec :: Spec-logNormalSpec = do-  rng <- runIO R.newRNG-  distributed2BoundsCheck rng (withStdv logNormal) (\a b x -> doesn'tCrash ())--geometricSpec :: Spec-geometricSpec = do-  rng <- runIO R.newRNG-  distributed1BoundsCheck rng geometric (forAll $ choose (0.0001, 0.9999)) (\a x -> doesn'tCrash ())--bernoulliSpec :: Spec-bernoulliSpec = do-  rng <- runIO R.newRNG-  distributed1BoundsCheck rng bernoulli (forAll $ choose (0.0001, 0.9999)) (\a x -> doesn'tCrash ())---- |Check that seeds work as intended-testScenario :: IO ()-testScenario = do-  rng <- R.newRNG-  manualSeed rng 332323401-  val1 <- normal rng 0.0 1000-  val2 <- normal rng 0.0 1000-  E.assert (val1 /= val2) pure ()-  manualSeed rng 332323401-  manualSeed rng 332323401-  val3 <- normal rng 0.0 1000.0-  E.assert (val1 == val3) pure ()----- ========================================================================= ----withStdv-  :: (Generator -> a -> b -> IO Double)-  -> Generator-  -> a-  -> NonZero (Positive b)-  -> IO Double-withStdv fn g a b = fn g a (getPositive (getNonZero b))---distributed2BoundsCheck-  :: (Show a, Show b, Arbitrary a, Arbitrary b)-  => Generator-  -> (Generator -> a -> b -> IO Double)-  -> (a -> b -> Double -> Bool)-  -> Spec-distributed2BoundsCheck g fun check = do-  it "should generate random numbers in the correct bounds" . property $ \(a, b) ->-      monadicIO $ do-        x <- run (fun g a b)-        assert (check a b x)--distributed1BoundsCheck :: (Show a, Arbitrary a) => Generator -> (Generator -> a -> IO b) -> ((a -> Property) -> Property) -> (a -> b -> Bool) -> Spec-distributed1BoundsCheck g fun pfun check = do-  it "should generate random numbers in the correct bounds" . pfun $ \a -> monadicIO $ do-    x <- run (fun g a)-    assert (check a x)---
− tests/Torch/Prelude/Extras.hs
@@ -1,18 +0,0 @@-module Torch.Prelude.Extras-  ( module X-  , doesn'tCrash-  , doesn'tCrashM-  ) where--import Test.Hspec as X-import Test.QuickCheck as X-import Test.QuickCheck.Monadic as X--import Orphans as X--doesn'tCrash :: a -> Bool-doesn'tCrash = const True--doesn'tCrashM :: Monad m => a -> m Bool-doesn'tCrashM = const (pure True)-
− tests/Torch/Static/NN/AbsSpec.hs
@@ -1,29 +0,0 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE ScopedTypeVariables #-}-module Torch.Static.NN.AbsSpec where--import Test.Hspec-import Torch.Double--main :: IO ()-main = hspec spec--spec :: Spec-spec = do-  describe "abs_updateOutput" $ do-    it "runs the absolute function" $ do-      Just (x :: DoubleTensor '[2, 4]) <- fromList [-4..4-1]-      y <- tensordata <$> abs_updateOutput x-      y `shouldSatisfy` all (>= 0)--  describe "abs_updateGradInput" $ do-    it "returns the input gradient" $ do-      Just (x :: DoubleTensor '[2, 4]) <- fromList [-4..4-1]-      let go :: DoubleTensor '[2, 4] = constant 1-      let rs = tensordata (signum x)-      ys <- tensordata <$> abs_updateGradInput x go-      zip ys rs `shouldSatisfy` all eqSigns-  where-    eqSigns :: (Double, Double) -> Bool-    eqSigns (y, r) = y == r || (r == 0 && y == 1)-
− tests/Torch/Static/NN/LinearSpec.hs
@@ -1,394 +0,0 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE TupleSections #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE TypeApplications #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE CPP #-}--#if MIN_VERSION_base(4,12,0)-{-# LANGUAGE NoStarIsType #-}-#endif--{-# OPTIONS_GHC -fno-cse #-}-module Torch.Static.NN.LinearSpec where--import GHC.TypeLits-import Control.Monad (join, void)-import Data.Function ((&))-import Data.Foldable-import Debug.Trace-import Data.Maybe-import GHC.Generics (Generic)-import Test.Hspec-import Lens.Micro.Platform-import Numeric.Backprop-import System.IO.Unsafe-import Data.Generics.Product-import qualified Numeric.Backprop as B--import Debug.Trace--import Torch.Double as Torch-import Torch.Double.NN.Linear-import qualified Torch.Long as Long--reasonablyUnsafeVector :: (KnownDim m, KnownNat m) => [HsReal] -> Tensor '[m]-reasonablyUnsafeVector = unsafePerformIO . unsafeVector-{-# NOINLINE reasonablyUnsafeVector #-}--reasonablyUnsafeLongVector :: (KnownDim m, KnownNat m) => [Long.HsReal] -> Long.Tensor '[m]-reasonablyUnsafeLongVector = unsafePerformIO . Long.unsafeVector-{-# NOINLINE reasonablyUnsafeLongVector #-}--reasonablyUnsafeMatrix-  :: All KnownDim '[m, n, n*m]-  => All KnownNat '[m, n, n*m]-  => [[HsReal]]-  -> Tensor '[n,m]-reasonablyUnsafeMatrix = unsafePerformIO . unsafeMatrix-{-# NOINLINE reasonablyUnsafeMatrix #-}--xavier :: forall d . Dimensions d => IO (Tensor d)-xavier = case (fromIntegral <$> listDims (dims :: Dims d)) of-  [] -> pure empty-  a:_ -> pure $ constant (1 / realToFrac (fromIntegral a))--data FF2Network i h o = FF2Network-  { layer1 :: Linear i h-  , layer2 :: Linear h o-  } deriving (Generic, Show)--instance (KnownDim i, KnownDim h, KnownDim o) => Pairwise (FF2Network i h o) HsReal where-  (FF2Network l0 l1) ^+ v = FF2Network (l0 ^+ v) (l1 ^+ v)-  (FF2Network l0 l1) ^- v = FF2Network (l0 ^+ v) (l1 ^+ v)-  (FF2Network l0 l1) ^* v = FF2Network (l0 ^+ v) (l1 ^+ v)-  (FF2Network l0 l1) ^/ v = FF2Network (l0 ^+ v) (l1 ^+ v)--weightsL :: Lens' (Linear i o) (Tensor '[i, o])-weightsL = field @"getTensors" . _1--biasL :: Lens' (Linear i o) (Tensor '[o])-biasL = field @"getTensors" . _2--specupdate-  :: forall i h o-  .  All KnownDim '[i, h, o]-  => FF2Network i h o-  -> FF2Network i h o-  -> FF2Network i h o-specupdate i g = FF2Network-  { layer1 = B.add (layer1 i) (layer1 g)-  , layer2 = B.add (layer2 i) (layer2 g)-  }--instance (KnownDim i, KnownDim h, KnownDim o) => Backprop (FF2Network i h o)---- ========================================================================= ----main :: IO ()-main = hspec spec--spec :: Spec-spec = do-  describe "a single linear layer" singleLayer-  describe "a two-layer feed forward network" $ do-    describe "with xavier initialization" twoLayerXavier-    describe "forcing ReLU activity"      twoLayerForceReLU-    describe "overfitting to [0, 1]" $ do-      describe "with one layer and binary cross-entropy"   oneLayerOverfit-      describe "with two layers and binary cross-entropy"   twoLayerOverfit-      -- describe "with logSoftmax and multiclass log-loss" $-      --   twoLayerOverfit logSoftMax (classNLLCriterion (reasonablyUnsafeLongVector [1])) Torch.exp---- ========================================================================= ----singleLayer :: Spec-singleLayer = do-  ll :: Linear 3 2 <- runIO $ mkLinear xavier-  xavierPurityCheck ll $ do-    describe "the forward pass" $ do-      let y = constant 5 :: Tensor '[3]-          o = evalBP2 (linear) ll y--      it "performs matrix multipication as you would expect" $ do-        o =##= ((5/3)*3) + 1/2-        o `elementsSatisfy` ((== 2) . length)--    describe "the backward pass" $ do-      let y = constant 1 :: Tensor '[3]-          (_, (ll', o)) = backprop2 linear ll y--      it "returns plain gradient of weights" $ weights ll' =##= 1   -- 1/2-      it "returns plain gradient of bias"    $ bias    ll' =##= 3/2 -- 2/3-      it "returns plain gradient of output tensor" $    o  =##= 2/3 -- 1/3---- ========================================================================= ----mkXavierNetwork :: All KnownDim '[i,h,o] => IO (FF2Network i h o)-mkXavierNetwork =-  FF2Network-    <$> mkLinear xavier-    <*> mkLinear xavier---mkUniform :: All KnownDim '[i,h,o] => IO (FF2Network i h o)-mkUniform = do-  g <- newRNG-  manualSeed g 1-  let Just rg = ord2Tuple (-1, 1)-  w0 <- uniform g rg-  w1 <- uniform g rg-  pure $ FF2Network-    (Linear (w0, constant 1))-    (Linear (w1, constant 1))---mkGaussianNetwork :: All KnownDim '[i,h,o] => IO (FF2Network i h o)-mkGaussianNetwork = do-  g <- newRNG-  manualSeed g 1-  let Just std = positive 2--  FF2Network-    <$> mkLinear (normal g 0 std)-    <*> mkLinear (normal g 0 std)---ff2network-  :: forall s i h o-  .  Reifies s W-  => All KnownDim '[i,h,o]-  => (forall s . Reifies s W => BVar s (Tensor '[o]) -> BVar s (Tensor '[o]))-  -> Double-  -> BVar s (FF2Network i h o)     -- ^ ff2network architecture-  -> BVar s (Tensor '[i])          -- ^ input-  -> BVar s (Tensor '[1, o])       -- ^ output-ff2network final lr arch inp-  = linear {-lr-} (arch ^^. field @"layer1") inp-  & relu-  & linear {-lr-} (arch ^^. field @"layer2")-  & final-  & foo-  where-    foo t = unsqueeze1dBP (dim :: Dim 0) t--twoLayerXavier :: Spec-twoLayerXavier = do-  ll :: FF2Network 4 6 2 <- runIO mkXavierNetwork-  describe "the forward pass" $ do-    describe "with xavier instantiation" $ do-      xavierPurityCheck (ll ^. field @"layer1") $-        xavierPurityCheck (ll ^. field @"layer2") $-          describe "with input all positive input" $ do-            let y = constant 4 :: Tensor '[4]-                (o, _) = backprop2 (ff2network softmax undefined) ll y-            it "performs matrix multipication as you would expect" $ o `approx` [1/2, 1/2]--      describe "with input that drops all values via ReLU" $ do-        let y = constant (-1) :: Tensor '[4]-            (o, _) = backprop2 (ff2network softmax undefined) ll y--        it "performs matrix multipication as you would expect" $ o `approx` [1/2, 1/2]-  where-    approx = lapproximately 0.0001---twoLayerForceReLU :: Spec-twoLayerForceReLU = do-  describe "operations that force relu activity" $ do-    let o1 = evalBP2 (relu    .: linear {-1-}) (ff2 ^. field @"layer1") oneInput-        o2 = evalBP2 (           linear {-1-}) (ff2 ^. field @"layer2") o1-        gin :: Tensor '[4]-        (out, (gff2, gin)) = backprop2 (ff2network logSoftMax 1) ff2 oneInput--    describe "dropping half the gradient during ReLU" $ do-      describe "the forward pass" $ do-        it "returns [0,0,0,4,4,4] after the first layer" $-          tensordata o1 `shouldBe` [0,0,0,4,4,4]--        it "returns [-12,0] after the second layer" $-          tensordata o2 `shouldBe` [-12, 0]--        it "returns [0, 1] as the output" $ do-          Torch.exp out `lapprox` [0, 1]--      describe "the backward pass" $ do-        it "returns a half zero-d out layer 1 gradient" $ do-          (gff2 ^. field @"layer1" . weightsL) `approx` l1weightgrad--        it "returns a quarter zero-d out layer 2 gradient" $ do-          (gff2 ^. field @"layer2" . weightsL) `approx` l2weightgrad--        it "returns a [3,3,3] input gradient" $ do-          gin `lapprox` replicate 4 (-3)-- where-  eps = 0.0001--  approx :: Tensor d -> Tensor d -> IO ()-  approx = approximately eps--  lapprox :: Tensor d -> [HsReal] -> IO ()-  lapprox = lapproximately eps--  ff2 :: FF2Network 4 6 2-  ff2 = FF2Network-    (Linear (reasonablyUnsafeMatrix $ replicate 4 [ -1, -1, -1, 1, 1, 1], constant 0))-    (Linear (reasonablyUnsafeMatrix $ replicate 6                [-1, 0], constant 0))--  oneInput :: Tensor '[4]-  oneInput = constant 1--  l1weightgrad :: (Tensor '[4, 6])-  l1weightgrad = reasonablyUnsafeMatrix $ replicate 4 [ 0, 0, 0,-1,-1,-1]--  l2weightgrad :: (Tensor '[6, 2])-  l2weightgrad = reasonablyUnsafeMatrix $ replicateN 3-    [ [ 0, 0]-    , [ 4,-4]-    ]--twoLayerOverfit :: Spec-twoLayerOverfit = do-  net0 <- runIO $ do-    g <- newRNG-    manualSeed g 1-    l0 <- (Linear . (,constant 1)) <$> uniform g rg-    l1 <- (Linear . (,constant 1)) <$> uniform g rg-    pure (l0, l1)--  it "returns around 50-50 on uniform random initialization" . void $ do-    let [l0, r0] = tensordata $ infer net0-    let pointapprox pred truth = Prelude.abs (pred - truth) < 0.3-    (l0, r0) `shouldSatisfy` (\(px, py) -> pointapprox px 0.5 && pointapprox py 0.5)--  it "backprops to yield a loss smaller than its prior" . void $ do-    let [l0, r0] = tensordata $ infer net0-    let lr = (-0.001) :: HsReal-    let (o, _) = bprop net0-    (fnet, (fo, fl, fr)) <--      foldlM (\(net, (o, l, r)) i -> do-        let (o, (Linear (gw0, gb0), Linear (gw1, gb1))) = bprop net-        let net' = B.add net (Linear (gw0 ^* lr, gb0 ^* lr), Linear (gw1 ^* lr, gb1 ^* lr))-        let (o', grad') = bprop net'-        let [l', r'] = tensordata $ infer net'-        o `shouldSatisfy` (> o')-        pure (net', (o', l', r'))-        ) (net0, (o, l0, r0)) [1..100]-    let pointapprox pred truth = Prelude.abs (pred - truth) < 0.01-    (fl, fr) `shouldSatisfy` (\(px, py) -> pointapprox px 0.0 && pointapprox py 1.0)--  where-    Just rg = ord2Tuple (-1, 1)--    x :: Tensor '[4]-    x = constant 1--    answer :: Tensor '[2]-    answer = reasonablyUnsafeVector [0,1]--    arch :: Reifies s W => BVar s (Linear 4 6, Linear 6 2) -> BVar s (Tensor '[4]) -> BVar s (Tensor '[2])-    arch arch inp-      = linear (arch ^^. _1) inp-      & relu-      & linear (arch ^^. _2)-      & softmax--    infer :: (Linear 4 6, Linear 6 2) -> Tensor '[2]-    infer net = evalBP2 arch net x--    bprop net = (fromJust $ get1d o 0, g)-     where-      (o, (g, _)) = backprop2 (bCECriterion answer .: arch) net x----oneLayerOverfit :: Spec-oneLayerOverfit = do-  net0 <- runIO (newRNG >>= \g -> manualSeed g 1 >> (Linear . (,constant 1)) <$> uniform g rg)-  it "returns around 50-50 on uniform random initialization" . void $ do-    let [l0, r0] = tensordata $ infer net0-    let pointapprox pred truth = Prelude.abs (pred - truth) < 0.3-    (l0, r0) `shouldSatisfy` (\(px, py) -> pointapprox px 0.5 && pointapprox py 0.5)--  it "backprops to yield a loss smaller than its prior" . void $ do-    let [l0, r0] = tensordata $ infer net0-    let lr = (-0.1) :: HsReal-    let (o, _) = bprop net0-    (fnet, (fo, fl, fr)) <--      foldlM (\(net, (o, l, r)) i -> do-        let (o, Linear (gw, gb)) = bprop net-        let net' = B.add net (Linear (gw ^* lr, gb ^* lr))-        let (o', grad') = bprop net'-        let [l', r'] = tensordata $ infer net'-        o `shouldSatisfy` (> o')-        pure (net', (o', l', r'))-        ) (net0, (o, l0, r0)) [1..100]-    let pointapprox pred truth = Prelude.abs (pred - truth) < 0.01-    (fl, fr) `shouldSatisfy` (\(px, py) -> pointapprox px 0.0 && pointapprox py 1.0)--  where-    Just rg = ord2Tuple (-1, 1)--    x :: Tensor '[6]-    x = constant 1--    answer :: Tensor '[2]-    answer = (reasonablyUnsafeVector [0,1])--    arch :: Reifies s W => BVar s (Linear 6 2) -> BVar s (Tensor '[6]) -> BVar s (Tensor '[2])-    arch a b = softmax $ linear a b--    infer :: Linear 6 2 -> Tensor '[2]-    infer net = evalBP2 arch net x--    bprop net = (fromJust $ get1d o 0, g)-     where-      (o, (g, _)) = backprop2 (bCECriterion answer .: arch) net x---xavierPurityCheck :: forall i o . (KnownDim i, KnownDim o) => Linear i o -> Spec -> Spec-xavierPurityCheck ll tests =-  it (header ++ "initializes with xavier correctly")-    (  weights ll =##= 1/i-    >> bias    ll =##= 1/o)-  >> tests-  >> it (header ++ "leaves weights unchanged") (weights ll =##= 1/i)-  >> it (header ++ "leaves bias unchanged")    (bias    ll =##= 1/o)- where-  header :: String-  header = "[ref-check] " ++ unwords ["Linear", show (truncate i), show (truncate o)] ++ ": "--  i, o :: Double-  i = fromIntegral (dimVal (dim :: Dim i))-  o = fromIntegral (dimVal (dim :: Dim o))---_lapproximately :: ([Double] -> Bool) -> Double -> Tensor d -> [Double] -> IO ()-_lapproximately pred e o dist = let os = tensordata o in-  zipWith (Prelude.abs .: subtract) os dist `shouldSatisfy` pred--_approximately :: ([Double] -> Bool) -> Double -> Tensor d -> Tensor d -> IO ()-_approximately pred e o dist = _lapproximately pred e o (tensordata dist)--approximately  e = _approximately  (all (< e)) e-notCloseTo     e = _approximately  (all (> e)) e-lapproximately e = _lapproximately (all (< e)) e-lnotCloseTo    e = _lapproximately (all (> e)) e--elementsSatisfy :: Tensor d -> ([Double] -> Bool) -> IO ()-elementsSatisfy o pred = tensordata o `shouldSatisfy` pred--replicateN :: Int -> [a] -> [a]-replicateN inner = concatMap (replicate inner)--(=##=) :: Tensor d -> Double -> IO ()-(=##=) o v = elementsSatisfy o (all (== v))--infixl 2 =##=--
− utils/Torch/Core/Exceptions.hs
@@ -1,109 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Core.Exceptions--- Copyright :  (c) Hasktorch devs 2017--- License   :  BSD3--- Maintainer:  Sam Stites <sam@stites.io>--- Stability :  experimental--- Portability: non-portable------ Package to start off hasktorch exception handling.------ TODO: Move this into a seperate package so that this can be used by--- 'hasktorch-classes'---------------------------------------------------------------------------------{-# LANGUAGE ForeignFunctionInterface #-}-module Torch.Core.Exceptions-  ( TorchException(..)-  , module X-  {--  , c_testHasktorchLib-  , p_testHasktorchLib-  , c_errorHandler-  , p_errorHandler-  , c_argErrorHandler-  , p_argErrorHandler-  , c_THSetErrorHandler-  -}-  ) where--import Control.Exception.Safe as X--- import Control.Exception.Base as X (catch)-import Data.Typeable (Typeable)-import Data.Text (Text)--import Foreign-import Foreign.C.String---- | The base Torch exception class-data TorchException-  = MathException Text-  deriving (Show, Typeable)--instance Exception TorchException--{- Hasktorch error handler -}-{--foreign import ccall unsafe "error_handler.h testFunction"-  c_testHasktorchLib :: IO ()--foreign import ccall unsafe "error_handler.h &testFunction"-  p_testHasktorchLib :: FunPtr (IO ())--foreign import ccall unsafe "error_handler.h errorHandler"-  c_errorHandler :: CString -> IO ()--foreign import ccall unsafe "error_handler.h &errorHandler"-  p_errorHandler :: FunPtr (CString -> IO ())--foreign import ccall unsafe "error_handler.h argErrorHandler"-  c_argErrorHandler :: CString -> IO ()--foreign import ccall unsafe "error_handler.h &argErrorHandler"-  p_argErrorHandler :: FunPtr (CString -> IO ())--{- THGeneral options to configure error handler -}----- TH_API void THSetErrorHandler(THErrorHandlerFunction new_handler, void *data);-foreign import ccall "THGeneral.h.in THSetErrorHandler"-  c_THSetErrorHandler :: FunPtr (CString -> IO ()) -> IO ()--}-{---- TH_API double THLog1p(const double x);-foreign import ccall unsafe "THGeneral.h.in THLog1p"-  c_THLog1p :: CDouble -> CDouble---- safe version of potrf--- |c_Torch.FFI.TH.Double.Tensor_potrf : ra_ a uplo -> void-foreign import ccall "THTensorLapack.h Torch.FFI.TH.Double.Tensor_potrf"-  c_safe_Torch.FFI.TH.Double.Tensor_potrf :: (Ptr CTHDoubleTensor) -> (Ptr CTHDoubleTensor) -> Ptr CChar -> IO ()--lapackTest :: IO ()-lapackTest = do-  putStrLn "Setting error handler"-  c_THSetErrorHandler p_errorHandler-  putStrLn "Cholesky decomposition should fail:"-  opt <- newCString "U"-  dims <- Dim.someDimsM [2, 2]-  a <- constant' dims 2--  Gen.c_set2d a 0 0 1.0-  Gen.c_set2d a 0 1 0.0-  Gen.c_set2d a 1 1 (-1.0)-  Gen.c_set2d a 1 0 0.0-  resA <- constant' dims 5.0-  dispRaw a-  c_safe_Torch.FFI.TH.Double.Tensor_potrf resA a opt-  dispRaw a-  -- dispRaw resA -- TODO: what should happen when potrf has an error-  c_Torch.FFI.TH.Double.Tensor_free a-  c_Torch.FFI.TH.Double.Tensor_free resA-  pure ()--test = do-  c_testHasktorchLib-  c_THSetErrorHandler p_errorHandler-  lapackTest-  putStrLn "Done"-  -}
− utils/Torch/Core/LogAdd.hs
@@ -1,50 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Core.LogAdd--- Copyright :  (c) Hasktorch devs 2017--- License   :  BSD3--- Maintainer:  Sam Stites <sam@stites.io>--- Stability :  experimental--- Portability: non-portable------ Various bindings to 'TH/THLogAdd.c' and haskell variants where possible---------------------------------------------------------------------------------{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE ScopedTypeVariables #-}-module Torch.Core.LogAdd-  ( logAdd-  , logSub-  , expMinusApprox-  ) where--import Torch.Core.Exceptions-import qualified Torch.FFI.TH.LogAdd as TH---- | Add two log values, calling out to TH-logAdd :: Double -> Double -> IO Double-logAdd a b = realToFrac <$> TH.c_THLogAdd (realToFrac a) (realToFrac b)---- | Subtract two log values, calling out to TH-logSub :: Double -> Double -> IO Double-logSub log_a log_b-  | log_a < log_b = throw $ MathException "log_a must be greater than log_b"-  | otherwise     = realToFrac <$> TH.c_THLogSub (realToFrac log_a) (realToFrac log_b)---- | A fast approximation of @exp(-x)@ for positive @x@. Calls out to TH-expMinusApprox :: Double -> IO Double-expMinusApprox a = realToFrac <$> TH.c_THExpMinusApprox (realToFrac a)---- | A pure version of 'expMinusApprox', transcribing the code from THLogAdd.c to haskell-expMinusApprox' :: forall f . RealFrac f => f -> Maybe f-expMinusApprox' x-  | x < 0     = Nothing-  | x < 13    = Just $ 1 / (y*y*y*y)-  | otherwise = Just   0-  where-   a0, a1, a2, a3, a4 :: f-   a0 = 1-   a1 = 0.125-   a2 = 0.0078125-   a3 = 0.00032552083-   a4 = 1.0172526e-5-   y  = a0 + x * (a1 + x * (a2 + x * (a3 + x * a4)))
− utils/Torch/Core/Random.hs
@@ -1,151 +0,0 @@----------------------------------------------------------------------------------- |--- Module    :  Torch.Core.Random--- Copyright :  (c) Sam Stites 2017--- License   :  BSD3--- Maintainer:  sam@stites.io--- Stability :  experimental--- Portability: non-portable------ Random number generation for single values. FFI over TH/THRandom.h---------------------------------------------------------------------------------module Torch.Core.Random-  ( Generator-  , Seed-  , newRNG-  , copy-  , seed-  , manualSeed-  , initialSeed-  , random-  , random64-  , uniform-  , uniformFloat-  , normal-  , exponential-  , standard_gamma-  , cauchy-  , logNormal-  , geometric-  , bernoulli-  ) where--import Foreign (Ptr)-import Foreign.ForeignPtr (ForeignPtr, withForeignPtr, newForeignPtr)-import Data.Word--import Torch.Types.TH-import qualified Torch.FFI.TH.Random as TH---- ========================================================================= ----- helpers--- ========================================================================= ----asRNG :: Ptr C'THGenerator -> IO Generator-asRNG = fmap Generator . newForeignPtr TH.p_THGenerator_free--with2RNGs :: (Ptr C'THGenerator -> Ptr C'THGenerator -> IO x) -> Generator -> Generator -> IO x-with2RNGs fn g0 g1 = _with2RNGs g0 g1 fn--_with2RNGs :: Generator -> Generator -> (Ptr C'THGenerator -> Ptr C'THGenerator -> IO x) -> IO x-_with2RNGs g0 g1 fn = _withRNG g0 (\g0' -> _withRNG g1 (\g1' -> fn g0' g1'))--withRNG :: (Ptr C'THGenerator -> IO x) -> Generator -> IO x-withRNG fn g = withForeignPtr (rng g) fn--_withRNG :: Generator -> (Ptr C'THGenerator -> IO x) -> IO x-_withRNG = flip withRNG---- ========================================================================= ------ | Construct a new 'Generator'-newRNG :: IO Generator-newRNG = TH.c_THGenerator_new >>= asRNG---- | Copy a 'Generator' state to a new generator-copy :: Generator -> Generator -> IO Generator-copy g0 g1 = (with2RNGs TH.c_THGenerator_copy g0 g1) >>= asRNG---- | Get the current 'Seed' of a 'Generator'-seed :: Generator -> IO Seed-seed = withRNG (fmap fromIntegral . TH.c_THRandom_seed)---- | Manually set the seed 'Seed' of a 'Generator'-manualSeed :: Generator -> Seed -> IO ()-manualSeed g s = _withRNG g $ \p -> TH.c_THRandom_manualSeed p (fromIntegral s)---- | Get the first 'Seed' that initialized a given 'Generator'-initialSeed :: Generator -> IO Seed-initialSeed = withRNG (fmap fromIntegral . TH.c_THRandom_initialSeed)--random :: Generator -> IO Seed-random = withRNG (fmap fromIntegral . TH.c_THRandom_random)--random64 :: Generator -> IO Seed-random64 = withRNG (fmap fromIntegral . TH.c_THRandom_random64)---- | Returns a random double according to uniform distribution on [a,b).-uniform-  :: Generator-  -> Double -- ^ lower bound-  -> Double -- ^ upper bound-  -> IO Double-uniform g a b = _withRNG g $ \p -> realToFrac <$> TH.c_THRandom_uniform p (realToFrac a) (realToFrac b)---- | Returns a random float according to uniform distribution on [a,b).-uniformFloat-  :: Generator-  -> Float -- ^ lower bound-  -> Float -- ^ upper bound-  -> IO Float-uniformFloat g a b = _withRNG g $ \p -> realToFrac <$> TH.c_THRandom_uniformFloat p (realToFrac a) (realToFrac b)---- | Returns a random real number according to a normal distribution with the given mean and standard deviation stdv. stdv must be positive, but this is not yet enforced.------ TODO: add a @newtype Pos a = Pos { getPos :: a }@ package with a smart constructor export-normal-  :: Generator-  -> Double -- ^ mean-  -> Double -- ^ stddev (must be positive)-  -> IO Double-normal g a b = _withRNG g $ \p -> realToFrac <$> TH.c_THRandom_normal p (realToFrac a) (realToFrac b)---- | Returns a random real number according to the exponential distribution @p(x) = lambda * exp(-lambda * x)@-exponential :: Generator -> Double -> IO Double-exponential g a = _withRNG g $ \p -> realToFrac <$> TH.c_THRandom_exponential p (realToFrac a)--standard_gamma :: Generator -> Double -> IO Double-standard_gamma g a = _withRNG g $ \p -> realToFrac <$> TH.c_THRandom_standard_gamma p (realToFrac a)---- | Returns a random real number according to the Cauchy distribution @p(x) = sigma/(pi*(sigma^2 + (x-median)^2))@-cauchy-  :: Generator-  -> Double -- ^ median-  -> Double -- ^ sigma-  -> IO Double-cauchy g a b = _withRNG g $ \p -> realToFrac <$> TH.c_THRandom_cauchy p (realToFrac a) (realToFrac b)---- | Returns a random real number according to the log-normal distribution, with the given mean and--- standard deviation stdv. mean and stdv are the corresponding mean and standard deviation of the--- underlying normal distribution, and not of the returned distribution.------ stdv must be positive.-logNormal-  :: Generator-  -> Double -- ^ mean-  -> Double -- ^ stddev (must be positive)-  -> IO Double-logNormal g a b = _withRNG g $ \p -> realToFrac <$> TH.c_THRandom_logNormal p (realToFrac a) (realToFrac b)---- | Returns a random integer number according to a geometric distribution--- @p(i) = (1-p) * p^(i-1)@. p must satisfy 0 < p < 1.-geometric :: Generator -> Double -> IO Int-geometric g a = _withRNG g $ \p -> fromIntegral <$> TH.c_THRandom_geometric p (realToFrac a)---- | Returns 1 with probability p and 0 with probability 1-p. p must satisfy 0 <= p <= 1.------ TODO: By default p is equal to 0.5 -- this isn't encoded in the API-bernoulli :: Generator -> Double -> IO Int-bernoulli g a = _withRNG g $ \p -> fromIntegral <$> TH.c_THRandom_bernoulli p (realToFrac a)--