Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@JasonGross
Copy link
Member

With the help of Paul Steckler (and @aspiwack and others at the Coq Coding Sprint), @tebbi's LtacProf now works with Coq 8.5. The append_end_library_hook should possibly be done differently, but I'm not sure how it should be done. I think this is reasonable to merge into 8.5 because it shouldn't change the behavior of any existing scripts or code, and the features it adds are used primarily for debugging, and shouldn't show up in production code (so code that works with this patch shouldn't stop working in older versions). And having a profiler for Ltac is really, really useful.

I can squash these commits and/or remove the trailing-spaces-stripping if desired.

(Paul is currently working on porting this to trunk.)

Patch by Paul A. Steckler

Example of the bug:
```
$ cat foo.v
Fixpoint fact n := match n with 0 => 1 | S n' => n * fact n' end.

Ltac a := idtac; let x := fresh in set (x := fact 7).

Definition foo := Eval compute in fact 7.
Goal fact 7 * 10 = foo * 10.
Proof.
  unfold foo.
  Start Profiling.
  Time a.
  Show Profile.
  Time a.
  Show Profile.
  Time a.
  Show Profile.
  Time a.
  Show Profile.
Abort.

In 8.4pl6 + ltacprof:
$ coqc foo.v
Finished transaction in 0. secs (0.144u,0.s)

total time:      0.144s

 tactic                                    self  total   calls       max
────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
─set (x := fact 7) --------------------- 100.0% 100.0%       1    0.144s
─a -------------------------------------   0.0% 100.0%       1    0.144s

 tactic                                    self  total   calls       max
────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
─a -------------------------------------   0.0% 100.0%       1    0.144s
└set (x := fact 7) --------------------- 100.0% 100.0%       1    0.144s
Finished transaction in 0. secs (0.128u,0.s)

total time:      0.272s

 tactic                                    self  total   calls       max
────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
─set (x := fact 7) --------------------- 100.0% 100.0%       2    0.144s
─a -------------------------------------   0.0% 100.0%       2    0.144s

 tactic                                    self  total   calls       max
────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
─a -------------------------------------   0.0% 100.0%       2    0.144s
└set (x := fact 7) --------------------- 100.0% 100.0%       2    0.144s
Finished transaction in 0. secs (0.132u,0.s)

total time:      0.404s

 tactic                                    self  total   calls       max
────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
─set (x := fact 7) --------------------- 100.0% 100.0%       3    0.144s
─a -------------------------------------   0.0% 100.0%       3    0.144s

 tactic                                    self  total   calls       max
────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
─a -------------------------------------   0.0% 100.0%       3    0.144s
└set (x := fact 7) --------------------- 100.0% 100.0%       3    0.144s
Finished transaction in 0. secs (0.128u,0.s)

total time:      0.532s

 tactic                                    self  total   calls       max
────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
─set (x := fact 7) --------------------- 100.0% 100.0%       4    0.144s
─a -------------------------------------   0.0% 100.0%       4    0.144s

 tactic                                    self  total   calls       max
────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
─a -------------------------------------   0.0% 100.0%       4    0.144s
└set (x := fact 7) --------------------- 100.0% 100.0%       4    0.144s

In v8.5+ltacprof (note: I've just rebased against upstreams v8.5 branch
and pushed, but I don't think it changes anything) (after trimming*):
Finished transaction in 0.323 secs (0.312u,0.011s) (successful)

total time:      0.324s

 tactic                                    self  total   calls       max
────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
─set (x := fact 7) --------------------- 100.0% 100.0%       1    0.324s
─a -------------------------------------   0.0% 100.0%       1    0.324s

 tactic                                    self  total   calls       max
────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
─a -------------------------------------   0.0% 100.0%       1    0.324s
└set (x := fact 7) --------------------- 100.0% 100.0%       1    0.324s

total time:      0.324s

 tactic                                    self  total   calls       max
────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
─set (x := fact 7) --------------------- 100.0% 100.0%       1    0.324s
─a -------------------------------------   0.0% 100.0%       1    0.324s

 tactic                                    self  total   calls       max
────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
─a -------------------------------------   0.0% 100.0%       1    0.324s
└set (x := fact 7) --------------------- 100.0% 100.0%       1    0.324s

Finished transaction in 0.292 secs (0.291u,0.s) (successful)

total time:      0.616s

 tactic                                    self  total   calls       max
────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
─set (x := fact 7) --------------------- 100.0%  52.6%       2    0.324s
─a -------------------------------------   0.0%  52.6%       2    0.324s

 tactic                                    self  total   calls       max
────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
─a -------------------------------------   0.0%  52.6%       2    0.324s
└set (x := fact 7) --------------------- 100.0%  52.6%       2    0.324s

total time:      0.616s

 tactic                                    self  total   calls       max
────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
─set (x := fact 7) --------------------- 100.0%  52.6%       2    0.324s
─a -------------------------------------   0.0%  52.6%       2    0.324s

 tactic                                    self  total   calls       max
────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
─a -------------------------------------   0.0%  52.6%       2    0.324s
└set (x := fact 7) --------------------- 100.0%  52.6%       2    0.324s

Finished transaction in 0.289 secs (0.284u,0.004s) (successful)

total time:      0.904s

 tactic                                    self  total   calls       max
────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
─set (x := fact 7) --------------------- 100.0%  35.8%       3    0.324s
─a -------------------------------------   0.0%  35.8%       3    0.324s

 tactic                                    self  total   calls       max
────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
─a -------------------------------------   0.0%  35.8%       3    0.324s
└set (x := fact 7) --------------------- 100.0%  35.8%       3    0.324s

total time:      0.904s

 tactic                                    self  total   calls       max
────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
─set (x := fact 7) --------------------- 100.0%  35.8%       3    0.324s
─a -------------------------------------   0.0%  35.8%       3    0.324s

 tactic                                    self  total   calls       max
────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
─a -------------------------------------   0.0%  35.8%       3    0.324s
└set (x := fact 7) --------------------- 100.0%  35.8%       3    0.324s

Finished transaction in 0.293 secs (0.288u,0.008s) (successful)

total time:      1.200s

 tactic                                    self  total   calls       max
────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
─set (x := fact 7) --------------------- 100.0%  27.0%       4    0.324s
─a -------------------------------------   0.0%  27.0%       4    0.324s

 tactic                                    self  total   calls       max
────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
─a -------------------------------------   0.0%  27.0%       4    0.324s
└set (x := fact 7) --------------------- 100.0%  27.0%       4    0.324s

total time:      1.200s

 tactic                                    self  total   calls       max
────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
─set (x := fact 7) --------------------- 100.0%  27.0%       4    0.324s
─a -------------------------------------   0.0%  27.0%       4    0.324s

 tactic                                    self  total   calls       max
────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
─a -------------------------------------   0.0%  27.0%       4    0.324s
└set (x := fact 7) --------------------- 100.0%  27.0%       4    0.324s

Note that the highest number in the total column gets lower after every
successive call to a tactic.
```
This does the equivalent of inserting `Start Profiling` at the top of
each file and `Show Profile` at the bottom.
@mattam82
Copy link
Member

@aspiwack @ppedrot What do you think on the implementation side? It can't be in a pl but certainly in the upcoming release.

@ppedrot
Copy link
Member

ppedrot commented Apr 14, 2016

This looks OK to me implementationwise. What is the average overhead due to this patch when not using the debugging feature? Is it observable?

@JasonGross
Copy link
Member Author

@mattam82 why shouldn't this go into a pl? (What's the boundary between acceptable for pl vs not? My understating was that pls can contain changes which do one of:

  • fix something that is obviously a bug (in performance or behavior)
  • have no effect on plugins nor developments (e.g., documentation)
  • fix regressions with respect to the previous version of Coq
  • add features or behavior that do not invalidate existing developments nor allow new developments which do not build with the old pl (e.g., saner error messages)

I think LtacProf basically fits into this last category, since none of the commands are meant to be used in non-testing settings.)

