/
core.clj
177 lines (124 loc) · 5.08 KB
/
core.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
(ns tech.datatype.core
"Generalized efficient manipulations of sequences of primitive datatype. Includes
specializations for java arrays and nio buffers. There are specializations to allow
implementations to provide efficient full typed copy functions when the types can be
ascertained. Usually this involves a double-dispatch on both the src and dest
arguments:
https://en.wikipedia.org/wiki/Double_dispatch.
Generic operations include:
1. datatype of this sequence.
2. Writing to, reading from.
3. Construction.
4. Efficient mutable copy from one sequence to another."
(:require [clojure.core.matrix.macros :refer [c-for]]
[clojure.core.matrix.protocols :as mp]
[clojure.core.matrix :as m]
[tech.datatype.base :as base]
[tech.datatype.java-primitive :as primitive]))
(set! *warn-on-reflection* true)
(set! *unchecked-math* :warn-on-boxed)
(defn get-datatype
[item]
(base/get-datatype item))
(defn set-value! [item offset value]
(base/set-value! item offset value))
(defn set-constant! [item offset value elem-count]
(base/set-constant! item offset value elem-count))
(defn get-value [item offset]
(base/get-value item offset))
(defn container-type [item]
(base/container-type item))
(defn ecount
"Type hinted ecount so numeric expressions run faster.
Calls clojure.core.matrix/ecount."
^long [item]
(base/ecount item))
(defn shape
"m/shape with fallback to m/ecount if m/shape is not available."
[item]
(base/shape item))
(defn copy-raw->item!
"Copy raw data into an array. Returns a tuple of
[ary-target result-offset-after-copy]"
([raw-data ary-target target-offset options]
(base/copy-raw->item! raw-data ary-target target-offset options))
([raw-data ary-target target-offset]
(base/copy-raw->item! raw-data ary-target target-offset {})))
(defn add-datatype->size-mapping
[datatype byte-size]
(base/add-datatype->size-mapping datatype byte-size))
(defn datatype->byte-size
^long [datatype]
(base/datatype->byte-size datatype))
(defn add-cast-fn
[datatype cast-fn]
(base/add-cast-fn datatype cast-fn))
(defn add-unchecked-cast-fn
[datatype cast-fn]
(base/add-unchecked-cast-fn datatype cast-fn))
(defn cast
[value datatype]
(base/cast value datatype))
(defn unchecked-cast
[value datatype]
(base/unchecked-cast value datatype))
(defn ->vector
"Conversion to persistent vector"
[item]
(base/->vector item))
(defn add-container-conversion-fn
"Add a container->container conversion. Function takes a dst-datatype and the src-container
and returns a tuple of [result-container result-offset]."
[src-container-type dst-container-type convert-fn]
(base/add-container-conversion-fn src-container-type dst-container-type convert-fn))
(defn add-copy-operation
"Add a new copy operation. Note that this is a single point in a 5 dimensional space
of operations."
[src-container-type dst-container-type src-dtype dst-dtype unchecked? copy-fn]
(base/add-copy-operation src-container-type dst-container-type src-dtype dst-dtype unchecked? copy-fn))
(defn copy!
([src src-offset dst dst-offset n-elems options]
(base/copy! src src-offset dst dst-offset n-elems options))
([src src-offset dst dst-offset n-elems]
(base/copy! src src-offset dst dst-offset n-elems {}))
([src dst]
(base/copy! src 0 dst 0 (ecount src) {})))
;; Primitive functions. Would be different for clojurescript.
(defn make-array-of-type
[datatype elem-count-or-seq & [options]]
(primitive/make-array-of-type datatype elem-count-or-seq
(or options {})))
(defn ->array
"Returns nil of item does not share a backing store with an array."
[item]
(primitive/->array item))
(defn ->array-copy
"Copy the data into an array that can correctly hold the datatype. This
array may not have the same datatype as the source item"
[item]
(primitive/->array-copy item))
(defn make-buffer-of-type
[datatype elem-count-or-seq & [options]]
(primitive/make-buffer-of-type datatype elem-count-or-seq
(or options {})))
(defn ->buffer-backing-store
"Convert to nio buffer that stores the data for the object. This may have
a different datatype than the object, so for instance the backing store for
the uint8 datatype is a nio buffer of type int8."
[src-ary]
(primitive/->buffer-backing-store src-ary))
(defn make-typed-buffer
"Support for unsigned datatypes comes via the typed buffer mechanism"
[datatype elem-count-or-seq & [options]]
;;Dynamic require because this auto-generates quite a bit of code and
;;I think most people will not need this.
(require '[tech.datatype.java-unsigned :as unsigned])
((resolve 'tech.datatype.java-unsigned/make-typed-buffer)
datatype elem-count-or-seq (or options {})))
(defn ->typed-buffer
"Conversion of a thing to a typed buffer"
[item & {:keys [datatype]}]
(require '[tech.datatype.java-unsigned :as unsigned])
(let [datatype (or datatype (get-datatype item))
retval ((resolve 'tech.datatype.java-unsigned/->typed-buffer) item)]
(assoc retval :dtype datatype)))