Tensor Comprehensions
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
dlpack-inl.h
Go to the documentation of this file.
1 
16 #pragma once
17 
18 namespace tc {
19 namespace dlutils {
20 
21 inline std::string toString(const DLDataType& t) {
22  if (t.lanes != 1) {
23  CHECK(false) << "NYI: toString for >1 lanes";
24  }
25  switch (t.code) {
26  case DLDataTypeCode::kDLFloat:
27  switch (t.bits) {
28  case 16:
29  return "Half";
30  case 32:
31  return "float";
32  case 64:
33  return "double";
34  }
35  break;
36  case DLDataTypeCode::kDLInt:
37  switch (t.bits) {
38  case 8:
39  return "int8_t";
40  case 16:
41  return "int16_t";
42  case 32:
43  return "int";
44  case 64:
45  return "int64_t";
46  }
47  break;
48  case DLDataTypeCode::kDLUInt:
49  switch (t.bits) {
50  case 8:
51  return "uint8_t";
52  }
53  break;
54  }
55  CHECK(false) << "NYI: toString for type: " << t.code << ", bits: " << t.bits;
56  return "";
57 }
58 
59 inline DLContext getCPUDLContext() {
60  DLContext res;
61  res.device_id = 0;
62  res.device_type = DLDeviceType::kDLCPU;
63  return res;
64 }
65 
66 // Can't have a CUDAContext object here, howdo we get the GPU id of a C2 Tensor
67 // ?
68 inline DLContext getGPUDLContext(int device_id) {
69  DLContext res;
70  res.device_id = device_id;
71  res.device_type = DLDeviceType::kDLGPU;
72  return res;
73 }
74 
75 template <typename T>
76 DLDataType getDLDataType();
77 
78 template <>
79 inline DLDataType getDLDataType<float>() {
80  DLDataType res;
81  res.code = DLDataTypeCode::kDLFloat;
82  res.bits = 32;
83  res.lanes = 1;
84  return res;
85 }
86 
87 template <>
88 inline DLDataType getDLDataType<int>() {
89  DLDataType res;
90  res.code = DLDataTypeCode::kDLInt;
91  res.bits = 32;
92  res.lanes = 1;
93  return res;
94 }
95 
96 inline void SetSizes(DLTensor& t, const std::vector<int64_t>& sizes) {
97  auto ndim = sizes.size();
98  for (size_t i = 0; i < ndim; ++i) {
99  t.shape[i] = sizes[i];
100  }
101 }
102 
103 inline void SetStrides(DLTensor& t, const std::vector<int64_t>& strides) {
104  auto ndim = strides.size();
105  for (size_t i = 0; i < ndim; ++i) {
106  t.strides[i] = strides[i];
107  }
108 }
109 
110 inline void SetStridesFromSizes(DLTensor& t, const std::vector<int64_t>&) {
111  auto ndim = t.ndim;
112  t.strides[ndim - 1] = 1;
113  for (int i = ndim - 2; i >= 0; --i) {
114  t.strides[i] = t.strides[i + 1] * t.shape[i + 1];
115  }
116 }
117 
119  DLContext ctx,
120  DLDataType dtype,
121  const std::vector<int64_t>& sizes) {
122  DLTensorUPtr res(new DLTensor);
123  res->data = nullptr;
124  res->ctx = ctx;
125  auto ndim = sizes.size();
126  res->ndim = ndim;
127  res->dtype = dtype;
128  res->shape = new int64_t[ndim];
129  SetSizes(*res, sizes);
130  res->strides = new int64_t[ndim];
131  SetStridesFromSizes(*res, sizes);
132  res->byte_offset = 0;
133  return res;
134 }
135 
136 inline std::vector<const DLTensor*> extractRawPtrs(
137  const std::vector<DLTensorUPtr>& uptrs) {
138  std::vector<const DLTensor*> res;
139  res.reserve(uptrs.size());
140  for (const auto& uptr : uptrs) {
141  res.push_back(uptr.get());
142  }
143  return res;
144 }
145 
146 inline std::vector<const DLTensor*> constPtrs(
147  const std::vector<DLTensor*>& ptrs) {
148  std::vector<const DLTensor*> res;
149  res.reserve(ptrs.size());
150  for (auto p : ptrs) {
151  res.push_back(p);
152  }
153  return res;
154 }
155 
156 inline DLTensorUPtr makeDLTensor(const DLTensor* ptr) {
157  auto res = DLTensorUPtr(new DLTensor);
158  // DLTensor is not owning, so just copy the pointer
159  res->data = ptr->data;
160  res->ctx = ptr->ctx;
161  res->ndim = ptr->ndim;
162  res->dtype = ptr->dtype;
163 
164  res->shape = new int64_t[ptr->ndim];
165  for (int i = 0; i < ptr->ndim; ++i) {
166  res->shape[i] = ptr->shape[i];
167  }
168  if (ptr->strides) {
169  res->strides = new int64_t[ptr->ndim];
170  for (int i = 0; i < ptr->ndim; ++i) {
171  res->strides[i] = ptr->strides[i];
172  }
173  } else {
174  res->strides = NULL;
175  }
176  res->byte_offset = ptr->byte_offset;
177  return res;
178 }
179 
180 template <typename T>
181 std::vector<DLTensorUPtr> makeDLTensorVector(const std::vector<T*>& ptrs) {
182  std::vector<DLTensorUPtr> res;
183  for (auto p : ptrs) {
184  res.push_back(makeDLTensor(p));
185  }
186  return res;
187 }
188 
189 inline std::string toString(const DLTensor& t) {
190  std::stringstream ss;
191  ss << "DLTensor(@" << t.data << ", dim=" << t.ndim << ")";
192  ss << " shape [";
193  for (int i = 0; i < t.ndim; ++i) {
194  ss << t.shape[i];
195  if (i < t.ndim - 1) {
196  ss << ", ";
197  }
198  }
199  ss << "], strides [";
200  for (int i = 0; i < t.ndim; ++i) {
201  ss << t.strides[i];
202  if (i < t.ndim - 1) {
203  ss << ", ";
204  }
205  }
206  ss << "]";
207  return ss.str();
208 }
209 
210 inline bool operator==(const DLDataType& t1, const DLDataType& t2) {
211  return t1.code == t2.code && t1.bits == t2.bits && t1.lanes == t2.lanes;
212 }
213 
214 inline std::ostream& operator<<(std::ostream& os, const DLDataType& t) {
215  return os << "typecode: " << t.code << " bits: " << t.bits
216  << " lanes: " << t.lanes;
217 }
218 
219 inline bool compareDLTensorMetadata(const DLTensor& t1, const DLTensor& t2) {
220  if (t1.ndim != t2.ndim) {
221  return false;
222  }
223  if (!(t1.dtype == t2.dtype)) {
224  return false;
225  }
226  if ((t1.strides == NULL) ^ (t2.strides == NULL)) {
227  return false;
228  }
229  for (int i = 0; i < t1.ndim; ++i) {
230  if (t1.shape[i] != t2.shape[i]) {
231  return false;
232  }
233  if (t1.strides && t1.strides[i] != t2.strides[i]) {
234  return false;
235  }
236  }
237  return true;
238 }
239 
240 // templating to have any combination of const/non-const
241 template <typename T, typename TT>
243  const std::vector<T*>& v1,
244  const std::vector<TT*>& v2) {
245  if (v1.size() != v2.size()) {
246  return false;
247  }
248  for (size_t i = 0; i < v1.size(); ++i) {
249  if (!compareDLTensorMetadata(*v1[i], *v2[i])) {
250  return false;
251  }
252  }
253  return true;
254 }
255 } // namespace dlutils
256 } // namespace tc
void SetSizes(DLTensor &t, const std::vector< int64_t > &sizes)
Definition: dlpack-inl.h:96
bool operator==(const DLDataType &t1, const DLDataType &t2)
Definition: dlpack-inl.h:210
std::vector< const DLTensor * > extractRawPtrs(const std::vector< DLTensorUPtr > &uptrs)
Definition: dlpack-inl.h:136
bool compareDLTensorMetadata(const DLTensor &t1, const DLTensor &t2)
Definition: dlpack-inl.h:219
std::ostream & operator<<(std::ostream &os, const DLDataType &t)
Definition: dlpack-inl.h:214
std::string toString(const DLDataType &t)
Definition: dlpack-inl.h:21
bool compareDLTensorVectorMetadata(const std::vector< T * > &v1, const std::vector< TT * > &v2)
Definition: dlpack-inl.h:242
std::vector< const DLTensor * > constPtrs(const std::vector< DLTensor * > &ptrs)
Definition: dlpack-inl.h:146
DLTensorUPtr makeDLTensorWithSizes(DLContext ctx, DLDataType dtype, const std::vector< int64_t > &sizes)
Definition: dlpack-inl.h:118
DLContext getCPUDLContext()
Definition: dlpack-inl.h:59
DLDataType getDLDataType()
std::unique_ptr< DLTensor, DLTensorDeleter > DLTensorUPtr
Definition: dlpack.h:52
DLDataType getDLDataType< int >()
Definition: dlpack-inl.h:88
void SetStridesFromSizes(DLTensor &t, const std::vector< int64_t > &)
Definition: dlpack-inl.h:110
DLContext getGPUDLContext(int device_id)
Definition: dlpack-inl.h:68
std::vector< DLTensorUPtr > makeDLTensorVector(const std::vector< T * > &ptrs)
Definition: dlpack-inl.h:181
DLTensorUPtr makeDLTensor(const DLTensor *ptr)
Definition: dlpack-inl.h:156
DLDataType getDLDataType< float >()
Definition: dlpack-inl.h:79
void SetStrides(DLTensor &t, const std::vector< int64_t > &strides)
Definition: dlpack-inl.h:103