@ppedrot I haven't tested, but I seem to recall @tebbi mentioning a 1%-2% slowdown. I'll plan to give you data on HoTT and the standard library later today.

@JasonGross
Copy link
Member Author

The overhead on the standard library seems to be about 2.5% (about 4% on the overall build time of Coq):

Build time of successive builds of Coq (4c078b0) without LtacProf:

real: 167.77, user: 512.88, sys: 39.43, mem: 820740 ko
real: 165.68, user: 506.92, sys: 37.36, mem: 820624 ko

with LtacProf:

real: 172.75, user: 525.70, sys: 40.20, mem: 807528 ko
real: 171.36, user: 523.31, sys: 39.28, mem: 810588 ko

The command was:

make clean && git clean -xfd && ./configure -local && /usr/bin/time -f "all coq (real: %e, user: %U, sys: %S, mem: %M ko)" make STDTIME='/usr/bin/time -f "$* (real: %e, user: %U, sys: %S, mem: %M ko)"' TIMED=1 -j4 2>&1

The only file that changed by more than 0.6s of user time was theories/Numbers/Rational/BigQ/QMake.v; the changes in the slowest files (>= 5s) in the standard library are:

After    | File Name                                | Before   || Change
---------------------------------------------------------------------------
7m46.28s | Total                                    | 7m34.10s || +0m12.18s
---------------------------------------------------------------------------
0m45.56s | Numbers/Rational/BigQ/QMake              | 0m43.99s || +0m01.57s
0m15.96s | plugins/setoid_ring/Ncring_polynom       | 0m15.93s || +0m00.03s
0m14.29s | Numbers/Cyclic/DoubleCyclic/DoubleCyclic | 0m14.28s || +0m00.00s
0m10.57s | Numbers/Cyclic/DoubleCyclic/DoubleSqrt   | 0m10.46s || +0m00.10s
0m09.88s | FSets/FMapAVL                            | 0m09.59s || +0m00.29s
0m09.81s | MSets/MSetRBT                            | 0m09.51s || +0m00.30s
0m07.24s | Numbers/Cyclic/DoubleCyclic/DoubleDiv    | 0m07.25s || -0m00.00s
0m07.08s | Numbers/Cyclic/Int31/Cyclic31            | 0m06.97s || +0m00.11s
0m05.94s | plugins/setoid_ring/Field_theory         | 0m05.93s || +0m00.01s
0m05.75s | FSets/FMapFullAVL                        | 0m05.71s || +0m00.04s
0m05.62s | Reals/Ratan                              | 0m05.49s || +0m00.12s
0m05.58s | plugins/setoid_ring/Ring_polynom         | 0m05.46s || +0m00.12s
0m05.32s | plugins/micromega/EnvRing                | 0m05.16s || +0m00.16s

