let app invariant failure, HALP Re: how to write a ghc primop that acts on an unevaluated argument?

Carter Schonwald carter.schonwald at gmail.com
Thu Nov 27 18:25:58 UTC 2014


ok,
the attached "output" file was made  using the following command
./inplace/bin/ghc-stage2 T8256.hs   -O2 -dcore-lint  -fforce-recomp
-ddump-simpl  -dverbose-core2core -ddump-occur-anal -ddump-inlinings  >
output ^&1

i've also attached the test hs file i used

the primop definitions i used were :

primop PrefetchValueOp0 "prefetchValue0#" GenPrimOp
   a -> State# s -> State# s
   with strictness  = { \ _arity -> mkClosedStrictSig [botDmd, topDmd]
topRes }


primop PrefetchValueOp1 "prefetchValue1#" GenPrimOp
   a -> State# s -> State# s
   with strictness  = { \ _arity -> mkClosedStrictSig [botDmd, topDmd]
topRes }


primop PrefetchValueOp2 "prefetchValue2#" GenPrimOp
   a ->  State# s -> State# s
   with strictness  = { \ _arity -> mkClosedStrictSig [botDmd, topDmd]
topRes }


primop PrefetchValueOp3 "prefetchValue3#" GenPrimOp
   a -> State# s -> State# s
   with strictness  = { \ _arity -> mkClosedStrictSig [botDmd, topDmd]
topRes }



(the idea of those strictness attributes is that the operations should be
lazy in their value arg)

thanks!
-Carter


On Thu, Nov 27, 2014 at 12:03 PM, Simon Peyton Jones <simonpj at microsoft.com>
wrote:

