2424#ifndef TVM_TARGET_TARGET_KIND_H_
2525#define TVM_TARGET_TARGET_KIND_H_
2626
27+ #include < tvm/ffi/container/map.h>
2728#include < tvm/ffi/function.h>
2829#include < tvm/ffi/reflection/registry.h>
29- #include < tvm/ir/attr_registry_map.h>
3030#include < tvm/ir/config_schema.h>
3131#include < tvm/runtime/base.h>
3232
33- #include < memory>
34- #include < unordered_map>
3533#include < utility>
3634#include < vector>
3735
@@ -50,9 +48,6 @@ using FTargetCanonicalizer =
5048
5149class TargetInternal ;
5250
53- template <typename >
54- class TargetKindAttrMap ;
55-
5651/* ! \brief Target kind, specifies the kind of the target */
5752class TargetKindNode : public ffi ::Object {
5853 public:
@@ -79,20 +74,10 @@ class TargetKindNode : public ffi::Object {
7974 TVM_FFI_DECLARE_OBJECT_INFO_FINAL (" target.TargetKind" , TargetKindNode, ffi::Object);
8075
8176 private:
82- /* ! \brief Return the index stored in attr registry */
83- uint32_t AttrRegistryIndex () const { return index_; }
84- /* ! \brief Return the name stored in attr registry */
85- ffi::String AttrRegistryName () const { return name; }
8677 /* ! \brief ConfigSchema for validating and resolving target attributes */
8778 ir::ConfigSchema schema_;
88- /* ! \brief Index used for internal lookup of attribute registry */
89- uint32_t index_;
90-
91- template <typename , typename >
92- friend class AttrRegistry ;
93- template <typename >
94- friend class AttrRegistryMapContainerMap ;
95- friend class TargetKindRegEntry ;
79+ friend class TargetKindRegistry ;
80+ friend class TargetKindDef ;
9681 friend class TargetInternal ;
9782};
9883
@@ -106,13 +91,10 @@ class TargetKind : public ffi::ObjectRef {
10691 explicit TargetKind (ffi::ObjectPtr<TargetKindNode> data) : ffi::ObjectRef(data) {
10792 TVM_FFI_ICHECK (data != nullptr );
10893 }
109- /* ! \brief Get the attribute map given the attribute name */
110- template <typename ValueType>
111- static inline TargetKindAttrMap<ValueType> GetAttrMap (const ffi::String& attr_name);
11294 /* !
11395 * \brief Retrieve the TargetKind given its name
11496 * \param target_kind_name Name of the target kind
115- * \return The TargetKind requested
97+ * \return The canonical kind, or nullopt when the name is unknown.
11698 */
11799 TVM_DLL static ffi::Optional<TargetKind> Get (const ffi::String& target_kind_name);
118100 /* ! \brief Mutable access to the container class */
@@ -121,198 +103,121 @@ class TargetKind : public ffi::ObjectRef {
121103 TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE (TargetKind, ffi::ObjectRef, TargetKindNode);
122104
123105 private:
124- TVM_DLL static const AttrRegistryMapContainerMap<TargetKind>& GetAttrMapContainer (
125- const ffi::String& attr_name);
126- friend class TargetKindRegEntry ;
127106 friend class TargetInternal ;
128107};
129108
130- /* !
131- * \brief ffi::Map<TargetKind, ValueType> used to store meta-information about TargetKind
132- * \tparam ValueType The type of the value stored in map
133- */
134- template <typename ValueType>
135- class TargetKindAttrMap : public AttrRegistryMap <TargetKind, ValueType> {
136- public:
137- using TParent = AttrRegistryMap<TargetKind, ValueType>;
138- using TParent::count;
139- using TParent::get;
140- using TParent::operator [];
141- explicit TargetKindAttrMap (const AttrRegistryMapContainerMap<TargetKind>& map) : TParent(map) {}
142- };
143-
144109/* ! \brief Value used with --runtime in target specs to indicate the C++ runtime. */
145110static constexpr const char * kTvmRuntimeCpp = " c++" ;
146111
147112/* ! \brief Value used with --runtime in target specs to indicate the C runtime. */
148113static constexpr const char * kTvmRuntimeCrt = " c" ;
149114
150115/* !
151- * \brief Helper structure to register TargetKind
152- * \sa TVM_REGISTER_TARGET_KIND
116+ * \brief Process-wide registry of canonical target kinds, keyed by name.
153117 */
154- class TargetKindRegEntry {
118+ class TargetKindRegistry {
155119 public:
156120 /* !
157- * \brief Register additional attributes to target_kind.
158- * \param attr_name The name of the attribute.
159- * \param value The value to be set.
160- * \param plevel The priority level of this attribute,
161- * an higher priority level attribute
162- * will replace lower priority level attribute.
163- * Must be bigger than 0.
164- *
165- * Cannot set with same plevel twice in the code.
166- *
167- * \tparam ValueType The type of the value to be set.
121+ * \brief Access the process-wide registry.
122+ * \return The singleton registry.
168123 */
169- template <typename ValueType>
170- inline TargetKindRegEntry& set_attr (const ffi::String& attr_name, const ValueType& value,
171- int plevel = 10 );
124+ TVM_DLL static TargetKindRegistry* Global ();
172125 /* !
173- * \brief Set DLPack's device_type the target
174- * \param device_type Device type
126+ * \brief Register a name or return its existing canonical kind.
127+ * \param name Target kind name.
128+ * \return The canonical target kind for name. Standard target options are
129+ * declared when the name is first registered.
175130 */
176- inline TargetKindRegEntry& set_default_device_type ( int device_type );
131+ TVM_DLL TargetKind RegisterOrGet ( const ffi::String& name );
177132 /* !
178- * \brief Set DLPack's device_type the target
179- * \param keys The default keys
133+ * \brief Look up a registered kind.
134+ * \param name Target kind name.
135+ * \return The canonical kind, or nullopt when name is unknown.
180136 */
181- inline TargetKindRegEntry& set_default_keys (std::vector< ffi::String> keys );
137+ TVM_DLL ffi::Optional<TargetKind> Get ( const ffi::String& name );
182138 /* !
183- * \brief Set the canonicalizer function applied upon target creation .
184- * \param canonicalizer The target canonicalizer function .
139+ * \brief List registered kind names .
140+ * \return Names of all registered target kinds .
185141 */
186- inline TargetKindRegEntry& set_target_canonicalizer (FTargetCanonicalizer canonicalizer );
142+ TVM_DLL ffi::Array<ffi::String> ListTargetKinds ( );
187143 /* !
188- * \brief Register a valid configuration option and its ValueType for validation
189- * \param key The configuration key
190- * \param traits Optional traits (e.g. refl::DefaultValue, doc string, or raw default value)
191- * \tparam ValueType The value type to be registered
192- * \tparam Traits Optional trait types
144+ * \brief List declared option names and types for a kind.
145+ * \param kind Registered target kind.
146+ * \return Map from option name to type string.
193147 */
194- template <typename ValueType, typename ... Traits>
195- inline TargetKindRegEntry& add_attr_option (const ffi::String& key, Traits&&... traits);
196- /* ! \brief Set name of the TargetKind to be the same as registry if it is empty */
197- inline TargetKindRegEntry& set_name ();
148+ TVM_DLL ffi::Map<ffi::String, ffi::String> ListTargetKindOptions (const TargetKind& kind);
149+
150+ private:
151+ ffi::Map<ffi::String, TargetKind> kinds_;
152+ };
153+
154+ /* !
155+ * \brief Temporary fluent builder for registering a target kind.
156+ *
157+ * The registry retains the canonical kind after this builder is destroyed.
158+ * Group related definitions inside TVM_FFI_STATIC_INIT_BLOCK():
159+ * \code
160+ * TVM_FFI_STATIC_INIT_BLOCK() {
161+ * TargetKindDef("llvm")
162+ * .set_default_device_type(kDLCPU)
163+ * .set_default_keys({"cpu"})
164+ * .def_option<ffi::String>("mcpu");
165+ * }
166+ * \endcode
167+ */
168+ class TargetKindDef {
169+ public:
198170 /* !
199- * \brief List all the entry names in the registry .
200- * \return The entry names .
171+ * \brief Register or retrieve the canonical kind with this name .
172+ * \param name Target kind name .
201173 */
202- TVM_DLL static ffi::Array<ffi::String> ListTargetKinds ();
174+ explicit TargetKindDef (const ffi::String& name)
175+ : kind_(TargetKindRegistry::Global()->RegisterOrGet(name)) {}
203176 /* !
204- * \brief Get all supported option names and types for a given Target kind.
205- * \return Map of option name to type
177+ * \brief Set the default DLPack device type.
178+ * \param device_type DLPack device type.
179+ * \return This builder for chaining.
206180 */
207- TVM_DLL static ffi::Map<ffi::String, ffi::String> ListTargetKindOptions (const TargetKind& kind);
208-
181+ TargetKindDef& set_default_device_type (int device_type) {
182+ kind_->default_device_type = device_type;
183+ return *this ;
184+ }
209185 /* !
210- * \brief Register or get a new entry .
211- * \param target_kind_name The name of the TargetKind .
212- * \return the corresponding entry .
186+ * \brief Set default target keys .
187+ * \param keys Default keys in priority order .
188+ * \return This builder for chaining .
213189 */
214- TVM_DLL static TargetKindRegEntry& RegisterOrGet (const ffi::String& target_kind_name);
215-
216- private:
217- TargetKind kind_;
218- ffi::String name;
219-
220- /* ! \brief private constructor */
221- explicit TargetKindRegEntry (uint32_t reg_index) : kind_(ffi::make_object<TargetKindNode>()) {
222- kind_->index_ = reg_index;
190+ TargetKindDef& set_default_keys (std::vector<ffi::String> keys) {
191+ kind_->default_keys = keys;
192+ return *this ;
223193 }
224194 /* !
225- * \brief update the attribute TargetKindAttrMap
226- * \param key The name of the attribute
227- * \param value The value to be set
228- * \param plevel The priority level
195+ * \brief Set the canonicalizer used when constructing targets of this kind.
196+ * \param canonicalizer Function from a validated config map to its canonical form.
197+ * \return This builder for chaining. Also updates the kind's ConfigSchema.
229198 */
230- TVM_DLL void UpdateAttr (const ffi::String& key, ffi::Any value, int plevel);
231- template <typename , typename >
232- friend class AttrRegistry ;
233- friend class TargetKind ;
234- };
235-
236- template <typename ValueType>
237- inline TargetKindAttrMap<ValueType> TargetKind::GetAttrMap (const ffi::String& attr_name) {
238- return TargetKindAttrMap<ValueType>(GetAttrMapContainer (attr_name));
239- }
240-
241- template <typename ValueType>
242- inline TargetKindRegEntry& TargetKindRegEntry::set_attr (const ffi::String& attr_name,
243- const ValueType& value, int plevel) {
244- TVM_FFI_ICHECK_GT (plevel, 0 ) << " plevel in set_attr must be greater than 0" ;
245- ffi::Any rv;
246- rv = value;
247- UpdateAttr (attr_name, rv, plevel);
248- return *this ;
249- }
250-
251- inline TargetKindRegEntry& TargetKindRegEntry::set_default_device_type (int device_type) {
252- kind_->default_device_type = device_type;
253- return *this ;
254- }
255-
256- inline TargetKindRegEntry& TargetKindRegEntry::set_default_keys (std::vector<ffi::String> keys) {
257- kind_->default_keys = keys;
258- return *this ;
259- }
260-
261- inline TargetKindRegEntry& TargetKindRegEntry::set_target_canonicalizer (
262- FTargetCanonicalizer canonicalizer) {
263- kind_->target_canonicalizer = canonicalizer;
264- kind_->schema_ .set_canonicalizer (canonicalizer);
265- return *this ;
266- }
267-
268- template <typename ValueType, typename ... Traits>
269- inline TargetKindRegEntry& TargetKindRegEntry::add_attr_option (const ffi::String& key,
270- Traits&&... traits) {
271- kind_->schema_ .def_option <ValueType>(key, std::forward<Traits>(traits)...);
272- return *this ;
273- }
274-
275- inline TargetKindRegEntry& TargetKindRegEntry::set_name () {
276- if (kind_->name .empty ()) {
277- kind_->name = name;
199+ TargetKindDef& set_target_canonicalizer (FTargetCanonicalizer canonicalizer) {
200+ kind_->target_canonicalizer = canonicalizer;
201+ kind_->schema_ .set_canonicalizer (canonicalizer);
202+ return *this ;
203+ }
204+ /* !
205+ * \brief Declare a typed target option in the kind's ConfigSchema.
206+ * \tparam ValueType Canonical option value type.
207+ * \tparam Traits Optional metadata or validator trait types.
208+ * \param key Option name.
209+ * \param traits Optional traits such as a default value or validator.
210+ * \return This builder for chaining. Duplicate option names raise ValueError.
211+ */
212+ template <typename ValueType, typename ... Traits>
213+ TargetKindDef& def_option (const ffi::String& key, Traits&&... traits) {
214+ kind_->schema_ .def_option <ValueType>(key, std::forward<Traits>(traits)...);
215+ return *this ;
278216 }
279- return *this ;
280- }
281-
282- #define TVM_TARGET_KIND_REGISTER_VAR_DEF \
283- [[maybe_unused]] static ::tvm::TargetKindRegEntry& __make_##TargetKind
284217
285- /* !
286- * \def TVM_REGISTER_TARGET_KIND
287- * \brief Register a new target kind, or set attribute of the corresponding target kind.
288- *
289- * \param TargetKindName The name of target kind
290- * \param DeviceType The DLDeviceType of the target kind
291- *
292- * \code
293- *
294- * TVM_REGISTER_TARGET_KIND("llvm")
295- * .set_attr<TPreCodegenPass>("TPreCodegenPass", a-pre-codegen-pass)
296- * .add_attr_option<Bool>("system_lib")
297- * .add_attr_option<ffi::String>("mtriple")
298- * .add_attr_option<ffi::String>("mattr");
299- *
300- * \endcode
301- */
302- #define TVM_REGISTER_TARGET_KIND (TargetKindName, DeviceType ) \
303- TVM_FFI_STR_CONCAT (TVM_TARGET_KIND_REGISTER_VAR_DEF , __COUNTER__) = \
304- ::tvm::TargetKindRegEntry::RegisterOrGet (TargetKindName) \
305- .set_name() \
306- .set_default_device_type(DeviceType) \
307- .add_attr_option<ffi::String>(" kind" ) \
308- .add_attr_option<ffi::Array<ffi::String>>(" keys" ) \
309- .add_attr_option<ffi::String>(" tag" ) \
310- .add_attr_option<ffi::String>(" device" ) \
311- .add_attr_option<ffi::String>(" model" ) \
312- .add_attr_option<ffi::Array<ffi::String>>(" libs" ) \
313- .add_attr_option<Target>(" host" ) \
314- .add_attr_option<int64_t>(" from_device" ) \
315- .add_attr_option<int64_t>(" target_device_type" )
218+ private:
219+ TargetKind kind_;
220+ };
316221
317222} // namespace tvm
318223
0 commit comments