chore: import upstream snapshot with attribution
cffconvert / validate (push) Has been skipped
License Check / license-check (push) Failing after 2s

This commit is contained in:
wehub-resource-sync
2026-07-13 12:14:16 +08:00
commit 8a852e4b4e
36502 changed files with 9277225 additions and 0 deletions
+76
View File
@@ -0,0 +1,76 @@
# Description:
# Tensorflow / MLIR utils.
load("//tensorflow/core/platform:rules_cc.bzl", "cc_library")
package(
# copybara:uncomment default_applicable_licenses = ["//tensorflow:license"],
default_visibility = ["//visibility:public"],
licenses = ["notice"],
)
cc_library(
name = "name_utils",
srcs = ["name_utils.cc"],
hdrs = ["name_utils.h"],
deps = [
"@llvm-project//llvm:Support",
"@llvm-project//mlir:IR",
"@llvm-project//mlir:Support",
],
)
cc_library(
name = "string_container_utils",
hdrs = ["string_container_utils.h"],
deps = [
"@com_google_absl//absl/strings",
"@llvm-project//llvm:Support",
],
)
cc_library(
name = "array_container_utils",
hdrs = ["array_container_utils.h"],
deps = [
"@com_google_absl//absl/types:span",
"@llvm-project//llvm:Support",
],
)
cc_library(
name = "saved_model_converter_utils",
srcs = ["saved_model_converter_utils.cc"],
hdrs = ["saved_model_converter_utils.h"],
visibility = [
"//tensorflow/cc/experimental/tfa:__subpackages__",
],
deps = [
"//tensorflow/cc/saved_model:loader",
"//tensorflow/compiler/mlir/tensorflow:mlir_import_options",
"//tensorflow/compiler/mlir/tensorflow:translate_lib",
"//tensorflow/compiler/mlir/tf2xla/api/v2:mlir_roundtrip_flags",
"//tensorflow/core/framework:op",
"//tensorflow/core/framework:op_def_builder",
"@com_google_absl//absl/log",
"@com_google_absl//absl/status:statusor",
"@com_google_absl//absl/types:span",
"@llvm-project//mlir:IR",
],
)
cc_library(
name = "validators",
srcs = [
"validators.cc",
],
hdrs = [
"validators.h",
],
deps = [
"@llvm-project//mlir:Dialect",
"@llvm-project//mlir:FuncDialect",
"@llvm-project//mlir:IR",
"@llvm-project//mlir:Support",
],
)
@@ -0,0 +1,46 @@
/* Copyright 2020 The TensorFlow 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.
==============================================================================*/
#ifndef TENSORFLOW_COMPILER_MLIR_UTILS_ARRAY_CONTAINER_UTILS_H_
#define TENSORFLOW_COMPILER_MLIR_UTILS_ARRAY_CONTAINER_UTILS_H_
#include "absl/types/span.h"
#include "llvm/ADT/ArrayRef.h"
namespace mlir {
template <typename T>
inline llvm::ArrayRef<T> SpanToArrayRef(absl::Span<const T> span) {
return llvm::ArrayRef<T>(span.data(), span.size());
}
template <typename T>
inline llvm::ArrayRef<T> SpanToArrayRef(absl::Span<T> span) {
return llvm::ArrayRef<T>(span.data(), span.size());
}
template <typename T>
inline llvm::MutableArrayRef<T> SpanToMutableArrayRef(absl::Span<T> span) {
return llvm::MutableArrayRef<T>(span.data(), span.size());
}
template <typename T>
inline absl::Span<const T> ArrayRefToSpan(llvm::ArrayRef<T> ref) {
return absl::Span<const T>(ref.data(), ref.size());
}
} // namespace mlir
#endif // TENSORFLOW_COMPILER_MLIR_UTILS_ARRAY_CONTAINER_UTILS_H_
@@ -0,0 +1,100 @@
/* Copyright 2020 The TensorFlow 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.
==============================================================================*/
#include "tensorflow/compiler/mlir/utils/name_utils.h"
#include <cctype>
#include <string>
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "mlir/IR/BuiltinAttributes.h" // from @llvm-project
#include "mlir/IR/Location.h" // from @llvm-project
#include "mlir/Support/LLVM.h" // from @llvm-project
namespace mlir {
namespace {
// Checks if a character is legal for a TensorFlow node name, with special
// handling if a character is at the beginning.
bool IsLegalChar(char c, bool first_char) {
if (llvm::isAlpha(c)) return true;
if (llvm::isDigit(c)) return true;
if (c == '.') return true;
if (c == '_') return true;
// First character of a node name can only be a letter, digit, dot or
// underscore.
if (first_char) return false;
if (c == '/') return true;
if (c == '-') return true;
return false;
}
} // anonymous namespace
void LegalizeNodeName(std::string& name) {
if (name.empty()) return;
if (!IsLegalChar(name[0], /*first_char=*/true)) name[0] = '.';
for (char& c : llvm::drop_begin(name, 1))
if (!IsLegalChar(c, /*first_char=*/false)) c = '.';
}
std::string GetNameFromLoc(Location loc) {
llvm::SmallVector<llvm::StringRef, 8> loc_names;
llvm::SmallVector<Location, 8> locs;
locs.push_back(loc);
bool names_is_nonempty = false;
while (!locs.empty()) {
Location curr_loc = locs.pop_back_val();
if (auto name_loc = mlir::dyn_cast<NameLoc>(curr_loc)) {
// Add name in NameLoc. For NameLoc we also account for names due to ops
// in functions where the op's name is first.
auto name = name_loc.getName().strref().split('@').first;
// Skip if the name is for op type.
if (!name.ends_with(":")) {
loc_names.push_back(name);
if (!name.empty()) names_is_nonempty = true;
}
continue;
} else if (auto call_loc = mlir::dyn_cast<CallSiteLoc>(curr_loc)) {
// Use location of the Callee to generate the name.
locs.push_back(call_loc.getCallee());
continue;
} else if (auto fused_loc = mlir::dyn_cast<FusedLoc>(curr_loc)) {
// Push all locations in FusedLoc in reverse order, so locations are
// visited based on order in FusedLoc.
auto reversed_fused_locs = llvm::reverse(fused_loc.getLocations());
locs.append(reversed_fused_locs.begin(), reversed_fused_locs.end());
continue;
}
// Location is not a supported, so an empty StringRef is added.
loc_names.push_back(llvm::StringRef());
}
if (names_is_nonempty)
return llvm::join(loc_names.begin(), loc_names.end(), ";");
return "";
}
} // namespace mlir
@@ -0,0 +1,34 @@
/* Copyright 2020 The TensorFlow 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.
==============================================================================*/
#ifndef TENSORFLOW_COMPILER_MLIR_UTILS_NAME_UTILS_H_
#define TENSORFLOW_COMPILER_MLIR_UTILS_NAME_UTILS_H_
#include <string>
#include "mlir/IR/Location.h" // from @llvm-project
namespace mlir {
// Converts characters in name that are considered illegal in TensorFlow Node
// name to '.'.
void LegalizeNodeName(std::string& name);
// Returns the TensorFlow node name associated with a location.
std::string GetNameFromLoc(Location loc);
} // namespace mlir
#endif // TENSORFLOW_COMPILER_MLIR_UTILS_NAME_UTILS_H_
@@ -0,0 +1,94 @@
/* Copyright 2019 The TensorFlow 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.
==============================================================================*/
#include "tensorflow/compiler/mlir/utils/saved_model_converter_utils.h"
#include <stdlib.h>
#include <memory>
#include <string>
#include <unordered_set>
#include <utility>
#include "absl/log/log.h"
#include "mlir/IR/BuiltinOps.h" // from @llvm-project
#include "mlir/IR/MLIRContext.h" // from @llvm-project
#include "mlir/IR/OwningOpRef.h" // from @llvm-project
#include "tensorflow/compiler/mlir/tensorflow/translate/mlir_import_options.h"
#include "tensorflow/compiler/mlir/tensorflow/translate/tf_mlir_translate.h"
#include "tensorflow/core/framework/op.h"
#include "tensorflow/core/framework/op_def_builder.h"
#include "tensorflow/compiler/mlir/tf2xla/api/v2/mlir_roundtrip_flags.h"
namespace tensorflow {
namespace utils {
// Util that registers 'extra_tf_opdefs' to the TF global registry.
// Return OK on success, failure if registering failed.
absl::Status RegisterExtraTfOpDefs(
absl::Span<const std::string> extra_tf_opdefs) {
for (const auto& tf_opdefs_string : extra_tf_opdefs) {
OpDef opdef;
// NOLINTNEXTLINE: Use tsl::protobuf to be compatible with OSS.
if (!tsl::protobuf::TextFormat::ParseFromString(tf_opdefs_string, &opdef)) {
LOG(ERROR) << "OpDef parsing failed for: " << tf_opdefs_string;
return absl::InvalidArgumentError("fail to parse extra OpDef");
}
// Register extra opdefs.
// TODO: b/133770952 - Support shape functions.
OpRegistry::Global()->Register(
[opdef](OpRegistrationData* op_reg_data) -> absl::Status {
*op_reg_data = OpRegistrationData(opdef);
return absl::OkStatus();
});
}
return absl::OkStatus();
}
absl::StatusOr<mlir::OwningOpRef<mlir::ModuleOp>> ImportSavedModel(
const std::string& input_filename, const int saved_model_version,
const std::unordered_set<std::string>& tags,
absl::Span<const std::string> extra_tf_opdefs,
absl::Span<std::string> exported_names, const GraphImportConfig& specs,
bool enable_variable_lifting, mlir::MLIRContext* context,
std::unique_ptr<SavedModelBundle>* saved_model_bundle) {
// Register extra TF ops passed as OpDef.
auto extra_opdefs_status = RegisterExtraTfOpDefs(extra_tf_opdefs);
if (!extra_opdefs_status.ok()) return extra_opdefs_status;
if (saved_model_version == 2) {
auto module_or = SavedModelObjectGraphToMlirImport(
input_filename, tags, exported_names, context,
/*unconditionally_use_set_output_shapes=*/true);
if (!module_or.status().ok()) return module_or.status();
return std::move(module_or).value();
} else if (saved_model_version == 1) {
MLIRImportOptions options;
options.upgrade_legacy = specs.upgrade_legacy;
options.unconditionally_use_set_output_shapes = true;
options.lift_variables = enable_variable_lifting;
auto module_or = SavedModelSignatureDefsToMlirImport(
input_filename, tags, exported_names, context, options,
saved_model_bundle);
if (!module_or.status().ok()) return module_or.status();
return std::move(module_or).value();
} else {
return absl::InvalidArgumentError("Should be either saved model v1 or v2.");
}
}
} // namespace utils
} // namespace tensorflow
@@ -0,0 +1,46 @@
/* Copyright 2019 The TensorFlow 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.
==============================================================================*/
#ifndef TENSORFLOW_COMPILER_MLIR_UTILS_SAVED_MODEL_CONVERTER_UTILS_H_
#define TENSORFLOW_COMPILER_MLIR_UTILS_SAVED_MODEL_CONVERTER_UTILS_H_
#include <memory>
#include <string>
#include <unordered_set>
#include "absl/status/statusor.h"
#include "absl/types/span.h"
#include "mlir/IR/BuiltinOps.h" // from @llvm-project
#include "mlir/IR/MLIRContext.h" // from @llvm-project
#include "mlir/IR/OwningOpRef.h" // from @llvm-project
#include "tensorflow/cc/saved_model/loader.h"
#include "tensorflow/compiler/mlir/tf2xla/api/v2/mlir_roundtrip_flags.h"
namespace tensorflow {
namespace utils {
// 'saved_model_bundle' will be initialized if V1 model was loaded.
absl::StatusOr<mlir::OwningOpRef<mlir::ModuleOp>> ImportSavedModel(
const std::string& input_filename, int saved_model_version,
const std::unordered_set<std::string>& tags,
absl::Span<const std::string> extra_tf_opdefs,
absl::Span<std::string> exported_names, const GraphImportConfig& specs,
bool enable_variable_lifting, mlir::MLIRContext* context,
std::unique_ptr<tensorflow::SavedModelBundle>* saved_model_bundle);
} // namespace utils
} // namespace tensorflow
#endif // TENSORFLOW_COMPILER_MLIR_UTILS_SAVED_MODEL_CONVERTER_UTILS_H_
@@ -0,0 +1,34 @@
/* Copyright 2020 The TensorFlow 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.
==============================================================================*/
#ifndef TENSORFLOW_COMPILER_MLIR_UTILS_STRING_CONTAINER_UTILS_H_
#define TENSORFLOW_COMPILER_MLIR_UTILS_STRING_CONTAINER_UTILS_H_
#include "absl/strings/string_view.h"
#include "llvm/ADT/StringRef.h"
namespace mlir {
inline absl::string_view StringRefToView(llvm::StringRef ref) {
return absl::string_view(ref.data(), ref.size());
}
inline llvm::StringRef StringViewToRef(absl::string_view view) {
return llvm::StringRef(view.data(), view.size());
}
} // namespace mlir
#endif // TENSORFLOW_COMPILER_MLIR_UTILS_STRING_CONTAINER_UTILS_H_
@@ -0,0 +1,147 @@
/* Copyright 2019 The TensorFlow 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.
==============================================================================*/
#include "tensorflow/compiler/mlir/utils/validators.h"
#include <algorithm>
#include <cstdint>
#include "mlir/Dialect/Traits.h" // from @llvm-project
#include "mlir/IR/Attributes.h" // from @llvm-project
#include "mlir/IR/Builders.h" // from @llvm-project
#include "mlir/IR/BuiltinAttributeInterfaces.h" // from @llvm-project
#include "mlir/IR/Operation.h" // from @llvm-project
#include "mlir/Support/LLVM.h" // from @llvm-project
namespace mlir {
namespace TF {
// Returns true if the given `op`
// * has an attribute with the given `name`,
// * and the attribute is an integer list of the form [1, X, Y, 1],
// and writes X, Y as 32-bit integer attribute to `x`, `y`.
bool TFIntListIs1XY1(Operation *op, StringRef name, IntegerAttr *x,
IntegerAttr *y) {
auto attr = op->getAttrOfType<ArrayAttr>(name);
if (!attr) return false;
auto elements = attr.getValue();
if (elements.size() != 4 ||
std::any_of(elements.begin(), elements.end(),
[](Attribute e) { return !mlir::isa<IntegerAttr>(e); }))
return false;
if (mlir::cast<IntegerAttr>(elements.front()).getInt() != 1 ||
mlir::cast<IntegerAttr>(elements.back()).getInt() != 1)
return false;
Builder b(op->getContext());
*x = b.getI32IntegerAttr(mlir::cast<IntegerAttr>(elements[1]).getInt());
*y = b.getI32IntegerAttr(mlir::cast<IntegerAttr>(elements[2]).getInt());
return true;
}
// Returns true if the attribute is an integer list of the form [1, X, Y, 1].
bool TFIntListIs1XY1(const Attribute attr) {
const auto &elements = mlir::cast<ArrayAttr>(attr).getValue();
if (elements.size() != 4 ||
std::any_of(elements.begin(), elements.end(),
[](Attribute e) { return !mlir::isa<IntegerAttr>(e); }))
return false;
if (mlir::cast<IntegerAttr>(elements.front()).getValue() != 1 ||
mlir::cast<IntegerAttr>(elements.back()).getValue() != 1)
return false;
return true;
}
// Returns true if the attribute is an integer list of the form [1, 1, X, Y].
bool TFIntListIs11XY(const Attribute attr) {
const auto &elements = mlir::cast<ArrayAttr>(attr).getValue();
if (elements.size() != 4 ||
std::any_of(elements.begin(), elements.end(),
[](Attribute e) { return !mlir::isa<IntegerAttr>(e); }))
return false;
const Attribute *data = elements.data();
if (mlir::cast<IntegerAttr>(data[0]).getValue() != 1 ||
mlir::cast<IntegerAttr>(data[1]).getValue() != 1)
return false;
return true;
}
// Returns true if the given `op`
// * has an attribute with the given `name`,
// * and the attribute is an integer list of the form [1, X, Y, Z, 1],
// and writes X, Y as 32-bit integer attribute to `x`, `y`, z.
bool TFIntListIs1XYZ1(Operation *op, StringRef name, IntegerAttr *x,
IntegerAttr *y, IntegerAttr *z) {
auto attr = op->getAttrOfType<ArrayAttr>(name);
if (!attr) return false;
auto elements = attr.getValue();
if (elements.size() != 5 ||
std::any_of(elements.begin(), elements.end(),
[](Attribute e) { return !mlir::isa<IntegerAttr>(e); }))
return false;
if (mlir::cast<IntegerAttr>(elements.front()).getInt() != 1 ||
mlir::cast<IntegerAttr>(elements.back()).getInt() != 1)
return false;
Builder b(op->getContext());
*x = b.getI32IntegerAttr(mlir::cast<IntegerAttr>(elements[1]).getInt());
*y = b.getI32IntegerAttr(mlir::cast<IntegerAttr>(elements[2]).getInt());
*z = b.getI32IntegerAttr(mlir::cast<IntegerAttr>(elements[3]).getInt());
return true;
}
// Returns true if every element of the attribute is 1. All elements of `attr`
// must be `IntegerAttr`.
bool TFIntListIsAllOnes(const Attribute attr) {
const auto &elements = mlir::cast<ArrayAttr>(attr).getValue();
return !std::any_of(elements.begin(), elements.end(), [](Attribute e) {
return mlir::cast<IntegerAttr>(e).getValue() != 1;
});
}
bool IsBroadcastableElementsAttrs(mlir::TypedAttr a, mlir::TypedAttr b) {
// This would return false if we had unranked tensors (where they should
// probably be considered as broadcastable), but given we are working with
// attributes here that shouldn't be an issue,
return OpTrait::util::getBroadcastedType(a.getType(), b.getType()) != Type();
}
bool IsDimensionsDegenerateExceptLastOne(ArrayRef<int64_t> elements_shape) {
if (elements_shape.empty()) return true;
for (auto dim : elements_shape.drop_back(1)) {
if (dim != 1) return false;
}
return true;
}
bool IsDimensionsDegenerateExceptLastOne(TypedAttr val) {
if (auto ranked_type = mlir::dyn_cast<RankedTensorType>(val.getType())) {
return IsDimensionsDegenerateExceptLastOne(ranked_type.getShape());
}
return false;
}
} // namespace TF
} // namespace mlir
+126
View File
@@ -0,0 +1,126 @@
/* Copyright 2019 The TensorFlow 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.
==============================================================================*/
// This header file defines common validators used by TFLite transformation
// passes to validate op attributes or values.
#ifndef TENSORFLOW_COMPILER_MLIR_UTILS_VALIDATORS_H_
#define TENSORFLOW_COMPILER_MLIR_UTILS_VALIDATORS_H_
#include <cstdint>
#include "mlir/Dialect/Func/IR/FuncOps.h" // from @llvm-project
#include "mlir/IR/Attributes.h" // from @llvm-project
#include "mlir/IR/BuiltinAttributeInterfaces.h" // from @llvm-project
#include "mlir/IR/BuiltinAttributes.h" // from @llvm-project
#include "mlir/IR/BuiltinTypes.h" // from @llvm-project
#include "mlir/IR/Operation.h" // from @llvm-project
#include "mlir/IR/Value.h" // from @llvm-project
#include "mlir/Support/LLVM.h" // from @llvm-project
namespace mlir {
namespace TF {
// TODO(jpienaar): Change these to being one of these variants and/or generate
// these predicates.
// Returns true if the given TensorFlow op does not have a `data_format`
// attribute (then default to "NHWC"), or its `data_format` attribute is "NHWC".
inline bool TFDataFormatIsNHWC(Operation *op) {
auto attr = op->getAttrOfType<StringAttr>("data_format");
return !attr || attr.getValue() == "NHWC";
}
// Returns true if the given TensorFlow op does not have a `data_format`
// attribute (then default to "NDHWC"), or its `data_format` attribute is
// "NDHWC".
inline bool TFDataFormatIsNDHWC(Operation *op) {
auto attr = op->getAttrOfType<StringAttr>("data_format");
return !attr || attr.getValue() == "NDHWC";
}
// Returns true if the given `op`
// * has an attribute with the given `name`,
// * and the attribute is an integer list of the form [1, X, Y, 1],
// and writes X, Y as 32-bit integer attribute to `x`, `y`.
bool TFIntListIs1XY1(Operation *op, StringRef name, IntegerAttr *x,
IntegerAttr *y);
// Returns true if the attribute is an integer list of the form [1, X, Y, 1].
bool TFIntListIs1XY1(Attribute attr);
// Returns true if the attribute is an integer list of the form [1, 1, X, Y].
bool TFIntListIs11XY(Attribute attr);
// Returns true if the given `op`
// * has an attribute with the given `name`,
// * and the attribute is an integer list of the form [1, X, Y, Z, 1],
// and writes X, Y as 32-bit integer attribute to `x`, `y`, z.
bool TFIntListIs1XYZ1(Operation *op, StringRef name, IntegerAttr *x,
IntegerAttr *y, IntegerAttr *z);
// Returns true if every element of the attribute is 1. All elements of `attr`
// must be `IntegerAttr`.
bool TFIntListIsAllOnes(Attribute attr);
// Returns true iff the given value is a float32 tensor.
// is "DT_FLOAT".
inline bool TFTypeIsFloat32Tensor(Value value) {
auto tensorType = mlir::dyn_cast<TensorType>(value.getType());
if (!tensorType) return false;
return tensorType.getElementType().isF32();
}
// Returns true iff the given value is a bf16 tensor.
inline bool TFTypeIsBFloat16Tensor(Value value) {
auto tensorType = mlir::dyn_cast<TensorType>(value.getType());
if (!tensorType) return false;
return tensorType.getElementType().isBF16();
}
// Returns true iff the given value is a f16 tensor.
inline bool TFTypeIsHalfTensor(Value value) {
auto tensorType = mlir::dyn_cast<TensorType>(value.getType());
if (!tensorType) return false;
return tensorType.getElementType().isF16();
}
// Returns true iff the given value is a f16 or bf16 tensor.
inline bool TFTypeIsBFloat16OrHalfTensor(Value value) {
return TFTypeIsBFloat16Tensor(value) || TFTypeIsHalfTensor(value);
}
// Returns true iff the given TensorFlow op has a `padding` attribute whose
// value is "SAME" or "VALID", and writes the attribute to `padding`.
inline bool TFPaddingIsSameOrValid(Operation *op, StringAttr *padding) {
auto padding_attr = op->getAttrOfType<StringAttr>("padding");
if (padding_attr.getValue() != "SAME" && padding_attr.getValue() != "VALID")
return false;
*padding = padding_attr;
return true;
}
/// Returns whether the given `a` and `b` have broadcast-compatible
/// types.
bool IsBroadcastableElementsAttrs(mlir::TypedAttr a, mlir::TypedAttr b);
// Returns true if every dimension of the attribute is 1 except the last one.
bool IsDimensionsDegenerateExceptLastOne(mlir::TypedAttr val);
// Returns true if every element is 1 except the last one.
bool IsDimensionsDegenerateExceptLastOne(ArrayRef<int64_t> elements_shape);
} // end namespace TF
} // end namespace mlir
#endif // TENSORFLOW_COMPILER_MLIR_UTILS_VALIDATORS_H_