# Creating a multidimensional array with Compile

For one of my programs I need to preallocate a multidimensional list/array. For performance reasons I want to do this within Compile and compile my program to C-code.

Now I made the following observation for the following minimal working example:

cf = Compile[{}, Block[{list},
list = Table[{0., 1.}, {1}, {1}];
list[[1, 1, 2]]], CompilationTarget :> "MVM"];


with CompilationTarget :> "MVM" this function works just fine. When I call cf[] I obtain the expected result 1.. Now if I change CompilationTarget->"C", I receive the following error message when I define the function cf in MMA

CCompilerDriverCreateLibrary::cmperr: Compile error: C:\Users\AppData\Roaming\Mathematica\ApplicationData\CCompilerDriver\BuildFolder\compiledFunction100.c(152) : error C2440: 'function' : cannot convert from 'mreal' to 'MTensor *' >>
Compile::nogen: A library could not be generated from the compiled function. >>


Note that for both CompilationTargets CompilePrint shows that the code just compiles nicely.

If I keep the code to be compiled to C but change the dimensionality of the list the error message disappears

(*Compiled function*)
cf = Compile[{}, Block[{list},
list = Table[{0., 1.}, {1}];
list[[1, 1]]], CompilationTarget :> "C"];


Any clue how this behaviour comes about? I guess the C-compiler cannot handle these kind of Tables where I give a List of rank 1 as a first argument and only accepts arguments of rank 0. However, since the error message only appears when I define the function but not when I call it, is it safe to use anyway? (since CompilePrint shows no call to MainEvaluate).

• I would do something like cf= With[{list =Table[{0.,1.},{1},{1}]}, Compile[{}, list[[1,1,2]],CompilationTarget:>"C"]] – Rolf Mertig Nov 23 '18 at 10:03
• This behavior exists since v8.0, not sure if this should be called a bug or a limitation, but I think it's worth reporting to WRI. – xzczd Nov 23 '18 at 12:18
• @MichaelE2: In your code you missed the third argument of list, i.e. when going down to the single element e.g. by list[[1,1,2]]. With list[[1,1]] everything works just fine I agree. – Display Name Nov 23 '18 at 14:07
• No problem. I think it is not a major issue, since some easy workaround exists. It was more an observation by myself which I wanted to share. And interesting that it seemed to work with older versions of MMA. – Display Name Nov 23 '18 at 14:10
• Note if integers are used, I get no error but the kernel crashes on execution of cf[]: cf = Compile[{}, Block[{list}, list = Table[{0, 1}, {1}, {1}]; list[[1, 1, 2]]], CompilationTarget :> "C"] – Michael E2 Nov 23 '18 at 14:12

…since the error message only appears when I define the function but not when I call it, is it safe to use anyway?

This depends on how you define safe. A CompiledFunction that's compiled to C succesfully owns a LibraryFunction as its last argument:

Compile[{}, 1, CompilationTarget -> C] // InputForm


CompiledFunction[……,LibraryFunction[……]]

This is what makes the CompiledFunction faster (in some cases). So, the cf will still give you the correct output, but it loses the blessing of C.

Finally, a possible workaround:

cffixed = Unevaluated@Compile[{}, Block[{list = {{{}}}}, list = Table[{0., 1.}, {1}, {1}];
list[[1, 1, 2]]], CompilationTarget -> C] /. Part -> CompileGetElement


The keypoint is list = {{{}}} i.e. initializing list with an empty list with correct dimension. Part -> CompileGetElement isn't necessary but it speeds up the code.

• Thank you for your extensive answer. I also like @Rolf Mertig 's comment. – Display Name Nov 23 '18 at 14:12
• @DisplayName To get an array of integers, you need to be explicit about the type in the dummy initialization of list: Compile[{}, Block[{list = {{{0}}}}, list = Table[{0, 1}, {1}, {1}]; list[[1, 1, 2]]], CompilationTarget -> "C"] -- By default, the type of the empty list will be assumed to be depth-3 array of type Real`. Similar type-inferencing problems are discussed here: (845), (43580) – Michael E2 Nov 23 '18 at 14:25
• Good to know, thank you! – Display Name Nov 23 '18 at 15:19