257 lines
6.7 KiB
C++
257 lines
6.7 KiB
C++
/*
|
|
* Licensed to the Apache Software Foundation (ASF) under one
|
|
* or more contributor license agreements. See the NOTICE file
|
|
* distributed with this work for additional information
|
|
* regarding copyright ownership. The ASF licenses this file
|
|
* to you 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.
|
|
*/
|
|
|
|
/*!
|
|
* \file tvm/ir/function.h
|
|
* \brief Function nodes.
|
|
*/
|
|
#ifndef TVM_IR_FUNCTION_H_
|
|
#define TVM_IR_FUNCTION_H_
|
|
|
|
#include <tvm/ffi/container/array.h>
|
|
#include <tvm/ffi/container/map.h>
|
|
#include <tvm/ffi/string.h>
|
|
#include <tvm/ir/attrs.h>
|
|
#include <tvm/ir/expr.h>
|
|
|
|
#include <string>
|
|
#include <type_traits>
|
|
|
|
namespace tvm {
|
|
|
|
/*!
|
|
* \brief Possible Calling conventions.
|
|
*
|
|
* NOTE: The calling convention also implies
|
|
* the way we implement the function during lowering.
|
|
*/
|
|
enum class CallingConv : int {
|
|
/*!
|
|
* \brief Default calling convention.
|
|
*
|
|
* - Uses the native calling convention of the target.
|
|
* - Implementation: specified by the native target.
|
|
*/
|
|
kDefault = 0,
|
|
/*!
|
|
* \brief ffi::Function that exposes a Cffi::Function signature.
|
|
*
|
|
* - Calling by ffi::Function calling convention.
|
|
* - Implementation: Expose a function with the Cffi::Function signature.
|
|
*/
|
|
kCPackedFunc = 1,
|
|
/*!
|
|
* \brief Device kernel launch
|
|
*
|
|
* - Call by ffi::Function calling convention.
|
|
* - Implementation: defined by device runtime(e.g. runtime/cuda)
|
|
*/
|
|
kDeviceKernelLaunch = 2,
|
|
};
|
|
|
|
/*!
|
|
* \brief Supported linkage types.
|
|
*/
|
|
enum class LinkageType : int {
|
|
/*!
|
|
* \brief Internal linkage.
|
|
*/
|
|
kInternal = 0,
|
|
/*!
|
|
* \brief External linkage.
|
|
- Function with external linkage should have a global symbol attached to it.
|
|
*/
|
|
kExternal = 1
|
|
};
|
|
|
|
/*!
|
|
* \brief Generic attribute names that can be attached to any function.
|
|
*
|
|
* \sa tvm::tirx::attr, tvm::relax::attr
|
|
*/
|
|
namespace attr {
|
|
/*!
|
|
* \brief Indicates the special calling convention.
|
|
*
|
|
* Type: IntImm
|
|
*
|
|
* \sa tvm::CallingConv
|
|
*/
|
|
constexpr const char* kCallingConv = "calling_conv";
|
|
|
|
/*!
|
|
* \brief Compilation target of the function.
|
|
*
|
|
* Type: Target
|
|
*
|
|
* \sa tvm::Target
|
|
*/
|
|
constexpr const char* kTarget = "target";
|
|
|
|
/*!
|
|
* \brief Global linker symbol of the function in generated code.
|
|
*
|
|
* This option forces the code generator to name the
|
|
* function with the given.
|
|
*
|
|
* For example, we could set a global_symbol of a function
|
|
* early to make sure that we can always refer to it by
|
|
* the symbol name in the generated DLL.
|
|
*
|
|
* We should not set the attribute for local functions,
|
|
* so that the compiler can freely rename them.
|
|
*
|
|
* A unique global symbol will be automatically assigned
|
|
* to each function in the module before the target code
|
|
* generation phase.
|
|
*
|
|
* Type: String
|
|
*/
|
|
constexpr const char* kGlobalSymbol = "global_symbol";
|
|
|
|
/*!
|
|
* \brief The function uses s_tir (apache-derived TIR) semantics:
|
|
* parser fills layout=None, ScriptComplete wraps body in a root SBlock,
|
|
* and printer emits `s_tir=True` on the decorator.
|
|
* Default (attr absent or False) is tirx semantics.
|
|
*
|
|
* Type: IntImm (bool dtype)
|
|
*/
|
|
constexpr const char* kSTir = "s_tir";
|
|
|
|
/*!
|
|
* \brief Number of inputs of the Primfunc
|
|
*
|
|
* Type: Int
|
|
*/
|
|
constexpr const char* kNumInputs = "num_inputs";
|
|
|
|
} // namespace attr
|
|
|
|
/*!
|
|
* \brief Base node of all functions.
|
|
*
|
|
* We support several variants of functions throughout the stack.
|
|
* All of the functions share the same type system
|
|
* to support cross variant calls.
|
|
*
|
|
* \sa BaseFunc
|
|
*/
|
|
class BaseFuncNode : public ExprNode {
|
|
public:
|
|
/*! \brief Additional attributes storing the meta-data */
|
|
DictAttrs attrs;
|
|
|
|
/*!
|
|
* \brief Get a function attribute.
|
|
*
|
|
* \param attr_key The attribute key.
|
|
* \param default_value The default value if the key does not exist, defaults to nullptr.
|
|
*
|
|
* \return The result
|
|
*
|
|
* \tparam TOBjectRef the expected object type.
|
|
* \throw Error if the key exists but the value does not match TObjectRef
|
|
*
|
|
* \code
|
|
*
|
|
* void GetAttrExample(const BaseFunc& f) {
|
|
* auto value = f->GetAttr<int64_t>("AttrKey", 0);
|
|
* }
|
|
*
|
|
* \endcode
|
|
*/
|
|
template <typename TObjectRef>
|
|
ffi::Optional<TObjectRef> GetAttr(const std::string& attr_key,
|
|
ffi::Optional<TObjectRef> default_value = std::nullopt) const {
|
|
return attrs.GetAttr(attr_key, default_value);
|
|
}
|
|
// variant that uses TObjectRef to enable implicit conversion to default value.
|
|
template <typename TObjectRef>
|
|
ffi::Optional<TObjectRef> GetAttr(const std::string& attr_key, TObjectRef default_value) const {
|
|
return GetAttr<TObjectRef>(attr_key, ffi::Optional<TObjectRef>(default_value));
|
|
}
|
|
|
|
/*!
|
|
* \brief Check whether the function has an non-zero integer attr.
|
|
*
|
|
* This function can be used to check whether an optional
|
|
* attribute mark(e.g. inline) exists.
|
|
*
|
|
* \param attr_key The key to the attribute.
|
|
* \return The check result.
|
|
*
|
|
* \code
|
|
*
|
|
* void HasNonzeroAttrExample(const BaseFunc& f) {
|
|
* if (f->HasNonzeroAttr(attr::kInline)) {
|
|
* // inline the function.
|
|
* }
|
|
* }
|
|
*
|
|
* \endcode
|
|
*/
|
|
bool HasNonzeroAttr(const std::string& attr_key) const { return attrs.HasNonzeroAttr(attr_key); }
|
|
/*!
|
|
* \brief Get the type of the linkage.
|
|
*
|
|
* Currently, we only consider external/internal linkage.
|
|
* This can be extended in the future when necessary.
|
|
*
|
|
* \return Linkage type.
|
|
*
|
|
* \code
|
|
*
|
|
* void Example(const BaseFunc& f) {
|
|
* if (f->GetLinkageType() == tvm::LinkageType::kExternal) {
|
|
* // Do not remove a function with external linkage
|
|
* }
|
|
* }
|
|
*
|
|
* \endcode
|
|
*/
|
|
|
|
LinkageType GetLinkageType() const {
|
|
if (GetAttr<ffi::String>(attr::kGlobalSymbol))
|
|
return LinkageType::kExternal;
|
|
else
|
|
return LinkageType::kInternal;
|
|
}
|
|
|
|
static void RegisterReflection() {
|
|
namespace refl = tvm::ffi::reflection;
|
|
refl::ObjectDef<BaseFuncNode>().def_ro("attrs", &BaseFuncNode::attrs);
|
|
}
|
|
|
|
static constexpr const uint32_t _type_child_slots = 2;
|
|
TVM_FFI_DECLARE_OBJECT_INFO("ir.BaseFunc", BaseFuncNode, ExprNode);
|
|
};
|
|
|
|
/*!
|
|
* \brief Managed reference to BaseFuncNode.
|
|
* \sa BaseFuncNode
|
|
*/
|
|
class BaseFunc : public Expr {
|
|
public:
|
|
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(BaseFunc, Expr, BaseFuncNode);
|
|
};
|
|
|
|
} // namespace tvm
|
|
#endif // TVM_IR_FUNCTION_H_
|