Message Boards Message Boards

0
|
7547 Views
|
3 Replies
|
0 Total Likes
View groups...
Share
Share this post:

RuntimeErrorHandler and Check[] in combination with CompiledFunction[]

Posted 9 years ago

Hi, I use Mathematica 10.0 and have following code where I want to stop the calculation if a CompiledFunction generates an error message:

offset = 4;(*3=ok, 4=error*)
func1 = Compile[{{v, _Real}}, Block[{r}, r = Sqrt[v - offset]], "RuntimeOptions" -> {"RuntimeErrorHandler" -> Function[Throw[$Failed]]}];
Off[General::stop];(*enable or disable, does not matter*)
Map[Catch[func1[#]] &, Range[10]]
On[General::stop];

Previous code works fine as long as no more than 3 messages are created, but starting from the 4th message only the RuntimeErrorHandler seems to be executed although the result should be valid. Switching off the "General::stop" message has no effect on the behaviour of the above code.

When I use Check[] instead of the RuntimeErrorHandler the behaviour is such that the first 3 messages are catched by Check[] but no further message is generated at all. The function returns complex numbers which must have been evaluated silently by non-compiled code.

offset = 5;(*3=ok, 4=ok(?), 5=complex results from non-compliled code?*)
func2 = Compile[{{v, _Real}}, Block[{r}, r = Sqrt[v - offset]]];
Off[General::stop];(*enable or disable,does not matter*)
Map[Check[func2[#], "error"] &, Range[10]]
On[General::stop];

A note why I want to catch messages from compiled code: I thought its a clever idea to use a compiled function with variables set to Reals which will generate an error whenever it starts to generate complex numbers - which are useless for me. In this case I would like to abort any evaluation immediately without loss of time (I am doing a computational heavy simulation).

What is your opinion? Is it a bug or do I do something wrong? Thanks a lot for your comments. Andreas

3 Replies

This is for sure a bug. You strictly followed The Wolfram System Compiler tutorial, entry Runtime Error Handling in the tool. On the web there is a description without Throw.

The thing is, after having thrown one error followed by an errorless evaluation, you can later on throw as much as you want.

   In[1]:= Remove[func8]
    func8 = Compile[{{v, _Real}}, Sqrt[v - 8], "RuntimeOptions" -> {"RuntimeErrorHandler" -> Function[Throw[$Failed]]}]

Out[2]= CompiledFunction[{10, 10., 4444}, {
Blank[Real]}, {{3, 0, 0}, {3, 0, 1}}, {{-8, {2, 0, 
   0}}}, {0, 1, 3, 0, 0}, {{10, 0, 1}, {13, 0, 1, 2}, {40, 57, 3, 0, 
  2, 3, 0, 1}, {1}}, Function[{v}, Sqrt[v - 8]], Throw[$Failed]& ]

In[3]:= Catch[func8[#]] & /@ {1, 15, 16, 17, 18}
During evaluation of In[3]:= CompiledFunction::cfn: Numerical error encountered at instruction 3; proceeding with uncompiled evaluation. >>   
Out[3]= {$Failed, 2.64575, 2.82843, 3., 3.16228}

In[4]:= Catch[func8[#]] & /@ {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 15, 16, 17, 18}
During evaluation of In[4]:= CompiledFunction::cfn: Numerical error encountered at instruction 3; proceeding with uncompiled evaluation. >>
During evaluation of In[4]:= CompiledFunction::cfn: Numerical error encountered at instruction 3; proceeding with uncompiled evaluation. >>
During evaluation of In[4]:= CompiledFunction::cfn: Numerical error encountered at instruction 3; proceeding with uncompiled evaluation. >>
During evaluation of In[4]:= General::stop: Further output of CompiledFunction::cfn will be suppressed during this calculation. >>

Out[4]= {$Failed, $Failed, $Failed, $Failed, $Failed, $Failed, \
$Failed, $Failed, $Failed, $Failed, $Failed, $Failed, $Failed, \
2.64575, 2.82843, 3., 3.16228}

If you throw 3 errors in the beginning, it will never work again, even with offset = 3:

In[8]:= Remove[func3]
func3 = Compile[{{v, _Real}}, Sqrt[v - 3], "RuntimeOptions" -> {"RuntimeErrorHandler" -> Function[Throw[$Failed]]}]

Out[9]= CompiledFunction[{10, 10., 4444}, {
Blank[Real]}, {{3, 0, 0}, {3, 0, 1}}, {{-3, {2, 0, 
   0}}}, {0, 1, 3, 0, 0}, {{10, 0, 1}, {13, 0, 1, 2}, {40, 57, 3, 0, 
  2, 3, 0, 1}, {1}}, 
Function[{v}, Sqrt[v - 3]], Throw[$Failed]& ]

In[10]:= Catch[func3[#]] & /@ {1, 1, 1, 5, 6, 7, 8}
During evaluation of In[10]:= CompiledFunction::cfn: Numerical error encountered at instruction 3; proceeding with uncompiled evaluation. >>
During evaluation of In[10]:= CompiledFunction::cfn: Numerical error encountered at instruction 3; proceeding with uncompiled evaluation. >>
During evaluation of In[10]:= CompiledFunction::cfn: Numerical error encountered at instruction 3; proceeding with uncompiled evaluation. >>
During evaluation of In[10]:= General::stop: Further output of CompiledFunction::cfn will be suppressed during this calculation. >>

Out[10]= {$Failed, $Failed, $Failed, $Failed, $Failed, $Failed, $Failed}

Do this again in the same session

In[14]:= Remove[func31]
func31 = Compile[{{v, _Real}}, Sqrt[v - 3], "RuntimeOptions" -> {"RuntimeErrorHandler" -> Function[Throw[$Failed]]}]

Out[15]= CompiledFunction[{10, 10., 4444}, {
Blank[Real]}, {{3, 0, 0}, {3, 0, 1}}, {{-3, {2, 0, 
   0}}}, {0, 1, 3, 0, 0}, {{10, 0, 1}, {13, 0, 1, 2}, {40, 57, 3, 0, 
  2, 3, 0, 1}, {1}}, 
Function[{v}, Sqrt[v - 3]], Throw[$Failed]& ]

In[16]:= Catch[func31[#]] & /@ {1, 5, 6, 7, 8}
During evaluation of In[16]:= CompiledFunction::cfn: Numerical error encountered at instruction 3; proceeding with uncompiled evaluation. >>
Out[16]= {$Failed, 1.41421, 1.73205, 2., 2.23607}

In[17]:= Catch[func31[#]] & /@ {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6,7, 8}
During evaluation of In[17]:= CompiledFunction::cfn: Numerical error encountered at instruction 3; proceeding with uncompiled evaluation. >>
During evaluation of In[17]:= CompiledFunction::cfn: Numerical error encountered at instruction 3; proceeding with uncompiled evaluation. >>

During evaluation of In[17]:= CompiledFunction::cfn: Numerical error encountered at instruction 3; proceeding with uncompiled evaluation. >>
During evaluation of In[17]:= General::stop: Further output of CompiledFunction::cfn will be suppressed during this calculation. >>

Out[17]= {$Failed, $Failed, $Failed, $Failed, $Failed, $Failed, \
$Failed, $Failed, $Failed, $Failed, $Failed, 1.41421, 1.73205, 2., \2.23607}

that works. Condition seems to be: Generate one or two errors then an errorless evaluation and now you can do whatever you want:

Remove[func17]
func17 = Compile[{{v, _Real}}, Sqrt[v - 17], "RuntimeOptions" -> {"RuntimeErrorHandler" -> Function[$Failed]}]

In[31]:= func17 /@ {1, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 22,23, 24}

During evaluation of In[31]:= CompiledFunction::cfn: Numerical error encountered at instruction 3; proceeding with uncompiled evaluation. >>
During evaluation of In[31]:= CompiledFunction::cfn: Numerical error encountered at instruction 3; proceeding with uncompiled evaluation. >>
During evaluation of In[31]:= CompiledFunction::cfn: Numerical error encountered at instruction 3; proceeding with uncompiled evaluation. >>
During evaluation of In[31]:= General::stop: Further output of CompiledFunction::cfn will be suppressed during this calculation. >>

Out[31]= {$Failed, 1.73205, $Failed, $Failed, $Failed, $Failed, $Failed, $Failed, $Failed, $Failed, $Failed, $Failed, $Failed, \
$Failed, 2., 2.23607, 2.44949, 2.64575}

This is Mathematica 10.0.2.0 under Windows 7 64 Bit Home Premium. Consider to file a bug to Wolfram, please.

POSTED BY: Udo Krause

As a work-around you can do this

In[6]:= Remove[func17]
func17 = Compile[{{v, _Real}}, Sqrt[v - 17], "RuntimeOptions" -> {"RuntimeErrorHandler" -> Function[$Failed]}];
Off[CompiledFunction::cfn]
(* unfreak the error handler *)
func17 /@ {1, 20};

In[10]:= func17 /@ {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 22, 23,24}
Out[10]= {$Failed, $Failed, $Failed, $Failed, $Failed, $Failed, \
$Failed, $Failed, $Failed, $Failed, $Failed, $Failed, $Failed, 2., \
2.23607, 2.44949, 2.64575}

to have it working like a charme. But that work-around seems to fail with a throwing error handler.

POSTED BY: Udo Krause

Hi Udo, thank you for your work-around!

I can confirm your observations (on Win7 64bit, Mathematica 10.0.2.0). Your work-around works like a charm.

It also works with a throwing error handler:

In[351]:= Remove[func27]
func27 = Compile[{{v, _Real}}, Sqrt[v - 27], "RuntimeOptions" -> {"RuntimeErrorHandler" -> Function[Throw[$Failed]]}];
If[True,(*if True unfreak the error handler, otherwise get always $Failed below*)
  Catch[func27[#]] & /@ {1, 27}
  ];
(*works if True above*)
Catch[func27[#]] & /@ Range[23, 30]
Out[354]= {$Failed, $Failed, $Failed, $Failed, 0., 1., 1.41421, 1.73205}

The work-around works also using Check:

In[313]:=Remove[func28]
func28 = Compile[{{v, _Real}}, Block[{r}, r = Sqrt[v - 28]]];
If[True,(*if True unfreak the error handler, otherwise get complex numbers below after 3x"error"*)
  func28[#] & /@ {1, 28}
  ];
Map[Check[func28[#], "error"] &, Range[24, 30]]    
Out[316]= {"error", "error", "error", "error", 0., 1., 1.41421}

I have sent a bug report to Wolfram Support. Andreas

Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract