You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tvm.apache.org by GitBox <gi...@apache.org> on 2022/02/23 18:50:33 UTC

[GitHub] [tvm] mehrdadh commented on a change in pull request #10361: [Hexagon] RPC server/client for simulator

mehrdadh commented on a change in pull request #10361:
URL: https://github.com/apache/tvm/pull/10361#discussion_r813211102



##########
File path: src/runtime/hexagon/rpc/simulator/session.cc
##########
@@ -0,0 +1,1322 @@
+/*
+ * 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.
+ */
+
+#include <HexagonWrapper.h>
+#include <dmlc/optional.h>
+#include <tvm/runtime/packed_func.h>
+#include <tvm/runtime/registry.h>
+// POSIX includes
+#include <dirent.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <cstdlib>
+#include <deque>
+#include <iterator>
+#include <map>
+#include <memory>
+#include <sstream>
+#include <string>
+#include <utility>
+
+#include "../../../rpc/rpc_channel.h"
+#include "../../../rpc/rpc_endpoint.h"
+#include "../../../rpc/rpc_session.h"
+#include "hexagon_sim_proto.h"
+
+#define CHECKED_CALL(func, ...)                                               \
+  do {                                                                        \
+    HEXAPI_Status s = sim_->func(__VA_ARGS__);                                \
+    ICHECK_EQ(s, HEX_STAT_SUCCESS)                                            \
+        << self_name_ << ": " #func " failed with code " << Status_{s}.str(); \
+  } while (false)
+
+namespace tvm {
+namespace runtime {
+namespace hexagon {
+
+using string_list = std::deque<std::string>;
+
+namespace detail {
+
+// An "Optional" class, originally a replacement for llvm::Optional, then an
+// extension of dmlc::optional to make it compatible with C++17's std::optional.
+template <typename T>
+struct Optional : public dmlc::optional<T> {
+  using dmlc::optional<T>::optional;
+  using dmlc::optional<T>::operator=;
+  Optional(const T& val) : dmlc::optional<T>(val) {}  // NOLINT(*)
+
+  T* operator->() { return &this->operator*(); }
+  const T* operator->() const { return &this->operator*(); }
+};
+
+// Replacement for llvm::StringSwitch.
+template <typename T>
+class StringSwitch {
+ public:
+  explicit StringSwitch(const std::string& key) : key(key) {}
+  operator T() const {
+    auto f = map.find(key);
+    if (f != map.end()) {
+      return f->second;
+    }
+    ICHECK(static_cast<bool>(def_val)) << "default value not set";
+    return *def_val;
+  }
+  StringSwitch& Case(const std::string& key, T val) {
+    map.insert(std::make_pair(key, val));
+    return *this;
+  }
+  StringSwitch& Default(T val) {
+    ICHECK(!static_cast<bool>(def_val)) << "default value already set";
+    def_val = val;
+    return *this;
+  }
+
+ private:
+  const std::string key;
+  std::map<std::string, T> map;
+  Optional<T> def_val;
+};
+
+using MaybeString = Optional<std::string>;
+
+MaybeString front(const string_list& deq) {
+  return !deq.empty() ? MaybeString(deq.front()) : MaybeString();
+}
+
+MaybeString pop_front(string_list& deq) {  // NOLINT(*)
+  if (deq.empty()) return MaybeString();
+  std::string f = deq.front();
+  deq.pop_front();
+  return MaybeString(f);
+}
+
+// Functions used when parsing the argument string.
+
+Optional<int64_t> to_int(const MaybeString& str) {
+  auto none = Optional<int64_t>();
+  if (str.has_value()) {
+    try {
+      size_t pos;
+      int64_t val = std::stoll(*str, &pos, 0);
+      return pos == str->size() ? Optional<int64_t>(val) : none;
+    } catch (std::invalid_argument&) {
+    }
+  }
+  return none;
+}
+
+Optional<uint64_t> to_uint(const MaybeString& str) {
+  auto none = Optional<uint64_t>();
+  if (str.has_value()) {
+    try {
+      size_t pos;
+      uint64_t val = std::stoull(*str, &pos, 0);
+      return pos == str->size() ? Optional<uint64_t>(val) : none;
+    } catch (std::invalid_argument&) {
+    }
+  }
+  return none;
+}
+
+Optional<float> to_float(const MaybeString& str) {
+  auto none = Optional<float>();
+  if (str.has_value()) {
+    try {
+      size_t pos;
+      float val = std::stof(*str, &pos);
+      return pos == str->size() ? Optional<float>(val) : none;
+    } catch (std::invalid_argument&) {
+    }
+  }
+  return none;
+}
+
+Optional<bool> to_bool(const MaybeString& str) {
+  auto none = Optional<bool>();
+  if (auto num = to_int(str)) {
+    if (*num == 0) return false;
+    if (*num == 1) return true;
+    return none;
+  }
+  if (str) {
+    if (*str == "true" || *str == "TRUE") return true;
+    if (*str == "false" || *str == "FALSE") return false;
+  }
+  return none;
+}
+
+template <typename T>
+using MaybeRange = Optional<std::pair<T, T>>;
+
+template <typename T, Optional<T> Parse(const MaybeString&)>
+MaybeRange<T> to_range(const MaybeString& str) {
+  auto none = MaybeRange<T>();
+  if (str && !str->empty()) {
+    auto n = str->find('-', 1);
+    if (n != std::string::npos) {
+      auto begin = Parse(str->substr(0, n));
+      auto end = Parse(str->substr(n + 1, str->size() - n - 1));
+      if (begin && end) {
+        return std::make_pair(*begin, *end);
+      }
+    }
+  }
+  return none;
+}
+
+}  // namespace detail
+
+class SimulatorRPCChannel final : public RPCChannel {
+ public:
+  SimulatorRPCChannel(std::string args);
+  ~SimulatorRPCChannel() final;
+  size_t Send(const void* data, size_t size) final;
+  size_t Recv(void* data, size_t size) final;
+
+ private:
+  struct Status_ {
+    HEXAPI_Status s;
+    std::string str() const;
+  };
+  struct Core_ {
+    HEXAPI_CoreState s;
+    std::string str() const;
+  };
+  struct Cpu_ {
+    HEXAPI_Cpu c;
+    std::string str() const;
+  };
+  struct SDKInfo_ {
+    SDKInfo_(const std::string& sdk_root, const std::string& cpu);
+    std::string root;
+    std::string qurt_root;  // sdk_root/rtos/qurt/computevNN.
+    std::string runelf;     // Path to runelf.pbn.
+    std::string runmain;    // Path to run_main_on_hexagon.
+  };
+
+  Message SendMsg(Message msg);
+  Message SendMsg(uint32_t code, uint32_t len, uint32_t va);
+  void ReadFromProcess(void* host_dst, HEX_VA_t src, size_t len);
+  void WriteToProcess(HEX_VA_t dst, const void* host_src, size_t len);
+
+  static HEX_8u_t PassVirtAddrCallback(void* handle, int threadno, HEX_8u_t RssV, HEX_8u_t RttV,
+                                       HEX_8u_t RxxV, HEX_1u_t imm);
+
+  detail::Optional<HEXAPI_Cpu> GetCPU(const detail::MaybeString& cpu_str);
+
+  // File name templates for mkstemps.
+#define SUFFIX ".cfg"
+  static constexpr int template_length_ = strlen("temp-xxxx-XXXXXX" SUFFIX) + 1;
+  char osam_file_[template_length_] = "temp-osam-XXXXXX" SUFFIX;
+  char cosim_file_[template_length_] = "temp-q6ss-XXXXXX" SUFFIX;
+  const int suffix_len_ = strlen(SUFFIX);
+#undef SUFFIX
+
+  static const constexpr char* self_name_ = "SimulatorRPCChannel";
+  static const constexpr char* default_cpu_ = "v68";
+  std::string cpu_;
+
+  HEX_VA_t dispatch_v_, message_buffer_v_;
+  std::unique_ptr<HexagonWrapper> sim_;
+
+  // Sim configuration routines.

Review comment:
       can you move all of these configurations to a header file and reuse it?




-- 
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.

To unsubscribe, e-mail: commits-unsubscribe@tvm.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org