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 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432
|
package tensor
// Memory is a representation of memory of the value.
//
// The main reason for requiring both Uintptr() and Pointer() methods is because while Go currently does not have a compacting
// garbage collector, from the docs of `unsafe`:
// Even if a uintptr holds the address of some object, the garbage collector, will not update that uintptr's value if the object moves,
// nor will that uintptr keep the object from being reclaimed.
type Memory interface {
Uintptr() uintptr
MemSize() uintptr
}
// Engine is a representation of an execution engine.
// While different execution engines can have different capabilities, all execution engines must be able to allocate and free memory
type Engine interface {
AllocAccessible() bool // AllocAccessible returns true if the engine return Go-accessible memory pointers?
Alloc(size int64) (Memory, error) // Alloc allocates memory
Free(mem Memory, size int64) error // Free rees memory
Memset(mem Memory, val interface{}) error // Memset - duh
Memclr(mem Memory) // Memclr - duh
Memcpy(dst, src Memory) error // Memcpy - duh
Accessible(mem Memory) (Memory, error) // Accessible returns Go-accesible memory pointers, or errors, if it cannot be done
WorksWith(order DataOrder) bool // WorksWith returns true if the data order can be directly worked with
}
type standardEngine interface {
Engine
Adder
Suber
Muler
Diver
Power
Moder
FMAer
MatMuler
MatVecMuler
OuterProder
Dotter
SVDer
Lter
Lteer
Gter
Gteer
ElEqer
MinBetweener
MaxBetweener
// Anything that returns interface{} cannot be added here because they will likely have additional
// optimized versions of the functions for types.
// For example: Tracer and InnerProder both have optimized interfaces for Float32 and Float64 which returns those types specifically.
}
type arrayMaker interface {
makeArray(arr *array, t Dtype, size int)
}
// NonStdEngine are any engines that do not allocate using the default built in allocator
type NonStdEngine interface {
NonStdAlloc() // noop
}
/* Data Agnostic Execution Engine Methods */
// Transposer is any engine that can perform an unsafe transpose of a tensor.
type Transposer interface {
Transpose(t Tensor, expStrides []int) error
}
// Concater is any enegine that can concatenate multiple Tensors together
type Concater interface {
Concat(t Tensor, axis int, others ...Tensor) (Tensor, error)
}
// Stacker is any engine that can stack multiple Tenosrs along an axis
type Stacker interface {
Stack(t Tensor, axis int, others ...Tensor) (Tensor, error)
}
// DenseStacker is any engine that can stack DenseTensors along an axis. This is a specialization of Stacker.
type DenseStacker interface {
StackDense(t DenseTensor, axis int, others ...DenseTensor) (retVal DenseTensor, err error)
}
// Repeater is any engine that can repeat values along the given axis.
type Repeater interface {
Repeat(t Tensor, axis int, repeats ...int) (Tensor, error)
RepeatReuse(t Tensor, reuse Tensor, axis int, repeeats ...int) (Tensor, error)
}
// Diager is any engine that can return a tensor that only contains the diagonal values of the input
type Diager interface {
Diag(a Tensor) (Tensor, error)
}
/* NUMBER INTERFACES
All these are expected to be unsafe on the first tensor
*/
// Adder is any engine that can perform elementwise addition.
type Adder interface {
// Add performs a + b
Add(a, b Tensor, opts ...FuncOpt) (Tensor, error)
// AddScalar adds a scalar to the tensor. leftTensor indicates if the tensor is the left operand.
// Whether or not the input tensor is clobbered is left to the implementation
AddScalar(a Tensor, b interface{}, leftTensor bool, opts ...FuncOpt) (Tensor, error)
}
// Suber is any engine that can perform elementwise subtraction.
type Suber interface {
// Sub performs a - b
Sub(a, b Tensor, opts ...FuncOpt) (Tensor, error)
// SubScalar subtracts a scalar from/to the tensor. leftTensor indicates if the tensor is the left operand.
// Whether or not the input tensor is clobbered is left to the implementation
SubScalar(a Tensor, b interface{}, leftTensor bool, opts ...FuncOpt) (Tensor, error)
}
// Muler is any engine that can perform elementwise multiplication.
// For matrix multiplication, an engine should implement MatMul() or MatVecMul() or Inner()
type Muler interface {
// Mul performs a * b
Mul(a, b Tensor, opts ...FuncOpt) (Tensor, error)
// MulScalar multiplies a scalar to the tensor. leftTensor indicates if the tensor is the left operand.
// Whether or not the input tensor is clobbered is left to the implementation
MulScalar(a Tensor, b interface{}, leftTensor bool, opts ...FuncOpt) (Tensor, error)
}
// Diver is any engine that can perform elementwise division.
type Diver interface {
// Div performs a / b
Div(a, b Tensor, opts ...FuncOpt) (Tensor, error)
// DivScalar divides a scalar from/to the tensor. leftTensor indicates if the tensor is the left operand.
// Whether or not the input tensor is clobbered is left to the implementation
DivScalar(a Tensor, b interface{}, leftTensor bool, opts ...FuncOpt) (Tensor, error)
}
// Power is any engine that can perform elementwise Pow()
type Power interface {
// Pow performs a ^ b
Pow(a, b Tensor, opts ...FuncOpt) (Tensor, error)
// PowScalar exponentiates a scalar from/to the tensor. leftTensor indicates if the tensor is the left operand.
// Whether or not the input tensor is clobbered is left to the implementation
PowScalar(a Tensor, b interface{}, leftTensor bool, opts ...FuncOpt) (Tensor, error)
}
// Moder is any engine that can perform elementwise Mod()
type Moder interface {
// Mod performs a % b
Mod(a, b Tensor, opts ...FuncOpt) (Tensor, error)
// ModScalar performs a % b where one of the operands is scalar. leftTensor indicates if the tensor is the left operand.
// Whether or not hte input tensor is clobbered is left to the implementation
ModScalar(a Tensor, b interface{}, leftTensor bool, opts ...FuncOpt) (Tensor, error)
}
// MinBetweener is any engine that can perform an elementwise min=between.
type MinBetweener interface {
MinBetween(a, b Tensor, opts ...FuncOpt) (Tensor, error)
MinBetweenScalar(a Tensor, b interface{}, leftTensor bool, opts ...FuncOpt) (Tensor, error)
}
// MaxBetweener is any engine that can perform an elementwise ma<x-between.
type MaxBetweener interface {
MaxBetween(a, b Tensor, opts ...FuncOpt) (Tensor, error)
MaxBetweenScalar(a Tensor, b interface{}, leftTensor bool, opts ...FuncOpt) (Tensor, error)
}
/* LINEAR ALGEBRA INTERFACES */
// Tracer is any engine that can return the trace (aka the sum of the diagonal elements).
type Tracer interface {
Trace(a Tensor) (interface{}, error)
}
// FMAer is any engine that can perform fused multiply add functions: A * X + Y. Also known as Axpy.
type FMAer interface {
FMA(a, x, y Tensor) (Tensor, error)
FMAScalar(a Tensor, x interface{}, y Tensor) (Tensor, error)
}
// MatMuler is any engine that can perform matrix multiplication
type MatMuler interface {
MatMul(a, b, preallocated Tensor) error
}
// MatVecMuler is any engine that can perform matrix vector multiplication
type MatVecMuler interface {
MatVecMul(a, b, preallocated Tensor) error
}
// InnerProder is any engine that can perform inner product multiplication
type InnerProder interface {
Inner(a, b Tensor) (interface{}, error) // Inner always returns a scalar value
}
// InnerProderF32 is an optimization for float32 - results are returned as float32.
type InnerProderF32 interface {
Inner(a, b Tensor) (float32, error)
}
// InnerProderF64 is an optimization for float64 - results are returned as float64
type InnerProderF64 interface {
Inner(a, b Tensor) (float64, error)
}
// OuterProder is any engine that can perform outer product (kronecker) multiplication
type OuterProder interface {
Outer(a, b, preallocated Tensor) error
}
// Dotter is used to implement sparse matrices
type Dotter interface {
Dot(a, b Tensor, opts ...FuncOpt) (Tensor, error)
}
// SVDer is any engine that can perform SVD
type SVDer interface {
SVD(a Tensor, uv, full bool) (s, u, v Tensor, err error)
}
/* ORD INTERFACES */
// Lter is any engine that can perform the Lt operation.
type Lter interface {
Lt(a, b Tensor, opts ...FuncOpt) (Tensor, error)
LtScalar(a Tensor, b interface{}, leftTensor bool, opts ...FuncOpt) (Tensor, error)
}
// Lteer is any engine that can perform the Lte operation.
type Lteer interface {
Lte(a, b Tensor, opts ...FuncOpt) (Tensor, error)
LteScalar(a Tensor, b interface{}, leftTensor bool, opts ...FuncOpt) (Tensor, error)
}
// Gter is any engine that can perform the Gt operation.
type Gter interface {
Gt(a, b Tensor, opts ...FuncOpt) (Tensor, error)
GtScalar(a Tensor, b interface{}, leftTensor bool, opts ...FuncOpt) (Tensor, error)
}
// Gteer is any engine that can perform the Gte operation.
type Gteer interface {
Gte(a, b Tensor, opts ...FuncOpt) (Tensor, error)
GteScalar(a Tensor, b interface{}, leftTensor bool, opts ...FuncOpt) (Tensor, error)
}
/* EQ INTERFACES */
// ElEqer is any engine that can perform the elementwise equality comparison operation.
type ElEqer interface {
ElEq(a, b Tensor, opts ...FuncOpt) (Tensor, error)
EqScalar(a Tensor, b interface{}, leftTensor bool, opts ...FuncOpt) (Tensor, error)
ElNe(a, b Tensor, opts ...FuncOpt) (Tensor, error)
NeScalar(a Tensor, b interface{}, leftTensor bool, opts ...FuncOpt) (Tensor, error)
}
/* Unary Operators for Numbers */
// Mapper is any engine that can map a function onto the values of a tensor.
type Mapper interface {
Map(fn interface{}, a Tensor, opts ...FuncOpt) (Tensor, error)
}
// Neger is any engine that can negate the sign of the values in the tensor.d
type Neger interface {
Neg(a Tensor, opts ...FuncOpt) (Tensor, error)
}
// Inver is any engine that can perform 1/x for each element in the Tensor.
type Inver interface {
Inv(a Tensor, opts ...FuncOpt) (Tensor, error)
}
// Squarer is any engine that can square the values elementwise in a Tensor.
type Squarer interface {
Square(a Tensor, opts ...FuncOpt) (Tensor, error)
}
// Cuber is any engine that can cube the values elementwise in a Tensor.
type Cuber interface {
Cube(a Tensor, opts ...FuncOpt) (Tensor, error)
}
// Exper is any engine that can perform elementwise natural exponentiation on the values in a Tensor.
type Exper interface {
Exp(a Tensor, opts ...FuncOpt) (Tensor, error)
}
// Tanher is any engine that can perform elementwise Tanh on the values in a Tensor.
type Tanher interface {
Tanh(a Tensor, opts ...FuncOpt) (Tensor, error)
}
// Loger is any engine that can perform natural log on the values in a Tensor.
type Loger interface {
Log(a Tensor, opt ...FuncOpt) (Tensor, error)
}
// Log2 is any engine that can perform base-2 logarithm on the values in a Tensor.
type Log2er interface {
Log2(a Tensor, opt ...FuncOpt) (Tensor, error)
}
// Log10er is any engine that can perform base-10 logarithm on the values in a Tensor.
type Log10er interface {
Log10(a Tensor, opt ...FuncOpt) (Tensor, error)
}
// Sqrter is any engine that can perform square root on the values in a Tensor.
type Sqrter interface {
Sqrt(a Tensor, opt ...FuncOpt) (Tensor, error)
}
// Cbrter is any engine that can perform cube root on the values in a Tensor.
type Cbrter interface {
Cbrt(a Tensor, opt ...FuncOpt) (Tensor, error)
}
// InvSqrter is any engine that can perform 1/sqrt(x) on the values of a Tensor.
type InvSqrter interface {
InvSqrt(a Tensor, opts ...FuncOpt) (Tensor, error)
}
// Signer is any engine that can perform a sign function on the values of a Tensor.
type Signer interface {
Sign(a Tensor, opts ...FuncOpt) (Tensor, error)
}
// Abser is any engine that can perform Abs on the values of a Tensor.
type Abser interface {
Abs(a Tensor, opts ...FuncOpt) (Tensor, error)
}
// Clamper is any engine that can clamp the values in a tensor to between min and max.
type Clamper interface {
Clamp(a Tensor, min, max interface{}, opts ...FuncOpt) (Tensor, error)
}
/* Reduction */
// Reducer is any engine that can perform a reduction function.
type Reducer interface {
Reduce(fn interface{}, a Tensor, axis int, defaultValue interface{}, opts ...FuncOpt) (Tensor, error)
}
// OptimizedReducer is any engine that can perform a reduction function with optimizations for the first dimension, last dimension and dimensions in between.
type OptimizedReducer interface {
OptimizedReduce(a Tensor, axis int, firstFn, lastFn, defaultFn, defaultValue interface{}, opts ...FuncOpt) (Tensor, error)
}
// Sumer is any engine that can perform summation along an axis of a Tensor.
type Sumer interface {
Sum(a Tensor, along ...int) (Tensor, error)
}
// Proder is any engine that can perform product along an axis of a Tensor.
type Proder interface {
Prod(a Tensor, along ...int) (Tensor, error)
}
// Miner is any engine that can find the minimum value along an axis of a Tensor.
type Miner interface {
Min(a Tensor, along ...int) (Tensor, error)
}
// Maxer is any engine that can find the maximum value along an axis of a Tensor.
type Maxer interface {
Max(a Tensor, along ...int) (Tensor, error)
}
/* Arg methods */
// Argmaxer is any engine that can find the indices of the maximum values along an axis.
// By convention the returned Tensor has Dtype of Int.
type Argmaxer interface {
Argmax(t Tensor, axis int) (Tensor, error)
}
// Argmaxer is any engine that can find the indices of the minimum values along an axis.
// By convention the returned Tensor has Dtype of Int.
type Argminer interface {
Argmin(t Tensor, axis int) (Tensor, error)
}
// NaNChecker checks that the tensor contains a NaN
// Errors are to be returned if the concept of NaN does not apply to the data type.
// Other errors may also occur. See specific implementations for details
type NaNChecker interface {
HasNaN(t Tensor) (bool, error)
}
// InfChecker checks that the tensor contains a Inf.
// Errors are to be returned if the concept of Inf does not apply to the data type.
// Other errors may also occur. See specific implementations for details
type InfChecker interface {
HasInf(t Tensor) (bool, error)
}
/* Advanced Indexing */
// ByIndiceser allows for values in tensor `a` to be selected by the indices listed in the `indices` tensor.
type ByIndiceser interface {
SelectByIndices(a, indices Tensor, axis int, opts ...FuncOpt) (retVal Tensor, err error)
SelectByIndicesB(input, outGrad, indices Tensor, axis int, opts ...FuncOpt) (retVal Tensor, err error)
}
/* Internal interfaces for faster shit */
type denseArgmaxer interface {
argmaxDenseTensor(t DenseTensor, axis int) (*Dense, error)
}
type denseArgminer interface {
argminDenseTensor(t DenseTensor, axis int) (*Dense, error)
}
type SoftMaxer interface {
LogSoftMax(x Tensor, axis int, opts ...FuncOpt) (retVal Tensor, err error)
LogSoftMaxB(output, grad Tensor, axis int, opts ...FuncOpt) (retVal Tensor, err error)
SoftMax(x Tensor, axis int, opts ...FuncOpt) (retVal Tensor, err error)
SoftMaxB(output, grad Tensor, axis int, opts ...FuncOpt) (retVal Tensor, err error)
}
|