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))


Reply via email to