# Closing over array values makes Compile choke with CompilationTarget -> “C”

When I attempt to Compile a closure which contains an array of the appropriate type, it works just fine with CompilationTarget -> "WVM":

In[1]:= cf = With[{id = N@IdentityMatrix@500},
Compile[{{v, _Real, 1}},
id.v]]
Out[1]= CompiledFunction[<>]


However, when I try to compile to C, awful things happen.

In[2]:= With[{id = N@IdentityMatrix@500},
Compile[{{v, _Real, 1}},
id.v,
CompilationTarget -> "C"]]
(* Kernel hangs and/or crashes here while trying to "render dynamic content" *)


Poking around in the directory that Compile compiles things in, I found a 6 MB source file that contained exactly 250 000 of lines of this (I gather it's supposed to be cleaned up, but that must not have happened when the kernel went kablooey):

#include "math.h"

#include "WolframLibrary.h"
[...]
static MTensor T0_1B = 0;

static MTensor* T0_1 = &T0_1B;

static mreal *P1;
[...]
P1 = MTensor_getRealDataMacro(*T0_1);
P1[0] = 1.;
P1[1] = 0.;
P1[2] = 0.;
P1[3] = 0.;
P1[4] = 0.;
P1[5] = 0.;
P1[6] = 0.;
P1[7] = 0.;
P1[8] = 0.;
P1[9] = 0.;
[...]
P1[249998] = 0.;
P1[249999] = 1.;


The compilation appears to have succeeded, because there's also a 2.6 MB library object there, but then it tried to render something (maybe the fancy little StandardForm icon they have for CompiledFunctions now) and everything came to a screeching halt. Also, I suspect that may not be the best way to initialize that data for the tensor. Is there a way to make the compiler do something more useful here?

mv = Compile[{{v, _Real, 1}, {id, _Real, 2}},
id.v,
CompilationTarget -> "C"
];

v = RandomReal[{0, 1}, 500];

id = N[IdentityMatrix[500]];

res=mv[v, id]


It works without trouble.

• +1, though for my particular use case it would be fairly painful, as the stuff that's going wrong is in generated, rather than handwritten, code. – Pillsy Sep 18 '15 at 21:32