MathGroup Archive 2011

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

Search the Archive

Compilation: Avoiding inlining

This message refers to the extensive exchange here:

The problem is to solve a system of N ordinary differential equations
(ODE) with Runge-Kutta-4 method with compilation. Here is an example
of working program

(* Runge-Kutta-4 routine *)
makeCompRK[fIn_] :=
  With[{f = fIn},
   Compile[{{x0, _Real,
      1}, {t0, _Real}, {tMax, _Real}, {n, _Integer}},
    Module[{h, K1, K2, K3, K4, SolList, x = x0, t},
     h = (tMax - t0)/n;
     SolList = Table[x0, {n + 1}];
     Do[t = t0 + k h;
      K1 = h f[t, x];
      K2 = h f[t + (1/2) h, x + (1/2) K1];
      K3 = h f[t + (1/2) h, x + (1/2) K2];
      K4 = h f[t + h, x + K3];
      x = x + (1/6) K1 + (1/3) K2 + (1/3) K3 + (1/6) K4;
      SolList[[k + 1]] = x
      , {k, 1, n}];

(* Definition of the equations *)
NN = 100;
 RHS = Quiet[
    Table[-x[[i]] Sin[
        0.3 t]^2/(1 + 300 Sum[x[[j]], {j, 1, NN}]^2/NN^2), {i, 1,
NN}]];] (* Quiet to suppress complaints *)
F = Function[{t, x},
   Evaluate[RHS]];  (* Evaluate to use actual form of RHS *)

(* Compilation *)
tt0 = AbsoluteTime[];
Timing[RK4Comp = makeCompRK[F];]
AbsoluteTime[] - tt0

(* Setting parameters and Calculation *)
x0 = Table[
  RandomReal[{0, 1}], {i, 1, NN}];   t0 = 0;    tMax = 100;   n = 500;
tt0 = AbsoluteTime[];
Sol = RK4Comp[x0, t0, tMax, n];
AbsoluteTime[] - tt0

Print["Compilation: ", Developer`PackedArrayQ@Sol]

(* Plotting time dependences *)
x1List = Table[{1. t0 + (tMax - t0) k/n, Sol[[k + 1, 1]]}, {k, 0,
x2List = Table[{1. t0 + (tMax - t0) k/n, Sol[[k + 1, 2]]}, {k, 0, n}];
x3List = Table[{1. t0 + (tMax - t0) k/n, Sol[[k + 1, 3]]}, {k, 0, n}];
ListLinePlot[{x1List, x2List, x3List}, PlotMarkers -> Automatic,
 PlotStyle -> {Blue, Green, Red}, PlotRange -> {0, 1}]


The drawback of this solution is what Oliver Ruebenkoenig called
"inlining". For large NN the RHS of the equations is a lot the
explicit code generated by Mathematica. This code then gets compiled
and the size of the compiled code strongly increases with NN (it can
be seen by the CompilePrint[RK4Comp] command). That is, we write a lot
of code inline instead of letting it be generated in the course of the
execution, with the compiled code being small.

Mathematica's own compiler tolerates inlining, although the large code
eats up the memory. If we uncomment the option "CompilationTarget-
>"C"", we will see that for large NN compilation goes for ages. That
is, inlining has to be avoided.

Daniel Lichtblau has rewritten my similar program in the vectorized
form that avoided inlining and could be compiled to C, and was fast.
But vectorization is not always possible or easy. Oliver wrote that
inlining can also be avoided by defining a function and then calling
it, but there were no examples at that time. Now I am interested in
the cases such as the program above where vectorization is unwanted.
How to avoid inlining by defining a function in this case? I have
tried to replace

RHS = Quiet[Table[-x[[i]] Sin[0.3 t]^2/(1 + 300 Sum[x[[j]], {j, 1,
NN}]^2/NN^2), {i, 1, NN}]];


FRHS[i_][x_List, t_] = -x[[i]] Sin[0.3 t]^2/(1 + 100 Sum[x[[i + j]],
{j, 1, Min[3, NN - i]}]^2);
RHS = Quiet[Table[FRHS[i][x, t], {i, 1, NN}]];

This works correctly but does not compile, and the execution time is
longer. Something is wrong here. Oliver, Daniel, and others, please,

Thank you,


  • Prev by Date: Re: Table->Value
  • Next by Date: Nonlinearregress with symbolic partial differential equation and integration
  • Previous by thread: Re: "Traveling salesman on a hemisphere" problem
  • Next by thread: Re: Compilation: Avoiding inlining