[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