seqaid 0.2.1.0 → 0.2.1.1
raw patch · 9 files changed
+246/−353 lines, 9 filesbinary-added
Files
- Seqaid/Config.hs +1/−1
- Seqaid/Demo.hs +108/−35
- Seqaid/Global.hs +1/−102
- Seqaid/Optim.hs +23/−191
- Seqaid/Prepro.hs +12/−0
- Seqaid/Runtime.hs +5/−0
- changelog.txt +12/−1
- dist/setup-config binary
- seqaid.cabal +84/−23
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