MathGroup Archive 2012

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Function return type in Compile


Hi,

unfortunately this is all far away from working fine. You have to  
check whether your testQ is really compiled or whether it is evaluated  
as a call to the kernel from within the compiled function. Here are  
your two versions that seem to work fine:

<< CompiledFunctionTools`
TestQ[x_Integer] := If[EvenQ[x], True, False];
cf1 = Compile[{{y, _Integer}},  If[TestQ[y], 1, 2], {{TestQ[_], True |
False}}];

TestQ2 = Function[{x}, If[EvenQ[x], True, False]];
cf2 = Compile[{{y, _Integer}},  If[TestQ2[y], 1, 2]];

CompilePrint/@{cf1,cf2}

Note that the code for TestQ is not used. Instead there is a  
MainEvaluate kernel call to get the answer of TestQ/TestQ2. Your way  
to go is (beside others)

cf3 = Compile[{{y, _Integer}}, If[TestQ2[y], 1, 2],
    CompilationOptions -> {"InlineExternalDefinitions" -> True}];

(* or *)

cf4 = Compile[{{y, _Integer}}, If[#[y], 1, 2]] &[TestQ2];


to inline the function definition inside the compile call.

Cheers
Patrick

Quoting Oleksandr Rasputinov <oleksandr_rasputinov at hmamail.com>:

> On Sat, 14 Jan 2012 08:02:32 -0000, Ashwini <aksingh21 at gmail.com> wrote:
>
>> Hi,
>> I have large number of small functions whose return type is  Boolean
>> or Integer.
>> How can I declare the function return type in a global way so that I
>> don't have to write it down in every Compile:
>>
>> Example:
>> TestQ[x_Integer] := If[EvenQ[x], True, False]; (*Just a wrapper on
>> EvenQ*)
>>
>> cf2 = Compile[{{y, _Integer}}, If[TestQ[y], 1, 2]];
>>
>> cf2[2]
>> CompiledFunction::cfex: Could not complete external evaluation at
>> instruction 1; proceeding with uncompiled evaluation.
>>
>> After including the return type of TestQ, It works fine
>> cf3 = Compile[{{y, _Integer}},  If[TestQ[y], 1, 2], {{TestQ[_], True |
>> False}}];
>>
>> cf3[2] works fine.
>>
>> But if I replace TestQ with EvenQ I don't have to specify the the
>> return type
>> cf4 = Compile[{{y, _Integer}}, If[EvenQ[y], 1, 2]];
>>
>> How can this be done for TestQ?
>>
>> regards,
>> Ashwini
>>
>
> The simple answer is that it can't, or at least not in the way that you
> want. The only functions that Compile understands are given by
>
> Compile`CompilerFunctions[]
>
> and, as far as I know, types cannot be provided by the user for functions
> that Compile doesn't know about except via the third argument.
>
> However, if you define TestQ as follows, it seems that the types are more
> transparent to Compile and it can handle them automatically:
>
> TestQ = Function[{x}, If[EvenQ[x], True, False]];
>
> And of course, since these are small functions that require calling out of
> the bytecode interpreter (which is fairly costly) one may wish to inline
> them for better performance by setting CompilationOptions ->
> "InlineExternalDefinitions" -> True.
>
> Another possible way is to wrap Compile inside your own function that
> writes out the third argument as required based on a type specification
> you have provided elsewhere. This might be more reliable in more
> complicated cases if Compile can't infer the types correctly on its own.
>
>



----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.





  • Prev by Date: Re: How to simplify this code with variable number of
  • Next by Date: Re: how can one use mathematica get the approximate derivative of {x,y} data points?
  • Previous by thread: Re: Function return type in Compile
  • Next by thread: Re: Can't use subscripted variables in function