Categorifier is failing to inline fmap on a fixed length vector and, based on the message, it looks like it should be able to do so since since Functor is in base.
I have a non-trivial expression that fails on zipWith but debugging that led me to the below.
Should I expect to be able to categorify expressions using Data.Vec.Lazy or does this and #84 indicate that it is unlikely to work?
Compiled using the .#ghc8107 environment with
ghc-options:
-O0 -fexpose-all-unfoldings -fmax-simplifier-iterations=0
-fno-ignore-interface-pragmas -fno-omit-interface-pragmas -Wall
-fplugin Categorifier -fplugin-opt
Categorifier:hierarchy:Categorifier.Hierarchy.UnconCat.hierarchy
-fplugin-opt
Categorifier:hierarchy:Categorifier.Hierarchy.ConCat.functionHierarchy
-fplugin-opt
Categorifier:hierarchy:Categorifier.Hierarchy.ConCatExtensions.hierarchy
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module F (fCategorified) where
import qualified Categorifier.C.CExpr.Cat as C
import Categorifier.C.CExpr.Cat.TargetOb (TargetOb)
import Categorifier.C.CTypes.CGeneric (CGeneric)
import qualified Categorifier.C.CTypes.CGeneric as CG
import Categorifier.C.CTypes.GArrays (GArrays)
import Categorifier.C.KTypes.C (C)
import Categorifier.C.KTypes.KLiteral (KLiteral, kliteral)
import qualified Categorifier.Categorify as Categorify
import qualified Categorifier.Client as Client
import Complex (Complex (..), realPart)
import Data.Int (Int32, Int64)
import Data.Nat (Nat (S, Z))
import Data.Type.Nat (SNatI)
import Data.Vec.Lazy (Vec (..))
import qualified Data.Vec.Lazy as Vec
import Data.Word (Word64)
import GHC.Generics (Generic)
Client.deriveHasRep ''Vec
data TwoInput = TwoInput
{ twoA :: C Word64,
twoB :: C Word64
}
deriving (Generic)
Client.deriveHasRep ''TwoInput
type Two = 'S ('S 'Z)
instance CGeneric TwoInput
instance GArrays C TwoInput
type instance TargetOb TwoInput = TargetOb (CG.Rep TwoInput ())
type instance TargetOb (Vec n a) = Vec n (TargetOb a)
f :: TwoInput -> C Double
f t = tkFirst $ fmap fromIntegral (twoA t ::: twoB t ::: VNil)
where
tkFirst :: Vec Two (C Double) -> C Double
tkFirst (a ::: b ::: _) = a
fCategorified :: TwoInput `C.Cat` C Double
fCategorified = Categorify.expression f
ghc: panic! (the 'impossible' happened)
(GHC version 8.10.7:
Categorifier failed to categorify the following expression:
\ (t :: TwoInput) ->
$ @ 'LiftedRep
@ (Vec Two (C Double))
@ (C Double)
(\ (ds_dn0F [OS=OneShot] :: Vec Two (C Double)) ->
join {
fail_dn2Z :: Void# -> C Double
[LclId[JoinId(1)],
Arity=1,
Str=<L,U>b,
Unf=Unf{Src=<vanilla>, TopLvl=False, Value=True, ConLike=True,
WorkFree=True, Expandable=True, Guidance=IF_ARGS [0] 120 0}]
fail_dn2Z _ [Occ=Dead, OS=OneShot]
= patError
@ 'LiftedRep @ (C Double) "app/F.hs:55:5-31|function tkFirst"# } in
case ds_dn0F of { ::: @ n1 co_akQ7 a ds_dn2X ->
case ds_dn2X of {
VNil ipv -> jump fail_dn2Z void#;
::: @ n1 co_akQ9 b ds_dn2Y -> a
}
})
(map
@ (C Word64)
@ (C Double)
@ ('S ('S 'Z))
(fromIntegral @ (C Word64) @ (C Double) $fIntegralC3 $dNum_akQV)
($W:::
@ (C Word64)
@ ('S 'Z)
(twoA t)
($W::: @ (C Word64) @ 'Z (twoB t) ($WVNil @ (C Word64)))))
- The Categorifier plugin was unable to inline map
@ (C Word64)
@ (C Double)
@ ('S ('S 'Z))
(fromIntegral @ (C Word64) @ (C Double) $fIntegralC3 $dNum_akQV)
($W:::
@ (C Word64)
@ ('S 'Z)
(twoA t)
($W::: @ (C Word64) @ 'Z (twoB t) ($WVNil @ (C Word64)))).
There is no unfolding available for the identifier. It's possible that the
identifier is an unspecialized type class method (methods never have
unfoldings), a name used for `RebindableSyntax`, or that the unfolding
somehow didn't get from the definition point to the module that called
`categorify`. There are a few things you can check. Is the definition in the
base library? If so, report this as a bug against the plugin. Does the
definition expose an unfolding? The module containing the definition to be
inlined should be compiled with `-fno-omit-interface-pragmas` (this is
implied by `-O`). That _may_ be enough, but if not, try adding an
`inlinable` pragma to the definition or compiling with
`-fexpose-all-unfoldings` to make _every_ operation inlinable. It's also
important that the module containing the call to `categorify` is compiled
with `-fno-ignore-interface-pragmas` (also implied by `-O`). If the
unfolding that's missing is for `$j` (GHC-internal join points), you may
need to bump `-funfolding-creation-threshold` on the modules you're
depending on. If there is still no unfolding available, please file an issue
against the plugin.
(seen 1 time)
Please report this as a GHC bug: https://www.haskell.org/ghc/reportabug
Categorifier is failing to inline
fmapon a fixed length vector and, based on the message, it looks like it should be able to do so since sinceFunctoris in base.I have a non-trivial expression that fails on
zipWithbut debugging that led me to the below.Should I expect to be able to categorify expressions using Data.Vec.Lazy or does this and #84 indicate that it is unlikely to work?
Compiled using the
.#ghc8107environment with{-# LANGUAGE DataKinds #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} module F (fCategorified) where import qualified Categorifier.C.CExpr.Cat as C import Categorifier.C.CExpr.Cat.TargetOb (TargetOb) import Categorifier.C.CTypes.CGeneric (CGeneric) import qualified Categorifier.C.CTypes.CGeneric as CG import Categorifier.C.CTypes.GArrays (GArrays) import Categorifier.C.KTypes.C (C) import Categorifier.C.KTypes.KLiteral (KLiteral, kliteral) import qualified Categorifier.Categorify as Categorify import qualified Categorifier.Client as Client import Complex (Complex (..), realPart) import Data.Int (Int32, Int64) import Data.Nat (Nat (S, Z)) import Data.Type.Nat (SNatI) import Data.Vec.Lazy (Vec (..)) import qualified Data.Vec.Lazy as Vec import Data.Word (Word64) import GHC.Generics (Generic) Client.deriveHasRep ''Vec data TwoInput = TwoInput { twoA :: C Word64, twoB :: C Word64 } deriving (Generic) Client.deriveHasRep ''TwoInput type Two = 'S ('S 'Z) instance CGeneric TwoInput instance GArrays C TwoInput type instance TargetOb TwoInput = TargetOb (CG.Rep TwoInput ()) type instance TargetOb (Vec n a) = Vec n (TargetOb a) f :: TwoInput -> C Double f t = tkFirst $ fmap fromIntegral (twoA t ::: twoB t ::: VNil) where tkFirst :: Vec Two (C Double) -> C Double tkFirst (a ::: b ::: _) = a fCategorified :: TwoInput `C.Cat` C Double fCategorified = Categorify.expression f