tvm
target_kind.h
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 
24 #ifndef TVM_TARGET_TARGET_KIND_H_
25 #define TVM_TARGET_TARGET_KIND_H_
26 
27 #include <tvm/ffi/function.h>
28 #include <tvm/ffi/reflection/registry.h>
30 #include <tvm/node/node.h>
31 
32 #include <memory>
33 #include <unordered_map>
34 #include <utility>
35 #include <vector>
36 
37 namespace tvm {
38 
39 class Target;
40 
44 using TargetFeatures = ffi::Map<ffi::String, ffi::Any>;
45 
53 using TargetJSON = ffi::Map<ffi::String, ffi::Any>;
54 using FTVMTargetParser = ffi::TypedFunction<TargetJSON(TargetJSON)>;
55 
56 namespace detail {
57 template <typename, typename, typename>
58 struct ValueTypeInfoMaker;
59 }
60 
61 class TargetInternal;
62 
63 template <typename>
64 class TargetKindAttrMap;
65 
67 class TargetKindNode : public Object {
68  public:
70  ffi::String name;
74  ffi::Array<ffi::String> default_keys;
79 
80  static void RegisterReflection() {
81  namespace refl = tvm::ffi::reflection;
82  refl::ObjectDef<TargetKindNode>()
83  .def_ro("name", &TargetKindNode::name)
84  .def_ro("default_device_type", &TargetKindNode::default_device_type,
85  refl::AttachFieldFlag::SEqHashIgnore())
86  .def_ro("default_keys", &TargetKindNode::default_keys,
87  refl::AttachFieldFlag::SEqHashIgnore());
88  }
89 
90  static constexpr TVMFFISEqHashKind _type_s_eq_hash_kind = kTVMFFISEqHashKindUniqueInstance;
91  TVM_FFI_DECLARE_OBJECT_INFO_FINAL("target.TargetKind", TargetKindNode, Object);
92 
93  private:
95  uint32_t AttrRegistryIndex() const { return index_; }
97  ffi::String AttrRegistryName() const { return name; }
99  struct ValueTypeInfo {
100  ffi::String type_key;
101  int32_t type_index;
102  std::unique_ptr<ValueTypeInfo> key;
103  std::unique_ptr<ValueTypeInfo> val;
104  };
106  std::unordered_map<ffi::String, ValueTypeInfo> key2vtype_;
108  std::unordered_map<ffi::String, ffi::Any> key2default_;
110  uint32_t index_;
111 
112  template <typename, typename, typename>
114  template <typename, typename>
115  friend class AttrRegistry;
116  template <typename>
118  friend class TargetKindRegEntry;
119  friend class TargetInternal;
120 };
121 
126 class TargetKind : public ObjectRef {
127  public:
128  TargetKind() = default;
129  explicit TargetKind(ObjectPtr<TargetKindNode> data) : ObjectRef(data) {
130  TVM_FFI_ICHECK(data != nullptr);
131  }
133  template <typename ValueType>
134  static inline TargetKindAttrMap<ValueType> GetAttrMap(const ffi::String& attr_name);
140  TVM_DLL static ffi::Optional<TargetKind> Get(const ffi::String& target_kind_name);
142  TargetKindNode* operator->() { return static_cast<TargetKindNode*>(data_.get()); }
143 
145 
146  private:
147  TVM_DLL static const AttrRegistryMapContainerMap<TargetKind>& GetAttrMapContainer(
148  const ffi::String& attr_name);
149  friend class TargetKindRegEntry;
150  friend class TargetInternal;
151 };
152 
157 template <typename ValueType>
158 class TargetKindAttrMap : public AttrRegistryMap<TargetKind, ValueType> {
159  public:
161  using TParent::count;
162  using TParent::get;
163  using TParent::operator[];
165 };
166 
168 static constexpr const char* kTvmRuntimeCpp = "c++";
169 
171 static constexpr const char* kTvmRuntimeCrt = "c";
172 
178  public:
192  template <typename ValueType>
193  inline TargetKindRegEntry& set_attr(const ffi::String& attr_name, const ValueType& value,
194  int plevel = 10);
204  inline TargetKindRegEntry& set_default_keys(std::vector<ffi::String> keys);
210  template <typename FLambda>
211  inline TargetKindRegEntry& set_attrs_preprocessor(FLambda f);
222  template <typename ValueType>
223  inline TargetKindRegEntry& add_attr_option(const ffi::String& key);
230  template <typename ValueType>
231  inline TargetKindRegEntry& add_attr_option(const ffi::String& key, ffi::Any default_value);
233  inline TargetKindRegEntry& set_name();
238  TVM_DLL static ffi::Array<ffi::String> ListTargetKinds();
243  TVM_DLL static ffi::Map<ffi::String, ffi::String> ListTargetKindOptions(const TargetKind& kind);
244 
250  TVM_DLL static TargetKindRegEntry& RegisterOrGet(const ffi::String& target_kind_name);
251 
252  private:
253  TargetKind kind_;
254  ffi::String name;
255 
257  explicit TargetKindRegEntry(uint32_t reg_index) : kind_(ffi::make_object<TargetKindNode>()) {
258  kind_->index_ = reg_index;
259  }
266  TVM_DLL void UpdateAttr(const ffi::String& key, ffi::Any value, int plevel);
267  template <typename, typename>
268  friend class AttrRegistry;
269  friend class TargetKind;
270 };
271 
272 namespace detail {
273 template <typename Type, template <typename...> class Container>
274 struct is_specialized : std::false_type {
275  using type = std::false_type;
276 };
277 
278 template <template <typename...> class Container, typename... Args>
279 struct is_specialized<Container<Args...>, Container> : std::true_type {
280  using type = std::true_type;
281 };
282 
283 template <typename ValueType,
284  typename IsArray = typename is_specialized<ValueType, ffi::Array>::type,
285  typename IsMap = typename is_specialized<ValueType, ffi::Map>::type>
287 
288 template <typename ValueType>
289 struct ValueTypeInfoMaker<ValueType, std::false_type, std::false_type> {
290  using ValueTypeInfo = TargetKindNode::ValueTypeInfo;
291 
292  ValueTypeInfo operator()() const {
293  ValueTypeInfo info;
294  info.key = nullptr;
295  info.val = nullptr;
296  if constexpr (std::is_base_of_v<ObjectRef, ValueType>) {
297  int32_t tindex = ffi::TypeToRuntimeTypeIndex<ValueType>::v();
298  info.type_index = tindex;
299  info.type_key = runtime::Object::TypeIndex2Key(tindex);
300  return info;
301  } else if constexpr (std::is_same_v<ValueType, ffi::String>) {
302  // special handle string since it can be backed by multiple types.
303  info.type_index = ffi::TypeIndex::kTVMFFIStr;
304  info.type_key = ffi::TypeTraits<ValueType>::TypeStr();
305  return info;
306  } else {
307  // TODO(tqchen) consider upgrade to leverage any system to support union type
308  constexpr int32_t tindex = ffi::TypeToFieldStaticTypeIndex<ValueType>::value;
309  static_assert(tindex != ffi::TypeIndex::kTVMFFIAny, "Do not support union type for now");
310  info.type_index = tindex;
311  info.type_key = runtime::Object::TypeIndex2Key(tindex);
312  return info;
313  }
314  }
315 };
316 
317 template <typename ValueType>
318 struct ValueTypeInfoMaker<ValueType, std::true_type, std::false_type> {
319  using ValueTypeInfo = TargetKindNode::ValueTypeInfo;
320 
321  ValueTypeInfo operator()() const {
322  using key_type = ValueTypeInfoMaker<typename ValueType::value_type>;
323  uint32_t tindex = ValueType::ContainerType::_GetOrAllocRuntimeTypeIndex();
324  ValueTypeInfo info;
325  info.type_index = tindex;
326  info.type_key = runtime::Object::TypeIndex2Key(tindex);
327  info.key = std::make_unique<ValueTypeInfo>(key_type()());
328  info.val = nullptr;
329  return info;
330  }
331 };
332 
333 template <typename ValueType>
334 struct ValueTypeInfoMaker<ValueType, std::false_type, std::true_type> {
335  using ValueTypeInfo = TargetKindNode::ValueTypeInfo;
336  ValueTypeInfo operator()() const {
337  using key_type = ValueTypeInfoMaker<typename ValueType::key_type>;
338  using val_type = ValueTypeInfoMaker<typename ValueType::mapped_type>;
339  uint32_t tindex = ValueType::ContainerType::_GetOrAllocRuntimeTypeIndex();
340  ValueTypeInfo info;
341  info.type_index = tindex;
342  info.type_key = runtime::Object::TypeIndex2Key(tindex);
343  info.key = std::make_unique<ValueTypeInfo>(key_type()());
344  info.val = std::make_unique<ValueTypeInfo>(val_type()());
345  return info;
346  }
347 };
348 
349 } // namespace detail
350 
351 template <typename ValueType>
352 inline TargetKindAttrMap<ValueType> TargetKind::GetAttrMap(const ffi::String& attr_name) {
353  return TargetKindAttrMap<ValueType>(GetAttrMapContainer(attr_name));
354 }
355 
356 template <typename ValueType>
357 inline TargetKindRegEntry& TargetKindRegEntry::set_attr(const ffi::String& attr_name,
358  const ValueType& value, int plevel) {
359  ICHECK_GT(plevel, 0) << "plevel in set_attr must be greater than 0";
360  ffi::Any rv;
361  rv = value;
362  UpdateAttr(attr_name, rv, plevel);
363  return *this;
364 }
365 
368  return *this;
369 }
370 
371 inline TargetKindRegEntry& TargetKindRegEntry::set_default_keys(std::vector<ffi::String> keys) {
372  kind_->default_keys = keys;
373  return *this;
374 }
375 
376 template <typename FLambda>
378  LOG(WARNING) << "set_attrs_preprocessor is deprecated please use set_target_parser instead";
379  kind_->preprocessor = ffi::Function::FromTyped(std::move(f));
380  return *this;
381 }
382 
384  kind_->target_parser = parser;
385  return *this;
386 }
387 
388 template <typename ValueType>
390  ICHECK(!kind_->key2vtype_.count(key))
391  << "AttributeError: add_attr_option failed because '" << key << "' has been set once";
392  kind_->key2vtype_[key] = detail::ValueTypeInfoMaker<ValueType>()();
393  return *this;
394 }
395 
396 template <typename ValueType>
398  Any default_value) {
399  add_attr_option<ValueType>(key);
400  kind_->key2default_[key] = default_value;
401  return *this;
402 }
403 
405  if (kind_->name.empty()) {
406  kind_->name = name;
407  }
408  return *this;
409 }
410 
411 #define TVM_TARGET_KIND_REGISTER_VAR_DEF \
412  static DMLC_ATTRIBUTE_UNUSED ::tvm::TargetKindRegEntry& __make_##TargetKind
413 
431 #define TVM_REGISTER_TARGET_KIND(TargetKindName, DeviceType) \
432  TVM_STR_CONCAT(TVM_TARGET_KIND_REGISTER_VAR_DEF, __COUNTER__) = \
433  ::tvm::TargetKindRegEntry::RegisterOrGet(TargetKindName) \
434  .set_name() \
435  .set_default_device_type(DeviceType) \
436  .add_attr_option<ffi::Array<ffi::String>>("keys") \
437  .add_attr_option<ffi::String>("tag") \
438  .add_attr_option<ffi::String>("device") \
439  .add_attr_option<ffi::String>("model") \
440  .add_attr_option<ffi::Array<ffi::String>>("libs") \
441  .add_attr_option<Target>("host") \
442  .add_attr_option<int64_t>("from_device") \
443  .add_attr_option<int64_t>("target_device_type")
444 
445 } // namespace tvm
446 
447 #endif // TVM_TARGET_TARGET_KIND_H_
Attribute map used in registry.
Generic attribute map.
Definition: attr_registry_map.h:38
ffi::Map<Key, ValueType> used to store meta-data.
Definition: attr_registry_map.h:105
ValueType get(const TargetKind &key, ValueType def_value) const
get the corresponding value element at key with default value.
Definition: attr_registry_map.h:136
int count(const TargetKind &key) const
Check if the map has op as key.
Definition: attr_registry_map.h:117
Definition: instruction.h:30
ffi::Map<TargetKind, ValueType> used to store meta-information about TargetKind
Definition: target_kind.h:158
TargetKindAttrMap(const AttrRegistryMapContainerMap< TargetKind > &map)
Definition: target_kind.h:164
Target kind, specifies the kind of the target.
Definition: target_kind.h:67
int default_device_type
Device type of target kind.
Definition: target_kind.h:72
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("target.TargetKind", TargetKindNode, Object)
FTVMTargetParser target_parser
Function used to parse a JSON target during creation.
Definition: target_kind.h:78
friend class TargetInternal
Definition: target_kind.h:119
ffi::String name
Name of the target kind.
Definition: target_kind.h:70
ffi::Array< ffi::String > default_keys
Default keys of the target.
Definition: target_kind.h:74
static void RegisterReflection()
Definition: target_kind.h:80
static constexpr TVMFFISEqHashKind _type_s_eq_hash_kind
Definition: target_kind.h:90
ffi::Function preprocessor
Function used to preprocess on target creation.
Definition: target_kind.h:76
Helper structure to register TargetKind.
Definition: target_kind.h:177
TargetKindRegEntry & set_attrs_preprocessor(FLambda f)
Set the pre-processing function applied upon target creation.
Definition: target_kind.h:377
TargetKindRegEntry & set_target_parser(FTVMTargetParser parser)
Set the parsing function applied upon target creation.
Definition: target_kind.h:383
TargetKindRegEntry & add_attr_option(const ffi::String &key)
Register a valid configuration option and its ValueType for validation.
Definition: target_kind.h:389
TargetKindRegEntry & set_name()
Set name of the TargetKind to be the same as registry if it is empty.
Definition: target_kind.h:404
static ffi::Map< ffi::String, ffi::String > ListTargetKindOptions(const TargetKind &kind)
Get all supported option names and types for a given Target kind.
TargetKindRegEntry & set_default_keys(std::vector< ffi::String > keys)
Set DLPack's device_type the target.
Definition: target_kind.h:371
static TargetKindRegEntry & RegisterOrGet(const ffi::String &target_kind_name)
Register or get a new entry.
static ffi::Array< ffi::String > ListTargetKinds()
List all the entry names in the registry.
TargetKindRegEntry & set_default_device_type(int device_type)
Set DLPack's device_type the target.
Definition: target_kind.h:366
TargetKindRegEntry & add_attr_option(const ffi::String &key, ffi::Any default_value)
Register a valid configuration option and its ValueType for validation.
TargetKindRegEntry & set_attr(const ffi::String &attr_name, const ValueType &value, int plevel=10)
Register additional attributes to target_kind.
Definition: target_kind.h:357
Managed reference class to TargetKindNode.
Definition: target_kind.h:126
TargetKind(ObjectPtr< TargetKindNode > data)
Definition: target_kind.h:129
friend class TargetInternal
Definition: target_kind.h:150
static TargetKindAttrMap< ValueType > GetAttrMap(const ffi::String &attr_name)
Get the attribute map given the attribute name.
Definition: target_kind.h:352
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(TargetKind, ObjectRef, TargetKindNode)
TargetKindNode * operator->()
Mutable access to the container class
Definition: target_kind.h:142
TargetKind()=default
static ffi::Optional< TargetKind > Get(const ffi::String &target_kind_name)
Retrieve the TargetKind given its name.
Managed reference to TypeNode.
Definition: type.h:100
Definition: repr_printer.h:91
tvm::relax::Function Function
Definition: transform.h:42
constexpr const char * device_type
The device type.
Definition: stmt.h:1063
Performance counters for profiling via the PAPI library.
Definition: analyzer.h:37
ffi::Map< ffi::String, ffi::Any > TargetFeatures
Map containing parsed features of a specific Target.
Definition: target_kind.h:44
ffi::TypedFunction< TargetJSON(TargetJSON)> FTVMTargetParser
Definition: target_kind.h:54
ffi::Map< ffi::String, ffi::Any > TargetJSON
TargetParser to apply on instantiation of a given TargetKind.
Definition: target_kind.h:53
Definitions and helper macros for IR/AST nodes.
Definition: target_kind.h:286
std::true_type type
Definition: target_kind.h:280
Definition: target_kind.h:274
std::false_type type
Definition: target_kind.h:275