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_TENSORFLOW_IR_TF_TRAITS_H_
#define TENSORFLOW_COMPILER_MLIR_TENSORFLOW_IR_TF_TRAITS_H_
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/OpDefinition.h"
#include "mlir/IR/TypeUtilities.h"
#include "mlir/Interfaces/SideEffectInterfaces.h"
#include "mlir/Support/LogicalResult.h"
#include "tf_types.h"
namespace mlir {
namespace OpTrait {
namespace TF {
static inline LogicalResult VerifyRefTypeMatch(mlir::Type type,
mlir::Type maybe_ref_type)
{
if (auto ref_type = maybe_ref_type.dyn_cast<mlir::TF::TensorFlowRefType>())
return success(ref_type.RemoveRef().getTypeID() == type.getTypeID());
return failure();
}
template<typename ConcreteType>
class OperandsSameAsResultsTypeOrRef
: public TraitBase<ConcreteType, OperandsSameAsResultsTypeOrRef>
{
public:
static LogicalResult verifyTrait(Operation* op)
{
LogicalResult shapeMatch = impl::verifySameOperandsAndResultShape(op);
if (failed(shapeMatch)) return shapeMatch;
Type type = op->getResult(0).getType();
for (auto result_type : llvm::drop_begin(op->getResultTypes(), 1))
{
if (!mlir::TF::HasCompatibleElementTypes(type, result_type))
return op->emitOpError()
<< "requires all return types to have compatible element types";
}
for (auto operand_type : op->getOperandTypes())
{
if (!mlir::TF::HasCompatibleElementTypes(
operand_type, type, true))
return op->emitError() << "requires all operands and results to have "
"compatible element types";
}
return success();
}
};
namespace detail {
inline LogicalResult verifySameOperandsAndResultElementTypeResolveRef(
Operation* op)
{
Type element_type;
if (op->getNumResults() > 0)
{
element_type = mlir::TF::GetElementTypeOrSelfResolveRef(op->getResult(0).getType());
}
else if (op->getNumOperands() > 0)
{
element_type = mlir::TF::GetElementTypeOrSelfResolveRef(op->getOperand(0).getType());
}
else
{
return success();
}
for (const auto& result_type : op->getResultTypes())
{
if (mlir::TF::GetElementTypeOrSelfResolveRef(result_type) != element_type)
{
return op->emitOpError(
"requires compatible element types for all operands and results");
}
}
for (const auto& operand_type : op->getOperandTypes())
{
if (mlir::TF::GetElementTypeOrSelfResolveRef(operand_type) != element_type)
{
return op->emitOpError(
"requires compatible element types for all operands and results");
}
}
return success();
}
}
template<typename ConcreteType>
class SameOperandsAndResultElementTypeResolveRef
: public TraitBase<ConcreteType,
SameOperandsAndResultElementTypeResolveRef>
{
public:
static LogicalResult verifyTrait(Operation* op)
{
return detail::verifySameOperandsAndResultElementTypeResolveRef(op);
}
};
template<typename ConcreteType>
class SameOperandsAndResultTypeResolveRef
: public TraitBase<ConcreteType, SameOperandsAndResultTypeResolveRef>
{
public:
static LogicalResult verifyTrait(Operation* op)
{
if (failed(impl::verifySameOperandsAndResultShape(op))) return failure();
return detail::verifySameOperandsAndResultElementTypeResolveRef(op);
}
};
template<typename ConcreteType>
class LayoutAgnostic : public TraitBase<ConcreteType, LayoutAgnostic>
{
};
template<typename ConcreteType>
class CannotDuplicate : public TraitBase<ConcreteType, CannotDuplicate>
{
public:
static LogicalResult verifyTrait(Operation* op)
{
if (MemoryEffectOpInterface::hasNoEffect(op))
return op->emitError(
"operations with no side effects cannot have CannotDuplicate trait");
return success();
}
};
template<typename ConcreteType>
class NoConstantFold : public TraitBase<ConcreteType, NoConstantFold>
{
};
template<typename ConcreteType>
class CwiseBinary : public TraitBase<ConcreteType, CwiseBinary>
{
};
template<typename ConcreteType>
class CwiseUnary : public TraitBase<ConcreteType, CwiseUnary>
{
};
}
}
}
#endif