MathGroup Archive 2012

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

Search the Archive

Re: Function return type in Compile

  • To: mathgroup at smc.vnet.net
  • Subject: [mg124301] Re: Function return type in Compile
  • From: Patrick Scheibe <pscheibe at trm.uni-leipzig.de>
  • Date: Mon, 16 Jan 2012 17:10:11 -0500 (EST)
  • Delivered-to: l-mathgroup@mail-archive0.wolfram.com
  • References: <jercqo$1f8$1@smc.vnet.net>

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