KRPO
KRPO

Reputation: 13

Compiling the Cuba library

I currently need to use the Cuba library in Julia to compute some three-dimensional integration. In fact, I need to use the cuhre function quite a lot of times within a single run for I need to do. However, this has the issue of making lots of allocation.

As an example, I can try to integrate f(x1,x2,x3) = x1*x2*x3, which gives me the result (when I use @time to quickly look at the performance)

julia> @time cuhre((x,f)->f[1]=x[1]*x[2]*x[3],3,1)
0.101907 seconds (115.82 k allocations: 5.809 MiB)
Component:
1: 0.125 ± 1.5700924586837752e-16 (prob.: 0.0)
Integrand evaluations: 381
Number of subregions:  2
Note: The desired accuracy was reached

The issue is that the allocation can only add up, meaning that I can quickly reach ten's of millions of allocations and GiB's. Since Julia doesn't seem to have a way to free memory, I looked more closely at the Cuba.jl package and saw that it wrapped the C library Cuba (using ccall). I looked a bit at the code (The cuhre part in the C labrary) and saw that it never freed the allocated memory. More precisely, I saw the use (in Integrate.c) of

RuleAlloc(t);

FrameAlloc(t, Master);

MemAlloc(cur, poolsize);

to the pointer

This *t

and

Pool *cur = NULL, *pool;

However, the only case where I seems to free memory is when there is an abort:

abort:
  while( (pool = cur) ) {
    cur = cur->next;
    free(pool);
  }
  FrameFree(t, Master);
  RuleFree(t);

  StateRemove(t);

  return fail;

whereas it never does when the program runs smoothly.

So I thought about manually modifying this function and adding the memory freeing myself and git-cloned the the cuba library. However, I am struggling to compile the latest version (4.1). I tried to follow the (very few) instructions that are given, namely typing

$ ./configure
$ ./makeshared.sh #

but the second one doesn't work

$ ./makeshared.sh #
bash: ./makeshared.sh: Aucun fichier ou dossier de ce type

(No file of folder of this type). I looked for solutions and found this topic, and tried the various answers that were given (to run the demo-c.c file), but none seemed to work, mainly because there is no longer a libcuba.a file within the files.

As this is of any help, here is the error I get when compiling the demo-c.c file

$ gcc -o demo-c.exe demo-c.c -lm
/tmp/ccAYMLVk.o : Dans la fonction « main » :
demo-c.c:(.text+0x123) : référence indéfinie vers « Vegas »
demo-c.c:(.text+0x226) : référence indéfinie vers « Suave »
demo-c.c:(.text+0x343) : référence indéfinie vers « Divonne »
demo-c.c:(.text+0x439) : référence indéfinie vers « Cuhre »
collect2: error: ld returned 1 exit status

(undefined reference towards ...). In the 1.1 version, this was solved by using the command

gcc -o demo-c.exe demo-c.c ../libcuba.a -lm

but it obviously works no longer as there is no such file anymore.

Upvotes: 1

Views: 368

Answers (1)

giordano
giordano

Reputation: 8344

Generally speaking, if you have any issue with the Cuba C library, the best thing to do is to contact the author: https://wwwth.mpp.mpg.de/members/hahn/. If an issue is fixed upstream, it'll be eventually included in the Cuba.jl Julia wrapper.


Understand that your memory allocation worry is misplaced for a few different reasons:

  1. you aren't doing the benchmark correctly: the BenchmarkTools.jl package provides more accurate and reliable tools for benchmarking:
    julia> using Cuba, BenchmarkTools
    
    julia> @time cuhre((x,f)->f[1]=x[1]*x[2]*x[3],3,1);
      0.055585 seconds (105.25 k allocations: 5.375 MiB)
    
    julia> @btime cuhre((x,f)->f[1]=x[1]*x[2]*x[3],3,1);
      37.067 μs (1527 allocations: 71.72 KiB)
    
    This is a couple of orders of magnitude less than what you were thinking;
  2. both @time and @btime macros measure memory allocations on the Julia side, not those of the C libraries that may be called, so the memory allocations you're seeing don't come from the Cuba library;
  3. you say that memory allocations add up, but this isn't exactly true: since memory allocated by each call to the integration function is eventually freed.

If performance of cuhre from Cuba.jl is really an issue for you in practice (it rarely is for me), I strongly recommend you looking into the HCubature.jl package: it is written entirely in Julia, implements the same algorithm as cuhre from Cuba.jl and allows you to use StaticArrays.jl, which are more memory-efficient than standard arrays when dealing with small sizes (less than ~16 elements).

Upvotes: 1

Related Questions