OK, this might not be that complicated after all, hear my analysis:
1. Assume there is only 1 (global) scope for $timedNameStack,
and it is only modified by push or pop, never gets assignment.
When an exception is thrown in somewhere and catched somewhere else,
now there's a "stopTimingProcess A", but the head of $timedNameStack
is B. We can simply attribute the stats to A, and continue.
(Current "savedTimerStack" is attributing the stats to B.)
The only downside is that $timedNameStack will grow indefinitely.
2. Now let's have a dynamic scope for $timedNameStack for each nested
"processInteractive". Problem solved. No need to wrap around every
CATCH. $timedNameStack will not grow indefinitely.
What I'm saying is:
1. dynamic scoping for $timedNameStack
2. do not use savedTimerStack around CATCH
3. do not check with "peekTimedName" in "stopTimingProcess".
(aka allow unbalanced $timedNameStack, which is a price has to be paid
for exception handling)
- Qian
On 12/24/23 18:48, Waldek Hebisch wrote:
On Sun, Dec 24, 2023 at 09:55:03AM +0800, Qian Yun wrote:
On 12/24/23 09:41, Waldek Hebisch wrote:
Well, with this '$timedNameStack' is balanced. But there is still
trouble with acconting: since 'stopTimingProcess' was not called
we will either ignore or assign to wrong context resources used
in context that did 'THROW'.
If there's throw to top level, then stats will not be printed,
so there's no need to continue collect stats.
Forget about toplevel. This tread is above recursive calls.
In particular algebra may perform call to interpreter and
catch errors. When algebra returns to outer interpreter
we should print statistics. Similar thing happens inside
interpreter.
BTW: It is debatable if not printing stats in case of errors
is right thing to do.
"When algebra returns to outer interpreter", the $timedNameStack
in outer interpreter is not affected by inner interpreter.
The total time spent in inner interpreter is accounted under
"evaluation" of outer interpreter.
Well, deciding what to do in such situation is part
of solving problem. AFAICS before your patches inner
interpreter messed statistic variables of outer one,
and printing nothing in outer interpreter masked the
trouble. IMO when some code is aborted, but error is
caught and computation continues, we should count
time spent in aborted code. Which means that we should
ensure consitent statistics. This may require use of
different function than 'processInteractive' (or change
to 'processInteractive').
To put this differently: there is 'read' which separately
times toplevel expressions in a file, which requires recursive
timing. But we also have calls from algebra to interpreter
and those IMO should be timed togethere with toplevel call.
If we assume that recursive calls via 'processInteractive'
only deal with 'read' than you change looks OK.
Can you give an example (inner interpreter catches exception)
so that I can verify if it messes up stats accounting?
In algebra we can use: 'trapNumericErrors', 'trappedSpadEval'
and 'eval_with_timeout'. More can be added if needed. Code
executed by constructs above may call 'interpret',
'interpret_block' or other interpeter constructs. There is
also possibility of passing interpeter functions to algebra
code. Normaly, such functions are compiled, but sometimes
interpreter really interpret functions. I am not sure if
interpretation is allowed for functions passed to algebra,
but one can argue that they should be supported.
Note: part of problem is deciding which calls should do recursive
timings and how those should behave. Past behaviour is of
limited help here, as we want to fix trouble with current
code which probably will involve changing behaviour to more
desirable one.
--
You received this message because you are subscribed to the Google Groups "FriCAS -
computer algebra system" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/fricas-devel/1263558d-26b4-4d13-846d-baf1d6dc1449%40gmail.com.