MathGroup Archive 2010

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

Search the Archive

Re: Pass by reference for compiled functions

Hi Eric,

You can  also kind of emulate pass-by-reference by inlining compiled
functions, but this will only
work if your caller function  is also Compiled, and all the ingredients are
compiled. Here is an example:

Clear[primeQ ];
primeQ  =
  Compile[{{n, _Integer}},
   Total[1 - Unitize@Mod[n, Range[2, IntegerPart[Sqrt[n]] + 1]]] ==

primes =
   list = Select[list, primeQ],
   CompilationOptions -> {"InlineExternalDefinitions" -> True,
     "InlineCompiledFunctions" -> True}];

test =
   Module[{list = Range[100000]},
   CompilationOptions -> {"InlineExternalDefinitions" -> True,
     "InlineCompiledFunctions" -> True}];


Note that the variable <list> has not been defined in <primes>, so <primes>
works essentially
like a macro. At the end, everything is inlined inside <test>, and for this
to work, this must
have happened before the variables are bound. So, we actually do change the
variable <list>
defined in <test>, even though it is done inside <primes>. At the same time,
the global <list>
does not acquire any value. But this would not work if <primes> would not
have entirely compiled -
for instance, if you change primeQ (compiled) to PrimeQ (uncompiled,
built-in, external call).

You can inspect the final compiled code for <test> by calling test[[6]] and
see that it indeed
did compile completely to byte-code. In particular, you should be able to
compile to C if needed.
So, this is not the true pass-by-reference since no arguments are passed
explicitly, but this seems
to give similar means of combining larger programs from smaller pieces
without copying data, more
like templates. I am not sure about the status of this "technique", I just
discovered it recently - this
looks more like a hack to me, but it seems to work.

Hope this helps.


On Mon, Nov 29, 2010 at 2:10 PM, Eric Michielssen
<emichiel at>wrote:

> For noncompiled functions, one can pass arguments "by reference" and then
> modify them inside the routine by assigning the function the attribute
> HoldAll.
> This does not work for compiled functions: it does not appear possible to
> modify arguments to compiled functions, even if they are passed as "global
> variables". That is, Mathematica responds to
> Myfunction = Compile[
> {{var1,_Real}},
> Module[{},
> Modify var 1 or var2;
> Return[]], {var2,_Real}];
> With
> Compile::argset: The assignment to var1 is illegal; it is not valid to
> assign a value to an argument. >>  And something similar for var2.
> HoldAll does not seem to apply here...
> This makes it memory-inefficient to modify large arrays in compiled
> functions, as one would have to operate on a copy of the array.
> Is there a workaround in Mathematica 8?
> Eric Michielssen

  • Prev by Date: Re: SelectionMove[] busted with InputField and DockedCells?
  • Next by Date: Re: Why are my 3D plots blue?
  • Previous by thread: Re: SelectionMove[] busted with InputField and DockedCells?
  • Next by thread: Re: Why are my 3D plots blue?