junrushao1994 commented on a change in pull request #6369:
URL: https://github.com/apache/incubator-tvm/pull/6369#discussion_r485273921



##########
File path: src/target/target.cc
##########
@@ -288,151 +405,177 @@ Map<String, ObjectRef> TargetNode::Export() const {
   return result;
 }
 
-const std::string& TargetNode::str() const {
-  if (str_repr_.empty()) {
-    std::ostringstream os;
-    os << kind->name;
-    if (!this->keys.empty()) {
-      os << " -keys=";
-      bool is_first = true;
-      for (const String& s : keys) {
-        if (is_first) {
-          is_first = false;
-        } else {
-          os << ',';
-        }
-        os << s;
-      }
-    }
-    if (Optional<String> attrs_str = this->StringifyAttrsToRaw(attrs)) {
-      os << ' ' << attrs_str.value();
+/*! \brief Entry to hold the Target context stack. */
+struct TVMTargetThreadLocalEntry {
+  /*! \brief The current target context */
+  std::stack<Target> context_stack;
+};
+
+/*! \brief Thread local store to hold the Target context stack. */
+using TVMTargetThreadLocalStore = 
dmlc::ThreadLocalStore<TVMTargetThreadLocalEntry>;
+
+void Target::EnterWithScope() {
+  TVMTargetThreadLocalEntry* entry = TVMTargetThreadLocalStore::Get();
+  entry->context_stack.push(*this);
+}
+
+void Target::ExitWithScope() {
+  TVMTargetThreadLocalEntry* entry = TVMTargetThreadLocalStore::Get();
+  CHECK(!entry->context_stack.empty());
+  CHECK(entry->context_stack.top().same_as(*this));
+  entry->context_stack.pop();
+}
+
+Target Target::Current(bool allow_not_defined) {
+  TVMTargetThreadLocalEntry* entry = TVMTargetThreadLocalStore::Get();
+  if (entry->context_stack.size() > 0) {
+    return entry->context_stack.top();
+  }
+  CHECK(allow_not_defined)
+      << "Target context required. Please set it by constructing a 
TargetContext";
+
+  return Target();
+}
+
+/**********  Creation  **********/
+
+void TargetInternal::ConstructorDispatcher(TVMArgs args, TVMRetValue* rv) {
+  if (args.num_args == 1) {
+    const auto& arg = args[0];
+    if (arg.IsObjectRef<Target>()) {
+      *rv = Target(arg.AsObjectRef<Target>());
+    } else if (String::CanConvertFrom(arg)) {
+      *rv = Target(arg.operator String());
+    } else if (arg.IsObjectRef<Map<String, ObjectRef>>()) {
+      *rv = Target(arg.operator Map<String, ObjectRef>());
+    } else if (arg.type_code() == kTVMObjectHandle) {
+      ObjectRef obj = arg;
+      LOG(FATAL) << "TypeError: Cannot create target with type: " << 
obj->GetTypeKey();
+    } else {
+      LOG(FATAL) << "TypeError: Cannot create target with type: "
+                 << runtime::ArgTypeCode2Str(arg.type_code());
     }
-    str_repr_ = os.str();
+    return;
   }
-  return str_repr_;
+  LOG(FATAL) << "ValueError: Invalid number of arguments. Expect 1, but gets: 
" << args.num_args;
 }
 
-bool StartsWith(const std::string& str, const std::string& pattern) {
-  return str.compare(0, pattern.length(), pattern) == 0;
+ObjectPtr<Object> TargetInternal::FromString(const String& 
tag_or_config_or_target_str) {
+  if (Optional<Target> target = TargetTag::Get(tag_or_config_or_target_str)) {
+    Target value = target.value();
+    return runtime::ObjectInternal::MoveObjectPtr(&value);
+  }
+  if (!tag_or_config_or_target_str.empty() && 
tag_or_config_or_target_str.data()[0] == '{') {
+    return TargetInternal::FromConfigString(tag_or_config_or_target_str);
+  }
+  return TargetInternal::FromRawString(tag_or_config_or_target_str);

Review comment:
       If the first character of the string is not `{`, it should be very easy 
for users to format it before sending to the constructor.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to