|
- /**
- * \file src/custom/test/tensor.cpp
- * MegEngine is Licensed under the Apache License, Version 2.0 (the "License")
- *
- * Copyright (c) 2014-2021 Megvii Inc. All rights reserved.
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- */
-
- #include "megbrain_build_config.h"
-
- #if MGB_CUSTOM_OP
-
- #include "megbrain/custom/tensor.h"
- #include "megbrain/custom/data_adaptor.h"
- #include "megbrain/comp_node.h"
- #include "megbrain/tensor.h"
- #include "gtest/gtest.h"
- #include "megbrain_build_config.h"
-
- #define TENSOR_TEST_LOG 0
-
- using namespace mgb;
-
- namespace custom {
-
- TEST(TestDevice, TestDevice) {
- #if MGB_CUDA
- ASSERT_TRUE(Device::is_legal("x86"));
- ASSERT_TRUE(Device::is_legal(DeviceEnum::cuda));
- ASSERT_FALSE(Device::is_legal("cpu"));
-
- Device dev1;
- ASSERT_TRUE(dev1.str() == "invalid");
-
- dev1 = "x86";
- ASSERT_TRUE("x86" == dev1);
-
- Device dev2 = "cuda";
- ASSERT_TRUE(dev2 == "cuda");
- ASSERT_FALSE(dev2 == dev1);
-
- Device dev3 = dev2;
- ASSERT_TRUE(dev3 == dev2);
- ASSERT_FALSE(dev3 == dev1);
-
- Device dev4 = DeviceEnum::cuda;
- ASSERT_TRUE(dev4.enumv() == DeviceEnum::cuda);
-
- #if TENSOR_TEST_LOG
- std::cout << dev1.str() << "\n" << dev2.str() << "\n"
- << dev3.str() << "\n" << dev4.str() << std::endl;
- #endif
-
- CompNode compnode = to_builtin<CompNode, Device>(dev3);
- ASSERT_TRUE(compnode.to_string_logical() == "gpux:0");
- compnode = CompNode::load("cpu0:0");
- Device dev5 = to_custom<CompNode, Device>(compnode);
- ASSERT_TRUE(dev5.str() == "x86");
-
- std::vector<Device> devs1 = {"x86", "cuda", "x86"};
- megdnn::SmallVector<CompNode> compnodes = to_builtin<CompNode, Device>(devs1);
- ASSERT_TRUE(compnodes[0].to_string_logical() == "cpux:0");
- ASSERT_TRUE(compnodes[1].to_string_logical() == "gpux:0");
- ASSERT_TRUE(compnodes[2].to_string_logical() == "cpux:0");
-
- std::vector<Device> devs2 = to_custom<CompNode, Device>(compnodes);
- ASSERT_TRUE(devs2[0] == "x86");
- ASSERT_TRUE(devs2[1].str() == "cuda");
- ASSERT_TRUE(devs2[2] == "x86");
- #endif
- }
-
- TEST(TestShape, TestShape) {
- Shape shape1, shape2;
- ASSERT_TRUE(shape1.ndim() == 0);
-
- shape1 = {16, 32, 8, 8};
- shape2 = shape1;
- ASSERT_TRUE(shape2.ndim() == 4);
- ASSERT_TRUE(shape2[0] == 16);
- ASSERT_TRUE(shape2[1] == 32);
- ASSERT_TRUE(shape2[2] == 8);
- ASSERT_TRUE(shape2[3] == 8);
-
- Shape shape3 = {16, 32, 8, 8};
- const Shape shape4 = shape1;
- ASSERT_TRUE(shape3 == shape4);
- shape3[0] = 32;
- ASSERT_FALSE(shape3 == shape4);
- ASSERT_TRUE(shape3[0] == 32);
- ASSERT_TRUE(shape4[0] == 16);
-
- Shape shape5 = {2, 3, 4};
- TensorShape bshape1 = to_builtin<TensorShape, Shape>(shape5);
- ASSERT_TRUE(bshape1.ndim == 3);
- ASSERT_TRUE(bshape1[0] == 2);
- ASSERT_TRUE(bshape1[1] == 3);
- ASSERT_TRUE(bshape1[2] == 4);
- bshape1 = {4, 2, 3};
- Shape shape6 = to_custom<TensorShape, Shape>(bshape1);
- ASSERT_TRUE(shape6.ndim() == 3);
- ASSERT_TRUE(shape6[0] == 4);
- ASSERT_TRUE(shape6[1] == 2);
- ASSERT_TRUE(shape6[2] == 3);
-
- Shape shape7;
- shape7.ndim(3);
- shape7[1] = 4;
- ASSERT_TRUE(shape7 == Shape({0, 4, 0}));
-
- std::vector<Shape> shapes1 = {{2, 3, 4}, {6}, {5, 7}};
- megdnn::SmallVector<TensorShape> bshapes = to_builtin<TensorShape, Shape>(shapes1);
- ASSERT_TRUE(bshapes[0].total_nr_elems() == 2*3*4);
- ASSERT_TRUE(bshapes[1].total_nr_elems() == 6);
- ASSERT_TRUE(bshapes[2].total_nr_elems() == 35);
-
- std::vector<Shape> shapes2 = to_custom<TensorShape, Shape>(bshapes);
- ASSERT_TRUE(shapes2[0] == Shape({2, 3, 4}));
- ASSERT_TRUE(shapes2[1] == Shape({6}));
- ASSERT_TRUE(shapes2[2] == Shape({5, 7}));
- }
-
- TEST(TestDType, TestDType) {
- #if !MEGDNN_DISABLE_FLOAT16
- ASSERT_TRUE(DType::is_legal("uint8"));
- ASSERT_TRUE(DType::is_legal(DTypeEnum::bfloat16));
-
- DType dtype1, dtype2;
- ASSERT_TRUE(dtype1.str() == "invalid");
-
- dtype1 = "float32";
- ASSERT_TRUE(dtype1.str() == "float32");
-
- dtype2 = dtype1;
- DType dtype3 = dtype2;
- ASSERT_TRUE(dtype3 == dtype1);
- ASSERT_TRUE(dtype3 == "float32");
-
- dtype3 = "int8";
- ASSERT_FALSE("float32" == dtype3.str());
- ASSERT_FALSE(dtype3 == dtype2);
-
- DType dtype4 = DTypeEnum::int8, dtype5 = dtype3;
- ASSERT_TRUE(dtype4 == dtype5);
- ASSERT_TRUE(dtype4.is_compatible<int8_t>());
- ASSERT_FALSE(dtype4.is_compatible<uint8_t>());
-
- DType dtype6 = "int32";
- megdnn::DType bdtype1 = to_builtin<megdnn::DType, DType>(dtype6);
- ASSERT_TRUE(bdtype1.name() == std::string("Int32"));
- bdtype1 = megdnn::DType::from_enum(megdnn::DTypeEnum::BFloat16);
- DType dtype7 = to_custom<megdnn::DType, DType>(bdtype1);
- ASSERT_TRUE(dtype7.enumv() == DTypeEnum::bfloat16);
-
- std::vector<DType> dtypes1 = {"int8", "uint8", "float16"};
- megdnn::SmallVector<megdnn::DType> bdtypes
- = to_builtin<megdnn::DType, DType>(dtypes1);
- ASSERT_TRUE(bdtypes[0].name() == std::string("Int8"));
- ASSERT_TRUE(bdtypes[1].name() == std::string("Uint8"));
- ASSERT_TRUE(bdtypes[2].name() == std::string("Float16"));
-
- std::vector<DType> dtypes2 = to_custom<megdnn::DType, DType>(bdtypes);
- ASSERT_TRUE(dtypes2[0] == "int8");
- ASSERT_TRUE(dtypes2[1] == "uint8");
- ASSERT_TRUE(dtypes2[2] == "float16");
- #endif
- }
-
- TEST(TestDType, TestDTypeQuantized) {
- DType quint8_1("quint8", 3.2, 15);
- DType quint8_2("quint8", 3.2, 15);
- DType quint8_3("quint8", 3.2, 16);
- DType quint8_4("quint8", 3.1, 15);
-
- ASSERT_TRUE(quint8_1 == quint8_2);
- ASSERT_FALSE(quint8_1 == quint8_3);
- ASSERT_FALSE(quint8_1 == quint8_4);
-
- ASSERT_TRUE(quint8_1.scale() == 3.2f);
- ASSERT_TRUE(quint8_1.zero_point() == 15);
-
- DType qint8("qint8", 3.3f);
- DType qint16("qint16", 3.4f);
- DType qint32("qint32", 3.5f);
-
- ASSERT_TRUE(qint8.scale() == 3.3f);
- ASSERT_TRUE(qint16.scale() == 3.4f);
- ASSERT_TRUE(qint32.scale() == 3.5f);
-
- ASSERT_TRUE(qint8.enumv() == DTypeEnum::qint8);
- ASSERT_TRUE(qint8.str() == "qint8");
- }
-
- TEST(TestFormat, TestFormat) {
- Format format1, format2("default");
- ASSERT_TRUE(format1.is_default());
- ASSERT_TRUE(format2.is_default());
- Format format3 = format1;
- ASSERT_TRUE(format3.is_default());
- }
-
- TEST(TestTensor, TestTensor) {
- CompNode builtin_device = CompNode::load("cpux:0");
- TensorShape builtin_shape = {3, 2, 4};
- megdnn::DType builtin_dtype = dtype::Int32{};
-
- DeviceTensorND dev_tensor(builtin_device, builtin_shape, builtin_dtype);
- Tensor tensor1 = to_custom<DeviceTensorND, Tensor>(dev_tensor);
- Tensor tensor2 = to_custom<DeviceTensorND, Tensor>(dev_tensor);
- Device device = tensor1.device();
- Shape shape = tensor1.shape();
- DType dtype = tensor1.dtype();
-
- ASSERT_TRUE(device == "x86");
- ASSERT_TRUE(shape.ndim() == 3);
- ASSERT_TRUE(shape[0] == 3);
- ASSERT_TRUE(shape[1] == 2);
- ASSERT_TRUE(shape[2] == 4);
- ASSERT_TRUE(shape == std::vector<size_t>({3, 2, 4}));
- ASSERT_TRUE(dtype == "int32");
-
- int *raw_ptr1 = tensor1.data<int>();
- for (size_t i=0; i<tensor1.size(); i++)
- raw_ptr1[i] = i;
-
- int *raw_ptr2 = tensor2.data<int>();
- for (size_t i=0; i<tensor2.size(); i++)
- ASSERT_TRUE(raw_ptr2[i] == static_cast<int>(i));
-
- Tensor tensor3 = tensor2;
- int *raw_ptr3 = tensor3.data<int>();
- for (size_t i=0; i<tensor3.size(); i++)
- ASSERT_TRUE(raw_ptr3[i] == static_cast<int>(i));
- ASSERT_TRUE(raw_ptr1 == raw_ptr2);
- ASSERT_TRUE(raw_ptr1 == raw_ptr3);
-
- for (size_t i=0; i<tensor3.size(); i++) {
- raw_ptr3[i] = -static_cast<int>(i);
- }
- for (size_t i=0; i<tensor1.size(); i++) {
- ASSERT_TRUE(raw_ptr1[i] == -static_cast<int>(i));
- }
-
- DeviceTensorND new_dev_tensor = to_builtin<DeviceTensorND, Tensor>(tensor3);
-
- int *builtin_ptr = new_dev_tensor.ptr<int>();
- for (size_t i=0; i<new_dev_tensor.shape().total_nr_elems(); i++) {
- ASSERT_TRUE(builtin_ptr[i] == -static_cast<int>(i));
- }
- }
-
- TEST(TestTensor, TestTensorQuantized) {
- #if MGB_CUDA
- CompNode builtin_device = CompNode::load("gpux:0");
- TensorShape builtin_shape = {3, 2, 4};
- megdnn::DType builtin_dtype = dtype::Quantized8Asymm{3.2f, uint8_t(15)};
-
- DeviceTensorND dev_tensor(builtin_device, builtin_shape, builtin_dtype);
-
- Tensor tensor1 = to_custom<DeviceTensorND, Tensor>(dev_tensor);
- Tensor tensor2 = to_custom<DeviceTensorND, Tensor>(dev_tensor);
- Device device1 = tensor1.device(), device2 = tensor2.device();
- Shape shape1 = tensor1.shape(), shape2 = tensor2.shape();
- DType dtype1 = tensor1.dtype(), dtype2 = tensor2.dtype();
-
- ASSERT_TRUE(device1 == "cuda");
- ASSERT_TRUE(shape1.ndim() == 3);
- ASSERT_TRUE(shape1[0] == 3);
- ASSERT_TRUE(shape1[1] == 2);
- ASSERT_TRUE(shape1[2] == 4);
- ASSERT_TRUE(shape1 == std::vector<size_t>({3, 2, 4}));
- ASSERT_TRUE(dtype1 == "quint8");
- ASSERT_TRUE(dtype1.scale() == 3.2f);
- ASSERT_TRUE(dtype1.zero_point() == 15);
-
- ASSERT_TRUE(device1 == device2);
- ASSERT_TRUE(shape1 == shape2);
- ASSERT_TRUE(dtype1 == dtype2);
- #endif
- }
-
- TEST(TestTensor, TestTensorAccessorND) {
- size_t N = 2, C = 4, H = 6, W = 8;
- CompNode builtin_device = CompNode::load("cpux");
- TensorShape builtin_shape = {N, C, H, W};
- megdnn::DType builtin_dtype = dtype::Int32{};
-
- DeviceTensorND dev_tensor(builtin_device, builtin_shape, builtin_dtype);
- int *builtin_ptr = dev_tensor.ptr<int>();
- for (size_t i=0; i<dev_tensor.shape().total_nr_elems(); i++) {
- builtin_ptr[i] = i;
- }
-
- Tensor tensor = to_custom_tensor(dev_tensor);
- auto accessor = tensor.accessor<int32_t, 4>();
- for (size_t n=0; n<N; ++n) {
- for (size_t c=0; c<C; ++c) {
- for (size_t h=0; h<H; ++h) {
- for (size_t w=0; w<W; ++w) {
- int32_t idx = n*C*H*W + c*H*W + h*W + w;
- ASSERT_TRUE(accessor[n][c][h][w] == idx);
- }
- }
- }
- }
- }
-
- TEST(TestTensor, TestTensorAccessor1D) {
- CompNode builtin_device = CompNode::load("cpux");
- TensorShape builtin_shape = {32};
- megdnn::DType builtin_dtype = dtype::Float32{};
-
- DeviceTensorND dev_tensor(builtin_device, builtin_shape, builtin_dtype);
- float *builtin_ptr = dev_tensor.ptr<float>();
- for (size_t i=0; i<dev_tensor.shape().total_nr_elems(); i++) {
- builtin_ptr[i] = i;
- }
-
- Tensor tensor = to_custom_tensor(dev_tensor);
- auto accessor = tensor.accessor<float, 1>();
- for (size_t n=0; n<32; ++n) {
- ASSERT_TRUE(accessor[n] == n);
- }
- }
-
- }
-
- #endif
|