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 }