I suspect that most of this overhead comes from either moving more things into the tactic monad, or stringifying the names of tactics even when not profiling. I'm currently testing a change that makes it so we only stringify tactic names when profiling, and after that I'll make a test case that stresses the calling of multiple tactics, and perhaps profile some chunk of bedrock.

@JasonGross
Copy link
Member Author

The lazy stringification patch brings the overhead down to 1%, and pushes the overall compilation time down to

real: 169.42, user: 518.18, sys: 39.32, mem: 816676 ko

The log for the standard library is:

After    | File Name                                | Before   || Change
---------------------------------------------------------------------------
7m38.71s | Total                                    | 7m34.10s || +0m04.60s
---------------------------------------------------------------------------
0m44.59s | Numbers/Rational/BigQ/QMake              | 0m43.99s || +0m00.60s
0m16.03s | plugins/setoid_ring/Ncring_polynom       | 0m15.93s || +0m00.10s
0m14.05s | Numbers/Cyclic/DoubleCyclic/DoubleCyclic | 0m14.28s || -0m00.22s
0m10.58s | Numbers/Cyclic/DoubleCyclic/DoubleSqrt   | 0m10.46s || +0m00.11s
0m09.73s | MSets/MSetRBT                            | 0m09.51s || +0m00.22s
0m09.57s | FSets/FMapAVL                            | 0m09.59s || -0m00.01s
0m07.25s | Numbers/Cyclic/DoubleCyclic/DoubleDiv    | 0m07.25s || +0m00.00s
0m07.01s | Numbers/Cyclic/Int31/Cyclic31            | 0m06.97s || +0m00.04s
0m06.10s | plugins/setoid_ring/Field_theory         | 0m05.93s || +0m00.16s
0m05.82s | FSets/FMapFullAVL                        | 0m05.71s || +0m00.11s
0m05.59s | plugins/setoid_ring/Ring_polynom         | 0m05.46s || +0m00.12s
0m05.54s | Reals/Ratan                              | 0m05.49s || +0m00.04s
0m05.20s | plugins/micromega/EnvRing                | 0m05.16s || +0m00.04s

