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 2020/04/07 04:11:34 UTC

[GitHub] [incubator-tvm] FrozenGene commented on a change in pull request #5252: [RUNTIME] Initial implementation of Hexagon runtime support

FrozenGene commented on a change in pull request #5252: [RUNTIME] Initial implementation of Hexagon runtime support
URL: https://github.com/apache/incubator-tvm/pull/5252#discussion_r404523734
 
 

 ##########
 File path: src/runtime/hexagon/target/hexagon_device_target.cc
 ##########
 @@ -0,0 +1,525 @@
+/*
+ * 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.
+ */
+
+#ifdef __ANDROID__
+
+#include <unistd.h>
+
+#include <algorithm>
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "../hexagon_module.h"
+#include "AEEStdErr.h"
+#include "fastrpc/tvm_hexagon_remote.h"
+#include "hexagon_dsprpcapi.h"
+#include "hexagon_stubapi.h"
+#include "hexagon_target_log.h"
+#include "remote64.h"
+#include "rpcmem.h"
+
+#pragma weak remote_session_control
+
+#define RPCMEM_HEAP 25
+
+// All log messages start with "HexagonTarget::%s", where %s is replaced
+// with the function name, so create macros that add that to avoid repetition.
+// The downside is that the format string must be given as a string literal,
+// but it seems to be a minor issue.
+#define VA_EXPANDER(...) , ##__VA_ARGS__
+#define TVM_LOGD_HT(fmt, ...) \
+  TVM_LOGD("HexagonTarget::%s: " fmt, __func__ VA_EXPANDER(__VA_ARGS__))
+#define TVM_LOGE_HT(fmt, ...) \
+  TVM_LOGE("HexagonTarget::%s: " fmt, __func__ VA_EXPANDER(__VA_ARGS__))
+
+namespace tvm {
+namespace runtime {
+namespace hexagon {
+
+static constexpr int kStackSize = 128 * 1024;  // 128kB stack
+
+class HexagonTarget : public tvm::runtime::hexagon::Device {
+ public:
+  HexagonTarget() {}
+  ~HexagonTarget() final {}
+  void* Alloc(unsigned size, unsigned align) final;
+  void Free(void* ptr) final;
+  void* AllocVtcm(unsigned size, unsigned align) final;
+  void FreeVtcm(void* ptr) final;
+  void CopyDeviceToDevice(void* dst, const void* src, unsigned len) final;
+  void CopyDeviceToHost(void* host_dst, const void* src, unsigned len) final;
+  void CopyHostToDevice(void* dst, const void* host_src, unsigned len) final;
+  void* Load(const std::string& data, const std::string& fmt) final;
+  void Unload(void* mod) final;
+  void* Resolve(const std::string& sym) final;
+  void Call(void* func, uint32_t* scalar, unsigned scalar_num, uint32_t* stack,
+            unsigned stack_num) final;
+
+ private:
+  std::pair<void*, size_t> AddAddrMapping(const void* dsp_addr,
+                                          void* apps_addr, size_t size);
+  std::pair<void*, size_t> GetAppsAddr(const void* dsp_addr, bool exact) const;
+  void RemoveAddrMapping(const void* dsp_addr);
+  int OpenDomainChannel(bool set_unsigned_pd);
+  int CloseDomainChannel();
+  void ReleaseLibrary();
+  void FreeMemoryBeforeChannelClose();
+
+  // Mapping from a DSP address to a pair <apps address, buffer size>.
+  // Using void* pointers is ok, since DSP pointers will always fit
+  // in apps's pointers, i.e. sizeof_dsp(void*) <= sizeof_apps(void*).
+  std::map<const void*, std::pair<void*, size_t>> dsp_to_apps_;
+  std::map<const void*, std::pair<void*, size_t>> vtcm_addr_;
+  remote_handle64 domain_channel_handle_ = AEE_EUNKNOWN;
+  tvm_hexagon_remote_handle_t module_pointer_ = AEE_EUNKNOWN;
+  uint64_t count_channel_open_ = 0;
+  // Global lock, used for all critical sections. This can be refined
+  // in the future.
+  mutable std::mutex crit_section_;
+};
+
+std::shared_ptr<Device> CreateHexagonTarget() {
+  return std::make_shared<HexagonTarget>();
+}
+
+std::pair<void*, size_t> HexagonTarget::AddAddrMapping(const void* dsp_addr,
+                                                       void* apps_addr,
+                                                       size_t size) {
+  crit_section_.lock();
+  auto p = dsp_to_apps_.insert({dsp_addr, {apps_addr, size}});
+  crit_section_.unlock();
+  if (!p.second) {
+    TVM_LOGE_HT(
+        "failed to insert address mapping: dsp:%p -> apps:%p, size:%zu",
+        dsp_addr, apps_addr, size);
+    return std::make_pair(nullptr, 0);
+  }
+  TVM_LOGD_HT("added address mapping: dsp:%p -> apps:%p, size:%zu", dsp_addr,
+              apps_addr, size);
+  return p.first->second;
+}
+
+void HexagonTarget::RemoveAddrMapping(const void* dsp_addr) {
+  crit_section_.lock();
+  auto f = dsp_to_apps_.find(dsp_addr);
+  if (f == dsp_to_apps_.end()) {
+    TVM_LOGE_HT("failed to remove address mapping for dsp:%p", dsp_addr);
+    crit_section_.unlock();
+    return;
+  }
+  dsp_to_apps_.erase(f);
+  crit_section_.unlock();
+}
+
+std::pair<void*, size_t> HexagonTarget::GetAppsAddr(const void* dsp_addr,
+                                                    bool exact) const {
+  struct AutoUnlock {
+    explicit AutoUnlock(std::mutex& m) : m(m) {}
+    ~AutoUnlock() { m.unlock(); }
+    std::mutex& m;
+  };
+
+  crit_section_.lock();
+  AutoUnlock u(crit_section_);
+
+  // If the address is in the map, simply return the result.
+  auto f = dsp_to_apps_.find(dsp_addr);
+  if (f != dsp_to_apps_.end()) return f->second;
+  // If exact mapping is requested, then it hasn't been found.
+  if (exact) return std::make_pair(nullptr, 0);
+
+  // If the address is not in the map, maybe it points to somewhere in the
+  // interior of a mapped buffer.
+  uintptr_t dsp_v = reinterpret_cast<uintptr_t>(dsp_addr);
+  for (const auto& v : dsp_to_apps_) {
+    uintptr_t dsp_k = reinterpret_cast<uintptr_t>(v.first);
+    size_t size = v.second.second;
+    if (dsp_v >= dsp_k && dsp_v < dsp_k + size) {
+      uintptr_t apps_k = reinterpret_cast<uintptr_t>(v.second.first);
+      size_t offset = dsp_v - dsp_k;
+      uintptr_t apps_v = apps_k + offset;
+      return std::make_pair(reinterpret_cast<void*>(apps_v), size - offset);
+    }
+  }
+  TVM_LOGE_HT("failed to locate apps address for dsp:%p", dsp_addr);
+  return std::make_pair(nullptr, 0);
+}
+
+int HexagonTarget::OpenDomainChannel(bool use_unsigned_pd) {
+  if (domain_channel_handle_ != AEE_EUNKNOWN) return AEE_SUCCESS;
+
+  const DspRpcAPI* dsp_api = DspRpcAPI::Global();
+  const StubAPI* stub_api = StubAPI::Global();
+
+  stub_api->rpcmem_init_ptr()();
 
 Review comment:
   I maybe forget a little bit, because I do it last year. However, I remember `rpcmem_init_ptr` will have problem when we set `use_unsigned_pd` be false. In your code logic of this pr, you will always set `use_unsigned_pd` be true. Could you double check it? I set it be false, because I find when we set it be `true`, we can not do parallel on DSP. But I don't have device now and can not verify it sadly.

----------------------------------------------------------------
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:
users@infra.apache.org


With regards,
Apache Git Services