# Escaping out of (or exiting) a Compiled Function

How do I manually escape out of a compiled function without forcing an error and compromising its speed?

Here is an example:

f::zero = "x is zero.";

f = Compile[{{x, _Complex}}, If[x == 0, Return[1/x], x^2],
"RuntimeOptions" -> {"RuntimeErrorHandler" ->
Function[Message[f::zero]; Throw[$Failed]]}];  As you can see, I want f to throw an error when x=0, but in order to do that, I needed to artificially think there actually was an error by returning 1/x. Here is the usage: Catch[f[0]]  CompiledFunction::cfne : Numeriacal Error encountered; proceeding with uncompiled evaluation. >> f::zero : x is zero 1. How do I prevent the kernel from proceeding with uncompiled evaluation of the artificial 1/0 like it says (which I believe compromises speed). 2. How do I escape out of a CompiledFunction without mimicking an error? • You could use a wrapper function that calls the compiled function and that catches numeric error codes, for instance in this case negative numbers and acts on them. Nov 29 '14 at 13:51 • The uncompiled evaluation on returning an infinite or not-a-number value seems to be hard-wired in the VM. I don't think it's possible to avoid that except as described by Sjoerd. Nov 29 '14 at 14:37 • Ok, it looks like @SjoerdC.deVries 's method works and doesn't compromise the speed too much (at least in the cases I'm working on) Nov 29 '14 at 17:54 • @SjoerdC.deVries would you kindly turn your comment into an answer. I'll accept and this question will go off the unanswered list. Nov 19 '15 at 10:30 • @QuantumDot OK, done Nov 19 '15 at 22:30 ## 2 Answers f::zero = "x is zero."; f = Compile[{{x, _Complex}}, If[x == 0, Throw[Message[f::zero];$Failed]; Return[1/x], x^2]];

Catch[f[0]]


Or

f = With[{cf = Compile[{{x, _Complex}}, If[x == 0, Throw[Message[f::zero]; $Failed], x^2]]}, Catch[cf[#]] &]; f[0]  In the case of x == 0 there will be one (thanks to the comment by Oleksandr) MainEvaluate call, but it shouldn't have a more significant impact on the speed than using a wrapper function. • Why not return $Failed, rather than throwing it, so the calling function doesn't have to be wrapped in Catch to have good behavior? Nov 20 '15 at 0:42
• @m_goldberg Because of type inconsistency. Nov 20 '15 at 0:46
• This is an excellent solution, especially if you're going to have to postprocess the return value anyway. Incidentally, the two calls out to the top level can be made into one by moving Message inside Throw, although I'm not sure that this really matters in practice. Nov 20 '15 at 1:03
• @OleksandrR. Although I couldn't find a measurable speed difference, I do prefer having only one MainEvaluate. Thanks. Nov 20 '15 at 3:16
ClearAll[f, fc]
f::zero = "x is zero.";

(* compiled part *)
fc =
Compile[{{x, _Complex}},
(* First part of the code; can be anything
.
.
*)
If[x == 0, (* Error test*)
{0, 0}, (* Error response, first part is status, second part is dummy *)
{1, x^2} (* Normal response, first part is status, second part actual result *)
]
];

(* wrapper part *)
f[x_] := With[{res = fc[x]},
If[Chop[res[[1]]] == 0, (* check status *)
Message[f::zero]; $Failed, (* error *) res[[2]] (* normal result *) ]] f[0]  f[1] (* 1. + 0. I *)  or with MichaelE2's suggestion: ClearAll[f, fc] f::zero = "x is zero."; fc = Compile[{{x, _Complex}}, (* First part of the code *) If[x == 0, (* Error test*) {},(* Error response, empty list *) {x^2} (* Normal response, list with result *) ] ]; f[x_] := With[{res = fc[x]}, If[res == {}, Message[f::zero];$Failed, First@res]]

• I might consider indicating the error by returning an empty array and a normal result in extra set of braces: E.g., If[x == 0, {}, {x^2}]. The empty array needs to be of the same rank as the other result. (Just an alternative for folks to choose from.) Nov 19 '15 at 22:41
• @MichaelE2 Good idea. Updated the answer. Nov 19 '15 at 22:58
• Catch and Throw are compilable. Therefore this answer could easily be modified to have an early escape. Nov 20 '15 at 2:51
• @MichaelE2 There will be an extra ArrayReshape when using an empty array. Shouldn't be significant for the speed, though. Nov 20 '15 at 3:02
• @MichaelE2 the other great advantage of using Throw, and which I think would outweigh any performance differences, is that you can put in it whatever you want--any values generated inside the compiled code; arbitrary top-level code; diagnostic messages... it is a lot more useful than just a numeric flag. Nov 20 '15 at 11:07