github.com/wzzhu/tensor@v0.9.24/flags.go (about) 1 package tensor 2 3 // DataOrder is a flag that indicates the order of data. The default DataOrder (0) 4 // is what this package uses by default. 5 type DataOrder byte 6 7 const ( 8 // ColMajor indicates that the data is stored in a col-major way. 9 // A data can only be stored in either ColMajor(1) or RowMajor(0). 10 // The way the DataOrder was designed causes the default to be RowMajor 11 ColMajor DataOrder = 1 << iota 12 // NonContiguous indicates that the data is not contiguous. 13 // A data can either be Contiguous (0) or NonContiguous (2). 14 // The way DataOrder was designed causes the default to be Contiguous. 15 NonContiguous 16 17 // Transposed indicates that the data has been transposed 18 Transposed 19 ) 20 21 var dataOrderNames = []rune("NonContiguous, RowMajorįµNonContiguous, ColMajorįµ") 22 23 // MakeDataOrder makes a data order. Typical examples: 24 // MakeDataOrder(DataOrder(0)) // Row Major, contiguous 25 // MakeDataOrder(NonContiguous // Row Major, non-contiguous 26 // MakeDataOrder(ColMajor) // Col Major, contiguous 27 // MakeDataOrder(ColMajor, NonContiguous) // what it says on the tin 28 func MakeDataOrder(fs ...DataOrder) (retVal DataOrder) { 29 if len(fs) == 1 { 30 return fs[0] 31 } 32 for _, f := range fs { 33 retVal |= f 34 } 35 return 36 } 37 38 // IsColMajor returns true if the data order describes a col-major data 39 func (f DataOrder) IsColMajor() bool { return (f & ColMajor) != 0 } 40 41 // IsRowMajor returns true if the data order describes a row-major data 42 func (f DataOrder) IsRowMajor() bool { return !f.IsColMajor() } 43 44 // IsContiguous returns true if the data order describes a contiguous data. 45 func (f DataOrder) IsContiguous() bool { return !f.IsNotContiguous() } 46 47 // IsNotContiguous returns true if the data order describes a noncontiguous data. 48 func (f DataOrder) IsNotContiguous() bool { return (f & NonContiguous) != 0 } 49 50 // IsTransposed returns true if the data order describes whether the data has been tranposed (but not moved) 51 func (f DataOrder) IsTransposed() bool { return (f & Transposed) != 0 } 52 53 func (f DataOrder) toggleColMajor() DataOrder { return f ^ (ColMajor) } 54 55 func (f DataOrder) clearTransposed() DataOrder { return f &^ (Transposed) } 56 57 // HasSameOrder returns true if both data orders are the same (either both are ColMajor or both are RowMajor) 58 func (f DataOrder) HasSameOrder(other DataOrder) bool { 59 return (f.IsColMajor() && other.IsColMajor()) || (f.IsRowMajor() && other.IsRowMajor()) 60 } 61 62 func (f DataOrder) String() string { 63 var start, end int 64 if f.IsRowMajor() { 65 end = 23 66 if f.IsContiguous() { 67 start = 3 68 } 69 } else { 70 end = 47 71 start = 24 72 if f.IsContiguous() { 73 start = 27 74 } 75 } 76 if f.IsTransposed() { 77 end++ 78 } 79 return string(dataOrderNames[start:end]) 80 } 81 82 // Triangle is a flag representing the "triangle"ness of a matrix 83 type Triangle byte 84 85 const ( 86 NotTriangle Triangle = iota 87 Upper 88 Lower 89 Symmetric 90 ) 91 92 // MemoryFlag is a flag representing the use possibilities of Memory 93 type MemoryFlag byte 94 95 const ( 96 // NativelyInaccessible indicates that the data in the memory cannot be accessed by Go code. 97 NativelyInaccessible MemoryFlag = 1 << iota 98 // ManuallyManaged indicates that the memory is managed by something else. Any Tensor with 99 // manually managed memory will not be returned to the pool. 100 ManuallyManaged 101 // IsOverallocated indicates that the memory for a given tensor is overallocated (i.e. the size-in-use is smaller than the size allocated) 102 IsOverallocated 103 ) 104 105 func MakeMemoryFlag(fs ...MemoryFlag) (retVal MemoryFlag) { 106 if len(fs) == 1 { 107 return fs[0] 108 } 109 110 for _, f := range fs { 111 retVal |= f 112 } 113 return 114 } 115 116 func (f MemoryFlag) nativelyAccessible() bool { return !((f & NativelyInaccessible) != 0) } 117 func (f MemoryFlag) manuallyManaged() bool { return (f & ManuallyManaged) != 0 } 118 func (f MemoryFlag) isOverallocated() bool { return (f & IsOverallocated) != 0 } 119 120 // OpOpt are the options used to call ops 121 type OpOpt struct { 122 reuse Tensor 123 incr Tensor 124 unsafe bool 125 same bool 126 t Dtype 127 } 128 129 // ParseFuncOpts parses a list of FuncOpt into a single unified method call structure. 130 func ParseFuncOpts(opts ...FuncOpt) *OpOpt { 131 retVal := borrowOpOpt() 132 for _, opt := range opts { 133 opt(retVal) 134 } 135 return retVal 136 } 137 138 // Incr returns the tensor to be incremented in the call. Can be nil. 139 func (fo *OpOpt) Incr() Tensor { return fo.incr } 140 141 // Reuse returns the tensor to be reused in the call. Can be nil. 142 func (fo *OpOpt) Reuse() Tensor { return fo.reuse } 143 144 // IncReuse returns whether a reuse tensor is to be used as the incr Tensor 145 func (fo *OpOpt) IncrReuse() (Tensor, bool) { 146 if fo.incr != nil { 147 return fo.incr, true 148 } 149 return fo.reuse, false 150 } 151 152 // Safe signals if the op is to be done safely 153 func (fo *OpOpt) Safe() bool { return !fo.unsafe } 154 155 // Same signals if the op is to return the same type as its inputs 156 func (fo *OpOpt) Same() bool { return fo.same } 157 158 // As returns the dtype of the return value of the method call. 159 // For example: 160 // a.Lt(b, As(Bool)) 161 // indicates that the result of the `Lt()` should be a Tensor of Bool. 162 // 163 // Another example: 164 // a.Add(b, As(Int)) 165 // indicates that the result of `Add()` should be converted to a Tensor of Int. 166 // Note that this function is not yet supported in most operations. 167 func (fo *OpOpt) As() Dtype { return fo.t }