Files
paddlepaddle--paddle/paddle/fluid/operators/ops_extra_info.h
T
2026-07-13 12:40:42 +08:00

224 lines
7.9 KiB
C++

// Copyright (c) 2023 PaddlePaddle Authors. All Rights Reserved.
//
// 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.
#pragma once
#include <string>
#include <unordered_map>
#include <vector>
#include "paddle/fluid/framework/attribute.h"
namespace paddle {
namespace operators {
// This file is to be compatible with the bad design and
// implementation of fluid in the past
// Many operators in fluid have extra attributes, which are generally added
// to implement some specific kernel selection and to meet the specialization
// needs of a specific operation library like mkldnn or cudnn
enum class ExtraAttrProperty : uint8_t {
// The attributes that are no longer used by any scene
DEPRECATED = 0,
// The attributes used for framework execution scheduling,
// such as `use_mkldnn`, `use_cudnn`, no need to save
SCHEDULE,
// The attributes for ONEDNN only, can be saved in OneDNNContext
ONEDNN,
// The attributes for GPUDNN only, can be saved in GPUContext
GPUDNN,
// Add necessary properties as needed
};
class ExtraAttrPropertySet final {
public:
constexpr ExtraAttrPropertySet() : bitset_(0) {}
constexpr ExtraAttrPropertySet(ExtraAttrProperty e) // NOLINT
: bitset_(e == ExtraAttrProperty::DEPRECATED
? 0
: 1ULL << (static_cast<uint8_t>(e) - 1)) {}
inline uint64_t bitset() const { return bitset_; }
bool inline Support(ExtraAttrProperty e) const {
// DEPRECATED ExtraAttr always return false
return static_cast<bool>(bitset_ & ExtraAttrPropertySet(e).bitset());
}
bool IsEmpty() const { return bitset_ == 0; }
ExtraAttrPropertySet operator|(const ExtraAttrPropertySet& other) const {
return ExtraAttrPropertySet(bitset_ | other.bitset());
}
ExtraAttrPropertySet operator&(const ExtraAttrPropertySet& other) const {
return ExtraAttrPropertySet(bitset_ & other.bitset());
}
ExtraAttrPropertySet operator-(const ExtraAttrPropertySet& other) const {
return ExtraAttrPropertySet(bitset_ & ~other.bitset());
}
ExtraAttrPropertySet operator^(const ExtraAttrPropertySet& other) const {
return ExtraAttrPropertySet(bitset_ ^ other.bitset());
}
bool operator==(const ExtraAttrPropertySet& other) const {
return bitset_ == other.bitset();
}
private:
constexpr ExtraAttrPropertySet(uint64_t bitset) : bitset_(bitset) {}
uint64_t bitset_;
};
const std::unordered_map<std::string, ExtraAttrPropertySet>
extra_attr_properties = {
// DEPRECATED attributes
{"use_quantizer", ExtraAttrProperty::DEPRECATED},
// SCHEDULE attributes
{"use_cudnn", ExtraAttrProperty::SCHEDULE},
{"use_mkldnn", ExtraAttrProperty::SCHEDULE},
{"use_onednn", ExtraAttrProperty::SCHEDULE},
// ONEDNN dedicated attributes
{"data_format", ExtraAttrProperty::ONEDNN},
{"force_fp32_output", ExtraAttrProperty::ONEDNN},
{"fuse_activation", ExtraAttrProperty::ONEDNN},
{"fuse_alpha", ExtraAttrProperty::ONEDNN},
{"fuse_beta", ExtraAttrProperty::ONEDNN},
{"fuse_relu", ExtraAttrProperty::ONEDNN},
{"fused_output_scale", ExtraAttrProperty::ONEDNN},
{"fuse_residual_connection", ExtraAttrProperty::ONEDNN},
{"fuse_with_relu", ExtraAttrProperty::ONEDNN},
{"mkldnn_data_type", ExtraAttrProperty::ONEDNN},
{"onednn_data_type", ExtraAttrProperty::ONEDNN},
{"scale_x", ExtraAttrProperty::ONEDNN},
{"scale_y", ExtraAttrProperty::ONEDNN},
{"scale_out", ExtraAttrProperty::ONEDNN},
{"Scale_in", ExtraAttrProperty::ONEDNN},
{"Scale_data", ExtraAttrProperty::ONEDNN},
{"Shift_data", ExtraAttrProperty::ONEDNN},
{"Scale_in_eltwise", ExtraAttrProperty::ONEDNN},
{"Scale_x", ExtraAttrProperty::ONEDNN},
{"Scale_y", ExtraAttrProperty::ONEDNN},
{"Scale_out", ExtraAttrProperty::ONEDNN},
{"Scale_weights", ExtraAttrProperty::ONEDNN},
{"x_data_format", ExtraAttrProperty::ONEDNN},
{"y_data_format", ExtraAttrProperty::ONEDNN},
{"fused_reshape2_shape", ExtraAttrProperty::ONEDNN},
// ONEDNN pass dedicated attributes
{"Activation_scale", ExtraAttrProperty::ONEDNN},
{"Bias_scales", ExtraAttrProperty::ONEDNN},
{"Output_shift_scale", ExtraAttrProperty::ONEDNN},
{"Sum_scale", ExtraAttrProperty::ONEDNN},
// GPUDNN dedicated attributes
{"exhaustive_search", ExtraAttrProperty::GPUDNN},
{"fuse_relu_before_depthwise_conv", ExtraAttrProperty::GPUDNN},
{"use_addto", ExtraAttrProperty::GPUDNN},
{"workspace_size_MB", ExtraAttrProperty::GPUDNN},
// Mixed-use attributes
{"is_test",
ExtraAttrPropertySet(ExtraAttrProperty::ONEDNN) |
ExtraAttrPropertySet(ExtraAttrProperty::GPUDNN)},
};
inline ExtraAttrPropertySet GetExtraAttrProperties(
const std::string& attr_name) {
auto iter = extra_attr_properties.find(attr_name);
if (iter != extra_attr_properties.end()) {
return iter->second;
}
return ExtraAttrPropertySet();
}
template <typename T>
struct ExtraAttrChecker {
ExtraAttrChecker(const std::string& attr_name, T default_value)
: attr_name(attr_name), default_val(default_value) {}
void operator()(framework::AttributeMap* attr_map,
bool only_check_exist_value) {
auto it = attr_map->find(attr_name);
if (it == attr_map->end()) {
if (!only_check_exist_value) {
attr_map->emplace(attr_name, default_val);
}
return;
}
framework::ExtractAttribute<T> extract_attr(attr_name);
extract_attr(it->second);
}
const std::string& attr_name;
T default_val;
};
class ExtraInfoUtils {
public:
static ExtraInfoUtils& Instance() {
static ExtraInfoUtils extra_info_utils;
return extra_info_utils;
}
const std::unordered_map<std::string, paddle::framework::AttributeMap>&
GetAllExtraAttrsMap() const {
return g_extra_attrs_map_;
}
const paddle::framework::AttributeMap& GetExtraAttrsMap(
const std::string& op_type) const {
auto iter = g_extra_attrs_map_.find(op_type);
if (iter != g_extra_attrs_map_.end()) {
return iter->second;
}
return empty_extra_attrs_map_;
}
const std::vector<std::function<void(framework::AttributeMap*, bool)>>&
GetExtraAttrsChecker(const std::string& op_type) const {
auto iter = g_extra_attrs_checker_.find(op_type);
if (iter != g_extra_attrs_checker_.end()) {
return iter->second;
}
return empty_extra_attrs_checker_;
}
const std::vector<std::string>& GetExtraInputNamesMap(
const std::string& op_type) const {
auto iter = g_extra_input_names_map_.find(op_type);
if (iter != g_extra_input_names_map_.end()) {
return iter->second;
}
return empty_extra_input_names_;
}
private:
ExtraInfoUtils();
std::unordered_map<std::string, paddle::framework::AttributeMap>
g_extra_attrs_map_;
paddle::framework::AttributeMap empty_extra_attrs_map_{};
std::unordered_map<
std::string,
std::vector<std::function<void(framework::AttributeMap*, bool)>>>
g_extra_attrs_checker_;
std::vector<std::function<void(framework::AttributeMap*, bool)>>
empty_extra_attrs_checker_{};
// TODO(chenweihang): move these extra inputs into op_compat.yaml
std::unordered_map<std::string, std::vector<std::string>>
g_extra_input_names_map_ = {{"conv2d_transpose", {"Bias"}}};
std::vector<std::string> empty_extra_input_names_;
};
} // namespace operators
} // namespace paddle