1. Karsten Schmidt
  2. simplecl

Commits

Karsten Schmidt  committed b812f9c Merge

flow: Merged <release> '0.1.5' to <master> ('default').

  • Participants
  • Parent commits 6d5c8c9, d75c75f
  • Branches default
  • Tags 0.1.5

Comments (0)

Files changed (7)

File .hgtags

View file
  • Ignore whitespace
+960f06e2f7fee5d1205bb3b489481a7d8e9e524f 0.1.4

File README.md

View file
  • Ignore whitespace
 4. apply a 3D distortion filter to all points
 5. do a standard 3d > 2d camera-screen projection
 
-A short video fragment too: [attractor.mp4](http://media.postspectacular.com/2012/simplecl/20121205-attractor-grad-hd720.mp4)
+A short video fragment too: [attractor.mp4](http://media.postspectacular.com/2012/simplecl/20121205-attractor-grad-hd720.mp4) (10M points/frame, ~780-840ms/frame)
 
 More examples & documentation will be added ASAP.
 

File pom.xml

View file
  • Ignore whitespace
   <groupId>com.postspectacular</groupId>
   <artifactId>simplecl</artifactId>
   <packaging>jar</packaging>
-  <version>0.1.4</version>
+  <version>0.1.5</version>
   <name>simplecl</name>
   <description>Clojure wrapper &amp; highlevel processing pipeline ops for JOCL/OpenCL.</description>
   <url>http://hg.postspectacular.com/simplecl</url>
   <repositories>
     <repository>
       <id>central</id>
-      <url>http://repo1.maven.org/maven2</url>
+      <url>http://repo1.maven.org/maven2/</url>
       <snapshots>
-        <enabled>true</enabled>
+        <enabled>false</enabled>
       </snapshots>
       <releases>
         <enabled>true</enabled>
     <dependency>
       <groupId>com.postspectacular</groupId>
       <artifactId>structgen</artifactId>
-      <version>0.1.1</version>
+      <version>0.1.2</version>
       <scope>test</scope>
     </dependency>
   </dependencies>

File project.clj

View file
  • Ignore whitespace
-(defproject com.postspectacular/simplecl "0.1.4"
+(defproject com.postspectacular/simplecl "0.1.5"
   :description "Clojure wrapper & highlevel processing pipeline ops for JOCL/OpenCL."
   :url "http://hg.postspectacular.com/simplecl"
   :license {:name "Eclipse Public License"
             :url "http://www.eclipse.org/legal/epl-v10.html"}
   :dependencies [[org.clojure/clojure "1.4.0"]
                  [org.clojars.toxi/jocl "2.0.0-rc10"]]
-  :profiles {:test {:dependencies [[com.postspectacular/structgen "0.1.1"]]
+  :profiles {:test {:dependencies [[com.postspectacular/structgen "0.1.2"]]
                     :jvm-opts ["-Xms512m" "-Xmx2g"]}}
 )

File src/simplecl/core.clj

View file
  • Ignore whitespace
   `(defmethod ^{:tag CLBuffer :private true} fill-buffer ~type
      [^CLBuffer b# f#]
      (let [^{:tag ~type} nb# (.getBuffer b#)]
-       (loop [pos# (.position nb#)]
-         (when (pos? (.remaining nb#))
+       (loop [pos# (.position nb#) remaining# (.remaining nb#)]
+         (when (pos? remaining#)
            (.put nb# (~cast (f# pos#)))
-           (recur (inc pos#))))
+           (recur (inc pos#) (dec remaining#))))
        (.rewind nb#))
      b#))
 

File src/simplecl/ops.clj

View file
  • Ignore whitespace
   Instantiates a CL buffer for each spec with each having the following keys:
 
       :usage - buffer usage (default :readwrite)
-      :type - default :float
-      :size - absolute size or
+      :type - buffer type (defaults to :float unless :wrap is present)
+       :size - absolute size or
       :factor - relative size as in (* factor (int (/ n group-size)) group-size)
       :fill - optional fn to fill buffer elements with (see fill-buffer fn)
       :data - optional data seq to fill buffer with
+      :wrap - optional, existing NIO buffer or Clojure seq to fully wrap using as-clbuffer fn
 
   Returns a map with same keys and CLBuffer instances as values."
   [n group-size & {:as specs}]
   (let [n (* (int (/ n group-size)) group-size)]
     (reduce
-        (fn [acc [k {:keys [usage size factor type fill data] :or {type :float usage :readwrite}}]]
-          (let [buf (cl/make-buffer type (if size size (* factor n)) usage)]
-            (assoc acc k
-              (cond
-                fill (cl/fill-buffer buf fill)
-                data (do (cl/into-buffer buf data) (cl/rewind buf))
-                :default buf))))
+        (fn [acc [k {:keys [usage size factor type fill data wrap] :or {usage :readwrite}}]]
+          (if wrap
+            (if type
+              (assoc acc k (cl/as-clbuffer type wrap usage))
+              (assoc acc k (cl/as-clbuffer wrap usage)))
+            (let [buf (cl/make-buffer (or type :float) (if size size (* factor n)) usage)]
+              (assoc acc k
+                (cond
+                  fill (cl/fill-buffer buf fill)
+                  data (do (cl/into-buffer buf data) (cl/rewind buf))
+                  :default buf)))))
         {} specs)))
 
 (defn init-kernel
       :verbose - pprint compiled queue and execution time (default false)
       :release - automatic release of all buffers (default true)"
   [{:keys [queue buffers final-out final-size]} &
-   {:keys [final-size verbose release] :or {release true}}]
+   {:keys [final-size final-type verbose release] :or {release true}}]
   (if verbose
     (do (pprint queue) (time (apply cl/enqueue queue)))
     (apply cl/enqueue queue))
   (if final-out
     (let [^Buffer nb (cl/nio-buffer final-out)
+          nb (condp = final-type
+               :int (.asIntBuffer nb)
+               :float (.asFloatBuffer nb)
+               :double (.asDoubleBuffer nb)
+               nb)
           final-size (or final-size (.capacity nb))
           ^Buffer result (cl/slice nb final-size)]
       (when release (apply cl/release buffers))

File test/simplecl/verlet_test.clj

View file
  • Ignore whitespace
   The ConstrainParticles phase includes a synchronous read operation of the
   particle buffer, ensuring the OpenCL computation is complete before
   returning to Clojure."
-  [& {:keys [p-buf q-buf s-buf c-buf bounds gravity drag nump nums numc iter]}]
+  [{:keys [p-buf q-buf s-buf c-buf bounds gravity drag nump nums numc iter]}]
   (ops/compile-pipeline :steps
     (concat
      [{:name "ParticleUpdate" :in [p-buf bounds gravity] :out q-buf
             p-struct (gen/make-struct :Particles [:particles :Particle2 nump])
             s-struct (gen/make-struct :Springs [:springs :Spring nums])
             c-struct (gen/make-struct :Circles [:circles :Circle numc])
-            p-buf (cl/as-clbuffer (gen/encode p-struct {:particles particles}) :readwrite)
-            q-buf (cl/as-clbuffer (gen/encode p-struct {}) :readwrite)
-            s-buf (cl/as-clbuffer (gen/encode s-struct {:springs springs}) :readonly)
-            c-buf (cl/as-clbuffer (gen/encode c-struct {:circles circles}) :readonly)
-            bounds (cl/as-clbuffer :float bounds :readonly)
-            gravity (cl/as-clbuffer :float gravity :readonly)
-            pipeline (make-pipeline
-                       :p-buf p-buf :q-buf q-buf :s-buf s-buf :c-buf c-buf
-                       :bounds bounds :gravity gravity :drag drag
-                       :nump nump :nums nums :numc numc :iter iter)]
-        {:cl-state cl-state
-         :p-struct p-struct
-         :s-struct s-struct
-         :c-struct c-struct
-         :p-buf p-buf
-         :q-buf q-buf
-         :s-buf s-buf
-         :c-buf c-buf
-         :pipeline pipeline
-         :grid grid
-         :circles circles
-         :bounds bounds
-         :gravity gravity
-         :drag drag
-         :iter iter
-         :nump nump
-         :nums nums
-         :numc numc}))))
+            state (merge
+                    {:cl-state cl-state
+                     :p-struct p-struct :s-struct s-struct :c-struct c-struct
+                     :drag drag :nump nump :nums nums :numc numc :iter iter
+                     :grid grid :circles circles}
+                    (ops/init-buffers 1 1
+                      :p-buf {:wrap (gen/encode p-struct {:particles particles})}
+                      :q-buf {:wrap (gen/encode p-struct {})}
+                      :s-buf {:wrap (gen/encode s-struct {:springs springs}) :usage :readonly}
+                      :c-buf {:wrap (gen/encode c-struct {:circles circles}) :usage :readonly}
+                      :bounds {:wrap bounds :type :float :usage :readonly}
+                      :gravity {:wrap gravity :type :float :usage :readonly}))]
+        (assoc state :pipeline (make-pipeline state))))))
 
 (defn update-pipeline
-  "Releases the current OpenCL particle buffer and generates a new one for
-  the current particles and builds an updated OpenCL processing pipeline.
+  "Releases the current OpenCL particle & spring buffers and generates new ones for
+  the current particles/spring, then builds an updated OpenCL processing pipeline.
   Returns updated physics state map."
-  [{:keys [cl-state grid p-struct s-struct p-buf q-buf s-buf c-buf
-           nump nums numc bounds gravity drag iter] :as state}]
+  [{:keys [cl-state grid p-struct s-struct p-buf s-buf] :as state}]
   (cl/with-state cl-state
     (cl/release p-buf s-buf)
     (let [{:keys [particles springs]} grid
-          cp (count particles)
-          cs (count springs)
-          p-buf (cl/as-clbuffer (gen/encode p-struct {:particles particles}) :readwrite)
-          s-buf (cl/as-clbuffer (gen/encode s-struct {:springs springs}) :readonly)
-          pipeline (make-pipeline
-                     :p-buf p-buf :q-buf q-buf :s-buf s-buf :c-buf c-buf
-                     :bounds bounds :gravity gravity :drag drag
-                     :nump cp :nums cs :numc numc :iter iter)]
-      (assoc state
-        :p-buf p-buf
-        :s-buf s-buf
-        :nump cp
-        :nums cs
-        :pipeline pipeline))))
+          state (merge state
+                  (ops/init-buffers 1 1
+                    :p-buf {:wrap (gen/encode p-struct {:particles particles})}
+                    :s-buf {:wrap (gen/encode s-struct {:springs springs}) :usage :readonly})
+                  {:nump (count particles) :nums (count springs)})]
+      (assoc state :pipeline (make-pipeline state)))))
 
 (defn physics-time-step
   "Executes `iter` iterations of the current OpenCL processing pipeline."