This brings the overhead on the standard library when not profiling down
from 2.5% to 1%.
@JasonGross
Copy link
Member Author

There is a bug in LtacProf that I'm not sure how to fix, though I'm not sure that this should prevent it from being merged: LtacProf can't handle backtracking into the middle of tactics with multiple successes, because it doesn't know how to reconstruct the trace tree. Here is a small example that gives rise to the anomaly:

Start Profiling.
Ltac multi := (idtac + idtac).
Goal True.
  try (multi; fail). (* Anomaly: Uncaught exception Failure("hd"). Please report. *)
Admitted.

Certainly, we could make the usage more friendly by catching this exception and printing a warning instead (what's the appropriate way to print a warning in Coq?).

I think for trunk, there should be a way to hook into the re-entering of a tactic with multiple successes, so that we can restart the timers appropriately. ( @aspiwack @ppedrot @tebbi, thoughts on this?)

@mattam82
Copy link
Member

mattam82 commented May 3, 2016

@JasonGross msg_warning would be the way to print a warning

@JasonGross
Copy link
Member Author

@mattam82 Thanks! I've turned the anomaly into a warning.

@JasonGross JasonGross mentioned this pull request May 5, 2016
@JasonGross
Copy link
Member Author

What's blocking this? @mattam82, any comments on my point in #150 (comment)?

@mattam82
Copy link
Member

I agree the feature can be considered for inclusion, but I'd like to know what @ppedrot and @aspiwack think. Couldn't you grab a few more seconds by specializing do_profile for the non-profiling case?

@ppedrot
Copy link
Member

ppedrot commented May 11, 2016

On a metalevel note, I am unsure that adding features after a release is a good development practice, but I am not too fond of outrageously strict rules either. Notwithstanding this point, I think we should indeed include it. What is the opinion of @maximedenes, all hail to our Great Good Development Practice Enforcer?

@gares
Copy link
Member

gares commented May 11, 2016

@ppedrot, a good point once made by @silene is that adding a feature in plX+1 is bad if then some code working with plX+1 does not work with plX. Eg. if we add a compilation flag in 8.5pl2, then coqc from8.5pl1 would complain (no way way to make a Makefile that works with all pl releases).

Said that, I don't know if LtacProf classifies: Start Profiling seems a debugging command to me. I mean, not something ending up in a standard file.

@JasonGross
Copy link
Member Author

I agree with the point about not adding new features in the middle of pls in general, but I think adding debugging features (and flags like -time, -profileltac, Start Profiling, etc) should be fine.

@mattam82 what do you mean by specializing do_profile? Do you mean storing the function in a ref cell and changing which function is stored when you change the profiling behavior?

@mattam82
Copy link
Member

No, I mean doing the condition on profiling earlier, avoiding a bind and finally

@JasonGross
Copy link
Member Author

@herbelin

  • 6cc5863 should make it easier, once I stop caring about supporting 8.5, 8.5pl1.
  • constr:x is no longer valid in 8.5.dev? or trunk? I can't recall where the commit is. But by 8.6, if not already, writing parentheses in constr:(x) and ltac:(x) are required (I think this might be part of @ppedrot 's work on making Ltac less special).
  • associativity of ; bit me once or twice; I now need things like foo; bar; bar rather than foo; bar in a few places, or, repeat repeat foo rather than repeat foo. As with most small changes in tactic semantics, it's really annoying to track down, but straightforward to fix once I pinpoint the issue.
  • There are two kinds of unification problems that tend to come up: either
    1. the solution found is convertible but not syntactically the same, and so later tactic scripts that work on syntactic equality fail; or
    2. apply or rewrite or refine fails to instantiate evars when there's an essentially unique, valid solution. (I recently hit a case where exact eq_refl failed on a goal of the form ?n = v for v an evar-free term, only if both (a) I was working in 8.5, and (b) I first ran subst H where H was in the context defined as an evar. I can track this down if it's useful, but it's in the middle of a long and slow proof script, and failure to unify evars is one of the trickiest forms of bug to minimize, because I can't just copy-paste the goal state and start my minimizer from there.) (I also hit another case where apply failed to solve a unification problem that, I believe, was trivially solvable by delaying all conversion problems and resolving evars by syntactic unification, and then checking the resulting terms for compatibility afterwards; switching to refine solved the problem.)

