octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: warnings shut off in ov.cc?


From: Rik
Subject: Re: warnings shut off in ov.cc?
Date: Tue, 15 Oct 2019 18:15:21 -0700

On 10/15/2019 02:26 PM, John W. Eaton wrote:
> On 10/15/19 5:13 PM, Rik wrote:
>
>> What about just not discarding warning messages?  I commented out this line
>>
>> //    es.discard_warning_messages (true);
>>
>> and then everything works as expected (no duplicate warning messages
>> either).
>
> That's OK for the command line where you are parsing and executing the
> code once.  But in a function, it means you'll get the warning when the
> function is parsed and not when it is executed.

True, although I don't have an easy command to parse the file, but not
execute it.

I created junk.m with

function r = junk ()
  r = [1, 2] : 5;
endfunction

and the first time the function is used the code gets parsed and the
warning is issued.

octave:2> y = junk ()
warning: colon arguments should be scalars
y =

   1   2   3   4   5

But the second time the code is run there is no warning

octave:3> z = junk ()
z =

   1   2   3   4   5

It is possible to detect that a warning has been issued and avoid constant
folding, although the mechanism is clumsy.  This diff does it

diff -r 5a0543de1e47 libinterp/parse-tree/oct-parse.yy
--- a/libinterp/parse-tree/oct-parse.yy Wed Oct 09 14:35:03 2019 +0200
+++ b/libinterp/parse-tree/oct-parse.yy Tue Oct 15 17:56:41 2019 -0700
@@ -2531,7 +2531,23 @@ namespace octave
           {
             tree_evaluator& tw = interp.get_evaluator ();
 
+            std::string oldmsg = es.last_warning_message ();
+            if (oldmsg.empty ())
+              {
+                oldmsg = "INTERPRETER";
+                es.last_warning_message (oldmsg);
+              }
+            else
+              {
+                oldmsg = "";
+                es.last_warning_message (oldmsg);
+              }
             octave_value tmp = e->evaluate (tw);
+            if (es.last_warning_message () != oldmsg)
+              {
+                retval = e;
+                return retval;
+              }
 
             tree_constant *tc_retval
               = new tree_constant (tmp, e->line (), e->column ());

There may be a more clever way to use frame.protect_var to restore the
member variable m_last_warning_message.

To benchmark things, I created this function

function [a,b,c,d] = tst_rangefold ()
  a = 1:100;
  b = 1:3:99;
  c = -1:.01:+1;
  d = 0:.001:1;
endfunction

Then I benchmarked things using

N = 1e4;
bm = zeros (N,1);
for i = 1:N
  tic;
  [a,b,c,d] = tst_rangefold ();
  bm(i) = toc;
  clear a b c d
endfor

The mean runtime (mean (bm)) for various configurations is

Baseline: 1.3343e-05
Warn Detection: 1.3592e-05
No Constant Folding: 1.5367e-05

So a 2% slowdown to add warning detection, but a 15% slowdown if constant
folding is removed altogether.  Although, let's be real, even if constant
folding is removed entirely the absolute difference is 2 microseconds which
isn't very meaningful.

Given that a future JIT might benefit from knowing when a range was
constant at compile time, I think we should leave the code in.  If you have
a more clever way of testing the lastwarn variable that would be good. 
Otherwise, I can implement what I have.

--Rik





reply via email to

[Prev in Thread] Current Thread [Next in Thread]