Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Does slime introduce errors into cmucl?

5 views
Skip to first unread message

Norbert_Paul

unread,
Mar 30, 2010, 2:20:33 PM3/30/10
to
I startet testing some matrix computation routines in slime using rt.
(This was useful: Made me spot a bug)

But then however I set up a test case using random dimensions and values
and let it run 10000 times and sometimes the tests fails, even when the
resulting matrix was correct. (I stored the fixture in global variables to
inspect).

All tests run fine in bare cmucl and bare sbcl (on my system sbcl doesn't work
together with slime). In the slime sbcl-repl (which I took, brother,
but there it didn't serve me well), however, the following sometimes fails:

(dotimes (i 100000)
(let* ((v1 (list (random 10d0)(random 10d0)))
(v2 (list (random 10d0)(random 10d0)))
(dot1 (reduce #'+ (mapcar #'* v1 v2)))
(dot2 (reduce #'+ (mapcar #'* v1 v2))))
(if (/= dot1 dot2)
(error "This REPL doesn't serve me well, brother."))))

I'm using Debian squeeze with
GNU Emacs 23.1.1 (i486-pc-linux-gnu, GTK+ Version 2.18.2) of 2009-11-02 on raven, modified by Debian
and
slime version 1:2010022-1.

Is that a known bug in slime or any other of aforementioned components?


Norbert

Norbert_Paul

unread,
Mar 30, 2010, 2:27:38 PM3/30/10
to
Norbert_Paul wrote:
...

> I'm using Debian squeeze with
> GNU Emacs 23.1.1 (i486-pc-linux-gnu, GTK+ Version 2.18.2) of 2009-11-02
> on raven, modified by Debian
> and
> slime version 1:2010022-1.
and
CMU CL "CVS 20a 20a-release + minimal debian patches (20A Unicode)"

vanekl

unread,
Mar 30, 2010, 3:31:35 PM3/30/10
to
Norbert_Paul wrote:
> (dotimes (i 100000)
> (let* ((v1 (list (random 10d0)(random 10d0)))
> (v2 (list (random 10d0)(random 10d0)))
> (dot1 (reduce #'+ (mapcar #'* v1 v2)))
> (dot2 (reduce #'+ (mapcar #'* v1 v2))))
> (if (/= dot1 dot2)
> (error "This REPL doesn't serve me well, brother."))))
>
> I'm using Debian squeeze with
> GNU Emacs 23.1.1 (i486-pc-linux-gnu, GTK+ Version 2.18.2) of
> 2009-11-02 on raven, modified by Debian and
> slime version 1:2010022-1.
>
> Is that a known bug in slime or any other of aforementioned
> components?
>
> Norbert


no worries here, brothuh

CL-USER> (dotimes (i 100000)


(let* ((v1 (list (random 10d0)(random 10d0)))
(v2 (list (random 10d0)(random 10d0)))
(dot1 (reduce #'+ (mapcar #'* v1 v2)))
(dot2 (reduce #'+ (mapcar #'* v1 v2))))
(if (/= dot1 dot2)
(error "This REPL doesn't serve me well, brother."))))

NIL
CL-USER> swank::*swank-wire-protocol-version*
"2010-03-29"
CL-USER> (swank-loader::slime-version-string)
"2010-03-29"
CL-USER> (lisp-implementation-version)
"1.0.36.38"
CL-USER> *features*
(:SB-BSD-SOCKETS-ADDRINFO :ASDF :SBCL-HOOKS-REQUIRE :ANSI-CL :COMMON-LISP
:SBCL
:SB-DOC :SB-TEST :SB-LDB :SB-PACKAGE-LOCKS :SB-UNICODE :SB-EVAL
:SB-SOURCE-LOCATIONS :IEEE-FLOATING-POINT :X86 :UNIX :ELF :LINUX :SB-THREAD
:LARGEFILE :GENCGC :STACK-GROWS-DOWNWARD-NOT-UPWARD
:C-STACK-IS-CONTROL-STACK
:COMPARE-AND-SWAP-VOPS :UNWIND-TO-FRAME-AND-CALL-VOP
:RAW-INSTANCE-INIT-VOPS
:STACK-ALLOCATABLE-CLOSURES :STACK-ALLOCATABLE-VECTORS
:STACK-ALLOCATABLE-LISTS :STACK-ALLOCATABLE-FIXED-OBJECTS :ALIEN-CALLBACKS
:CYCLE-COUNTER :INLINE-CONSTANTS :LINKAGE-TABLE :OS-PROVIDES-DLOPEN
:OS-PROVIDES-PUTWC :OS-PROVIDES-SUSECONDS-T)
CL-USER> (SB-SYS:GET-MACHINE-VERSION )
"Intel(R) Pentium(R) 4 CPU 3.00GHz"

>emacs-X11.exe --version
GNU Emacs 23.1.1


Peter Keller

unread,
Mar 30, 2010, 4:00:01 PM3/30/10
to
Norbert_Paul <norbertpau...@yahoo.com> wrote:
> (dotimes (i 100000)
> (let* ((v1 (list (random 10d0)(random 10d0)))
> (v2 (list (random 10d0)(random 10d0)))
> (dot1 (reduce #'+ (mapcar #'* v1 v2)))
> (dot2 (reduce #'+ (mapcar #'* v1 v2))))
> (if (/= dot1 dot2)
> (error "This REPL doesn't serve me well, brother."))))

I would think this code is suspect since you don't take into consideration
numerical analysis techniques for comparing floating point numbers.

I'd suppose the test should be:

(when (> (abs (- dot1 dot2)) *tolerance*)
(format t "Not equal!~%"))

and *tolerance* would be something like 10e-8 or so.

-pete

Norbert_Paul

unread,
Mar 30, 2010, 4:22:05 PM3/30/10
to
Peter Keller wrote:
> Norbert_Paul<norbertpau...@yahoo.com> wrote:
>> (dotimes (i 100000)
>> (let* ((v1 (list (random 10d0)(random 10d0)))
>> (v2 (list (random 10d0)(random 10d0)))
>> (dot1 (reduce #'+ (mapcar #'* v1 v2)))
>> (dot2 (reduce #'+ (mapcar #'* v1 v2))))
>> (if (/= dot1 dot2)
>> (error "This REPL doesn't serve me well, brother."))))
>
> I would think this code is suspect since you don't take into consideration
> numerical analysis techniques for comparing floating point numbers.
No. I know about these errors, but note that the expressions to compute
dot1 and dot2 are absolutely equal. Therefore they /must/ produce the same
results (with the same errors).
My initial version was dot1 = v1 . v2 and dot2 = v2 . v1, but later I
suspected this might introduce such floating-point errors.
Therefore I also tried the above.
Also in my test cases where the error occured for the first time the
differences between both values werde significant and not only by an error.

These

(0.0d0 12.230520293356577d0)
(37.202197698216956d0 51.02715433387322d0)

are some outputs of

(dotimes (i 100000)
(let* ((v1 (list (random 10d0)(random 10d0)))
(v2 (list (random 10d0)(random 10d0)))
(dot1 (reduce #'+ (mapcar #'* v1 v2)))
(dot2 (reduce #'+ (mapcar #'* v1 v2))))

(when (/= dot1 dot2)
(print `(,dot1 ,dot2)))))

The error occurs extremely seldom. I had to run it several times
to get such output.

Norbert

Tim Bradshaw

unread,
Mar 30, 2010, 4:23:21 PM3/30/10
to
On 2010-03-30 21:00:01 +0100, Peter Keller said:

> I would think this code is suspect since you don't take into consideration
> numerical analysis techniques for comparing floating point numbers.

I don't think so. I think it should only fail if the same operations
on bitwise-identical doubles can sometimes produce different answers
(where the operations are multiplication and addition).

Norbert_Paul

unread,
Mar 30, 2010, 4:30:13 PM3/30/10
to

Such a new and shiny environment, you have! And I thought I got the bleeding cutting
edge newest by using Debian testing. And all I got is:

CL-USER> swank::*swank-wire-protocol-version*
"2010-02-20"
CL-USER> (swank-loader::slime-version-string)
"2010-02-20"
CL-USER> (lisp-implementation-version)


"CVS 20a 20a-release + minimal debian patches (20A Unicode)"

CL-USER> *features*
(:ASDF :CLC-OS-DEBIAN :COMMON-LISP-CONTROLLER :GERDS-PCL :PCL-STRUCTURES
:PORTABLE-COMMONLOOPS :PCL :CMU20 :CMU20A :PYTHON :CONSERVATIVE-FLOAT-TYPE
:MODULAR-ARITH :CMUCL-20A-PATCH-000 :MP :X86 :SSE2 :LINKAGE-TABLE
:RELATIVE-PACKAGE-NAMES :EXECUTABLE :ELF :LINUX :GLIBC2 :UNIX :RANDOM-MT19937
:GENCGC :UNICODE :COMPLEX-FP-VOPS :PENTIUM :I486 :HASH-NEW :DOUBLE-DOUBLE
:HEAP-OVERFLOW-CHECK :STACK-CHECKING :COMMON :COMMON-LISP :ANSI-CL
:IEEE-FLOATING-POINT :CMU)
CL-USER>

>> emacs-X11.exe --version
> GNU Emacs 23.1.1

Yeah! Here we meet!

Norbert

vanekl

unread,
Mar 30, 2010, 4:36:13 PM3/30/10
to

Numerical analysis techniques should not have to be considered when the two
equations are identical and executed with identical environments. Computers
are not always precise, but they are deterministic. You may have a point if
the precision of the calculations were revised upwards/downwards by CL
during the calculation, but the numbers are too small to require a change in
math operators, and the change in precision should occur identically for
both equations.

Also, Pete, take into account that Norbert said that this problem does not
exist when slime/swank is not an intermediary.


Peter Keller

unread,
Mar 30, 2010, 4:35:38 PM3/30/10
to
Norbert_Paul <norbertpau...@yahoo.com> wrote:

> Peter Keller wrote:
>> I would think this code is suspect since you don't take into consideration
>> numerical analysis techniques for comparing floating point numbers.
> No. I know about these errors, but note that the expressions to compute
> dot1 and dot2 are absolutely equal. Therefore they /must/ produce the same
> results (with the same errors).
> My initial version was dot1 = v1 . v2 and dot2 = v2 . v1, but later I
> suspected this might introduce such floating-point errors.
> Therefore I also tried the above.
> Also in my test cases where the error occured for the first time the
> differences between both values werde significant and not only by an error.
>
> These
>
> (0.0d0 12.230520293356577d0)
> (37.202197698216956d0 51.02715433387322d0)
>
> are some outputs of
>
> (dotimes (i 100000)
> (let* ((v1 (list (random 10d0)(random 10d0)))
> (v2 (list (random 10d0)(random 10d0)))
> (dot1 (reduce #'+ (mapcar #'* v1 v2)))
> (dot2 (reduce #'+ (mapcar #'* v1 v2))))
> (when (/= dot1 dot2)
> (print `(,dot1 ,dot2)))))
>
> The error occurs extremely seldom. I had to run it several times
> to get such output.

Hrm. Maybe you should print out the lists too, and once you get the actual
numerical inputs which produced the problem, you can test it out by hand
to see what happens.

-pete

Peter Keller

unread,
Mar 30, 2010, 4:42:52 PM3/30/10
to
vanekl <va...@acd.net> wrote:
> equations are identical and executed with identical environments. Computers
> are not always precise, but they are deterministic. You may have a point if
> the precision of the calculations were revised upwards/downwards by CL
> during the calculation, but the numbers are too small to require a change in
> math operators, and the change in precision should occur identically for
> both equations.
>
> Also, Pete, take into account that Norbert said that this problem does not
> exist when slime/swank is not an intermediary.

I agree with your statement.

-pete

vanekl

unread,
Mar 30, 2010, 5:01:55 PM3/30/10
to
Norbert_Paul wrote:
> Such a new and shiny environment, you have! And I thought I got the
> bleeding cutting edge newest by using Debian testing.

I shoot up straight from the source, as you can probably tell.

I hope you didn't get one of those AMD cpus that allow you to unlock one of
the cores. Now might be a good time to run Memtest86+ and check cpu temps.


Lieven Marchand

unread,
Mar 30, 2010, 5:17:35 PM3/30/10
to
Tim Bradshaw <t...@tfeb.org> writes:

They still can. Doubles in the FPU registers are 80 bits but are
typically stored back to memory as 64 bits. So a computation can have
different results depending on how many of the registers are already in
use or when and how the compiler decides to store them back.

Tim Bradshaw

unread,
Mar 30, 2010, 5:37:02 PM3/30/10
to
On 2010-03-30 22:17:35 +0100, Lieven Marchand said:

> They still can. Doubles in the FPU registers are 80 bits but are
> typically stored back to memory as 64 bits. So a computation can have
> different results depending on how many of the registers are already in
> use or when and how the compiler decides to store them back.

This has to be wrong, doesn't it? Are you saying that on x86s the
multiplying two doubles produces results which have essentially random
bits in them?

Raymond Toy

unread,
Mar 30, 2010, 10:47:47 PM3/30/10
to

What swank:*communication-style* do you use? I think, but I'm not sure,
that anything other than :fd-handler is suspect. CMUCL is not
interrupt-safe.

Ray

Raymond Toy

unread,
Mar 30, 2010, 10:53:02 PM3/30/10
to

But he is using the sse2 version of cmucl (as indicated by the :SSE2
*features*). The 80 bit registers are not used.

Ray

Raymond Toy

unread,
Mar 30, 2010, 11:27:53 PM3/30/10
to

There are some bugs in the 20a release that affect SSE2 and complex
arithmetic. (See www.cons.org/cmucl.) This is probably not the cause
of the issue you see now, but if you're going to be working with complex
numbers, you might want to get the 2010-03 snapshot (or wait a couple of
days and get the 2010-04 snapshot). These are available at
common-lisp.net/project/cmucl/downloads.

Ray

Norbert_Paul

unread,
Mar 31, 2010, 1:51:54 AM3/31/10
to
Tim Bradshaw wrote:
> On 2010-03-30 22:17:35 +0100, Lieven Marchand said:
>
>> They still can. Doubles in the FPU registers are 80 bits but are
>> typically stored back to memory as 64 bits. So a computation can have
>> different results depending on how many of the registers are already in
>> use or when and how the compiler decides to store them back.
>
> This has to be wrong, doesn't it?
Of course it has to be. A (standard) computer *has* to be deterministic.

Norbert_Paul

unread,
Mar 31, 2010, 2:04:10 AM3/31/10
to
vanekl wrote:
> I shoot up straight from the source, as you can probably tell.
Good habit.

> I hope you didn't get one of those AMD cpus that allow you to unlock one of
> the cores. Now might be a good time to run Memtest86+ and check cpu temps.

Did so, no problems.

Norbert_Paul

unread,
Mar 31, 2010, 2:25:15 AM3/31/10
to
Peter Keller wrote:
>> The error occurs extremely seldom. I had to run it several times
>> to get such output.
>
> Hrm. Maybe you should print out the lists too, and once you get the actual
> numerical inputs which produced the problem, you can test it out by hand
> to see what happens.
>
> -pete

Here is a session. I changed the vector coordinatess to multiples of 1d0
to be able to calculate it in gray soft memory.
I also tried integers and single floats. No problems with integers but
the same issue with single floats.
Thr wrong result is always too small. It looks like the value was returned
before computation ended. Are there hidden running conditions?


CL-USER> (dotimes (i 100000)
(let* ((v1 (list (* 1d0 (random 10)) (* 1d0 (random 10))))
(v2 (list (* 1d0 (random 10)) (* 1d0 (random 10))))


(dot1 (reduce #'+ (mapcar #'* v1 v2)))
(dot2 (reduce #'+ (mapcar #'* v1 v2))))
(when (/= dot1 dot2)

(print `(vdot1 ,dot2)))))

(15.0d0 50.0d0)
NIL
CL-USER> (dotimes (i 100000)
(let* ((v1 (list (* 1d0 (random 10)) (* 1d0 (random 10))))
(v2 (list (* 1d0 (random 10)) (* 1d0 (random 10))))


(dot1 (reduce #'+ (mapcar #'* v1 v2)))
(dot2 (reduce #'+ (mapcar #'* v1 v2))))
(when (/= dot1 dot2)

(print `(v1 ,v1 v2 ,v2 dot1 ,dot1 dot2 ,dot2)))))
NIL
CL-USER> (dotimes (i 100000)
(let* ((v1 (list (* 1d0 (random 10)) (* 1d0 (random 10))))
(v2 (list (* 1d0 (random 10)) (* 1d0 (random 10))))


(dot1 (reduce #'+ (mapcar #'* v1 v2)))
(dot2 (reduce #'+ (mapcar #'* v1 v2))))
(when (/= dot1 dot2)

(print `(v1 ,v1 v2 ,v2 dot1 ,dot1 dot2 ,dot2)))))

(V1 (6.0d0 3.0d0) V2 (6.0d0 6.0d0) DOT1 36.0d0 DOT2 54.0d0)
(V1 (0.0d0 2.0d0) V2 (5.0d0 3.0d0) DOT1 6.0d0 DOT2 0.0d0)
NIL
CL-USER> (dotimes (i 100000)
(let* ((v1 (list (* 1d0 (random 10)) (* 1d0 (random 10))))
(v2 (list (* 1d0 (random 10)) (* 1d0 (random 10))))


(dot1 (reduce #'+ (mapcar #'* v1 v2)))
(dot2 (reduce #'+ (mapcar #'* v1 v2))))
(when (/= dot1 dot2)

(print `(v1 ,v1 v2 ,v2 dot1 ,dot1 dot2 ,dot2)))))
NIL
CL-USER> (dotimes (i 100000)
(let* ((v1 (list (* 1d0 (random 10)) (* 1d0 (random 10))))
(v2 (list (* 1d0 (random 10)) (* 1d0 (random 10))))


(dot1 (reduce #'+ (mapcar #'* v1 v2)))
(dot2 (reduce #'+ (mapcar #'* v1 v2))))
(when (/= dot1 dot2)

(print `(v1 ,v1 v2 ,v2 dot1 ,dot1 dot2 ,dot2)))))

(V1 (1.0d0 1.0d0) V2 (4.0d0 6.0d0) DOT1 10.0d0 DOT2 0.0d0)
NIL
CL-USER>

Norbert_Paul

unread,
Mar 31, 2010, 2:28:23 AM3/31/10
to
Raymond Toy wrote:
> What swank:*communication-style* do you use? I think, but I'm not sure,
> that anything other than :fd-handler is suspect. CMUCL is not
> interrupt-safe.
:SIGIO

Norbert_Paul

unread,
Mar 31, 2010, 3:34:47 AM3/31/10
to
Norbert_Paul wrote:
> [...] Are there hidden running conditions?

I had a suspect: gc

Note that tin the following session the output always has
i-gc-ed-u bound to T. So the error seems to occur after gc, and,
maybe, on bare cmucl this error is less probable (no slime in memory)
but still possible.
Or could one of the (before/after) gc-hooks of slime cause trouble?

CL-USER> (defun testfn ()
(let* ((i-gc-ed-u nil)
(extensions:*gc-notify-after*
#'(lambda (a b c)
(declare (ignore a b c))
(setf i-gc-ed-u T))))
(dotimes (i 100000)
(setf i-gc-ed-u nil)


(let* ((v1 (list (* 1d0 (random 10)) (* 1d0 (random 10))))
(v2 (list (* 1d0 (random 10)) (* 1d0 (random 10))))
(dot1 (reduce #'+ (mapcar #'* v1 v2)))
(dot2 (reduce #'+ (mapcar #'* v1 v2))))
(when (/= dot1 dot2)

(print `(gc ,i-gc-ed-u v1 ,v1 v2 ,v2 dot1 ,dot1 dot2 ,dot2)))))
(if i-gc-ed-u :gc-occured :no-gc-yet)
))
TESTFN
CL-USER> (testfn)
:NO-GC-YET
CL-USER> (testfn)

(GC T V1 (1.0d0 3.0d0) V2 (3.0d0 2.0d0) DOT1 0.0d0 DOT2 9.0d0)
(GC T V1 (6.0d0 7.0d0) V2 (9.0d0 0.0d0) DOT1 0.0d0 DOT2 54.0d0)
(GC T V1 (0.0d0 5.0d0) V2 (7.0d0 5.0d0) DOT1 0.0d0 DOT2 25.0d0)
:NO-GC-YET
CL-USER> (testfn)
:NO-GC-YET
CL-USER> (testfn)

(GC T V1 (5.0d0 7.0d0) V2 (6.0d0 8.0d0) DOT1 86.0d0 DOT2 30.0d0)
(GC T V1 (8.0d0 5.0d0) V2 (2.0d0 5.0d0) DOT1 41.0d0 DOT2 25.0d0)
:NO-GC-YET
CL-USER> (testfn)
:NO-GC-YET

Norbert_Paul

unread,
Mar 31, 2010, 3:35:09 AM3/31/10
to
Norbert_Paul wrote:
> [...] Are there hidden running conditions?

I had a suspect: gc

Note that in the following session the output always has


i-gc-ed-u bound to T. So the error seems to occur after gc, and,
maybe, on bare cmucl this error is less probable (no slime in memory)
but still possible.
Or could one of the (before/after) gc-hooks of slime cause trouble?

CL-USER> (defun testfn ()
(let* ((i-gc-ed-u nil)
(extensions:*gc-notify-after*
#'(lambda (a b c)
(declare (ignore a b c))
(setf i-gc-ed-u T))))
(dotimes (i 100000)
(setf i-gc-ed-u nil)

(let* ((v1 (list (* 1d0 (random 10)) (* 1d0 (random 10))))
(v2 (list (* 1d0 (random 10)) (* 1d0 (random 10))))
(dot1 (reduce #'+ (mapcar #'* v1 v2)))
(dot2 (reduce #'+ (mapcar #'* v1 v2))))
(when (/= dot1 dot2)

Helmut Eller

unread,
Mar 31, 2010, 8:39:50 AM3/31/10
to
* Norbert_Paul [2010-03-31 09:35+0200] writes:

> Norbert_Paul wrote:
>> [...] Are there hidden running conditions?
>
> I had a suspect: gc
>
> Note that in the following session the output always has
> i-gc-ed-u bound to T. So the error seems to occur after gc, and,
> maybe, on bare cmucl this error is less probable (no slime in memory)
> but still possible.
> Or could one of the (before/after) gc-hooks of slime cause trouble?

Not any more than other gc-hooks that use FP ops:

(defun testfn ()
(let* ((i-gc-ed-u nil)

(ext:*gc-notify-before* (lambda (a) (/ a 0.34d0))))


(dotimes (i 100000)
(setf i-gc-ed-u nil)
(let* ((v1 (list (* 1d0 (random 10)) (* 1d0 (random 10))))
(v2 (list (* 1d0 (random 10)) (* 1d0 (random 10))))
(dot1 (reduce #'+ (mapcar #'* v1 v2)))
(dot2 (reduce #'+ (mapcar #'* v1 v2))))
(when (/= dot1 dot2)

(print `(gc ,i-gc-ed-u v1 ,v1 v2 ,v2 dot1 ,dot1 dot2 ,dot2)))))))

also prints something in a tty session with CMUCL Snapshot 2010-02.

Helmut

Raymond Toy

unread,
Mar 31, 2010, 9:02:27 AM3/31/10
to
On 3/31/10 3:34 AM, Norbert_Paul wrote:
> Norbert_Paul wrote:
>> [...] Are there hidden running conditions?
>
> I had a suspect: gc
>
> Note that tin the following session the output always has
> i-gc-ed-u bound to T. So the error seems to occur after gc, and,
> maybe, on bare cmucl this error is less probable (no slime in memory)
> but still possible.
> Or could one of the (before/after) gc-hooks of slime cause trouble?

I can reproduce this. It's some issue with sse2 support. If you run it
using x87, there are no errors. It will take some time to figure this
out but having this simple test case will help a lot.


Ray

Norbert_Paul

unread,
Mar 31, 2010, 9:59:44 AM3/31/10
to
Norbert_Paul wrote:
> Norbert_Paul wrote:
>> [...] Are there hidden running conditions?
>
> I had a suspect: gc
It is slimes *gc-notify-<before|after>*.

When I replace *both* notifications in testfn (i.e. also do the
*gc-notify-before* -part ) by own functions no such error occurs.

So I guess SWANK-BACKEND::PRE-GC-HOOK and SWANK-BACKEND::POST-GC-HOOK
cause trouble.

I will just deactivate gc-notification, then.

Thank you, brothers, for your comments.

Norbert

\begin{source}
CL-USER> (defun testfn (verbosity &optional (op #'*))
"Thou hast a smoking gun in thy hand, brother:"
(let* ((i-gc-ed-u nil)
(extensions:*gc-verbose* verbosity)
; (extensions:*gc-notify-before*
; #'(lambda (a)
; (declare (ignore a))
; (setf i-gc-ed-u T)))


(extensions:*gc-notify-after*
#'(lambda (a b c)
(declare (ignore a b c))
(setf i-gc-ed-u T)))
)

(dotimes (i 1000000)
(let* ((v1 (list 1d0 2d0 ))
(v2 (list 3d0 4d0 )))
(setf i-gc-ed-u nil)
(let*((dot1 (mapcar op v1 v2))
(gc1 i-gc-ed-u)
(dummy (setf i-gc-ed-u nil))
(dot2 (mapcar op v1 v2))
(gc2 i-gc-ed-u))
(declare (ignore dummy))
(when (not (equal dot1 dot2))
(print `(v1 ,v1 v2 ,v2
dot1 ,dot1 gc1 ,(if gc1 'Y 'N)
dot2 ,dot2 gc2 ,(if gc2 'Y 'N)))))))


(if i-gc-ed-u :gc-occured :no-gc-yet)
))
TESTFN

CL-USER> (testfn nil #'*)
:NO-GC-YET
CL-USER> (testfn nil #'/)
:NO-GC-YET
CL-USER> (testfn nil #'+)
:NO-GC-YET
CL-USER> (testfn nil #'-)
:NO-GC-YET
CL-USER> (testfn T #'*)

(V1 (1.0d0 2.0d0) V2 (3.0d0 4.0d0) DOT1 (3.0d0 8.0d0) GC1 N DOT2 (3.0d0 0.0d0) GC2 Y)
(V1 (1.0d0 2.0d0) V2 (3.0d0 4.0d0) DOT1 (3.0d0 0.0d0) GC1 Y DOT2 (3.0d0 8.0d0) GC2 N)
(V1 (1.0d0 2.0d0) V2 (3.0d0 4.0d0) DOT1 (3.0d0 8.0d0) GC1 N DOT2 (3.0d0 0.0d0) GC2 Y)
(V1 (1.0d0 2.0d0) V2 (3.0d0 4.0d0) DOT1 (0.0d0 8.0d0) GC1 Y DOT2 (3.0d0 8.0d0) GC2 N)
(V1 (1.0d0 2.0d0) V2 (3.0d0 4.0d0) DOT1 (3.0d0 8.0d0) GC1 N DOT2 (0.0d0 8.0d0) GC2 Y)
:NO-GC-YET
CL-USER> (testfn T #'/)

(V1 (1.0d0 2.0d0) V2 (3.0d0 4.0d0) DOT1 (0.3333333333333333d0 0.0d0) GC1 Y DOT2 (0.3333333333333333d0 0.5d0) GC2 N)
(V1 (1.0d0 2.0d0) V2 (3.0d0 4.0d0) DOT1 (0.3333333333333333d0 0.0d0) GC1 Y DOT2 (0.3333333333333333d0 0.5d0) GC2 N)
(V1 (1.0d0 2.0d0) V2 (3.0d0 4.0d0) DOT1 (0.3333333333333333d0 0.0d0) GC1 Y DOT2 (0.3333333333333333d0 0.5d0) GC2 N)
(V1 (1.0d0 2.0d0) V2 (3.0d0 4.0d0) DOT1 (0.3333333333333333d0 0.0d0) GC1 Y DOT2 (0.3333333333333333d0 0.5d0) GC2 N)
(V1 (1.0d0 2.0d0) V2 (3.0d0 4.0d0) DOT1 (0.3333333333333333d0 0.0d0) GC1 Y DOT2 (0.3333333333333333d0 0.5d0) GC2 N)
(V1 (1.0d0 2.0d0) V2 (3.0d0 4.0d0) DOT1 (0.3333333333333333d0 0.0d0) GC1 Y DOT2 (0.3333333333333333d0 0.5d0) GC2 N)
(V1 (1.0d0 2.0d0) V2 (3.0d0 4.0d0) DOT1 (0.3333333333333333d0 0.0d0) GC1 Y DOT2 (0.3333333333333333d0 0.5d0) GC2 N)
:NO-GC-YET
CL-USER> (testfn T #'+)

(V1 (1.0d0 2.0d0) V2 (3.0d0 4.0d0) DOT1 (4.0d0 0.0d0) GC1 Y DOT2 (4.0d0 6.0d0) GC2 N)
(V1 (1.0d0 2.0d0) V2 (3.0d0 4.0d0) DOT1 (0.0d0 6.0d0) GC1 Y DOT2 (4.0d0 6.0d0) GC2 N)
(V1 (1.0d0 2.0d0) V2 (3.0d0 4.0d0) DOT1 (4.0d0 6.0d0) GC1 N DOT2 (0.0d0 6.0d0) GC2 Y)
(V1 (1.0d0 2.0d0) V2 (3.0d0 4.0d0) DOT1 (4.0d0 6.0d0) GC1 N DOT2 (0.0d0 6.0d0) GC2 Y)
(V1 (1.0d0 2.0d0) V2 (3.0d0 4.0d0) DOT1 (4.0d0 0.0d0) GC1 Y DOT2 (4.0d0 6.0d0) GC2 N)
(V1 (1.0d0 2.0d0) V2 (3.0d0 4.0d0) DOT1 (0.0d0 6.0d0) GC1 Y DOT2 (4.0d0 6.0d0) GC2 N)
(V1 (1.0d0 2.0d0) V2 (3.0d0 4.0d0) DOT1 (4.0d0 6.0d0) GC1 N DOT2 (4.0d0 0.0d0) GC2 Y)
(V1 (1.0d0 2.0d0) V2 (3.0d0 4.0d0) DOT1 (4.0d0 6.0d0) GC1 N DOT2 (0.0d0 6.0d0) GC2 Y)
:NO-GC-YET
CL-USER> (testfn T #'-)

(V1 (1.0d0 2.0d0) V2 (3.0d0 4.0d0) DOT1 (0.0d0 -2.0d0) GC1 Y DOT2 (-2.0d0 -2.0d0) GC2 N)
(V1 (1.0d0 2.0d0) V2 (3.0d0 4.0d0) DOT1 (0.0d0 -2.0d0) GC1 Y DOT2 (-2.0d0 -2.0d0) GC2 N)
(V1 (1.0d0 2.0d0) V2 (3.0d0 4.0d0) DOT1 (0.0d0 -2.0d0) GC1 Y DOT2 (-2.0d0 -2.0d0) GC2 N)
(V1 (1.0d0 2.0d0) V2 (3.0d0 4.0d0) DOT1 (0.0d0 -2.0d0) GC1 Y DOT2 (-2.0d0 -2.0d0) GC2 N)
(V1 (1.0d0 2.0d0) V2 (3.0d0 4.0d0) DOT1 (0.0d0 -2.0d0) GC1 Y DOT2 (-2.0d0 -2.0d0) GC2 N)
(V1 (1.0d0 2.0d0) V2 (3.0d0 4.0d0) DOT1 (0.0d0 -2.0d0) GC1 Y DOT2 (-2.0d0 -2.0d0) GC2 N)
(V1 (1.0d0 2.0d0) V2 (3.0d0 4.0d0) DOT1 (0.0d0 -2.0d0) GC1 Y DOT2 (-2.0d0 -2.0d0) GC2 N)
(V1 (1.0d0 2.0d0) V2 (3.0d0 4.0d0) DOT1 (0.0d0 -2.0d0) GC1 Y DOT2 (-2.0d0 -2.0d0) GC2 N)
(V1 (1.0d0 2.0d0) V2 (3.0d0 4.0d0) DOT1 (0.0d0 -2.0d0) GC1 Y DOT2 (-2.0d0 -2.0d0) GC2 N)
(V1 (1.0d0 2.0d0) V2 (3.0d0 4.0d0) DOT1 (0.0d0 -2.0d0) GC1 Y DOT2 (-2.0d0 -2.0d0) GC2 N)
(V1 (1.0d0 2.0d0) V2 (3.0d0 4.0d0) DOT1 (-2.0d0 0.0d0) GC1 Y DOT2 (-2.0d0 -2.0d0) GC2 N)
:NO-GC-YET
\end{source}

Raymond Toy

unread,
Mar 31, 2010, 11:42:38 AM3/31/10
to

IIRC, this will cause signals to be generated when IO is needed. That's
causes problems with cmucl. I'd recommend using :fd-handler. :spawn
might work, but I've used :fd-handler ever since I started using slime
many years ago.

Ray

Raymond Toy

unread,
Mar 31, 2010, 11:45:13 AM3/31/10
to

I think I found the problem. CMUCL was saving the x87 state but wasn't
saving the sse2 state. I think this is fixed now. At least your test
function no longer causes bogus results.

This should be available in the 2010-04 snapshot that will be available
soon. Please try this out when you get a chance.

Thanks,

Ray

Norbert_Paul

unread,
Apr 1, 2010, 5:11:59 AM4/1/10
to
Raymond Toy wrote:
> IIRC, this will cause signals to be generated when IO is needed. That's
> causes problems with cmucl. I'd recommend using :fd-handler. :spawn
> might work, but I've used :fd-handler ever since I started using slime
> many years ago.
OK. How do I use it?

Norbert_Paul

unread,
Apr 1, 2010, 5:16:34 AM4/1/10
to
Raymond Toy wrote:
> This should be available in the 2010-04 snapshot that will be available
> soon. Please try this out when you get a chance.
>
> Thanks,
>
> Ray

Thanks to you.
See you on the next bug.

Norbert

Raymond Toy

unread,
Apr 1, 2010, 8:45:17 AM4/1/10
to

In ~/.swank.lisp, just add:

(setf swank:*communication-style* :fd-handler)

Ray

Lieven Marchand

unread,
Apr 1, 2010, 9:14:23 AM4/1/10
to
Tim Bradshaw <t...@tfeb.org> writes:

You can tell your compiler to store the full 80 bits. Or as Raymond Toy
mentions in this thread, use 64 bits registers. This is a page from a
compiler firm that discusses it in more detail:

http://www.pgroup.com/support/execute.htm#diff_answers

Tim Bradshaw

unread,
Apr 6, 2010, 6:40:47 AM4/6/10
to
On 2010-04-01 14:14:23 +0100, Lieven Marchand said:

> You can tell your compiler to store the full 80 bits. Or as Raymond Toy
> mentions in this thread, use 64 bits registers. This is a page from a
> compiler firm that discusses it in more detail:

Yes, but I don't think any of this means that for the same sequence of
instructions on the same initial data (including whatever flags control
the extended precision stuff), I will get differing results. I might
get results I don't *expect*, but the processor does not dynamically
decide whether to use 80-bit or 64-bit registers for the same
instructions as far as I can tell.

(And indeed it looks as if the underlying problem was CMUCL not saving
enough state on interrupts, and (I guess) SLIME generating such
interrupts)

Norbert_Paul

unread,
Apr 6, 2010, 8:25:44 AM4/6/10
to

I suppose that slime interrups (for gc-notification) use floating-point
arithmetics thus destroying the corresponding processor state whereas
cmucl doesn't, thus accidentally maintainig that sate. This would at least
explain why the error doesn't occur on bare cmucl.

My problem now is, that I am used to apt-get install prebuilt Debian packages
but the fixed cmucl packages seem to differ somewhat from Debian's common-lisp
policy. So I don't want to just paste them into my file system.

What would a Debian-compliant replacement of cmucl by the latest release
look like?

Norbert

Raymond Toy

unread,
Apr 6, 2010, 10:02:44 AM4/6/10
to
On 4/6/10 8:25 AM, Norbert_Paul wrote:
> Tim Bradshaw wrote:
>> On 2010-04-01 14:14:23 +0100, Lieven Marchand said:
>> (And indeed it looks as if the underlying problem was CMUCL not saving
>> enough state on interrupts, and (I guess) SLIME generating such
>> interrupts)
>
> I suppose that slime interrups (for gc-notification) use floating-point
> arithmetics thus destroying the corresponding processor state whereas
> cmucl doesn't, thus accidentally maintainig that sate. This would at least
> explain why the error doesn't occur on bare cmucl.

As Helmet's example shows, it's not the interrupts from Slime. It was
the GC hook. This happens because at certain times, GC will happen
which causes cmucl to run some C code which will then run Lisp code to
handle the GC hooks. But since Lisp doesn't understand this path, the
routine that calls the Lisp code needs to save the FP state so that any
live FP registers are preserved across the call. Normally the compiler
will save any live registers before calling a Lisp function, but the
compiler doesn't know about this. (Perhaps it should?)

>
> My problem now is, that I am used to apt-get install prebuilt Debian
> packages
> but the fixed cmucl packages seem to differ somewhat from Debian's
> common-lisp
> policy. So I don't want to just paste them into my file system.
>
> What would a Debian-compliant replacement of cmucl by the latest release
> look like?

I don't have a Debian system so I don't know, but is the layout
different from what official tarballs from common-lisp.net? (CMUCL's
layout is something like <path>/bin/lisp and <path>/lib/cmucl/<more
cmucl stuff>.)

Maybe you can install the tarballs somewhere and have a simple script
call that for now. When there's a Debian update, point the script to
the Debian location.

Ray


Ray

Norbert_Paul

unread,
Apr 6, 2010, 11:59:34 AM4/6/10
to
Raymond Toy wrote:
> I don't have a Debian system so I don't know, but is the layout
> different from what official tarballs from common-lisp.net? (CMUCL's
> layout is something like<path>/bin/lisp and<path>/lib/cmucl/<more
> cmucl stuff>.)
Did it. Now slime is broken.

> Maybe you can install the tarballs somewhere and have a simple script
> call that for now. When there's a Debian update, point the script to
> the Debian location.

Debian has something called common-lisp-controller.
This is more or less what one should do to install a new lisp on Debian ...
https://alioth.debian.org/scm/viewvc.php/*checkout*/clc/DESIGN.txt?revision=1.2&root=clc
...be he a package or a human.

I'll keep trying.

Norbert

Tamas K Papp

unread,
Apr 6, 2010, 12:00:50 PM4/6/10
to
On Tue, 06 Apr 2010 17:59:34 +0200, Norbert_Paul wrote:

> Debian has something called common-lisp-controller. This is more or less
> what one should do to install a new lisp on Debian ...
> https://alioth.debian.org/scm/viewvc.php/*checkout*/clc/DESIGN.txt?
revision=1.2&root=clc
> ...be he a package or a human.

I disagree, CLC was more of a source of a headache for me than an
useful layer. My Lisp experience on Debian has been the smoothest
with clbuild (for SLIME, libraries) and an SBCL compiled from source.
I only use the Debian-packaged SBCL to compile the latter.

Best,

Tamas

Norbert_Paul

unread,
Apr 6, 2010, 12:50:18 PM4/6/10
to
Tamas K Papp wrote:
> I disagree, CLC was more of a source of a headache for me than an
> useful layer. My Lisp experience on Debian has been the smoothest
> with clbuild (for SLIME, libraries) and an SBCL compiled from source.
> I only use the Debian-packaged SBCL to compile the latter.
Yeah!
Now I have Debian squeeze + slime + sbcl running together!
(Note that Debian's slime + Debian's sbcl crashed on my box).

I also did
$clbuild projects|grep cmu
and it seems as if clbuild didn't know cmucl. Is that true?
But then I can't test the latest CMU release which initially was the
point of that recent install party.

Besides, what would be a convenient location for the clbuild tree?
Now, I have it at $HOME/clbuild with root rights which looks
strange.

Norbert

Raymond Toy

unread,
Apr 6, 2010, 12:49:27 PM4/6/10
to
On 4/6/10 11:59 AM, Norbert_Paul wrote:
> Raymond Toy wrote:
>> I don't have a Debian system so I don't know, but is the layout
>> different from what official tarballs from common-lisp.net? (CMUCL's
>> layout is something like<path>/bin/lisp and<path>/lib/cmucl/<more
>> cmucl stuff>.)
> Did it. Now slime is broken.

Insufficient info to fix anything. FWIW, I have a script cmulisp that
calls some random version of cmucl from common-lisp.net. This works
just great with slime, but I do need to be a little careful with my init
files if the version is sufficiently different from previous versions.

Ray

Rupert Swarbrick

unread,
Apr 6, 2010, 4:34:39 PM4/6/10
to
Norbert_Paul <norbertpau...@yahoo.com> writes:

> What would a Debian-compliant replacement of cmucl by the latest release
> look like?

Ok, so it's probably too late to be useful for you, but in case anyone's
reading the intawebs in the future:

Debian packages are built from (vanilla upstream) source tarballs by
unpacking the tarball, applying a patch and calling some magical build
scripts. The patch generally just adds a debian/ directory, which
contains information on how the package should be built (this bit's
usually trivial), and how it should be installed and integrated into the
system in a way that can be uninstalled again.

If the newest upstream sources are similar to those for which the debian
patch was created, you're in luck: Download the vanilla files and then
apply the debian patch. Then take note of what you want the new version
string to be and cd into the debian/ directory that got created. Now you
can probably type "dch -v <myversion>" [1], which will create a new
version in the changelog.

Go back up to the main directory and call "dpkg-buildpackage" [2] and
with a bit of luck a brand spanking new version of the package will be
built. (This assumes that I got everything right...) Note that you might
want to do something like "apt-get build-depends cmucl" to pull all the
libraries that debian thinks you need to build it.

Finally you can "sudo dpkg -i <mynewcmucl.deb>" or something to install
it.

You can find the relevant debian tarballs and diffs at the package page,
which seems to be [3]. Since I've almost certainly made at least one
mistake in the above, you might want to look at the debian new
maintainers guide [4]. This is sort of oriented to people that are
building official packages, but of course the technical details are all
identical.

I hope this is of some use,

Rupert


[1] dch is in the devscripts package
[2] dpkg-buildpackage is in the dpkg-dev package
[3] http://packages.qa.debian.org/c/cmucl.html
[4] http://www.debian.org/doc/maint-guide/

Norbert_Paul

unread,
Apr 7, 2010, 2:47:11 AM4/7/10
to
Thank you for the info, i'll try this later.
But for now I have a working, yet possibly messy, environment which I will
use to continue on my work.

Norbert

Rupert Swarbrick wrote:
> Norbert_Paul<norbertpau...@yahoo.com> writes:
>
>> What would a Debian-compliant replacement of cmucl by the latest release
>> look like?
>
> Ok, so it's probably too late to be useful for you, but in case anyone's
> reading the intawebs in the future:

...

Tamas K Papp

unread,
Apr 7, 2010, 8:13:50 AM4/7/10
to
On Tue, 06 Apr 2010 18:50:18 +0200, Norbert_Paul wrote:

> Tamas K Papp wrote:
>> I disagree, CLC was more of a source of a headache for me than an
>> useful layer. My Lisp experience on Debian has been the smoothest with
>> clbuild (for SLIME, libraries) and an SBCL compiled from source. I only
>> use the Debian-packaged SBCL to compile the latter.
> Yeah!
> Now I have Debian squeeze + slime + sbcl running together! (Note that
> Debian's slime + Debian's sbcl crashed on my box).
>
> I also did
> $clbuild projects|grep cmu
> and it seems as if clbuild didn't know cmucl. Is that true? But then I
> can't test the latest CMU release which initially was the point of that
> recent install party.

AFAIK CMUCL is not supported, but you can always install it
separately.

> Besides, what would be a convenient location for the clbuild tree? Now,
> I have it at $HOME/clbuild with root rights which looks strange.

Anywhere. I have it in software/clbuild. I don't see why it has to
be root: libraries certainly don't need to be root, SBCL compiles file
for any user, I just su for make install. But even that is not needed
if you set up the paths for SBCL. So just do everything as a regular
user.

Tamas

Norbert_Paul

unread,
Apr 7, 2010, 10:55:54 AM4/7/10
to
Tamas K Papp wrote:
> On Tue, 06 Apr 2010 18:50:18 +0200, Norbert_Paul wrote:
> AFAIK CMUCL is not supported, but you can always install it
> separately.
I did that. I was just wondering-

> Anywhere. I have it in software/clbuild. I don't see why it has to
> be root: libraries certainly don't need to be root, SBCL compiles file
> for any user, I just su for make install. But even that is not needed
> if you set up the paths for SBCL. So just do everything as a regular
> user.

OK.
Besides, then do you have 'software' at ${HOME}?
I thought, I should be root, as I am used to installing software as root.
Sometimes, however, when I'm lazy (err ... "often"?), I install(ed?) my
Java libraries at ${HOME}.

Norbert

Tamas K Papp

unread,
Apr 7, 2010, 11:09:24 AM4/7/10
to

All of the Common Lisp software I use, including libraries and SBCL,
is inside my home directory, managed as a regular user. The only
thing I use root for is installing SBCL ("sh install.sh").

Tamas

0 new messages