1 /** 2 * Copyright 2019 Huawei Technologies Co., Ltd 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #include <memory> 17 #include <string> 18 #include "minddata/dataset/core/client.h" 19 #include "common/common.h" 20 #include "gtest/gtest.h" 21 #include "securec.h" 22 #include "minddata/dataset/core/tensor.h" 23 #include "minddata/dataset/core/cv_tensor.h" 24 #include "minddata/dataset/core/data_type.h" 25 26 using namespace mindspore::dataset; 27 28 namespace py = pybind11; 29 30 class MindDataTestTensorDE : public UT::Common { 31 public: 32 MindDataTestTensorDE() {} 33 34 void SetUp() { GlobalInit(); } 35 }; 36 37 TEST_F(MindDataTestTensorDE, Basics) { 38 std::shared_ptr<Tensor> t; 39 Tensor::CreateEmpty(TensorShape({2, 3}), DataType(DataType::DE_UINT64), &t); 40 41 ASSERT_EQ(t->shape(), TensorShape({2, 3})); 42 ASSERT_EQ(t->type(), DataType::DE_UINT64); 43 ASSERT_EQ(t->SizeInBytes(), 2 * 3 * 8); 44 ASSERT_EQ(t->Rank(), 2); 45 t->SetItemAt<uint64_t>({0, 0}, 1); 46 t->SetItemAt<uint64_t>({0, 1}, 2); 47 t->SetItemAt<uint64_t>({0, 2}, 3); 48 t->SetItemAt<uint64_t>({1, 0}, 4); 49 t->SetItemAt<uint64_t>({1, 1}, 5); 50 t->SetItemAt<uint64_t>({1, 2}, 6); 51 Status rc = t->SetItemAt<uint64_t>({2, 3}, 7); 52 ASSERT_TRUE(rc.IsError()); 53 uint64_t o; 54 t->GetItemAt<uint64_t>(&o, {0, 0}); 55 ASSERT_EQ(o, 1); 56 t->GetItemAt<uint64_t>(&o, {0, 1}); 57 ASSERT_EQ(o, 2); 58 t->GetItemAt<uint64_t>(&o, {0, 2}); 59 ASSERT_EQ(o, 3); 60 t->GetItemAt<uint64_t>(&o, {1, 0}); 61 ASSERT_EQ(o, 4); 62 t->GetItemAt<uint64_t>(&o, {1, 1}); 63 ASSERT_EQ(o, 5); 64 t->GetItemAt<uint64_t>(&o, {1, 2}); 65 ASSERT_EQ(o, 6); 66 rc = t->GetItemAt<uint64_t>(&o, {2, 3}); 67 ASSERT_TRUE(rc.IsError()); 68 ASSERT_EQ(t->ToString(), "Tensor (shape: <2,3>, Type: uint64)\n[[1,2,3],[4,5,6]]"); 69 std::vector<uint64_t> x = {1, 2, 3, 4, 5, 6}; 70 std::shared_ptr<Tensor> t2; 71 Tensor::CreateFromVector(x, TensorShape({2, 3}), &t2); 72 73 ASSERT_EQ(*t == *t2, true); 74 ASSERT_EQ(*t != *t2, false); 75 } 76 77 TEST_F(MindDataTestTensorDE, Fill) { 78 std::shared_ptr<Tensor> t; 79 Tensor::CreateEmpty(TensorShape({2, 2}), DataType(DataType::DE_FLOAT32), &t); 80 t->Fill<float>(2.5); 81 std::vector<float> x = {2.5, 2.5, 2.5, 2.5}; 82 std::shared_ptr<Tensor> t2; 83 Tensor::CreateFromVector(x, TensorShape({2, 2}), &t2); 84 ASSERT_EQ(*t == *t2, true); 85 } 86 87 TEST_F(MindDataTestTensorDE, Reshape) { 88 std::shared_ptr<Tensor> t; 89 Tensor::CreateEmpty(TensorShape({2, 2}), DataType(DataType::DE_UINT8), &t); 90 t->Fill<uint8_t>(254); 91 t->Reshape(TensorShape({4})); 92 std::vector<uint8_t> x = {254, 254, 254, 254}; 93 std::shared_ptr<Tensor> t2; 94 Tensor::CreateFromVector(x, &t2); 95 96 ASSERT_EQ(*t == *t2, true); 97 Status rc = t->Reshape(TensorShape({5})); 98 ASSERT_TRUE(rc.IsError()); 99 t2->ExpandDim(0); 100 ASSERT_EQ(t2->shape(), TensorShape({1, 4})); 101 t2->ExpandDim(2); 102 ASSERT_EQ(t2->shape(), TensorShape({1, 4, 1})); 103 rc = t2->ExpandDim(4); 104 ASSERT_TRUE(rc.IsError()); 105 } 106 107 TEST_F(MindDataTestTensorDE, CopyTensor) { 108 std::shared_ptr<Tensor> t; 109 Tensor::CreateEmpty(TensorShape({}), DataType(DataType::DE_INT16), &t); 110 t->SetItemAt<int16_t>({}, -66); 111 ASSERT_EQ(t->shape(), TensorShape({})); 112 ASSERT_EQ(t->type(), DataType::DE_INT16); 113 int16_t o; 114 t->GetItemAt<int16_t>(&o, {}); 115 ASSERT_EQ(o, -66); 116 const unsigned char *addr = t->GetBuffer(); 117 auto t2 = std::make_shared<Tensor>(std::move(*t)); 118 ASSERT_EQ(t2->shape(), TensorShape({})); 119 ASSERT_EQ(t2->type(), DataType::DE_INT16); 120 t2->GetItemAt<int16_t>(&o, {}); 121 ASSERT_EQ(o, -66); 122 const unsigned char *new_addr = t2->GetBuffer(); 123 ASSERT_EQ(addr, new_addr); 124 ASSERT_EQ(t->shape(), TensorShape::CreateUnknownRankShape()); 125 ASSERT_EQ(t->type(), DataType::DE_UNKNOWN); 126 ASSERT_EQ(t->GetBuffer(), nullptr); 127 Status rc = t->GetItemAt<int16_t>(&o, {}); 128 ASSERT_TRUE(rc.IsError()); 129 } 130 131 TEST_F(MindDataTestTensorDE, InsertTensor) { 132 std::shared_ptr<Tensor> t; 133 Tensor::CreateEmpty(TensorShape({2, 3}), DataType(DataType::DE_FLOAT64), &t); 134 std::vector<double> x = {1.1, 2.1, 3.1}; 135 std::shared_ptr<Tensor> t2; 136 Tensor::CreateFromVector(x, &t2); 137 138 std::vector<double> y = {1.2, 2.2, 3.2}; 139 std::shared_ptr<Tensor> t3; 140 Tensor::CreateFromVector(y, &t3); 141 142 ASSERT_TRUE(t->InsertTensor({0}, t2).OK()); 143 ASSERT_TRUE(t->InsertTensor({1}, t3).OK()); 144 std::vector<double> z = {1.1, 2.1, 3.1, 1.2, 2.2, 3.2}; 145 146 std::shared_ptr<Tensor> t4; 147 Tensor::CreateFromVector(z, TensorShape({2, 3}), &t4); 148 ASSERT_EQ(*t == *t4, true); 149 150 std::shared_ptr<Tensor> t5; 151 Tensor::CreateScalar<double>(0, &t5); 152 153 ASSERT_TRUE(t->InsertTensor({1, 2}, t5).OK()); 154 z[5] = 0; 155 std::shared_ptr<Tensor> t6; 156 Tensor::CreateFromVector(z, TensorShape({2, 3}), &t6); 157 158 ASSERT_EQ(*t == *t6, true); 159 ASSERT_EQ(t->InsertTensor({2}, t5).StatusCode(), StatusCode::kMDUnexpectedError); 160 ASSERT_EQ(t->InsertTensor({1}, t5).StatusCode(), StatusCode::kMDUnexpectedError); 161 ASSERT_EQ(t->InsertTensor({1, 2}, t6).StatusCode(), StatusCode::kMDUnexpectedError); 162 t6->Fill<double>(-1); 163 ASSERT_TRUE(t->InsertTensor({}, t6).OK()); 164 ASSERT_EQ(*t == *t6, true); 165 } 166 167 // Test the bug of Tensor::ToString will exec failed for Tensor which store bool values 168 TEST_F(MindDataTestTensorDE, BoolTensor) { 169 std::shared_ptr<Tensor> t; 170 Tensor::CreateEmpty(TensorShape({2}), DataType(DataType::DE_BOOL), &t); 171 t->SetItemAt<bool>({0}, true); 172 t->SetItemAt<bool>({1}, true); 173 std::string out = t->ToString(); 174 ASSERT_TRUE(out.find("Template type and Tensor type are not compatible") == std::string::npos); 175 } 176 177 TEST_F(MindDataTestTensorDE, GetItemAt) { 178 std::shared_ptr<Tensor> t; 179 Tensor::CreateEmpty(TensorShape({2, 2}), DataType(DataType::DE_UINT8), &t); 180 t->Fill<uint8_t>(254); 181 uint64_t o1; 182 t->GetItemAt<uint64_t>(&o1, {0, 0}); 183 ASSERT_EQ(o1, 254); 184 uint32_t o2; 185 t->GetItemAt<uint32_t>(&o2, {0, 1}); 186 ASSERT_EQ(o2, 254); 187 uint16_t o3; 188 t->GetItemAt<uint16_t>(&o3, {1, 0}); 189 ASSERT_EQ(o3, 254); 190 uint8_t o4; 191 t->GetItemAt<uint8_t>(&o4, {1, 1}); 192 ASSERT_EQ(o4, 254); 193 std::shared_ptr<Tensor> t2; 194 Tensor::CreateEmpty(TensorShape({2, 2}), DataType(DataType::DE_INT8), &t2); 195 t2->Fill<int8_t>(-10); 196 int64_t o5; 197 t2->GetItemAt<int64_t>(&o5, {0, 0}); 198 ASSERT_EQ(o5, -10); 199 int32_t o6; 200 t2->GetItemAt<int32_t>(&o6, {0, 1}); 201 ASSERT_EQ(o6, -10); 202 int16_t o7; 203 t2->GetItemAt<int16_t>(&o7, {1, 0}); 204 ASSERT_EQ(o7, -10); 205 int8_t o8; 206 t2->GetItemAt<int8_t>(&o8, {1, 1}); 207 ASSERT_EQ(o8, -10); 208 std::shared_ptr<Tensor> t3; 209 Tensor::CreateEmpty(TensorShape({2, 2}), DataType(DataType::DE_FLOAT32), &t3); 210 t3->Fill<float>(1.1); 211 double o9; 212 t3->GetItemAt<double>(&o9, {0, 0}); 213 ASSERT_FLOAT_EQ(o9, 1.1); 214 float o10; 215 t3->GetItemAt<float>(&o10, {0, 1}); 216 ASSERT_FLOAT_EQ(o10, 1.1); 217 } 218 219 TEST_F(MindDataTestTensorDE, OperatorAssign) { 220 std::shared_ptr<Tensor> t; 221 Tensor::CreateEmpty(TensorShape({2, 2}), DataType(DataType::DE_UINT8), &t); 222 t->Fill<uint8_t>(1); 223 std::shared_ptr<Tensor> t2; 224 Tensor::CreateEmpty(TensorShape({2, 2}), DataType(DataType::DE_UINT8), &t2); 225 *t2 = std::move(*t); 226 uint8_t o; 227 t2->GetItemAt(&o, {0, 0}); 228 ASSERT_EQ(o, 1); 229 t2->GetItemAt(&o, {0, 1}); 230 ASSERT_EQ(o, 1); 231 t2->GetItemAt(&o, {1, 0}); 232 ASSERT_EQ(o, 1); 233 t2->GetItemAt(&o, {1, 1}); 234 ASSERT_EQ(o, 1); 235 } 236 237 TEST_F(MindDataTestTensorDE, Strides) { 238 std::shared_ptr<Tensor> t; 239 Tensor::CreateEmpty(TensorShape({4, 2, 2}), DataType(DataType::DE_UINT8), &t); 240 std::vector<dsize_t> x1 = t->Strides(); 241 std::vector<dsize_t> x2 = {4, 2, 1}; 242 ASSERT_EQ(x1, x2); 243 Tensor::CreateEmpty(TensorShape({4, 2, 2}), DataType(DataType::DE_UINT32), &t); 244 x1 = t->Strides(); 245 x2 = {16, 8, 4}; 246 ASSERT_EQ(x1, x2); 247 } 248 249 void checkCvMat(TensorShape shape, DataType type) { 250 std::shared_ptr<CVTensor> t; 251 CVTensor::CreateEmpty(shape, type, &t); 252 cv::Mat m = t->mat(); 253 ASSERT_EQ(m.data, t->GetBuffer()); 254 ASSERT_EQ(static_cast<uchar>(m.type()) & static_cast<uchar>(CV_MAT_DEPTH_MASK), type.AsCVType()); 255 if (shape.Rank() < 4) { 256 if (shape.Rank() > 1) { 257 for (dsize_t i = 0; i < 2; i++) ASSERT_EQ(m.size[static_cast<int>(i)], shape[i]); 258 } else if (shape.Rank() == 0) { 259 ASSERT_EQ(m.size[0], 1); 260 ASSERT_EQ(m.size[1], 1); 261 } else { 262 ASSERT_EQ(m.size[0], shape[0]); 263 } 264 if (shape.Rank() == 3) { 265 ASSERT_EQ(m.channels(), shape[2]); 266 } 267 ASSERT_EQ(m.dims, 2); 268 ASSERT_EQ(m.size.dims(), 2); 269 if (shape.Rank() > 0) { 270 ASSERT_EQ(m.rows, shape[0]); 271 } 272 if (shape.Rank() > 1) { 273 ASSERT_EQ(m.cols, shape[1]); 274 } 275 } else { 276 for (dsize_t i = 0; i < shape.Rank(); i++) ASSERT_EQ(m.size[static_cast<int>(i)], shape[i]); 277 ASSERT_EQ(m.dims, shape.Rank()); 278 ASSERT_EQ(m.size.dims(), shape.Rank()); 279 ASSERT_EQ(m.rows, -1); 280 ASSERT_EQ(m.cols, -1); 281 } 282 } 283 284 TEST_F(MindDataTestTensorDE, CVTensorBasics) { 285 checkCvMat(TensorShape({4, 5}), DataType(DataType::DE_UINT8)); 286 checkCvMat(TensorShape({4, 5, 3}), DataType(DataType::DE_UINT8)); 287 checkCvMat(TensorShape({4, 5, 10}), DataType(DataType::DE_UINT8)); 288 checkCvMat(TensorShape({4, 5, 3, 2}), DataType(DataType::DE_UINT8)); 289 checkCvMat(TensorShape({4}), DataType(DataType::DE_UINT8)); 290 checkCvMat(TensorShape({}), DataType(DataType::DE_INT16)); 291 checkCvMat(TensorShape({4, 5}), DataType(DataType::DE_INT16)); 292 checkCvMat(TensorShape({4, 5, 3}), DataType(DataType::DE_INT16)); 293 checkCvMat(TensorShape({4, 5, 10}), DataType(DataType::DE_INT16)); 294 checkCvMat(TensorShape({4, 5, 3, 2}), DataType(DataType::DE_INT16)); 295 checkCvMat(TensorShape({4}), DataType(DataType::DE_INT16)); 296 checkCvMat(TensorShape({}), DataType(DataType::DE_INT16)); 297 } 298 299 TEST_F(MindDataTestTensorDE, CVTensorFromMat) { 300 cv::Mat m(2, 2, CV_8U); 301 m.at<uint8_t>(0, 0) = 10; 302 m.at<uint8_t>(0, 1) = 20; 303 m.at<uint8_t>(1, 0) = 30; 304 m.at<uint8_t>(1, 1) = 40; 305 std::shared_ptr<CVTensor> cvt; 306 TensorShape shape{2, 2}; 307 CVTensor::CreateFromMat(m, 2, &cvt); 308 std::shared_ptr<Tensor> t; 309 Tensor::CreateEmpty(TensorShape({2, 2}), DataType(DataType::DE_UINT8), &t); 310 t->SetItemAt<uint8_t>({0, 0}, 10); 311 t->SetItemAt<uint8_t>({0, 1}, 20); 312 t->SetItemAt<uint8_t>({1, 0}, 30); 313 t->SetItemAt<uint8_t>({1, 1}, 40); 314 ASSERT_TRUE(*t == *cvt); 315 int size[] = {4}; 316 cv::Mat m2(1, size, CV_8U); 317 m2.at<uint8_t>(0) = 10; 318 m2.at<uint8_t>(1) = 20; 319 m2.at<uint8_t>(2) = 30; 320 m2.at<uint8_t>(3) = 40; 321 std::shared_ptr<CVTensor> cvt2; 322 CVTensor::CreateFromMat(m2, 2, &cvt2); 323 std::shared_ptr<Tensor> t2; 324 Tensor::CreateEmpty(TensorShape({4}), DataType(DataType::DE_UINT8), &t2); 325 t2->SetItemAt<uint8_t>({0}, 10); 326 t2->SetItemAt<uint8_t>({1}, 20); 327 t2->SetItemAt<uint8_t>({2}, 30); 328 t2->SetItemAt<uint8_t>({3}, 40); 329 t2->ExpandDim(1); 330 ASSERT_TRUE(*t2 == *cvt2); 331 } 332 333 TEST_F(MindDataTestTensorDE, CVTensorAs) { 334 std::shared_ptr<Tensor> t; 335 Tensor::CreateEmpty(TensorShape({3, 2}), DataType(DataType::DE_FLOAT64), &t); 336 t->Fill<double>(2.2); 337 const unsigned char *addr = t->GetBuffer(); 338 std::shared_ptr<Tensor> t2; 339 Tensor::CreateEmpty(TensorShape({3, 2}), DataType(DataType::DE_FLOAT64), &t2); 340 t2->Fill<double>(4.4); 341 std::shared_ptr<CVTensor> ctv = CVTensor::AsCVTensor(t); 342 ASSERT_EQ(t->GetBuffer(), nullptr); 343 ASSERT_EQ(ctv->GetBuffer(), addr); 344 cv::Mat m = ctv->mat(); 345 m = 2 * m; 346 ASSERT_EQ(ctv->GetBuffer(), addr); 347 ASSERT_TRUE(*t2 == *ctv); 348 MS_LOG(DEBUG) << *t2 << std::endl << *ctv; 349 cv::Mat m2 = ctv->matCopy(); 350 m2 = 2 * m2; 351 ASSERT_EQ(ctv->GetBuffer(), addr); 352 ASSERT_TRUE(*t2 == *ctv); 353 } 354 355 TEST_F(MindDataTestTensorDE, CVTensorMatSlice) { 356 cv::Mat m(2, 3, CV_32S); 357 m.at<int32_t>(0, 0) = 10; 358 m.at<int32_t>(0, 1) = 20; 359 m.at<int32_t>(0, 2) = 30; 360 m.at<int32_t>(1, 0) = 40; 361 m.at<int32_t>(1, 1) = 50; 362 m.at<int32_t>(1, 2) = 60; 363 std::shared_ptr<CVTensor> cvt; 364 CVTensor::CreateFromMat(m, 2, &cvt); 365 cv::Mat mat; 366 cvt->MatAtIndex({1}, &mat); 367 cv::Mat m2(3, 1, CV_32S); 368 m2.at<int32_t>(0) = 40; 369 m2.at<int32_t>(1) = 50; 370 m2.at<int32_t>(2) = 60; 371 std::shared_ptr<CVTensor> cvt2; 372 CVTensor::CreateFromMat(mat, 2, &cvt2); 373 std::shared_ptr<CVTensor> cvt3; 374 CVTensor::CreateFromMat(m2, 2, &cvt3); 375 376 ASSERT_TRUE(*cvt2 == *cvt3); 377 cvt->MatAtIndex({0}, &mat); 378 m2.at<int32_t>(0) = 10; 379 m2.at<int32_t>(1) = 20; 380 m2.at<int32_t>(2) = 30; 381 CVTensor::CreateFromMat(mat, 2, &cvt2); 382 CVTensor::CreateFromMat(m2, 2, &cvt3); 383 ASSERT_TRUE(*cvt2 == *cvt3); 384 } 385 386 TEST_F(MindDataTestTensorDE, TensorIterator) { 387 std::vector<uint32_t> values = {1, 2, 3, 4, 5, 6}; 388 std::vector<uint32_t> values2 = {2, 3, 4, 5, 6, 7}; 389 390 std::shared_ptr<Tensor> t; 391 Tensor::CreateFromVector(values, &t); 392 393 auto i = t->begin<uint32_t>(); 394 auto j = values.begin(); 395 uint32_t ctr = 0; 396 for (; i != t->end<uint32_t>(); i++, j++) { 397 ASSERT_TRUE(*i == *j); 398 ctr++; 399 } 400 ASSERT_TRUE(ctr == 6); 401 t->Reshape(TensorShape{2, 3}); 402 i = t->begin<uint32_t>(); 403 j = values.begin(); 404 ctr = 0; 405 for (; i != t->end<uint32_t>(); i++, j++) { 406 ASSERT_TRUE(*i == *j); 407 ctr++; 408 } 409 ASSERT_TRUE(ctr == 6); 410 for (auto it = t->begin<uint32_t>(); it != t->end<uint32_t>(); it++) { 411 *it = *it + 1; 412 } 413 i = t->begin<uint32_t>(); 414 j = values2.begin(); 415 ctr = 0; 416 for (; i != t->end<uint32_t>(); i++, j++) { 417 ASSERT_TRUE(*i == *j); 418 ctr++; 419 } 420 ASSERT_TRUE(ctr == 6); 421 } 422 423 TEST_F(MindDataTestTensorDE, TensorSlice) { 424 std::shared_ptr<Tensor> t; 425 Tensor::CreateFromVector(std::vector<dsize_t>{0, 1, 2, 3, 4}, &t); 426 std::shared_ptr<Tensor> t2; 427 auto x = std::vector<dsize_t>{0, 3, 4}; 428 std::vector<SliceOption> slice_options = {SliceOption(x)}; 429 std::shared_ptr<Tensor> expected; 430 Tensor::CreateFromVector(x, &expected); 431 t->Slice(&t2, slice_options); 432 ASSERT_EQ(*t2, *expected); 433 } 434 435 TEST_F(MindDataTestTensorDE, TensorPartialInsert) { 436 std::vector<uint32_t> values1 = {1, 2, 3, 0, 0, 0}; 437 std::vector<uint32_t> values2 = {4, 5, 6}; 438 std::vector<uint32_t> expected = {1, 2, 3, 4, 5, 6}; 439 440 std::shared_ptr<Tensor> t1; 441 Tensor::CreateFromVector(values1, &t1); 442 443 std::shared_ptr<Tensor> t2; 444 Tensor::CreateFromVector(values2, &t2); 445 446 std::shared_ptr<Tensor> out; 447 Tensor::CreateFromVector(expected, &out); 448 Status s = t1->InsertTensor({3}, t2, true); 449 EXPECT_TRUE(s.IsOk()); 450 451 auto i = out->begin<uint32_t>(); 452 auto j = t1->begin<uint32_t>(); 453 for (; i != out->end<uint32_t>(); i++, j++) { 454 ASSERT_TRUE(*i == *j); 455 } 456 457 // should fail if the concatenated vector is too large 458 s = t1->InsertTensor({5}, t2, true); 459 EXPECT_FALSE(s.IsOk()); 460 } 461 462 TEST_F(MindDataTestTensorDE, TensorEmpty) { 463 TensorPtr t; 464 Status rc = Tensor::CreateEmpty(TensorShape({0}), DataType(DataType::DE_UINT64), &t); 465 ASSERT_TRUE(rc.IsOk()); 466 467 ASSERT_EQ(t->shape(), TensorShape({0})); 468 ASSERT_EQ(t->type(), DataType::DE_UINT64); 469 ASSERT_EQ(t->SizeInBytes(), 0); 470 ASSERT_EQ(t->GetBuffer(), nullptr); 471 ASSERT_TRUE(!t->HasData()); 472 473 rc = t->SetItemAt<uint64_t>({0}, 7); 474 ASSERT_TRUE(rc.IsError()); 475 476 rc = Tensor::CreateEmpty(TensorShape({1, 0}), DataType(DataType::DE_STRING), &t); 477 ASSERT_TRUE(rc.IsOk()); 478 ASSERT_EQ(t->shape(), TensorShape({1, 0})); 479 ASSERT_EQ(t->type(), DataType::DE_STRING); 480 ASSERT_EQ(t->SizeInBytes(), 0); 481 ASSERT_EQ(t->GetBuffer(), nullptr); 482 ASSERT_TRUE(!t->HasData()); 483 484 std::vector<uint16_t> data; 485 rc = Tensor::CreateFromVector(data, &t); 486 ASSERT_TRUE(rc.IsOk()); 487 ASSERT_EQ(t->shape(), TensorShape({0})); 488 ASSERT_EQ(t->type(), DataType::DE_UINT16); 489 ASSERT_EQ(t->SizeInBytes(), 0); 490 ASSERT_EQ(t->GetBuffer(), nullptr); 491 ASSERT_TRUE(!t->HasData()); 492 493 std::vector<std::string> data2; 494 rc = Tensor::CreateFromVector(data2, &t); 495 ASSERT_TRUE(rc.IsOk()); 496 ASSERT_EQ(t->shape(), TensorShape({0})); 497 ASSERT_EQ(t->type(), DataType::DE_STRING); 498 ASSERT_EQ(t->SizeInBytes(), 0); 499 ASSERT_EQ(t->GetBuffer(), nullptr); 500 ASSERT_TRUE(!t->HasData()); 501 502 rc = Tensor::CreateFromVector(data, TensorShape({0, 2}), &t); 503 ASSERT_TRUE(rc.IsOk()); 504 ASSERT_EQ(t->shape(), TensorShape({0, 2})); 505 ASSERT_EQ(t->type(), DataType::DE_UINT16); 506 ASSERT_EQ(t->SizeInBytes(), 0); 507 ASSERT_EQ(t->GetBuffer(), nullptr); 508 ASSERT_TRUE(!t->HasData()); 509 510 rc = Tensor::CreateFromVector(data2, TensorShape({0, 0, 6}), &t); 511 ASSERT_TRUE(rc.IsOk()); 512 ASSERT_EQ(t->shape(), TensorShape({0, 0, 6})); 513 ASSERT_EQ(t->type(), DataType::DE_STRING); 514 ASSERT_EQ(t->SizeInBytes(), 0); 515 ASSERT_EQ(t->GetBuffer(), nullptr); 516 ASSERT_TRUE(!t->HasData()); 517 518 rc = Tensor::CreateFromMemory(TensorShape({0}), DataType(DataType::DE_INT8), nullptr, &t); 519 ASSERT_TRUE(rc.IsOk()); 520 ASSERT_EQ(t->shape(), TensorShape({0})); 521 ASSERT_EQ(t->type(), DataType::DE_INT8); 522 ASSERT_EQ(t->SizeInBytes(), 0); 523 ASSERT_EQ(t->GetBuffer(), nullptr); 524 ASSERT_TRUE(!t->HasData()); 525 526 rc = Tensor::CreateFromMemory(TensorShape({0}), DataType(DataType::DE_STRING), nullptr, &t); 527 ASSERT_TRUE(rc.IsOk()); 528 ASSERT_EQ(t->shape(), TensorShape({0})); 529 ASSERT_EQ(t->type(), DataType::DE_STRING); 530 ASSERT_EQ(t->SizeInBytes(), 0); 531 ASSERT_EQ(t->GetBuffer(), nullptr); 532 533 std::vector<uint32_t> values = {1, 2, 3, 0, 0, 0}; 534 std::shared_ptr<Tensor> t2; 535 Tensor::CreateFromVector(values, &t2); 536 ASSERT_TRUE(t2->HasData()); 537 t2->Invalidate(); 538 ASSERT_TRUE(!t2->HasData()); 539 } 540