[Openmcl-devel] Erroneous results if function is untraced
R. Matthew Emerson
rme at clozure.com
Tue Dec 30 20:42:40 PST 2008
On Dec 30, 2008, at 9:05 PM, Liam Healy wrote:
> (lisp-implementation-version)
> "Version 1.2-r10552 (LinuxX8664)"
>
> In testing my system GSLL, an interface to the GNU Scientific Library
> (GSL), I have found a few failures under CCL. These tests will run
> correctly if the function is traced, or if the values are defined with
> a defparameter. In this example, #(0 0 0 0) is the wrong answer, #(3
> 2 1 0) is the correct answer:
>
> Welcome to Clozure Common Lisp Version 1.2-r10552 (LinuxX8664)!
> ? (clc:clc-require :gsll-tests)
> T
> ? (in-package :gsl)
> #<Package "GSLL">
>
> ;; Call inside let, fails
> ? (let ((perm (make-permutation 4 T))) (permutation-reverse perm))
> #<PERMUTATION #(0 0 0 0)>
>
> ;; Trace the function and repeat, suceeds:
> ? (trace permutation-reverse)
> NIL
> ? (let ((perm (make-permutation 4 T))) (permutation-reverse perm))
> 0> Calling (PERMUTATION-REVERSE #<PERMUTATION #(0 1 2 3)>)
> <0 PERMUTATION-REVERSE returned #<PERMUTATION #(3 2 1 0)>
> #<PERMUTATION #(3 2 1 0)>
>
> ;; No tracing, use defparameter, succeeds:
> ? (defparameter *perm* (make-permutation 4 t))
> *PERM*
> ? *perm*
> #<PERMUTATION #(0 1 2 3)>
> ? (permutation-reverse *perm*)
> #<PERMUTATION #(3 2 1 0)>
>
> ;; Direct call fails:
> ? (permutation-reverse (make-permutation 4 t))
> #<PERMUTATION #(0 0 0 0)>
>
> ;; Tracing, direct call fails
> ? (permutation-reverse (make-permutation 4 t))
> 0> Calling (PERMUTATION-REVERSE #<PERMUTATION #(0 1 2 3)>)
> <0 PERMUTATION-REVERSE returned #<PERMUTATION #(3 2 1 0)>
> #<PERMUTATION #(3 2 1 0)>
>
> All the calls that exhibit the problem are FFI calls via CFFI. For
> example,
> (DEFUN PERMUTATION-REVERSE (P)
> (DECLARE)
> "Reverse the order of the elements of the permutation p."
> (LET NIL
> (COPY-CL-TO-C P)
> (LET ((#:CRETURN (FOREIGN-FUNCALL "gsl_permutation_reverse"
> :POINTER (MPOINTER P) :VOID)))
> (DECLARE (IGNORE #:CRETURN))
> (SETF (CL-INVALID P) T)
> (VALUES P))))
> (from a macro expansion)
One thing I noticed that might help you:
? (progn (setq junk (make-permutation 4 t)) nil)
NIL
? (slot-value junk 'cl-array)
#(0 0 0 0)
? (slot-value junk 'c-invalid)
T
So, it would appear that when you call PERMUTATION-REVERSE, COPY-CL-TO-
C duly copies the contents of the cl-array slot to the foreign memory
(since the c-invalid slot is T), and that explains why the answer is
#(0 0 0 0).
So maybe MAKE-PERMUTATION needs to update the cl-array slot or set the
c-valid slot to T or do some other appropriate thing.
As gb already guessed, the act of printing a permutation object synchs
up the contents of the cl-array slot with the contents of the foreign
memory, so the PERMUTATION-REVERSE subsequently works.
More information about the Openmcl-devel
mailing list