tech.v3.tensor.dimensions

Dimensions implement a projection from ND space in the the address space of the buffer along with a reverse projection from the address space back into ND space.

->2d-shape

(->2d-shape {:keys [shape]})

Given dimensions, return new dimensions with the lowest (fastest-changing) dimension unchanged and the rest of the dimensions multiplied into the higher dimension.

->batch-shape

(->batch-shape {:keys [shape]})

Given dimensions, return new dimensions with the lowest (fastest-changing) dimension unchanged and the rest of the dimensions multiplied into the higher dimension.

->global->local

(->global->local dims)

Get the ND->N addressing operator for these dimensions.

->least-rapidly-changing-dimension

(->least-rapidly-changing-dimension {:keys [shape-ecounts]})

Get the size of the least rapidly changing dimension

->local->global

(->local->global dims)

Get an inverse operator for these dims. Inverting the global->local dimensions means that for some dimensions (like broadcasted dimensions) each local index may correspond to a set of global indexes.

->most-rapidly-changing-dimension

(->most-rapidly-changing-dimension {:keys [shape-ecounts]})

Get the size of the most rapidly changing dimension

access-increasing?

(access-increasing? {:keys [access-increasing?]})

Are these dimensions setup such a naive seq through the data will be accessing memory in order. This is necessary for external library interfaces (blas, cudnn). An example would be after any nontrivial transpose that is not made concrete (copied) this condition will not hold.

broadcast

(broadcast {:keys [shape shape-ecounts strides], :as dims} new-shape)

Broadcast one or more dimensions. End result is shape of target matches new-shape

buffer-ecount

(buffer-ecount {:keys [buffer-ecount]})

What is the necessary ecount for a given buffer. Maybe nil if this could not be detected from the dimension arguments.

create-dimension-transforms

(create-dimension-transforms dims)

dense?

(dense? dims)

Do the strides indicate a packed data buffer with no holes. Currently mapped to native?

dimensions

(dimensions shape strides shape-ecounts shape-ecount-strides)(dimensions shape strides)(dimensions shape)

Dimensions contain information about how to map logical global indexes to local buffer addresses.

dimensions->column-stride

(dimensions->column-stride {:keys [shape strides]})

direct?

(direct? dims)

Is this dimension object a direct dimensions meaning the shape has no indirect (indexed) access.

ecount

(ecount {:keys [overall-ecount]})

Grab the ecount from a dimensions record

get-elem-dims-local->global

(get-elem-dims-local->global dims global->local*)

Harder translation than above. May return nil in the case where the inverse operation hasn't yet been derived. In this case, the best you can do is a O(N) iteration similar to dense math.

in-place-reshape

(in-place-reshape existing-dims shape)

Return new dimensions that correspond to an in-place reshape. This is a very difficult algorithm to get correct as it needs to take into account changing strides and dense vs non-dense dimensions.

indirect?

(indirect? dims)

Are these dimensions indirect meaning one of the shape entries is an index buffer (or some other index abstraction like a range with an increment other than 1)?

local-address->local-shape

(local-address->local-shape shape offsets strides shape-mins addr)

Shape and strides are not transposed. Returns valid? local-shape-as-list

matrix-column-stride

(matrix-column-stride {:keys [shape strides]})

Returns the larger of the 2 strides

matrix-element-stride

(matrix-element-stride {:keys [shape strides]})

native?

(native? dims)

Does this dimension object describe packed, in-order access of the underlying data buffer?

rotate

(rotate {:keys [shape], :as dims} new-offset-vec)

Dimensional rotations are applied via offsetting.

select

(select dims & args)

Expanded implementation of the core.matrix select function call. Each dimension must have an entry and each entry may be: :all (identity) :lla (reverse) persistent-vector: 0 1 2 3 4 4 5 (not supported by all backends) map: {:type :+ :- :min-item 0 :max-item 50} Monotonically increasing/decreasing bounded (inclusive) sequences

tensor : int32, dense vector only. Not supported by all backends.

;;Some examples https://cloojure.github.io/doc/core.matrix/clojure.core.matrix.html#var-select

shape

(shape {:keys [shape-ecounts]})

Get the shape of the dimensions object.

slice

(slice {:keys [shape strides], :as original-dims} n-elems)

Slice off the leftmost n-elems dimensions. Return a sub-dim object that doesn't change and a long reader of offsets. Returns {:dimension - dimensions for every sub object :offsets - long reader of offsets for the buffer. }

slice-right

(slice-right {:keys [shape strides], :as original-dims} n-elems)

Slice off the rightmost n-elems dimensions. Return a sub-dim object that doesn't change and a long reader of offsets. Returns {:dimension - dimensions for every sub object :offsets - long reader of offsets for the buffer. }

strides

(strides {:keys [strides]})

Get the strides of the dimensions object.

trans-2d-shape

(trans-2d-shape trans-a? dims)

transpose

(transpose {:keys [shape strides shape-ecounts]} reorder-vec)

Transpose the dimensions. Returns a new dimensions that will access memory in a transposed order. Dimension 0 is the leftmost (greatest) dimension:

(transpose tens (range (count (shape tens))))

is the identity operation.