Blame view
src/cudamatrix/cu-array.h
7.03 KB
8dcb6dfcb first commit |
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 |
// cudamatrix/cu-array.h // Copyright 2009-2012 Karel Vesely // 2013 Johns Hopkins University (author: Daniel Povey) // 2017 Shiyin Kang // See ../../COPYING for clarification regarding multiple authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, // MERCHANTABLITY OR NON-INFRINGEMENT. // See the Apache 2 License for the specific language governing permissions and // limitations under the License. #ifndef KALDI_CUDAMATRIX_CU_ARRAY_H_ #define KALDI_CUDAMATRIX_CU_ARRAY_H_ #include "matrix/kaldi-vector.h" namespace kaldi { template <typename T> class CuArray; template <typename T> class CuSubArray; /** Class CuArrayBase, CuSubArray and CuArray are analogues of classes CuVectorBase, CuSubVector and CuVector, except that they are intended to store things other than float/double: they are intended to store integers or small structs. Their CPU-based equivalents are std::vector, and we provide ways to copy to/from a std::vector of the same type. */ template<typename T> class CuArrayBase { friend class CuArray<T>; friend class CuSubArray<T>; public: /// Return the vector dimension MatrixIndexT Dim() const { return dim_; } /// Get raw pointer const T* Data() const { return data_; } T* Data() { return data_; } /// Sets the memory for the object to zero, via memset. You should verify /// that this makes sense for type T. void SetZero(); /// The caller is responsible to ensure dim is equal between *this and src. /// Note: copying to GPU is done via memcpy, /// and any constructors or assignment operators are not called. void CopyFromArray(const CuArrayBase<T> &src); /// The caller is responsible to ensure dim is equal between *this and src. /// Note: copying to GPU is done via memcpy, /// and any constructors or assignment operators are not called. void CopyFromVec(const std::vector<T> &src); /// This function resizes *dst if needed. On resize of "dst", the STL vector /// may call copy-constructors, initializers, and assignment operators for /// existing objects (which will be overwritten), but the copy from GPU to CPU /// is done via memcpy. So be very careful calling this function if your /// objects are more than plain structs. void CopyToVec(std::vector<T> *dst) const; /// Version of the above function that copies contents to a host array /// (i.e. to regular memory, not GPU memory, assuming we're using a GPU). /// This function requires *dst to be allocated before calling. The allocated /// size should be dim_ * sizeof(T) void CopyToHost(T *dst) const; /// Set to a constant value. Note: any copying is done as if using memcpy, and /// assignment operators or destructors are not called. This is NOT IMPLEMENTED /// YET except for T == int32 (the current implementation will just crash). void Set(const T &value); /// Fill with the sequence [base ... base + Dim()) /// This is not implemented except for T=int32 void Sequence(const T base); /// Add a constant value. This is NOT IMPLEMENTED YET except for T == int32 /// (the current implementation will just crash). void Add(const T &value); /// Get minimum value (for now implemented on CPU, reimplement if slow). /// Asserts the vector is non-empty, otherwise crashes. T Min() const; /// Get minimum value (for now implemented on CPU, reimplement if slow). /// Asserts the vector is non-empty, otherwise crashes. T Max() const; protected: /// Default constructor: make it protected so the user cannot /// instantiate this class. CuArrayBase<T>(): data_(NULL), dim_(0) { } T *data_; ///< GPU data pointer (if GPU not available, ///< will point to CPU memory). MatrixIndexT dim_; ///< dimension of the vector }; /** Class CuArray represents a vector of an integer or struct of type T. If we are using a GPU then the memory is on the GPU, otherwise it's on the CPU. This class owns the data that it contains from a memory allocation perspective; see also CuSubArrary which does not own the data it contains. */ template<typename T> class CuArray: public CuArrayBase<T> { public: /// Default constructor, initialized data_ to NULL and dim_ to 0 via /// constructor of CuArrayBase. CuArray<T>() { } /// Constructor with memory initialisation. resize_type may be kSetZero or /// kUndefined. explicit CuArray<T>(MatrixIndexT dim, MatrixResizeType resize_type = kSetZero) { Resize(dim, resize_type); } /// Constructor from CPU-based int vector explicit CuArray<T>(const std::vector<T> &src) { CopyFromVec(src); } /// Copy constructor. We don't make this explicit because we want to be able /// to create a std::vector<CuArray>. CuArray<T>(const CuArray<T> &src) { CopyFromArray(src); } /// Destructor ~CuArray() { Destroy(); } /// Allocate the memory. resize_type may be kSetZero or kUndefined. /// kCopyData not yet supported (can be implemented if needed). void Resize(MatrixIndexT dim, MatrixResizeType resize_type = kSetZero); /// Deallocate the memory and set dim_ and data_ to zero. Does not call any /// destructors of the objects stored. void Destroy(); /// This function resizes if needed. Note: copying to GPU is done via memcpy, /// and any constructors or assignment operators are not called. void CopyFromVec(const std::vector<T> &src); /// This function resizes if needed. void CopyFromArray(const CuArrayBase<T> &src); CuArray<T> &operator= (const CuArray<T> &in) { this->CopyFromArray(in); return *this; } CuArray<T> &operator= (const std::vector<T> &in) { this->CopyFromVec(in); return *this; } /// Shallow swap with another CuArray<T>. void Swap(CuArray<T> *other); /// I/O void Read(std::istream &is, bool binary); void Write(std::ostream &is, bool binary) const; }; template<typename T> class CuSubArray: public CuArrayBase<T> { public: /// Constructor as a range of an existing CuArray or CuSubArray. Note: like /// similar constructors in class CuVector and others, it can be used to evade /// 'const' constraints; don't do that. explicit CuSubArray<T>(const CuArrayBase<T> &src, MatrixIndexT offset, MatrixIndexT dim); /// Construct from raw pointers CuSubArray(const T* data, MatrixIndexT length) { // Yes, we're evading C's restrictions on const here, and yes, it can be used // to do wrong stuff; unfortunately the workaround would be very difficult. CuArrayBase<T>::data_ = const_cast<T*>(data); CuArrayBase<T>::dim_ = length; } }; /// I/O template<typename T> std::ostream &operator << (std::ostream &out, const CuArray<T> &vec); } // namespace #include "cudamatrix/cu-array-inl.h" #endif |