packages feed

seqaid 0.2.1.0 → 0.2.1.1

raw patch · 9 files changed

+246/−353 lines, 9 filesbinary-added

Files

Seqaid/Config.hs view
@@ -49,7 +49,7 @@ -- -- More documentation is pending, but for additional explanations -- about this particular example, please refer to--- <http://www.fremissant.net/seqaid/seqaid.html#using this document>.+-- <http://www.fremissant.net/seqaid#using this document>.    module Seqaid.Config where 
Seqaid/Demo.hs view
@@ -16,10 +16,22 @@ -- <http://hackage.haskell.org/package/deepseq-bounded deepseq-bounded> -- for more information about this methodology. +#ifdef mingw32_HOST_OS+#define USE_DOS 0+#else+#if IS_WINDOWS+#define USE_DOS 1+#else+#define USE_DOS 0+#endif+#endif+   module Main ( main ) where --module Seqaid.Demo ( main ) where    import System.Environment ( getArgs )+  import System.IO ( hGetContents, hClose )+  import Control.Exception ( evaluate )   import qualified System.IO.Temp as T   import qualified System.Directory as D   import System.Process@@ -29,61 +41,122 @@   import Data.Version   import Data.List ( intercalate ) -  leaky_version = (intercalate "." $ map show $ take 3 $ versionBranch version) ++ ".0"---leaky_version = "0.1.6.0"  -- XXX need a better way!!....+#if USE_DOS+  -- Not using the constraint, because requires performing regex+  -- on the output of a system command.  I'd like to provide the+  -- demo for non-mingw32 Windows users, but I have no means of+  -- testing that (or mingw32 for that matter).  Hopefully what's+  -- here works (presuming there's even such a thing as Haskell+  -- on Windows without mingw32).+  leaky_hard_version_windows+   = (intercalate "." $ map show $ take 3 $ versionBranch version) ++ ".0"+-- = "0.1.6.0"  -- XXX need a better way!!....+#else+  leaky_constraint+   = let vlo = take 3 $ versionBranch version+         vhi = take 2 vlo ++ [1 + last vlo]+     in    "'leaky >= "+        ++ (intercalate "." $ map show vlo)+        ++ " && < "+        ++ (intercalate "." $ map show vhi)+        ++ "'"+#endif    main :: IO ExitCode   main = do --          putStrLn $ leaky_version --          error "DEVEXIT"             args <- getArgs+             if args /= ["demo"]             then do               putStrLn "seqaid: \"seqaid demo\" is the only supported invocation at this time."               return $ ExitFailure 1             else do+               tdir <- T.createTempDirectory "." "leaky_"--- XXX Note that "cabal get" already extracts the tarball for you.--- XXX Note mingw32 still uses bash.-              let dos_str = concat-                   [ "@echo off\n"-                   , "cabal get leaky-" ++ leaky_version ++ "\n"-                   , "cd leaky-" ++ leaky_version ++ "\n"-                   , "cabal configure\n"-                   , "cabal build\n"-                   , "cabal run 234\n"-                   , "echo.\n"-                   , "echo \"(Please see " ++ tdir ++ "/leaky-" ++ leaky_version ++ "/README for the interpretation.)\"\n"-                   , "echo.\n"-                   ]+              D.setCurrentDirectory tdir -              let nix_str = concat-                   [ "#!/bin/bash\nset -e\n" ++ ""-                   , "cabal get leaky-" ++ leaky_version ++ "\n"-                   , "cd leaky-" ++ leaky_version ++ "\n"-                   , "cabal configure\n"-                   , "cabal build\n"-                   , "cabal run 234\n"-                   , "echo\n"-                   , "echo \"(Please see " ++ tdir ++ "/leaky-" ++ leaky_version ++ "/README for the interpretation.)\"\n"-                   , "echo\n"+#if ! USE_DOS++              -- Find the most recent available version of package leaky+              -- which satisfies the constraint computed above.  (We use+              -- cabal-install to do this for us.)+              let command_to_resolve_constraint_for_get+                   =    "#!/bin/bash\nset -e\n"+                     ++ "cabal install leaky --dry-run --constraint="+                     ++ leaky_constraint+                     ++ " | tail -1"+--                   ++ " | grep -e '^leaky-'"+                     ++ " | sed -e 's/\\([^ ][^ ]*\\)\\($|..*\\)/\\1/'"+                     ++ "\n"  -- so file ends with EOL (good practice)++              writeFile "seqaidresolveleaky.sh" command_to_resolve_constraint_for_get+              p <- D.getPermissions "seqaidresolveleaky.sh"+              D.setPermissions+                 "seqaidresolveleaky.sh" p { D.executable = True }+              -- not sure how to handle exit status this way+              (_, Just hout, _, _)+                <- createProcess (proc "seqaidresolveleaky.sh" [])+                                   { std_out = CreatePipe }+              resolved <- hGetContents hout+              evaluate $ length resolved  -- force reading of whole file!+              hClose hout++#endif++#if USE_DOS++-- XXX Note that "cabal get" already extracts the tarball for you.+-- XXX Note mingw32 uses bash (not DOS/CMD).+              let dos_str = intercalate "\n"+                   [ "@echo off"+                   , "cabal get leaky-" ++ leaky_hard_version_windows+                   , "cd leaky-" ++ leaky_hard_version_windows+                   , "cabal configure"+                   , "cabal build"+                   , "cabal run 234"+                   , "echo."+                   , "echo \"(Please see " ++ tdir ++ "/leaky-" ++ leaky_hard_version_windows ++ "/README for the interpretation.)\""+                   , "echo."+                   , ""  -- so file ends with EOL (good practice)                    ] -#ifdef mingw32_HOST_OS-              let seqaid_init_bash = nix_str #else-#if IS_WINDOWS-              let seqaid_init_bash = dos_str++              let nix_str = intercalate "\n"+                   [ "#!/bin/bash\nset -e"+#if 1+                   , "cabal get " ++ resolved+                   , "cd " ++ resolved #else-              let seqaid_init_bash = nix_str+                   , "cabal get leaky --constraint \"" ++ leaky_constraint ++ "\""  -- sadly not+                   , "cd leaky-*" #endif+                   , "cabal configure"+                   , "cabal build"+                   , "cabal run 234"+                   , "echo"+                   , "echo \"(Please see " ++ tdir ++ "/" ++ resolved ++ "/README for the interpretation.)\""+--                 , "echo \"(Please see " ++ tdir ++ "/*" ++ "/README for the interpretation.)\""+                   , "echo"+                   , ""  -- so file ends with EOL (good practice)+                   ]+ #endif -              D.setCurrentDirectory tdir-              writeFile "seqaidinit.sh" seqaid_init_bash-              p <- D.getPermissions "seqaidinit.sh"-              D.setPermissions "seqaidinit.sh" (p { D.executable = True })-              st <- system "./seqaidinit.sh"+#if USE_DOS+              let seqaid_init_script_contents = dos_str+              let seqaid_init_script_name = "seqaidinit.bat"+#else+              let seqaid_init_script_contents = nix_str+              let seqaid_init_script_name = "seqaidinit.sh"+#endif++              writeFile seqaid_init_script_name seqaid_init_script_contents+              p <- D.getPermissions seqaid_init_script_name+              D.setPermissions seqaid_init_script_name p { D.executable = True }+              st <- system $ "./" ++ seqaid_init_script_name               case st of                 ExitSuccess -> return ExitSuccess                 ExitFailure n -> do
Seqaid/Global.hs view
@@ -8,21 +8,6 @@    {-# LANGUAGE CPP #-} --- Later: This (now) has no effect when new grammar is in effect.--- This is temporary, so seqaid demo output remains compatible--- with the documentation already written around it.  (The new--- shrinkPat has more finesse, but you have to run the demo--- longer to see the heap stabilise -- the demonstration is--- not nearly as effective.  Also, the patterns have a lot--- of #'s in them which looks noisy and confusing, although--- it's natural enough.)  We could attempt vertical alignment--- since flanking whitespace is now supported, and that would--- do more than anything to improve the presentation...--- However, with DEMO_MODE off, one would definitely prefer--- the new shrinkPat.  This comment will probably be--- as writ on water...-#define USE_OLD_SHRINK_PAT 0- -- XXX Should scour the code for "max_depth" etc. -- all those -- names which are specific to this DEMO_MODE hack!... And get -- them into CPP guards. And get something sane in the OTHER@@ -41,7 +26,7 @@ -- -- Maintainer  :  Andrew Seniuk <rasfar@gmail.com> -- Stability   :  provisional--- Portability :  GHC+-- Portability :  GHC (uses global IORefs) -- -- Collects 'IORef's used by the seqaid runtime. --@@ -206,102 +191,16 @@   fixed_pat_sequence    = let shrink_pat           | deepseq_bounded_flag__new_improved_pattern_grammar  = shrinkPat-#if USE_OLD_SHRINK_PAT-          | otherwise  = shrinkPat_old-#else           | otherwise  = shrinkPat-#endif      in    ( map (\i -> compilePat ('*':show i)) [0,1..8] )         ++ ( reverse $ condenseEq shrink_pat fixed_pat ) --- [Debugging notes for recent changes to deepseq-bounded.]--- leaky: DeepSeqBounded_PingException "NFDataP: PING: 0 Int\n()\n"--- leaky: DeepSeqBounded_PingException "NFDataP: PING: 1 Int\n()\n"--- leaky: DeepSeqBounded_PingException "NFDataP: PING: 3 Int\n()\n"--- leaky: DeepSeqBounded_PingException "NFDataP: PING: 7 Int\n()\n"--- leaky: DeepSeqBounded_PingException "NFDataP: PING: 12 Int\n()\n"--- leaky: DeepSeqBounded_PingException "NFDataP: PING: 13 Int\n()\n"--- leaky: DeepSeqBounded_PingException "NFDataP: PING: 14 Int\n()\n"--- This is what we see. If wait (only see 0 repeating for a while).--- (And the system grinds to a crawl, although it appears to be--- a stable crawl.)--------- See cotemp (20150111130916) 000-readme for the labelling of the tree...--- This mystery is largely solved. As for "slowdown" well, it's no--- wonder if we're trying to print something for every one of the--- gizillion exceptions, but if it was a quick stats update or something,--- might actually be fine at full speed...--- Speaking of "speed", a threadDelay-type attribute would be useful...--- Too useful not to do it! (Except that threadDelay is known to be--- a bit flakey...). (But you gotta try...)-#if 1   fixed_pat    | deepseq_bounded_flag__new_improved_pattern_grammar       = setPatternPatNodeUniqueIDs 0 $---        compilePat "=>cab((!(!)(((^!).!(!))))!(^!(!)))"---        compilePat "=>cab((!(!)(((+!).!(!))))!(+!(!)))"---        compilePat "((!(!)(((+^/!).!(!))))!(!(!)))"---        compilePat "((!(!)(((+^!).!(!))))!(!(!)))"---        compilePat "+^(+^(+^!+^(+^/!)+^/(+^/(+^/(+^/!)+^/.+^/!+^/(+^/!))))+^/!+^/(+^/!+^/(+^/!)))"---        compilePat "+^/(+^/(+^/!+^/(+^/!)+^/(+^/(+^/(+^/!)+^/.+^/!+^/(+^/!))))+^/!+^/(+^/!+^/(+^/!)))"---        compilePat "+^(+^(+^!+^(+^!)+^(+^(+^(+^!)+^.+^!+^(+^!))))+^!+^(+^!+^(+^!)))"---        compilePat "((!(!)+(+(+(+!).!(!))))!(!(!)))"  -- yes, it works (if you wait a wee bit) -- trying the full-blanket-+'d one again!!!---        compilePat "((!(!)(((+!).!(!))))!+(!(!)))"  -- ---        compilePat "((!(!)((+(+!).!(!))))!(!(!)))"  -- ACTUALLY WORKS -- at FIRST you see only TC, then after the next stats line you see "4 TC / 3 Int" (or maybe the other way around, but I think this is the order...)---        compilePat "((!(!)(((+!).!(!))))!(!(!)))"  -- still works--- XXX Oh, I see what happened: I made !(!) -> . at some point,--- as part of testing, and this got propagated and forgotten,--- and changed back . -> ! (instead of !(!)) -- but this is--- harmless actually?!!!---        compilePat "((!(!)(((+^!)+^/.!(!))))!(!(!)))"---        compilePat "((!+^/.(((!)+^/.!(!))))!(!(!)))"  -- nothing.---        compilePat "+(+(+!+(+!)+(+(+(+!).!(!))))!(!(!)))"   -- XXX XXX---        compilePat "(+(!+.(+((!)+.!(!))))!(!(!)))"-----      compilePat "((!(!)((+.(!)+.+!(!))))!(!(!)))"------     compilePat "+(+(+!+!+(+(+(+!).!(!))))!(!(!)))"      -- XXX XXX---        compilePat "+(+(+!+(+!)+(+(+(+!).!(!))))!(!(!)))"   -- XXX XXX---        compilePat "((+!^(!)(+((!).+^!/^(+^!))))!(!(!)))"  -- yep---        compilePat "((+!^(!)(+((!).+^!^(+^!))))!(!(!)))"  -- all working- --       compilePat "((!(+^/.)(((!)+^/.!+^/.)))!(!(!)))"  -- nothing---        compilePat "((!(/.)(((!)/.!/.)))!(!(!)))"  -- nothing----       compilePat "((!/.(((!)/.!(!))))!(!(!)))"  -- nope, neither calls handleAttrs (incididentally, this leaks noticeably and monotonically, while the one with just . on the Blob, if not technically leak-free [? it seems to accumulate heap and then periodically discharge it, notwithstanding our frequent performGC calls...], at least not exhibiting net growth over longrunning...)  This is a better test at the moment as the first . is of simple base nullary type Int.---        compilePat "((!(!)(((!)/.!(!))))!(!(!)))"  -- the problem with this test is that the .'d node is of unusual type Blob, which has hack NFData instances etc...----       compilePat "((!+.(((!)+.+!(!))))+!(!(+!)))"----       compilePat "((+!+.((+(+!)+.!(!))))+!(!(+!)))"----       compilePat "((!+.(((!)+.!(!))))!(!(!)))"----       compilePat "((!.(((!)+.!(!))))!(!(!)))"----       compilePat "((!.(((!)+.!(!))))!(!(!)))"---        compilePat "((!(!)(((!)+.!(!))))!(!(!)))"---        compilePat "+(+(+!+(+!)+(+(+(+!)+.+!+(+!))))+!+(+!+(+!)))"  -- this is working now for generic nodes, but NOT for any of the others; so we see it for exactly the OTHER 9 nodes not among the 8 listed below! ch!... [later: fixed GNFDataP]---        compilePat "^(^(^!^(^!)^(^(^(^!)^.^!^(^!))))^!^(^!^(^!)))"  -- AMAZINGLY WORKS!!! See IDs 0 1 3 7 12 13 14---        compilePat "((!(!)(((^!).!(!))))!(!(!)))"  -- works---        compilePat "((!(!)(((!).^!(!))))!(!(!)))"  -- NO WORKY: FREEZES (same)-#if 0--- (Reproducible serious bug!)---        compilePat "((!(!)(((!).+!(!))))!(!(!)))"  -- NO WORKY: FREEZES-                                                     -- AFTER "trc msg.":----  P  (( ()((() + ()))) ( ()))              duty       918272    8720160  TA----  P  ((!(!)(((!) +!(!))))!(!(!)))          duty      1660356    2185992  TA----  P  ((!(!)(((!) +!(!))))!(!(!)))          duty      2348988    2244528  TA----  P  ((!(!)(((!) +!(!))))!(!(!)))          duty      3037620    2240528  TA----  P  ((!(!)(((!) +!(!))))!(!(!)))          duty      3693484    2207760  TA---- trc msg.---- ^C-#endif---        compilePat "((!(!)(((!)+.!(!))))!(!(!)))"  -- NO WORKY---        compilePat "((!(!)(((+!).!(+!))))!(!(!)))"  -- works! "(TRACE: 3 Int) (TRACE: 7 Int)" repeating---        compilePat "((!(!)(((!).!(+!))))!(!(!)))"  -- works! "(TRACE: 7 Int)"---        compilePat "((!(!)(((!)+^/.!(!))))!(!(!)))"  -- no worky!---        compilePat "(+^/(!(!)(((!).!(!))))!(!(!)))"  -- no worky---        compilePat "(+(!(!)(((!).!(!))))!(!(!)))"  -- no worky---        compilePat "(+(!(!)(((+!).!(!))))!(!(!)))"---        compilePat "((!(!)(((+!).!(!))))!(!(!)))"  -- works! "(TRACE: 3 Int)"           compilePat "((!(!)(((!).!(!))))!(!(!)))"    | otherwise       = compilePat ".{.{..{.}.{.{.{.}#..{.}}}}..{..{.}}}"-#else-  fixed_pat = compilePat ".{.{..{.}.{.{.{.}#..{.}}}}..{..{.}}}"-#endif  ------------------------------------------------------------------------------- 
Seqaid/Optim.hs view
@@ -1,69 +1,6 @@  ------------------------------------------------------------------------------- --- Plans------ Try to make the optimiser pure.------ For simplicity, let's assume a steady-state program; this will--- still be useful with minimal change if need to respond adaptively...------ If you can afford the sum-of-products weighting coefficients,--- you can get pretty flexible objective functions out of the--- three main quantities of interest (that I can think of):------   (1) Time.---       The amount of time elapsed since last checkpoint---       should preferably not increase.------   (2) Heap size.---       The size of the live heap since last checkpoint---       should preferably not increase.------   (3) Bytes allocated (this frame).---       The amount of GC activity since last checkpoint---       should preferably not increase.------ Any of these, taken individually (i.e. extremes of the l.c.)--- would be interesting and useful, but it seems reasonable--- to expect a non-trivial blend of two, or all, to be--- most "meta-performant" (best convergence rates).  Or who knows!------ Need to experiment.------ I don't yet have code in place measuring (1); only (2) and (3).------------------------------------------------------------------------------------- The specific strategy for this next round at least:--- Two-phase optimisation:------   (1) N-phase : sweep forcen n=0,1,... until either:---        - gets too costly in Time [once can measure that...]; or---        - achieve dramatic improvement in objective function (at n' say)------   (2) P-phase : begin with mkPatN n'---        - forcep . (mkPatN n) = forcen n---       Then call erodePat (with weighting of choice).---       keep doing this, accepting steps only if performance---       improves (rel. to your objective criterion).  Eventually---       no improvement will be made for a long time -- this is---       taken as an "approximation to global optimum", and a---       fresh pass through the P-phase can be used to try---       additional stochastic trials.------ Also, in principle, you might be better to start mkPatN at--- an n' higher than the very lowest which plugged leak.--- This seems a bit unlikely, but I don't know why not...--- That you might arrive at a better global optimum--- if you allow some "surplus forcing" at one or more points.------ These are the nagging questions that I'm not sure about,--- and expect to learn more as begin testing and seqaid on--- a corpus of programs.----------------------------------------------------------------------------------   {-  OPTIONS_GHC -O2 #-}    {-# LANGUAGE CPP #-}@@ -100,11 +37,6 @@      optimIO , -    optim ,--    optim_N_phase ,-    optim_P_phase ,-   ) where  -------------------------------------------------------------------------------@@ -132,6 +64,10 @@  --import Debug.Trace ( trace ) +#if SAI_FORK+  import Seqaid.Optim_sai+#endif+ -------------------------------------------------------------------------------    import Seqaid.Global ( depth_ioref                  )@@ -182,132 +118,21 @@   -- which also takes care of the IORef stuff...  ---------------------------------------------------------------------------------  -- XXX Why is depth global, but patterns is per-site?...-  ------  -- This needs to read the (most recently cached) GHC.Stats data.-  -- If N-phase, needs to affect the depth_ioref.-  -- If P-phase, needs to affect the patterns_ioref.-  -- It could actually have type IO (), but might like to-  -- return some pertinent information as well.-  optimIO :: IO ()---optimIO :: IO (Int,Int,Pattern,SeqNode,Int64,Int64,Int64,Int64,Int64)-  optimIO = do---- XXX Based on a clone of run_IO_SM.--#if 0--    stats_query_idx <- do-                        sqi <- readIORef stats_query_idx_ioref-                        return sqi-    depth <- do-              d <- readIORef depth_ioref-              return d-#if 0--- XXX a code fragment expected to be useful (see seqaidDispatch where clause)-    tmp = stats_query_idx-(2+max_depth)-    pat' | tmp < length fixed_pat_sequence-            = fixed_pat_sequence!!tmp-         | otherwise-            = last fixed_pat_sequence-#endif-#if NFDATAN_ONLY-#error "NFDATAN_ONLY is not valid at this time."-#else-#if 1-    pat <- do-#if 1 || DEMO_MODE-            let tmp = stats_query_idx---          let tmp = stats_query_idx-(2+max_depth)-            let p | tmp < length fixed_pat_sequence-                     = fixed_pat_sequence!!tmp-                  | otherwise-                     = last fixed_pat_sequence-#if 0-            H.insert ht sid_hash p-#endif-            return p-#else-            ht <- readIORef patterns_ioref-            let sid_hash = thd3 sid-            mp <- H.lookup ht sid_hash-            if isNothing mp-            then do-              let p = compilePat "#"-              H.insert ht sid_hash p-              return p-            else do-              return $ fromJust mp-#endif-#else--- XXX wrong and never tested, obviously-    pat = patterns_ioref!(fst3 sid)-#endif-#endif--#endif--    i <- do-          ii <- readIORef counter_ioref-          modifyIORef' counter_ioref (1+)-          return ii-    ba <- readIORef bytes_allocated_ioref-    cbu <- readIORef current_bytes_used_ioref--#if 0--#if 0-    if stats_query_idx >= max_depth && i >= t-    then do-      let j = stats_query_idx - max_depth-      writeIORef pattern_ioref (fixed_pat_sequence!!j)-      return ()-    else return ()-#endif-    if depth <= max_depth && i >= t-    then do-#if 1-      modifyIORef' depth_ioref (1+)-#else--- XXX need Data instances...---    writeIORef pattern_ioref (mkPatN depth x)-#endif-      return ()-    else return ()--#endif----- !_ <- return x  -- magic! thank you!!----  return (stats_query_idx,depth,pat,snk,i,t,size,cbu,t')-    return ()-----------------------------------------------------------------------------------  optim :: ()-  optim = ()-----------------------------------------------------------------------------------  optim_N_phase :: ()-  optim_N_phase = ()-----------------------------------------------------------------------------------  optim_P_phase :: ()-  optim_P_phase = ()----------------------------------------------------------------------------------+  -- | This is for internal use only.+  --+  -- /The seemingly redundant superclass constraints are necessary/+  -- /due to some weirdness in the TH or Core code (I forget the/+  -- /details); should try to get rid of them in case it's/+  -- /since become possible.../+{--}   -- Okay!   -- Now it is time to use the hash values-+{--}   -- XXX This is simply the collected unsafePerformIO calls   -- that were initially scattered throughout seqaidDispatch.   -- It happened to behave the same as that did, without change;   -- but a once-over reorganising the logic slightly would be good...-+{--}   -- is this pragma necessary? does it even make sense with IO?...   {-# NOINLINE run_IO_SM #-} #if SEQABLE_ONLY@@ -344,11 +169,11 @@ #endif  #if SEQABLE_ONLY-    let pat = compilePat "#"  -- just whatever+    let pat = emptyPat #else #if NFDATAN_ONLY --- #error "NFDATA_ONLY is not valid at this time."-    let pat = compilePat "#"  -- just whatever+    let pat = emptyPat #else     pat <- do #if 1 || DEMO_MODE@@ -370,7 +195,7 @@             mp <- H.lookup ht sid_hash             if isNothing mp             then do-              let p = compilePat "#"+              let p = emptyPat               H.insert ht sid_hash p               return p             else do@@ -448,6 +273,13 @@      return (stats_query_idx,depth,pat,snk,i,t,size,cbu,t') --  return ()++-------------------------------------------------------------------------------++#if ! SAI_FORK+  optimIO :: IO ()+  optimIO = return ()+#endif  ------------------------------------------------------------------------------- 
Seqaid/Prepro.hs view
@@ -26,6 +26,12 @@ -- Portability :  GHC -- -- Seqaid preprocessor, run via GHC -F.+-- In order to use seqaid there is some configuration required,+-- both in your project .cabal file, and in a seqaid.config file.+-- Refer to the project+-- <http://www.fremissant.net/seqaid#using homepage>+-- (also distributed locally in the HTML directory of the seqaid package)+-- for more details.    module Main where --module Seqaid.Prepro where@@ -378,6 +384,8 @@          -- (3) Inject the Seqaid.TH import statement:         -- Later: And also some type imports (for omnitypic wrapper injection).+-- XXX Later: Why is this #if 1 here??... If figure out that it should+-- be here, please leave a comment as to why! #if 1         let go2 s = indent ++ "import Seqaid.TH\n" ++ omni_imports ++ s #else@@ -575,7 +583,11 @@           [ ghcopts'           , "--make "           , "-c "+#if USE_CPPHS           , "-pgmPcpphs -optP--cpp"+#else+--        , "-cpp"  -- (see comments in the seqaid.cabal file)+#endif           , "" ++ nowneeded           , "-fplugin-opt=Seqaid.Plugin:prepro=" ++ modname           , "-fplugin-opt=Seqaid.Plugin:" ++ omni_types_pname
Seqaid/Runtime.hs view
@@ -21,6 +21,11 @@ -- Portability :  GHC (unsafePerformIO) -- -- This module is for seqaid internal use.+--+-- /The seemingly redundant superclass constraints are necessary/+-- /due to some weirdness in the TH or Core code (I forget the/+-- /details); should try to get rid of them in case it's/+-- /since become possible.../    module Seqaid.Runtime ( 
changelog.txt view
@@ -1,9 +1,20 @@ +0.2.1.0 -> 0.2.1.1+ - added a non-manual USE_CPPHS flag to seqaid.cabal, which should+   in principle allow the client build system to try cpphs first, and+   if that build fails, then try again with a native cpp if there's+   one in the path (which is usually the case)+    - this auto-toggle works for me with GHC 7.8.4 and Cabal 1.22.0.0+    - what is the oldest version of cabal-install that this+      auto-toggling will happen in?...+ - improvements in platform-dependent handling in Demo.hs+ - and also in choice of leaky version in Demo.hs+ 0.2.0.0 -> 0.2.1.0  - realised I should be using Manual: True in all my .cabal flags,    or else the constraint solver is free to toggle them!! -0.1.7.0 -> 0.2.0.0+** 0.1.7.0 -> 0.2.0.0  - deepseq-bounded had a major version bump  - fixed cpphs missing dependency (Seqaid lib, and seqaid and seqaidpp exe's)  - more...
+ dist/setup-config view

binary file changed (absent → 229686 bytes)

seqaid.cabal view
@@ -2,7 +2,7 @@ -------------------------------------------------------------------------------  name:                seqaid-version:             0.2.1.0+version:             0.2.1.1 synopsis:            Dynamic strictness control, including space leak repair license:             BSD3 license-file:        LICENSE@@ -12,9 +12,10 @@ bug-reports:         http://fremissant.net/seqaid/trac ---bug-reports:         Andrew Seniuk <rasfar@gmail.com> category:            Compiler Plugin+--hackage-tags:        parallel, leak, space, strictness, forcing, diagnostic, remedial, auto-instrumentation, instrumentation, tools, bsd3, ghc-plugin, program, library build-type:          Simple stability:           provisional, nascent-cabal-version:       >= 1.16+cabal-version:       >= 1.18  -- NOTE: Version of GHC /must/ be >= 7.8, due to need to use TH >= 2.9. -- Could possibly relax to TH >= 2.8 (which would include GHC 7.6.*),@@ -24,7 +25,7 @@ --tested-with:         GHC==7.8.*, GHC==7.10.1  -- illegal syntax (Cabal 1.20) --tested-with:         GHC==7.6.3, GHC==7.8.1, GHC==7.8.3, GHC==7.8.4 -description:         Seqaid is a GHC plugin for non-invasive auto-instrumentation of dynamic strictness (and parallelism) control, shortly to include optimisation for automated space leak relief using minimal strictification. [The optimiser is still in development however.]+description:         Seqaid is a GHC plugin providing non-invasive auto-instrumentation of Haskell projects, for dynamic strictness (and parallelism) control. This will soon include optimisation for automated space leak relief using minimal strictification. [The optimiser is still in development however.]                      .                      Refer to the seqaid <http://www.fremissant.net/seqaid homepage> for more information.                      .@@ -62,6 +63,12 @@   Default: False   Manual: True +Flag SAI_FORK+  Description: .+--Default: True+  Default: False+  Manual: True+ Flag TRY_INJECT_NOINLINE_ON_REQUESTED_BINDS   Description: If we can prevent inlining of injected binds (without requiring user edits), that would probably be a good trade-off in terms of lost optimiser opportunities in exchange for assurance that the bind won't be inlined. This didn't work, and is a poor solution anyway. --Default: True@@ -132,6 +139,15 @@ --Default: False   Manual: True +-- This does indeed work for me (it is auto-toggled when cpphs is unavailable).+-- Default to False, since it seems more likely there's a native cpp, than+-- that a cpphs installation works smoothly.+Flag USE_CPPHS+  Description: Non-manual flag to allow the build system to try cpphs first, and if that fails, then to try system-wide cpp (typically GNU). I've actually toggled the default, so the build system will try for a system-wide cpp first, and failing that, will try to use cpphs, installing it if necessary. I prefer cpp. I am not getting my most invaluable -Wundef option with cpphs using -optP-Wundef -optP--cpp in my ghc-options. Does cpphs implement it? Not sure...+  Default: False+--Default: True+  Manual: False+ -------------------------------------------------------------------------------  library {@@ -154,6 +170,8 @@     , Seqaid.TH_710     , Seqaid.TH_extra_710 +  other-modules:+   -- These are the dependencies of modulespection which, at this   -- time (20150106), are not (otherwise) also dependencies of seqaid.   -- Later: Really? I thought temporary was... (Oh! only of seqaid exe.)@@ -174,8 +192,14 @@    build-depends:       base == 4.*-    , cpphs >= 1.14 +  -- We don't really depend on the cpphs /library/, but installing+  -- the library also installs the cpphs executable, so in case+  -- build-tools doesn't nab it, this ought to!+  if flag(USE_CPPHS)+     build-depends:+         cpphs >= 1.14+   if flag(GHC_710)      build-depends:          ghc == 7.10.*@@ -258,7 +282,6 @@ --  , deepseq == 1.3.0.2    ghc-options: -optP-Wundef -fno-warn-overlapping-patterns-  ghc-options: -pgmPcpphs -optP--cpp   ghc-options:                  -funbox-strict-fields -fwarn-tabs --ghc-options:        -Wall -O2 -funbox-strict-fields -fwarn-tabs @@ -275,9 +298,27 @@   -- http://stackoverflow.com/questions/2549167/cpp-extension-and-multiline-literals-in-haskell   -- I prefer string gaps to unlines [ l1, l2, ... ] b/c then lines   -- can start at the left margin!---ghc-options:        -pgmP cpphs -optP--cpp---ghc-options: -cpp+  if flag(USE_CPPHS)+     -- Which is most portable, a space after the P or not???+     -- See the comment on the other branch of this Cabal "condition".+     ghc-options: -pgmPcpphs -optP--cpp+--else+--   -- This is no longer needed, but SINCE WHEN?? i.e. for+--   -- which versions of GHC (and perhaps cabal-install)?...+--   -- Without a reasonable means to answer this question+--   -- (short of tracking down and scouring changelogs+--   -- in reverse chronological order), the conscientious+--   -- programmer has no recourse but to try to cover+--   -- all the bases.+--   --   But since recent cabal-install screams loudly about it,+--   -- better comment it out.+--   ghc-options: -cpp +  if flag(SAI_FORK)+     cpp-options: -DSAI_FORK=1+  else+     cpp-options: -DSAI_FORK=0+   if flag(SEQABLE_ONLY)      cpp-options: -DSEQABLE_ONLY=1   else@@ -335,14 +376,13 @@    default-extensions: CPP   default-language:   Haskell2010+ }  ------------------------------------------------------------------------------- --- XXX Note that the flags in library section are NOT present here.--- (Which is fine so long as the executable's code doesn't try to use them;--- and will get a warning anyhow if it does.) executable seqaid {+ -- It seems you cannot put the seqaid Main module in Seqaid.Main namespace?   hs-source-dirs:     .   main-is:            Seqaid/Demo.hs@@ -351,19 +391,28 @@    build-depends:       base == 4.*-    , cpphs >= 1.14     , temporary == 1.2.*     , directory == 1.2.* -- Finally needed to drop to 1.* for testing GHC 7.6.3!     , process == 1.* --  , process == 1.2.*++  -- We don't really depend on the cpphs /library/, but installing+  -- the library also installs the cpphs executable, so in case+  -- build-tools doesn't nab it, this ought to!+  if flag(USE_CPPHS)+     build-depends:+         cpphs >= 1.14+   ghc-options:                  -funbox-strict-fields -fwarn-tabs -threaded --ghc-options:        -Wall -O2 -funbox-strict-fields -fwarn-tabs -threaded    ghc-options: -optP-Wundef -fno-warn-overlapping-patterns   -- [See comments in the library part above.]-  ghc-options: -pgmP cpphs -optP--cpp---ghc-options: -cpp+  if flag(USE_CPPHS)+     ghc-options: -pgmPcpphs -optP--cpp+--else+--   ghc-options: -cpp  -- Test #ifdef mingw32_HOST_OS instead! (it's built-in to GHC) ------@@ -372,26 +421,24 @@ -- to that by executing a Cmnd batch script. -- -- And, if it /is/ MinGW, then it's the same bash script as run on *nix...-if os(windows)-   cpp-options: -DIS_WINDOWS=1-else-   cpp-options: -DIS_WINDOWS=0+  if os(windows)+     cpp-options: -DIS_WINDOWS=1+  else+     cpp-options: -DIS_WINDOWS=0    default-extensions: CPP   default-language:   Haskell2010+ }  ------------------------------------------------------------------------------- --- XXX Note that the flags in library section are NOT present here.--- (Which is fine so long as the executable's code doesn't try to use them;--- and will get a warning anyhow if it does.) executable seqaidpp {+   hs-source-dirs:     .   main-is:            Seqaid/Prepro.hs   build-depends:       base == 4.*-    , cpphs >= 1.14     , regex-base <= 0.93.2     , regex-pcre <= 0.94.4 -- (process may still be uncommented b/c using to debug...)@@ -404,10 +451,24 @@     , Cabal >= 1.10 --  , Cabal >= 1.18 +  -- We don't really depend on the cpphs /library/, but installing+  -- the library also installs the cpphs executable, so in case+  -- build-tools doesn't nab it, this ought to!+  if flag(USE_CPPHS)+     build-depends:+         cpphs >= 1.14+   ghc-options: -optP-Wundef -fno-warn-overlapping-patterns   -- [See comments in the library part above.]-  ghc-options: -pgmP cpphs -optP--cpp---ghc-options: -cpp+  if flag(USE_CPPHS)+     ghc-options: -pgmPcpphs -optP--cpp+--else+--   ghc-options: -cpp++  if flag(USE_CPPHS)+     cpp-options: -DUSE_CPPHS=1+  else+     cpp-options: -DUSE_CPPHS=0    if flag(TRY_INJECT_NOINLINE_ON_REQUESTED_BINDS)      cpp-options: -DTRY_INJECT_NOINLINE_ON_REQUESTED_BINDS=1