@JasonGross
Copy link
Member Author

@gares can I just override the freeze function with one that does a deep copy of the mutable data structure? Am I correct in inferring that this occurs between tactic invocations only?

@ppedrot
Copy link
Member

ppedrot commented May 14, 2016

As a general rule of thumb, I think you should go for the immutable structure instead. That removes a lot of potential interaction bugs...

@JasonGross
Copy link
Member Author

@maximedenes on the Bedrock src target (with a few admits, made with -j5), the stats are:

  • 8.5pl1 without ltacprof:
real: 1700.64, user: 2529.76, sys: 10.91, mem: 842312 ko
  • 8.5pl1 with ltacprof
real: 1701.26, user: 2528.96, sys: 11.55, mem: 843320 ko
  • 8.5pl1 with ltacprof and -profile-ltac:
real: 1737.94, user: 2576.83, sys: 17.04, mem: 839768 ko

Of the user time reported by the profiler, 2302.384s of it was spent in tactic-land. This is well under 0.05% overhead when the profiler is off, and the overhead when it's turned on seems to be about 2% on tactics.

This is suboptimal, because mutation leaves room for subtle bugs, but
rewriting @tebbi's code to be functional was a pain, and not something I
could figure out how to do easily.  I'm working under the assumption
that there is no sharing in a single treenode, which I'm not completely
sure is valid.  That said, a few simple tests seem to indicate that this
works as expected.
@JasonGross
Copy link
Member Author

@ppedrot @gares @herbelin I've pushed a commit synchronizing the profiling data with the document state. I spent the afternoon and evening trying to recode it as a functional data structure, and did not succeed (@tebbi's mutation-using code is too tricky for me), so I just provided a deepcopy freeze method, which seems to work in the basic tests I did. Eventually we'll want to reimplement this as a plugin on top of a nonlogical extension to the tactic monad that supports Trace, Info, and LtacProf, but first I have to figure out what the plugin interface should be, and I think that's a job for 8.6 or later.

@JasonGross
Copy link
Member Author

To be clear, it's now the case that with Stop Profiling do tac, once it exists, will do the same thing as stop profiling; tac; start profiling. @herbelin, I can replace the tactics with that syntax now, if you think it's a good thing to do.

@JasonGross
Copy link
Member Author

There's now Set Ltac Profiling and Unset Ltac Profiling, rather than the Stop/Start, and I've made the tactic names start ltac profiling and stop ltac profiling.

