Skip to content

Commit

Permalink
Better object overloads for copy-raw-item. Bug deep in nio buffer han…
Browse files Browse the repository at this point in the history
…dling.
  • Loading branch information
cnuernber committed Oct 31, 2019
1 parent f837bf5 commit 2ec1ab5
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 36 deletions.
53 changes: 26 additions & 27 deletions src/tech/v2/datatype/base.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -277,31 +277,34 @@
(set-value! ary-target target-offset raw-data)
[ary-target (+ target-offset 1)])

RandomAccess
Object
(copy-raw->item! [raw-data ary-target ^long target-offset options]
(let [^List raw-data raw-data
num-elems (.size raw-data)]
(if (= 0 num-elems)
[ary-target target-offset]
(if (number? (.get raw-data 0))
(do
(parallel-for/parallel-for
idx num-elems
(set-value! ary-target (+ idx target-offset) (.get raw-data idx)))
[ary-target (+ target-offset num-elems)])
(copy-raw-seq->item! raw-data ary-target target-offset options)))))

java.lang.Iterable
(copy-raw->item! [raw-data ary-target target-offset options]
(copy-raw-seq->item! (seq raw-data) ary-target target-offset options))
(cond
(dtype-proto/convertible-to-reader? raw-data)
(let [src-reader (dtype-proto/as-reader raw-data)]
(if (or (not= :object (casting/flatten-datatype
(get-datatype src-reader)))
(= :object (casting/flatten-datatype (get-datatype ary-target))))
(raw-dtype-copy! src-reader ary-target target-offset options)
(copy-raw-seq->item! (seq raw-data) ary-target target-offset options)))
(instance? RandomAccess raw-data)
(let [^List raw-data raw-data
num-elems (.size raw-data)]
(if (= 0 num-elems)
[ary-target target-offset]
(if (number? (.get raw-data 0))
(do
(parallel-for/parallel-for
idx num-elems
(set-value! ary-target (+ idx target-offset) (.get raw-data idx)))
[ary-target (+ target-offset num-elems)])
(copy-raw-seq->item! raw-data ary-target target-offset options))))
(instance? java.lang.Iterable raw-data)
(copy-raw-seq->item! (seq raw-data) ary-target
target-offset options)

Object
(copy-raw->item! [raw-data ary-target offset options]
(if-let [reader (dtype-proto/as-reader raw-data)]
(raw-dtype-copy! reader ary-target offset options)
(if-let [base-type (dtype-proto/as-base-type raw-data)]
(raw-dtype-copy! base-type ary-target offset options)
(throw (ex-info "Raw copy not supported on object" {}))))))
:else
(throw (ex-info "Raw copy not supported on object" {})))))


(extend-protocol dtype-proto/PBuffer
Expand Down Expand Up @@ -354,10 +357,6 @@
(make-container :java-array (get-datatype item) (ecount item) {})]
(copy! item retval)))

dtype-proto/PCopyRawData
(copy-raw->item! [raw-data ary-target target-offset options]
(copy-raw-seq->item! (seq raw-data) ary-target target-offset options))


dtype-proto/PSetConstant
(set-constant! [item offset value n-elems]
Expand Down
3 changes: 2 additions & 1 deletion src/tech/v2/datatype/io.clj
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@
[item indexes values options]
(let [datatype (or (:datatype options) (dtype-proto/get-datatype item))]
(fast-copy/parallel-write! values (indexed-reader/make-indexed-reader
indexes values (assoc options :datatype datatype))
indexes values (assoc options :datatype
datatype))
true)
values))

Expand Down
38 changes: 30 additions & 8 deletions src/tech/v2/datatype/nio_buffer.clj
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,17 @@
(declare make-buffer-of-type)


(defmacro datatype->buffer-creation
[datatype src-ary]
(case datatype
:int8 `(ByteBuffer/wrap ^bytes ~src-ary)
:int16 `(ShortBuffer/wrap ^shorts ~src-ary)
:int32 `(IntBuffer/wrap ^ints ~src-ary)
:int64 `(LongBuffer/wrap ^longs ~src-ary)
:float32 `(FloatBuffer/wrap ^floats ~src-ary)
:float64 `(DoubleBuffer/wrap ^doubles ~src-ary)))


(defn in-range?
[^long lhs-off ^long lhs-len ^long rhs-off ^long rhs-len]
(or (and (>= rhs-off lhs-off)
Expand Down Expand Up @@ -128,14 +139,25 @@


dtype-proto/PBuffer
{:sub-buffer (fn [buffer# offset# length#]
(let [buf# (.slice (typecast/datatype->buffer-cast-fn
~datatype buffer#))
offset# (long offset#)
len# (long length#)]
(.position buf# offset#)
(.limit buf# (+ offset# len#))
buf#))}
{:sub-buffer
(fn [buffer# offset# length#]
(let [buffer# (typecast/datatype->buffer-cast-fn
~datatype buffer#)
sub-array-data# (dtype-proto/->sub-array buffer#)]
(if sub-array-data#
(let [{java-array# :java-array
ary-offset# :offset} sub-array-data#
buf# (datatype->buffer-creation ~datatype java-array#)
new-offset# (+ (long offset#) (long ary-offset#))]
(.position buf# new-offset#)
(.limit buf# (+ new-offset# (long length#)))
buf#)
(let [buf# (.slice buffer#)
offset# (long offset#)
len# (long length#)]
(.position buf# offset#)
(.limit buf# (+ offset# len#))
buf#))))}
dtype-proto/PToWriter
{:convertible-to-writer? (constantly true)
:->writer
Expand Down
18 changes: 18 additions & 0 deletions test/tech/v2/tensor/copy_test.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
(ns tech.v2.tensor.copy-test
(:require [tech.v2.datatype :as dtype]
[tech.v2.datatype.functional :as dfn]
[tech.v2.tensor :as dtt]
[clojure.test :refer :all]))


(deftest tensor-copy-test
(let [new-tens (repeat 2 (dtt/->tensor [[2] [3]]))
dest-tens (dtt/new-tensor [2 2])]
(dtype/copy-raw->item! (->> new-tens
(map #(dtt/select % 0 :all)))
(dtt/select dest-tens 0 :all))
(is (dfn/equals dest-tens (dtt/->tensor [[2 2] [0 0]])))
(dtype/copy-raw->item! (->> new-tens
(map #(dtt/select % 1 :all)))
(dtt/select dest-tens 1 :all))
(is (dfn/equals dest-tens (dtt/->tensor [[2 2] [3 3]])))))

0 comments on commit 2ec1ab5

Please sign in to comment.