meta_tensor.cc 7.8 KB
Newer Older
1
/* Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
2 3 4 5 6 7 8 9 10 11 12 13 14

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

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */

15
#include "paddle/phi/core/meta_tensor.h"
16

17 18
#include "glog/logging.h"

19 20 21
#include "paddle/phi/core/dense_tensor.h"
#include "paddle/phi/core/enforce.h"
#include "paddle/phi/core/selected_rows.h"
J
Jack Zhou 已提交
22 23
#include "paddle/phi/core/string_tensor.h"
#include "paddle/phi/core/string_tensor_utils.h"
24
#include "paddle/phi/core/tensor_utils.h"
25

26
namespace phi {
27

28 29 30 31 32 33
static inline void ValidCheck(const MetaTensor& meta_tensor) {
  PADDLE_ENFORCE_EQ(meta_tensor.initialized(),
                    true,
                    phi::errors::InvalidArgument(
                        "The current MetaTensor is not initialized."));
}
34

35 36 37 38
int64_t MetaTensor::numel() const {
  ValidCheck(*this);
  return tensor_->numel();
}
39

40 41 42 43
DDim MetaTensor::dims() const {
  ValidCheck(*this);
  return tensor_->dims();
}
44

45 46 47 48 49 50 51 52 53
DataType MetaTensor::dtype() const {
  ValidCheck(*this);
  return tensor_->dtype();
}

DataLayout MetaTensor::layout() const {
  ValidCheck(*this);
  return tensor_->layout();
}
54 55

void MetaTensor::set_dims(const DDim& dims) {
56
  ValidCheck(*this);
57
  if (phi::DenseTensor::classof(tensor_)) {
58 59
    DenseTensorUtils::GetMutableMeta(static_cast<DenseTensor*>(tensor_))->dims =
        dims;
J
Jack Zhou 已提交
60 61 62
  } else if (phi::StringTensor::classof(tensor_)) {
    StringTensorUtils::GetMutableMeta(static_cast<StringTensor*>(tensor_))
        ->dims = dims;
63
  } else if (phi::SelectedRows::classof(tensor_)) {
64 65 66
    DenseTensorUtils::GetMutableMeta(
        static_cast<SelectedRows*>(tensor_)->mutable_value())
        ->dims = dims;
67 68 69 70 71 72
  } else if (phi::SparseCooTensor::classof(tensor_)) {
    DenseTensorUtils::GetMutableMeta(static_cast<SparseCooTensor*>(tensor_))
        ->dims = dims;
  } else if (phi::SparseCsrTensor::classof(tensor_)) {
    DenseTensorUtils::GetMutableMeta(static_cast<SparseCsrTensor*>(tensor_))
        ->dims = dims;
73
  } else {
74
    PADDLE_THROW(phi::errors::Unimplemented(
75 76 77 78 79
        "Unsupported setting dims for `%s`.", tensor_->type_info().name()));
  }
}

void MetaTensor::set_dtype(DataType dtype) {
80
  ValidCheck(*this);
81
  if (phi::DenseTensor::classof(tensor_)) {
82
    DenseTensorUtils::GetMutableMeta(static_cast<DenseTensor*>(tensor_))
83
        ->dtype = dtype;
J
Jack Zhou 已提交
84 85
  } else if (phi::StringTensor::classof(tensor_)) {
    // No need to set dtype
86
  } else if (phi::SelectedRows::classof(tensor_)) {
87 88 89
    DenseTensorUtils::GetMutableMeta(
        static_cast<SelectedRows*>(tensor_)->mutable_value())
        ->dtype = dtype;
90 91 92 93 94 95 96
  } else if (phi::SparseCooTensor::classof(tensor_)) {
    DenseTensorUtils::GetMutableMeta(static_cast<SparseCooTensor*>(tensor_))
        ->dtype = dtype;
  } else if (phi::SparseCsrTensor::classof(tensor_)) {
    DenseTensorUtils::GetMutableMeta(static_cast<SparseCsrTensor*>(tensor_))
        ->dtype = dtype;
    // No need to set dtype
97
  } else {
98
    PADDLE_THROW(phi::errors::Unimplemented(
99 100 101 102 103
        "Unsupported settting dtype for `%s`.", tensor_->type_info().name()));
  }
}

void MetaTensor::set_layout(DataLayout layout) {
104
  ValidCheck(*this);
105
  if (phi::DenseTensor::classof(tensor_)) {
106
    DenseTensorUtils::GetMutableMeta(static_cast<DenseTensor*>(tensor_))
107
        ->layout = layout;
J
Jack Zhou 已提交
108 109
  } else if (phi::StringTensor::classof(tensor_)) {
    // No need to set layout
110
  } else if (phi::SelectedRows::classof(tensor_)) {
111 112 113
    DenseTensorUtils::GetMutableMeta(
        static_cast<SelectedRows*>(tensor_)->mutable_value())
        ->layout = layout;
114 115 116 117 118 119
  } else if (phi::SparseCooTensor::classof(tensor_)) {
    DenseTensorUtils::GetMutableMeta(static_cast<SparseCooTensor*>(tensor_))
        ->layout = layout;
  } else if (phi::SparseCsrTensor::classof(tensor_)) {
    DenseTensorUtils::GetMutableMeta(static_cast<SparseCsrTensor*>(tensor_))
        ->layout = layout;
120
  } else {
121
    PADDLE_THROW(phi::errors::Unimplemented(
122 123 124 125 126
        "Unsupported settting layout for `%s`.", tensor_->type_info().name()));
  }
}

void MetaTensor::share_lod(const MetaTensor& meta_tensor) {
127 128
  ValidCheck(*this);
  ValidCheck(meta_tensor);
129 130 131 132
  if (phi::SparseCooTensor::classof(tensor_) ||
      phi::SparseCsrTensor::classof(tensor_)) {
    return;
  }
H
hong 已提交
133 134 135 136
  if (meta_tensor.lod().size() == 0) {
    // no need share
    return;
  }
137
  if (phi::DenseTensor::classof(tensor_)) {
138 139
    DenseTensorUtils::GetMutableMeta(static_cast<DenseTensor*>(tensor_))->lod =
        meta_tensor.lod();
140
  } else if (phi::SelectedRows::classof(tensor_)) {
141 142 143
    DenseTensorUtils::GetMutableMeta(
        static_cast<SelectedRows*>(tensor_)->mutable_value())
        ->lod = meta_tensor.lod();
144
  } else {
145
    PADDLE_THROW(
146 147
        phi::errors::Unimplemented("Unsupported sharing lod inplace for `%s`.",
                                   tensor_->type_info().name()));
148 149 150
  }
}

151
void MetaTensor::share_meta(const MetaTensor& meta_tensor) {
152
  ValidCheck(*this);
Y
YuanRisheng 已提交
153
  if (phi::DenseTensor::classof(tensor_) ||
154 155 156
      phi::SelectedRows::classof(tensor_) ||
      phi::SparseCooTensor::classof(tensor_) ||
      phi::SparseCsrTensor::classof(tensor_)) {
Y
YuanRisheng 已提交
157
    share_dims(meta_tensor);
158 159 160
    set_dtype(meta_tensor.dtype());
    set_layout(meta_tensor.layout());
    share_lod(meta_tensor);
161
  } else {
162
    PADDLE_THROW(phi::errors::Unimplemented(
163
        "Unsupported sharing meta for `%s`.", tensor_->type_info().name()));
164 165 166
  }
}

167 168 169
bool MetaTensor::is_dense() const { return DenseTensor::classof(tensor_); }
bool MetaTensor::is_tensor_array() const { return false; }

Y
YuanRisheng 已提交
170
void MetaTensor::share_dims(const MetaTensor& meta_tensor) {
171
  ValidCheck(*this);
Y
YuanRisheng 已提交
172 173
  bool is_dense_tensor = phi::DenseTensor::classof(tensor_);
  bool is_selected_rows = phi::SelectedRows::classof(tensor_);
174 175 176
  bool is_sparse_coo = phi::SparseCooTensor::classof(tensor_);
  bool is_sparse_csr = phi::SparseCsrTensor::classof(tensor_);
  if (is_dense_tensor || is_selected_rows || is_sparse_coo || is_sparse_csr) {
Y
YuanRisheng 已提交
177 178
    set_dims(meta_tensor.dims());
    if (is_selected_rows) {
C
Chen Weihang 已提交
179
      const auto in_tensor_base = meta_tensor.tensor();
Y
YuanRisheng 已提交
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
      PADDLE_ENFORCE_EQ(
          phi::SelectedRows::classof(in_tensor_base),
          true,
          errors::InvalidArgument("The input MetaTensor is SelectedRows, but "
                                  "the output MetaTensor is not this type."));
      auto* selected_rows_out = static_cast<SelectedRows*>(tensor_);
      auto* selected_rows_in = static_cast<SelectedRows*>(in_tensor_base);
      selected_rows_out->set_rows(selected_rows_in->rows());
      selected_rows_out->set_height(selected_rows_in->height());
    }
  } else {
    PADDLE_THROW(phi::errors::Unimplemented(
        "Unsupported sharing dims for `%s`.", tensor_->type_info().name()));
  }
}

196 197
bool MetaTensor::initialized() const { return tensor_ != nullptr; }

198 199 200 201 202 203 204
// Private Member Methods

const LoD& MetaTensor::lod() const {
  if (phi::DenseTensor::classof(tensor_)) {
    return static_cast<DenseTensor*>(tensor_)->lod();
  } else if (phi::SelectedRows::classof(tensor_)) {
    return static_cast<SelectedRows*>(tensor_)->value().lod();
205 206 207 208
  } else if (phi::SparseCooTensor::classof(tensor_)) {
    return static_cast<SparseCooTensor*>(tensor_)->non_zero_elements().lod();
  } else if (phi::SparseCsrTensor::classof(tensor_)) {
    return static_cast<SparseCsrTensor*>(tensor_)->non_zero_elements().lod();
209 210 211 212 213 214 215 216
  } else {
    PADDLE_THROW(phi::errors::Unimplemented("Unsupported getting lod of `%s`.",
                                            tensor_->type_info().name()));
  }
}

TensorBase* MetaTensor::tensor() const { return tensor_; }

217
}  // namespace phi