Current status of this PR, as I understand it: waiting for general feedback from @aspiwack , an ack from @gares / @ppedrot on the freeze function I wrote, comments from @maximedenes on if the profiling of bedrock src is satisfactory, and a response from @herbelin on whether I should stick with start ltac profiling and stop ltac profiling or should instead combine them into with Set Ltac Profiling do tac and with Unset Ltac Profiling do tac.

Set Ltac Profiling.
Ltac multi := (idtac + idtac).
Goal True.
try (multi; fail). (* Anomaly: Uncaught exception Failure("hd"). Please report. *)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this comment up to date? I thought this had been changed to a warning.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've taken to annotating test suite lines with the error messages they're supposed to prevent, to make it easier to debug their purpose if they break as Coq changes. I'll add a "used to be: " to the front of the comment.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

@aspiwack
Copy link
Contributor

Sorry for being late to the party.

TL;DR: I'm fine with this.

I like that it is a fairly non-intrusive change (on that subject, @JasonGross: if you use emacs, I would recommend using ws-butler (kindly available on melpa) rather than delete-trailing-withespace it would avoid pushing a number of irrelevant trailing whitespace changes (it is distracting for code review)).

I'm less fond of the fact that this profiler interacts purely with the Ltac layer. But as we had seen in the last coding sprint, it may not be obvious how to plug this sort of things directly within the tactic monad (@JasonGross had troubles trying to implement a tracing mechanism). So I'm ok with settling for a pragmatic solution.

I must say I am a bit concerned about the issue with backtracking (it means that if backtracking is used, even a little, in commonly used tactics, profiling may start to be mostly useless). It's probably not an issue for 8.5, but for subsequent versions of Coq, it may be useful to identify what is required for profiling to handle backtracking.

@JasonGross JasonGross closed this May 20, 2016
@JasonGross JasonGross reopened this May 20, 2016
@JasonGross
Copy link
Member Author

Thanks for the ws-butler suggestion.

Plugging the profiler into the tactic monad will eventually fix the issue with backtracking, at the cost of additional not-yet--determined overhead. The trace info calculation is already working, all that remains there is figuring out the right interface for plugins. But there's extra overhead there, especially when profiling (we have to compare call stacks on every call) because there's no naive way to be notified when backtracking has happened, at least none that I've seen. So I'd rather get this merged, because it's noninvasive and low overhead and works, and update it when I next have time to work on tracing, which is rather invasive.

If we don't plug the profiler into the monad, the minimum requirement for handling backtracking is some way to be notified of the diff between the call stack before backtracking and the call stack after back tacking. Note that the call_trace argument actually contains only a tiny segment of the call stack, and so can't be used for this purpose.

@aspiwack
Copy link
Contributor

Thanks for the ws-butler suggestion.

You are very welcome :-)

So I'd rather get this merged, because it's noninvasive and low overhead and works

As said above, I do agree.

If we don't plug the profiler into the monad, the minimum requirement for handling backtracking is some way to be notified of the diff between the call stack before backtracking and the call stack after back tacking.

I'm afraid I don't really understand what you mean. Can you elaborate a bit, on how this would be used?

@JasonGross
Copy link
Member Author

I'm afraid I don't really understand what you mean. Can you elaborate a bit, on how this would be used?

The profiler maintains it's own copy of the current call stack. Whenever you enter a new tactic, you push that call on the stack; whenever you leave a tactic, you "close" the most recent stack entry, update the children of the entry above it (because this tactic you just closed is a child, and it ran for some time), and subtract off the time spent in the child from the local time that was spent in the parent itself. The code assumes the invariant that if you wrap each tactic tac in open "tac"; tclIFCATCH tac THEN close "tac" WITH exn -> (close "tac"; raise exn), every tactic will be opened, run, then closed. This is not the case with reentrant (multisuccess) tactics. The way I know to get around this is to maintain the entire call stack at all times (both in backtracking and nonbacktracking data), so that when you reenter a tactic, you can compare the stacks, and close the tactics you left, and open the tactics you reentered.