>  are you quite sure you did –dverbose-core2core –ddump-occur-anal?   I
> see none of that output in the file.
>
>
>
> Regardless of  the flags you set for the primop, I’m surprised that the
> invariant is invalidated.  Should not happen.
>
>
>
> As well as the revised output, could you enclose a snippet of
> primops.txt.pp for prefetchValue1,2,3#
>
>
>
> S
>
>
>
> *From:* Carter Schonwald [mailto:carter.schonwald at gmail.com]
> *Sent:* 25 November 2014 06:47
> *To:* Simon Peyton Jones
> *Cc:* Edward Kmett; ghc-devs at haskell.org; Joachim Breitner
>
> *Subject:* Re: let app invariant failure, HALP Re: how to write a ghc
> primop that acts on an unevaluated argument?
>
>
>
> ok attached is the log of
>
> ./inplace/bin/ghc-stage2 codetester.hs  -O2 -dcore-lint  -fforce-recomp
> -ddump-simpl -ddump-to-file -dverbose-core2core -ddump-occur-anal
> -ddump-inlinings  > output ^&1
>
>
>
>
>
> the relevant snippet is bellow.
>
>
>
> It looks like the Float-Out transformation is what tripping it.
>
>
>
>
>
> That said, reading through what the semantics are implied by
> has_side_effects = True, the prefetch* family of operations ARE side
> effectful with respect the fact that they DO modify the CPU cache in a way
> that changes what memory locations are in various levels of CPU cache, so
> despite seeming read-like, they are modifying the state of the system, just
> in a way that is ONLY visible wrt the performance characteristics/runtime
>  of the resulting program.
>
>
>
> specifically, Duplication, Floating out, and Specultive evaluation all
> change *when* the prefetch runs and changes the CPU state, and Discard
> means this "mutation" of the CPU cache state would not happen.
>
>
>
> if prefetch was pure semantically (ie equiv to a -> ()  ) , they'd just be
> no op, they're exclusively a tool for performance engineering, and
> accordingly when and where they appear in code matters!
>
>
>
> i'm more than happy to write out a more detailed version of this
> explanation somewhere if you like.
>
>
>
> -Carter
>
>
>
> """"
>
>
>
> *** Core Linted result of Simplifier:
>
> *** Float out(FOS {Lam = Just 0, Consts = True, OverSatApps = True}):
>
> *** Core Linted result of Float out(FOS {Lam = Just 0, Consts = True,
> OverSatApps = True}):
>
> *** Core Lint errors : in result of Float out(FOS {Lam = Just 0,
>
>                                                    Consts = True,
>
>                                                    OverSatApps = True}) ***
>
> <no location info>: Warning:
>
>     In the expression: prefetchValue2#
>
>                          @ [Char]
>
>                          @ RealWorld
>
>                          lvl_s3Oi
>
>                          (prefetchValue1#
>
>                             @ Int
>
>                             @ RealWorld
>
>                             lvl_s3Oj
>
>                             (prefetchAddr3# @ RealWorld ds1_a3zg 0
> ds_a3zf))
>
>     This argument does not satisfy the let/app invariant:
>
>       prefetchValue1#
>
>         @ Int
>
>         @ RealWorld
>
>         lvl_s3Oj
>
>
>
>
>
> """
>
>
>
>
>
>
>
> On Mon, Nov 24, 2014 at 10:43 PM, Carter Schonwald <
> carter.schonwald at gmail.com> wrote:
>
>  huh, apparently i was mixing up '-' and some other similar dash
> character, time to let my rebuild of ghc go through then try gain :)
>
>
>
> On Mon, Nov 24, 2014 at 10:37 PM, Carter Schonwald <
> carter.schonwald at gmail.com> wrote:
>
>  when i run
>
> ./inplace/bin/ghc-stage2 codetester.hs  -O2 -dcore-lint -S  -fforce-recomp
> -ddump-simpl -ddump-to-file –dverbose-core2core –ddump-occur-anal
> –ddump-inlinings
>
> i get
>
> target ‘–dverbose-core2core’ is not a module name or a source file
>
>
>
> what am I doing wrong in this CLI invocation?
>
>
>
> On Mon, Nov 24, 2014 at 10:23 AM, Simon Peyton Jones <
> simonpj at microsoft.com> wrote:
>
>  Carter
>
>
>
> That smells wrong to me.  These flags have a very carefully defined
> meaning; see
>
>             Note [PrimOp can_fail and has_side_effects]
>
> in PrimOp.lhs
>
>
>
> If you say it has side effects when it doesn’t, you’ll confuse your
> successor reading the code in five years time.
>
>
>
> Better to find out what is going on and why.  Might you do that? What
> transformation invalidates the let/app invariant?  Make a small test case,
> use –dverbose-core2core –ddump-occur-anal –ddump-inlinings.  I would far
> rather that than install a land-mine in the code.
>
>
>
> Simon
>
>
>
> *From:* Carter Schonwald [mailto:carter.schonwald at gmail.com]
> *Sent:* 24 November 2014 00:54
> *To:* Edward Kmett
> *Cc:* ghc-devs at haskell.org; Simon Peyton Jones; Joachim Breitner
> *Subject:* Re: let app invariant failure, HALP Re: how to write a ghc
> primop that acts on an unevaluated argument?
>
>
>
> woot, solved it, at least in a way thats OK for now.
>
>
>
> if I mark the prefetchValue operations as has_side_effects=True, the core
> lint failure goes away! I'm not sure if thats the right semantics in the
> long term, but it does give me a simple way to make sure it works safely
> for 7.10
>
>
>
> pardon all the noise
>
> -Carter
>
>
>
> On Sun, Nov 23, 2014 at 4:26 PM, Carter Schonwald <
> carter.schonwald at gmail.com> wrote:
>
>  ok, i'm getting a let/app invariant failure when i build my test case
> with O1 or O2 but not without
>
>
>
> http://lpaste.net/114881
>
>
>
> any help would be appreciated on how to address that
>
>
>
> On Sun, Nov 23, 2014 at 4:13 PM, Carter Schonwald <
> carter.schonwald at gmail.com> wrote:
>
>  yup, i have that!
>
>
>
>     wrapFetch prefetchValue0# (error "this shouldn't get evaluated")
>
>
>
> in the test suite!
>
>
>
> in contrast
>
>     wrapFetch prefetchValue0# $! (error "this shouldn't get evaluated")
> does explode
>
>
>
> shall I add a "should fail" test with the latter? (it doesn't seem
> worthwhile)
>
>
>
> On Sun, Nov 23, 2014 at 3:53 PM, Edward Kmett <ekmett at gmail.com> wrote:
>
>  Maybe test for laziness in the argument by just putting something in
> that goes boom when forced, e.g. 'undefined'?
>
>
>
>
>
> On Sun, Nov 23, 2014 at 2:04 PM, Carter Schonwald <
> carter.schonwald at gmail.com> wrote:
>
>   Hey All,
>
> as part of trying to get some fixups for how prefetch works into 7.10,
>
> i'm adding a "prefetchValue" primop that prefetchs the memory location of
> a lifted heap value
>
>
>
> namely
>
>
>
> several operations of the following form
>
>
>
> primop PrefetchValueOp1 "prefetchValue1#" GenPrimOp
>
>    a -> State# s -> State# s
>
>    with strictness  = { \ _arity -> mkClosedStrictSig [botDmd, topDmd]
> topRes }
>
>
>
> I'd like some feedback on the strictness information design by someone
> who's familiar with how that piece of GHC. the idea being that
> prefetchValue is lazy in its polymorphic argument (it doesn't force it, it
> just does a prefetch on the heap location, which may or may not be
> evaluated).
>
>
>
> https://phabricator.haskell.org/D350
>
>
>
> is the code in question. And i *believe* i'm testing for being lazy in
> that argument correctly.
>
>
>
> thoughts?
>
>
>
> many thanks!
>
> -Carter
>
>
>
>
>
> _______________________________________________
> ghc-devs mailing list
> ghc-devs at haskell.org
> http://www.haskell.org/mailman/listinfo/ghc-devs
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/ghc-devs/attachments/20141127/ea4b9e8a/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: output
Type: application/octet-stream
Size: 279598 bytes
Desc: not available
URL: <http://www.haskell.org/pipermail/ghc-devs/attachments/20141127/ea4b9e8a/attachment-0002.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: T8256.hs
Type: application/octet-stream
Size: 953 bytes
Desc: not available
URL: <http://www.haskell.org/pipermail/ghc-devs/attachments/20141127/ea4b9e8a/attachment-0003.obj>


More information about the ghc-devs mailing list