I'm calling a C function from CMUCL to do hierarchical clustering on a
computer with 2 GB's of RAM. This C function allocates memory to store
distances between the observations being clustered. When I cluster a
data set of 18500 observations, this C function fails to allocate the
required 1306 MB's of memory when my computer still has around 1800 MB's
of free memory. However, I can allocate 1306 MB's of memory with plain
C code without any problem.
The 3 files attached at the end illustrate my problem.
On a computer with 2 or more GB's of RAM, you can allocate 1306 MB's of
memory with straight C code by doing:
gcc main.c
a.out
and you'll get "yes..."
To call a C function from CMUCL to allocate the same amount of memory,
you first do:
gcc -c big.c
and fire up CMUCL and enter:
(ext:load-foreign "big.o")
(load "allocate")
(allocated-p 171115750)
and you'll get NIL.
Does anybody know why a C function called from CMUCL can not allocate as
much memory as a C function invoked from a Unix shell? Most importantly,
any way to get around this problem?
Best,
-cph
;;-------------------- File: main.c ---------------------------------
#include <stdio.h>
main ()
{
double *dist;
dist = (double *)calloc (171115750, 8);
if (dist) {
(void)printf("yes...\n");
free (dist);
} else {
(void)printf("no...\n");
}
return 0;
}
;;-------------------- File: big.c ---------------------------------
#include <stdio.h>
int big (int *len,int *ok)
{
double *dist;
dist = (double *)calloc (*len, 8);
if (dist) {
*ok = 1;
free (dist);
} else {
*ok = 0;
}
return 0;
}
;;-------------------- File: allocate.lisp ---------------------------------
(eval-when (:execute :compile-toplevel :load-toplevel)
(progn
(declaim (inline c-big))
(alien:def-alien-routine ("big" c-big)
c-call:void
(len c-call:int :copy)
(ok-p (* c-call:int) :in))
(defun call-c-big (len)
(let ((ok-p (make-array '(1)
:element-type '(Unsigned-Byte 32)
:initial-contents '(0))))
(system:without-gcing
(let ((addr-ok-p (system:vector-sap ok-p)))
(c-big len
addr-ok-p)))
(aref ok-p 0)))))
(defun allocated-p (len)
(if (zerop (call-c-big len))
nil
t))