As said above, I do agree.

Great!

Current status of this PR, as I understand it: waiting for an ack from @gares / @ppedrot on the freeze function, comments from @maximedenes on if the profiling of bedrock src is satisfactory, and a response from @herbelin on whether I should stick with start ltac profiling and stop ltac profiling or should instead combine them into with Set Ltac Profiling do tac and with Unset Ltac Profiling do tac. (Have acks from aspiwack and mattam82.)

@JasonGross
Copy link
Member Author

@ppedrot
Copy link
Member

ppedrot commented May 26, 2016

No special comments here, I'm OK with it.

@aspiwack
Copy link
Contributor

The profiler maintains it's own copy of the current call stack. Whenever you enter a new tactic, you push that call on the stack; whenever you leave a tactic, you "close" the most recent stack entry, update the children of the entry above it (because this tactic you just closed is a child, and it ran for some time), and subtract off the time spent in the child from the local time that was spent in the parent itself. The code assumes the invariant that if you wrap each tactic tac in open "tac"; tclIFCATCH tac THEN close "tac" WITH exn -> (close "tac"; raise exn), every tactic will be opened, run, then closed. This is not the case with reentrant (multisuccess) tactics. The way I know to get around this is to maintain the entire call stack at all times (both in backtracking and nonbacktracking data), so that when you reenter a tactic, you can compare the stacks, and close the tactics you left, and open the tactics you reentered.

I see. I believe the only sane way to do that would be to keep a call stack in the monad (I believe the mechanism for Info can easily be extended for call stack).

@JasonGross
Copy link
Member Author

@aspiwack are you thinking of something like what we worked on for debug traces, or something else?

@JasonGross
Copy link
Member Author

What's the expected timeline on this? / Who's the one to give the final green-light and merge this?

@aspiwack
Copy link
Contributor

aspiwack commented Jun 1, 2016

@aspiwack are you thinking of something like what we worked on for debug traces, or something else?

Yes. Though I assume that a call stack will be more like the Info trace (which is easy) than a debug trace (which is hard).

Who's the one to give the final green-light and merge this?

I'm guessing @ppedrot or @mattam82 are best placed for that.

JasonGross added a commit to JasonGross/coq that referenced this pull request Jun 6, 2016
rocq-prover#150 (comment)

```bash
git grep --name-only profileltac | xargs sed s'/profileltac/profile-ltac/g' -i
```
JasonGross added a commit to JasonGross/fiat that referenced this pull request Jun 10, 2016
This is rocq-prover/rocq#150,
LtacProf can't handle backtracking into multi-success tactics.
JasonGross added a commit to JasonGross/fiat that referenced this pull request Jun 10, 2016
This is rocq-prover/rocq#150,
LtacProf can't handle backtracking into multi-success tactics.
@JasonGross
Copy link
Member Author

Closing; it's been merged in trunk, and will not be merged in 8.5.

@JasonGross JasonGross closed this Jun 15, 2016
jfehrle pushed a commit to jfehrle/coq that referenced this pull request Dec 19, 2022
150: Add better names for `Sort`s; introduce notation. r=Janno a=Janno

This commit gives longer names to the constructors of `Sort`: `Type_sort` and `Prop_sort`. To avoid having to type those names, the commit also introduces notation `Typeₛ` and `Propₛ`. On top of that, I also added some more speculative notations: `funₛ, λₛ, forallₛ, ∀ₛ, ->ₛ`. These are not used yet explicitly yet but I think they improve readability in functions that use `Fun` and `ForAll`.

Note that this commit disables the `unrecognized_unicode` warning. Hopefully this will not be necessary in the future once rocq-prover#9500 is resolved.

Co-authored-by: Jan-Oliver Kaiser <[email protected]>
proux01 pushed a commit to proux01/rocq that referenced this pull request Sep 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants