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.