anchor.diff:  (defun draw-points (pos num-bodies)
     (ecase (array-type pos)
       (:cpu (draw-points-host pos num-bodies))
  -    (:gpu (memcpy-array-device-to-host pos)
  +    (:gpu (sync-array pos :device-to-host)
             (draw-points-host pos num-bodies))
       (:gpu/interop
             (draw-points-interop pos num-bodies))))
  
positive.code:   (velocity-scale 2.64  :read-only t))
  
  (defun init-body-system (num-bodies &key (gpu t) (interop nil))
    (when (and (null gpu) interop)
      (error "Interoperability is available only on GPU"))
    (let ((system (make-body-system)))
      (setf (num-bodies system) num-bodies)
      (init-cuda-context 0 :interop t)
      (init-memory-blocks system gpu interop)
      (reset-body-system system)
      (when gpu
        (memcpy-array-host-to-device (old-pos system))
        (memcpy-array-host-to-device (vel system)))
      system))
  
  (defun lookup-array-type (gpu interop)
    (if gpu
        (if interop
            :gpu/interop
            :gpu)
        (if interop
            (error "Interoperability is available only on GPU")
            :cpu)))
  
  (defun init-memory-blocks (system gpu interop)
    (symbol-macrolet ((new-pos    (new-pos system))
                      (old-pos    (old-pos system))
                      (vel        (vel system))
                      (num-bodies (num-bodies system)))
      (let ((array-type (lookup-array-type gpu interop)))
        (setf new-pos (alloc-array num-bodies array-type)
              old-pos (alloc-array num-bodies array-type)
              vel     (alloc-array num-bodies array-type)))))
  
  (defun release-body-system (system)
    (release-memory-blocks system)
    (release-cuda-context))
  
  (defun release-memory-blocks (system)
    (free-array (vel     system))
    (free-array (old-pos system))
    (free-array (new-pos system)))
  
  (defun reset-body-system (system)
    (let ((old-pos        (old-pos system))
          (vel            (vel system))
          (cluster-scale  (cluster-scale system))
          (velocity-scale (velocity-scale system))
          (num-bodies     (num-bodies system)))
      (randomize-bodies old-pos vel cluster-scale velocity-scale num-bodies)))
  
  (defun update-body-system (system)
    (symbol-macrolet ((new-pos    (new-pos system))
                      (old-pos    (old-pos system)))
      (let ((vel        (vel system))
            (delta-time (delta-time system))
            (damping    (damping system))
            (num-bodies (num-bodies system))
            (p          (p system)))
        (ecase (array-type new-pos)
          ((:gpu :gpu/interop)
           (integrate-nbody-system-gpu new-pos old-pos vel delta-time damping num-bodies p))
          (:cpu
           (integrate-nbody-system-cpu new-pos old-pos vel delta-time damping num-bodies)))
        (rotatef new-pos old-pos))))
  
  
  ;;;
  ;;; Particle renderer
  ;;;
  
  (defstruct (particle-renderer :conc-name)
    ;; for rendering
    (point-size  1.0                :read-only t)
    (sprite-size 2.0                :read-only t)
    (base-color  #(1.0 0.6 0.3 1.0) :read-only t)
    ;; for shaders
    program vertex-shader pixel-shader
    ;; for texture
    texture texture-data)
  
  (defun init-particle-renderer ()
    (let ((renderer (make-particle-renderer)))
      (init-shaders renderer)
      (create-texture renderer 32)
      renderer))
  
  (defun init-shaders (renderer)
    (symbol-macrolet ((program       (program       renderer))
                      (vertex-shader (vertex-shader renderer))
                      (pixel-shader  (pixel-shader  renderer)))
      ;; create shader objects
      (setf vertex-shader (gl:create-shader :vertex-shader)
            pixel-shader  (gl:create-shader :fragment-shader))
      ;; set shader source codes
      (gl:shader-source vertex-shader +vertex-shader+)
      (gl:shader-source pixel-shader  +pixel-shader+)
      ;; compile source codes
      (gl:compile-shader vertex-shader)
      (gl:compile-shader pixel-shader)
      ;; create an empty program object
  
negative.code: ;;; NBody Demo
  ;;;
  
  (defstruct (nbody-demo (:constructor %make-nbody-demo))
    system renderer)
  
  (defun init-nbody-demo (num-bodies &key (gpu t) (interop nil))
    (let ((system (init-body-system num-bodies :gpu gpu :interop interop))
          (renderer (init-particle-renderer)))
      ;; Reset body system
      (reset-body-system system)
      ;; Synchronize memory form host to device
      (when (body-system-gpu system)
        (sync-body-system system :host-to-device))
      ;; Make NBody demo
      (%make-nbody-demo :system system :renderer renderer)))
  
  (defun release-nbody-demo (demo)
    (release-particle-renderer (nbody-demo-renderer demo))
    (release-nbody-system (nbody-demo-system demo)))
  
  (defmacro with-nbody-demo ((var num-bodies &key (gpu t) (interop nil))
                             &body body)
    `(let ((,var (init-nbody-demo ,num-bodies :gpu ,gpu :interop ,interop)))
       (unwind-protect (progn ,@body)
         (release-nbody-demo ,var))))
  
  (defun update-nbody-demo (demo)
    (update-body-system (nbody-demo-system demo)))
  
  (defun display-nbody-demo (demo)
    (let ((system (nbody-demo-system demo))
          (renderer (nbody-demo-renderer demo)))
      (let ((pos (body-system-old-pos system))
            (num-bodies (body-system-num-bodies system)))
        (display-particle-renderer renderer pos num-bodies :particle-sprites))))
  
  (defun nbody-demo-num-bodies (demo)
    (body-system-num-bodies (nbody-demo-system demo)))
  
  
  ;;;
  ;;; Body System
  ;;;
  
  (defstruct (body-system (:constructor %make-body-system))
    ;; CUDA device ID
    (dev-id :dev-id :read-only t)
    ;; Memory blocks
    (new-pos :new-pos)                    ; Not read-only to flip
    (old-pos :old-pos)
    (vel :vel :read-only t)
    ;; Flags
    (gpu :gpu :read-only t)
    (interop :interop :read-only t)
    ;; Number of bodies
    (num-bodies :num-bodies :read-only t)
    ;; Simulation parameters
    (delta-time     0.016 :read-only t)
    (damping        1.0   :read-only t)
    (p              256   :read-only t)
  