anchor.diff:        (set (aref new-pos index) position)
         (set (aref vel index) velocity))))
   
  +
  +;;;
  +;;; cl-glut window subclass
  +;;;
  +
  +(defclass nbody-window (glut:window)
  +  ((new-pos :initform nil)
  +   (old-pos :initform nil)
  +   (vel :initform nil)
  +   (delta-time :initform 0)
  +   (damping :initform 0)
  +   (num-bodies :initform 0)
  +   (p :initform 0))
  +  (:default-initargs :width 640 :height 480 :pos-x 100 :pos-y 100
  +                     :mode '(:double :rgb) :title "nbody"))
  +
  +
  +;;;
  +;;; cl-glut event handlers
  +;;;
  +
  +(defmethod glut:display-window :before ((w nbody-window))
  +  (gl:clear-color 0 0 0 0))
  +
  +(defmethod glut:display ((w nbody-window))
  +  ;; clear buffers
  +  (gl:clear :color-buffer :depth-buffer-bit)
  +  ;; view transform
  +  (gl:matrix-mode :modelview)
  +  (gl:load-identity)
  +  (gl:translate 0.0 0.0 -100.0)
  +  (gl:rotate 0.0 1.0 0.0 0.0)
  +  (gl:rotate 0.0 0.0 1.0 0.0)
  +  ;; draw points
  +  (gl:color 1.0 1.0 1.0)
  +  (gl:point-size 1.0)
  +  (gl:begin :points)
  +  (with-slots (old-pos num-bodies) w
  +    (memcpy-device-to-host old-pos)
  +    (dotimes (i num-bodies)
  +      (let ((p (mem-aref old-pos i)))
  +        (gl:vertex (float4-x p) (float4-y p) (float4-z p)))))
  +  (gl:end)
  +  ;; swap buffers
  +  (glut:swap-buffers)
  +  ;; display frame rate
  +  (display-frame-rate (slot-value w 'num-bodies)))
  +
  +(defmethod glut:reshape ((w nbody-window) width height)
  +  ;; configure on projection mode
  +  (gl:matrix-mode :projection)
  +  (gl:load-identity)
  +  (glu:perspective 60.0 (/ width height) 0.1 1000.0)
  +  ;; configure on model-view mode
  +  (gl:matrix-mode :modelview)
  +  (gl:viewport 0 0 width height))
  +
  +(defmethod glut:idle ((w nbody-window))
  +  (with-slots (new-pos old-pos vel delta-time damping num-bodies p) w
  +    (update new-pos old-pos vel delta-time damping num-bodies p)
  +    (rotatef new-pos old-pos)
  +    (glut:post-redisplay)))
  +
  +
  +;;;
  +;;; performance measurement functions
  +;;;
  +
  +(defvar *flops-per-interaction* 20)
  +
  +(defun compute-perf-stats (num-bodies elapsed-time fps-count iterations)
  +  (let ((milliseconds (/ elapsed-time fps-count)))
  +    (let* ((ifps (/ 1.0 (/ milliseconds 1000.0)))
  +           (interactions-per-second (/ (* num-bodies num-bodies iterations)
  +                                       (/ milliseconds 1000)
  +                                       1.0e9))
  +           (gflops (* interactions-per-second *flops-per-interaction*)))
  +      (values ifps interactions-per-second gflops))))
  +
  +(let ((fps-count 0)
  +      (fps-limit 5)
  +      (template "CUDA N-Body (~A bodies): ~,1F fps | ~,1F BIPS | ~,1F GFLOP/s | single precision~%"))
  +  (defun display-frame-rate (num-bodies)
  +    (incf fps-count)
  +    (when (>= fps-count fps-limit)
  +      (multiple-value-bind (ifps interactions-per-second gflops)
  +          (compute-perf-stats num-bodies (get-elapsed-time) fps-count 1)
  +        (glut:set-window-title
  +          (format nil template num-bodies ifps interactions-per-second gflops))
  +        (setf fps-count 0)
  +        (setf fps-limit (max ifps 1.0))))))
  +
  +
  +;;;
  +;;; timing functions
  +;;;
  +
  +(let (start-event stop-event)
  +
  +  (defmacro with-cuda-timer (&body body)
  +    `(unwind-protect
  +          (progn
  +            (create-timer-events)
  +            ,@body)
  +       (destroy-timer-events)))
  +
  +  (defun create-timer-events ()
  +    (setf start-event (cffi:foreign-alloc 'cu-event)
  +          stop-event (cffi:foreign-alloc 'cu-event))
  +    (cu-event-create start-event cu-event-default)
  +    (cu-event-create stop-event cu-event-default))
  +  
  +  (defun destroy-timer-events ()
  +    (cu-event-destroy (cffi:mem-ref start-event 'cu-event))
  +    (cu-event-destroy (cffi:mem-ref stop-event 'cu-event))
  +    (cffi:foreign-free start-event)
  +    (cffi:foreign-free stop-event))
  +
  +  (defun start-timer ()
  +    (cu-event-record (cffi:mem-ref start-event 'cu-event)
  +                     (cffi:null-pointer)))
  +
  +  (defun stop-and-synchronize-timer ()
  +    (cu-event-record (cffi:mem-ref stop-event 'cu-event)
  +                     (cffi:null-pointer))
  +    (cu-event-synchronize (cffi:mem-ref stop-event 'cu-event)))
  +
  +  (defun get-elapsed-time ()
  +    (let (milliseconds)
  +      (cffi:with-foreign-object (pmilliseconds :float)
  +        (stop-and-synchronize-timer)
  +        (cu-event-elapsed-time pmilliseconds
  +                               (cffi:mem-ref start-event 'cu-event)
  +                               (cffi:mem-ref stop-event 'cu-event))
  +        (start-timer)
  +        (setf milliseconds (cffi:mem-ref pmilliseconds :float)))
  +      milliseconds)))
  +
  +
  +;;;
  +;;; main
  +;;;
  +
   (defun integrate-nbody-system (new-pos old-pos vel delta-time damping num-bodies p)
     (let ((grid-dim (list (ceiling (/ num-bodies p)) 1 1))
           (block-dim (list p 1 1)))
  
positive.code: 
  (defun update (new-pos old-pos vel delta-time damping num-bodies p)
    (integrate-nbody-system new-pos old-pos vel delta-time damping num-bodies p))
  
  
  ;;;
  ;;; cl-glut window subclass
  ;;;
  
  (defclass nbody-window (glut:window)
    ((new-pos :initform nil)
     (old-pos :initform nil)
     (vel :initform nil)
     (delta-time :initform 0)
     (damping :initform 0)
     (num-bodies :initform 0)
     (p :initform 0))
    (:default-initargs :width 640 :height 480 :pos-x 100 :pos-y 100
                       :mode '(:double :rgb) :title "nbody"))
  
  
  ;;;
  ;;; cl-glut event handlers
  ;;;
  
  (defmethod glut:display-window :before ((w nbody-window))
    (gl:clear-color 0 0 0 0))
  
  (defmethod glut:display ((w nbody-window))
    ;; clear buffers
    (gl:clear :color-buffer :depth-buffer-bit)
    ;; view transform
    (gl:matrix-mode :modelview)
    (gl:load-identity)
    (gl:translate 0.0 0.0 -100.0)
    (gl:rotate 0.0 1.0 0.0 0.0)
    (gl:rotate 0.0 0.0 1.0 0.0)
    ;; draw points
    (gl:color 1.0 1.0 1.0)
    (gl:point-size 1.0)
    (gl:begin :points)
    (with-slots (old-pos num-bodies) w
      (memcpy-device-to-host old-pos)
      (dotimes (i num-bodies)
        (let ((p (mem-aref old-pos i)))
          (gl:vertex (float4-x p) (float4-y p) (float4-z p)))))
    (gl:end)
    ;; swap buffers
    (glut:swap-buffers)
    ;; display frame rate
    (display-frame-rate (slot-value w 'num-bodies)))
  
  (defmethod glut:reshape ((w nbody-window) width height)
    ;; configure on projection mode
    (gl:matrix-mode :projection)
    (gl:load-identity)
    (glu:perspective 60.0 (/ width height) 0.1 1000.0)
    ;; configure on model-view mode
    (gl:matrix-mode :modelview)
    (gl:viewport 0 0 width height))
  
  (defmethod glut:idle ((w nbody-window))
    (with-slots (new-pos old-pos vel delta-time damping num-bodies p) w
      (update new-pos old-pos vel delta-time damping num-bodies p)
      (rotatef new-pos old-pos)
      (glut:post-redisplay)))
  
  
  ;;;
  ;;; performance measurement functions
  ;;;
  
  (defvar *flops-per-interaction* 20)
  
  (defun compute-perf-stats (num-bodies elapsed-time fps-count iterations)
    (let ((milliseconds (/ elapsed-time fps-count)))
      (let* ((ifps (/ 1.0 (/ milliseconds 1000.0)))
             (interactions-per-second (/ (* num-bodies num-bodies iterations)
                                         (/ milliseconds 1000)
                                         1.0e9))
             (gflops (* interactions-per-second *flops-per-interaction*)))
        (values ifps interactions-per-second gflops))))
  
  (let ((fps-count 0)
        (fps-limit 5)
        (template "CUDA N-Body (~A bodies): ~,1F fps | ~,1F BIPS | ~,1F GFLOP/s | single precision~%"))
    (defun display-frame-rate (num-bodies)
      (incf fps-count)
      (when (>= fps-count fps-limit)
        (multiple-value-bind (ifps interactions-per-second gflops)
            (compute-perf-stats num-bodies (get-elapsed-time) fps-count 1)
          (glut:set-window-title
            (format nil template num-bodies ifps interactions-per-second gflops))
          (setf fps-count 0)
          (setf fps-limit (max ifps 1.0))))))
  
  
  ;;;
  ;;; timing functions
  ;;;
  
  (let (start-event stop-event)
  
    (defmacro with-cuda-timer (&body body)
      `(unwind-protect
            (progn
              (create-timer-events)
              ,@body)
         (destroy-timer-events)))
  
    (defun create-timer-events ()
      (setf start-event (cffi:foreign-alloc 'cu-event)
            stop-event (cffi:foreign-alloc 'cu-event))
      (cu-event-create start-event cu-event-default)
      (cu-event-create stop-event cu-event-default))
    
    (defun destroy-timer-events ()
      (cu-event-destroy (cffi:mem-ref start-event 'cu-event))
      (cu-event-destroy (cffi:mem-ref stop-event 'cu-event))
      (cffi:foreign-free start-event)
      (cffi:foreign-free stop-event))
  
    (defun start-timer ()
      (cu-event-record (cffi:mem-ref start-event 'cu-event)
                       (cffi:null-pointer)))
  
    (defun stop-and-synchronize-timer ()
      (cu-event-record (cffi:mem-ref stop-event 'cu-event)
                       (cffi:null-pointer))
      (cu-event-synchronize (cffi:mem-ref stop-event 'cu-event)))
  
    (defun get-elapsed-time ()
      (let (milliseconds)
        (cffi:with-foreign-object (pmilliseconds :float)
          (stop-and-synchronize-timer)
          (cu-event-elapsed-time pmilliseconds
                                 (cffi:mem-ref start-event 'cu-event)
                                 (cffi:mem-ref stop-event 'cu-event))
          (start-timer)
          (setf milliseconds (cffi:mem-ref pmilliseconds :float)))
        milliseconds)))
  
  
  ;;;
  ;;; main
  ;;;
  
  (defun main ()
    (let ((dev-id 0)
  
negative.code:         :cl-cuda)
    (:export :main))
  (in-package :cl-cuda-examples.nbody)
  
  
  ;;;
  ;;; Kernel functions
  ;;;
  
  (defkernel body-body-interaction (float3 ((ai float3) (bi float4) (bj float4)))
    (let ((r (float3 (- (float4-x bj) (float4-x bi))
  