From: Greg Buchholz
Subject: default float point types (GCL vs CMUCL)
Date: 
Message-ID: <1148839511.890520.322690@i39g2000cwa.googlegroups.com>
    I'm attempting to write a lisp version of the partial sums
benchmark for the Great Computer Langauge Shootout (
http://shootout.alioth.debian.org/debian/benchmark.php?test=partialsums&lang=all
), and I've come across a snag when it comes to floating point types
and/or rounding modes.  The code below gives the correct results with
GCL, but incorrect results for CMUCL.  I'm assuming this is because GCL
defaults to selecting the native double precision floating point
numbers for its floating point computations, while CMUCL might be using
single precision numbers, or somesuch.  What's the idiomatic lisp way
to get a consistant behavior?  Is there a global variable I should
diddle?   I suppose using "declare" is the right answer, but it isn't
obvious to me how to decorate the variables inside of a "do" macro.

Thanks,

Greg Buchholz

(defmacro psum (name f)
  `(format t "~,9F~A~A~%"
     (do ((k 1.0 (+ k 1.0))
          (sum 0.0 (+ sum ,f)))
         ((> k n) sum))
     #\tab ,name))

(defun main ()
  (let* ((args #+sbcl sb-ext:*posix-argv*
               #+cmu extensions:*command-line-strings*
               #+gcl si::*command-args*)
         (n (parse-integer (car (last args)))))
    (psum "(2/3)^k"       (expt (/ 2.0 3.0) (- k 1.0)))
    (psum "k^-0.5"        (/ 1.0 (sqrt k)))
    (psum "1/k(k+1)"      (/ 1.0 (* k (+ 1.0 k))))
    (psum "Flint Hills"   (let ((s (sin k)))
                            (/ 1.0 (* (* k k k) (* s s)))))
    (psum "Cookson Hills" (let ((c (cos k)))
                            (/ 1.0 (* (* k k k) (* c c)))))
    (psum "Harmonic"      (/ 1.0 k))
    (psum "Riemann Zeta"  (/ 1.0 (* k k)))
    (let ((a -1.0))
      (psum "Alternating Harmonic"
            (progn (setf a (- a))
                   (/ a k))))
    (let ((a -1.0))
      (psum "Gregory"
            (progn (setf a (- a))
                   (/ a (1- (* 2.0 k))))))))

From: Wade Humeniuk
Subject: Re: default float point types (GCL vs CMUCL)
Date: 
Message-ID: <a7meg.35913$Qq.15285@clgrps12>
The simplest thing I can think of is to do

(defmacro psum (name f)
   `(format t "~,9F~A~A~%"
      (do ((k 1.0d0 (+ k 1.0d0))
           (sum 0.0d0 (+ sum ,f)))
          ((> k n) sum))
      #\tab ,name))

(defun main ()
   (let* ((args #+sbcl sb-ext:*posix-argv*
                #+cmu extensions:*command-line-strings*
                #+gcl si::*command-args*)
          (n (parse-integer (car (last args)))))
     (psum "(2/3)^k"       (expt (/ 2.0d0 3.0d0) (- k 1.0d0)))
     (psum "k-0.5"        (/ 1.0d0 (sqrt k)))
     (psum "1/k(k+1)"      (/ 1.0d0 (* k (+ 1.0d0 k))))
     (psum "Flint Hills"   (let ((s (sin k)))
                             (/ 1.0d0 (* (* k k k) (* s s)))))
     (psum "Cookson Hills" (let ((c (cos k)))
                             (/ 1.0d0 (* (* k k k) (* c c)))))
     (psum "Harmonic"      (/ 1.0d0 k))
     (psum "Riemann Zeta"  (/ 1.0d0 (* k k)))
     (let ((a -1.0d0))
       (psum "Alternating Harmonic"
             (progn (setf a (- a))
                    (/ a k))))
     (let ((a -1.0d0))
       (psum "Gregory"
             (progn (setf a (- a))
                    (/ a (1- (* 2.0d0 k))))))))
From: Greg Buchholz
Subject: Re: default float point types (GCL vs CMUCL)
Date: 
Message-ID: <1148842039.303698.199370@i39g2000cwa.googlegroups.com>
Wade Humeniuk wrote:
> The simplest thing I can think of is to do

    Ah.  That does it.

Thanks,

Greg Buchholz
From: Pierpaolo BERNARDI
Subject: Re: default float point types (GCL vs CMUCL)
Date: 
Message-ID: <op.s99yzag8xbm8ci@eraora>
On Sun, 28 May 2006 20:05:12 +0200, Greg Buchholz <················@yahoo.com> wrote:

> Is there a global variable I should diddle?

*READ-DEFAULT-FLOAT-FORMAT*


-- 
Anything below this line is being added by the newsserver

Inviato da X-Privat.Org - Registrazione gratuita http://www.x-privat.org/join.php
From: Raymond Toy
Subject: Re: default float point types (GCL vs CMUCL)
Date: 
Message-ID: <sxdd5dvinji.fsf@rtp.ericsson.se>
>>>>> "Greg" == Greg Buchholz <················@yahoo.com> writes:

    Greg>     I'm attempting to write a lisp version of the partial sums
    Greg> benchmark for the Great Computer Langauge Shootout (
    Greg> http://shootout.alioth.debian.org/debian/benchmark.php?test=partialsums&lang=all
    Greg> ), and I've come across a snag when it comes to floating point types
    Greg> and/or rounding modes.  The code below gives the correct results with
    Greg> GCL, but incorrect results for CMUCL.  I'm assuming this is because GCL
    Greg> defaults to selecting the native double precision floating point
    Greg> numbers for its floating point computations, while CMUCL might be using
    Greg> single precision numbers, or somesuch.  What's the idiomatic lisp way
    Greg> to get a consistant behavior?  Is there a global variable I should
    Greg> diddle?   I suppose using "declare" is the right answer, but it isn't
    Greg> obvious to me how to decorate the variables inside of a "do" macro.

GCL uses the following formats for floating point numbers:

GCL          Machine
long-float   double precision
double-float double precision
single-float double precision
short-float  single precision

CMUCL        Machine
long-float   double precision
double-float double precision
single-float single precision
short-float  single precision

Your code has lots of single-float numbers (if you didn't change
*read-default-float-format*, as mentioned elsewhere), so you'll get
different results.

Ray
From: ···············@yahoo.com
Subject: Re: default float point types (GCL vs CMUCL)
Date: 
Message-ID: <1149012052.614779.171460@j55g2000cwa.googlegroups.com>
To add to the other replies, you can put 'declare' into 'do' this way:

(do ((k 1.0d0 (+ k 1.0d0))
     (sum 0.0d0 (+ sum (the double-float ,f))))
    ((> k n) sum))
  (declare (double-float k sum))
  [body])

Don't forget to declare n [maybe coerce it to double-float?].
Wrap (the double-float ...) around (sqrt k),
because Lisp can't assume the return type of sqrt is
more precise than 'complex': Lisp doesn't "know" your k
is always non-negative.  For the same reason,
wrap (the double-float ...) around the expt example,
put (declare (double-float s)) after the line where s is defined,
and similarly for c.
Finally, put
(declaim (optimize speed))
at the top of the file.
From: Juho Snellman
Subject: Re: default float point types (GCL vs CMUCL)
Date: 
Message-ID: <slrne7pe7g.dba.jsnell@sbz-30.cs.Helsinki.FI>
···············@yahoo.com <···············@yahoo.com> wrote:
> To add to the other replies, you can put 'declare' into 'do' this way:
> 
> (do ((k 1.0d0 (+ k 1.0d0))
>      (sum 0.0d0 (+ sum (the double-float ,f))))
>     ((> k n) sum))
>   (declare (double-float k sum))
>   [body])
> 
> Don't forget to declare n [maybe coerce it to double-float?].
> Wrap (the double-float ...) around (sqrt k),
> because Lisp can't assume the return type of sqrt is
> more precise than 'complex': Lisp doesn't "know" your k
> is always non-negative.

An implementation can reasonably infer that K is always a positive
double-float without the added declarations, since it's one at the
start of the loop, and is only incremented (by a positive d-f) on
further iterations. (At least SBCL does this. CMUCL might not, since
has some trouble dealing with non-integer induction variables).

-- 
Juho Snellman
From: Shyamal Prasad
Subject: [OT] Re: default float point types (GCL vs CMUCL)
Date: 
Message-ID: <87pshvl3to.fsf@turtle.local>
>>>>> "Greg" == Greg Buchholz <················@yahoo.com> writes:

    Greg>     I'm attempting to write a lisp version of the partial
    Greg> sums benchmark for the Great Computer Langauge Shootout (
    Greg> http://shootout.alioth.debian.org/debian/benchmark.php?test=partialsums&lang=all

Co-incidentally, I made a contribution Sunday morning myself for
exactly the same problem. (a jet lag thing :-)

I see you've solved your problem with double-floats, but I'm curious
if you are attempting any more of the open Lisp benchmarks.

My contribution was not nearly as succint as yours because I wrote
each loop one at a time and optimized to match the gcc version's
performance (I'm within a few percent on my old Pentium 600 Mhz
laptop, but on my powerpc G4 desktop SBCL simply doesn't seem to cut
it).

Cheers!
Shyamal
From: Greg Buchholz
Subject: Re: default float point types (GCL vs CMUCL)
Date: 
Message-ID: <1149097597.500358.109860@y43g2000cwc.googlegroups.com>
Shyamal Prasad wrote:
> I see you've solved your problem with double-floats, but I'm curious
> if you are attempting any more of the open Lisp benchmarks.

    I don't have any immediate plans to.   Looks like there's a few
tests that are already written, but just need some tweaking to work
correctly on the Shootout's machines (both "partial-sums" an
"recursive" fail with CMUCL on the Debian machine, while
"cheap-concurrency" and "mandelbrot" fail on SBCL).  And we'd need to
convince management to install something like CL-PPCRE to do the regex
benchmark.

> My contribution was not nearly as succint as yours because I wrote
> each loop one at a time and optimized to match the gcc version's
> performance

    Yeah, I just copied the C++ version, including the ugly scope
breaking macros.  But, the shootout is about speed, not elegance,
right?

Greg
From: ··············@ericsson.com
Subject: Re: default float point types (GCL vs CMUCL)
Date: 
Message-ID: <zmgxvbgz.fsf@ericsson.com>
    "Greg" == Greg Buchholz <················@yahoo.com> writes:

    Greg> to work correctly on the Shootout's machines (both
    Greg> "partial-sums" an "recursive" fail with CMUCL on the Debian
    Greg> machine, while "cheap-concurrency" and "mandelbrot" fail on
    Greg> SBCL).  

Hmmm...it seems CMUCL is broken in some way on those machines. I tend
to use SBCL so I'm not sure what that error means. 

The SBCL lisp failures seem to be coding faults. I'm guessing from a
very cursory look that mandelbrot fails because of formatting the
fixnum to a char stream. cheap-concurrency might be running into a
thread limit as far as I recall; I could swear I read someplace that
SBCL can only do 500 or some such number of thread allocs at a
time by default.....

    Greg> And we'd need to convince management to install
    Greg> something like CL-PPCRE to do the regex benchmark.

It's a debian machine. apt-get install cl-ppcre :-)

    Greg> But, the shootout is about speed, not elegance, right?

I hope so :) But its vaguely entertaining just looking at all the code
there.

Cheers!
Shyamal