This is an automated email from the ASF dual-hosted git repository.

junrushao pushed a commit to branch unity
in repository https://gitbox.apache.org/repos/asf/tvm.git


The following commit(s) were added to refs/heads/unity by this push:
     new aab076e2bf [Unity] NDArray Cache Efficient Load in OpenCL (#14816)
aab076e2bf is described below

commit aab076e2bf6ab59e04baf226119edcb71db55285
Author: Ruihang Lai <[email protected]>
AuthorDate: Wed May 10 01:53:39 2023 -0400

    [Unity] NDArray Cache Efficient Load in OpenCL (#14816)
    
    OpenCL runtime may allocate mirror memory
    for device memory that serves as host copy target.
    
    This PR uses a staging buffer for parameter load
    to avoid this problem.
    
    Co-authored-by: tqchen <[email protected]>
---
 jvm/pom.xml                                   |  4 ++--
 src/runtime/relax_vm/ndarray_cache_support.cc | 32 ++++++++++++++++++++++++---
 2 files changed, 31 insertions(+), 5 deletions(-)

diff --git a/jvm/pom.xml b/jvm/pom.xml
index 1aeaa0e579..46cf44b7a4 100644
--- a/jvm/pom.xml
+++ b/jvm/pom.xml
@@ -164,8 +164,8 @@
         <artifactId>maven-compiler-plugin</artifactId>
         <version>3.3</version>
         <configuration>
-          <source>1.7</source>
-          <target>1.7</target>
+          <source>1.8</source>
+          <target>1.8</target>
           <encoding>UTF-8</encoding>
         </configuration>
       </plugin>
diff --git a/src/runtime/relax_vm/ndarray_cache_support.cc 
b/src/runtime/relax_vm/ndarray_cache_support.cc
index 3e4bcce20e..2f97556ce7 100644
--- a/src/runtime/relax_vm/ndarray_cache_support.cc
+++ b/src/runtime/relax_vm/ndarray_cache_support.cc
@@ -102,13 +102,39 @@ class NDArrayCache {
     auto shard_records = 
json_info.get<picojson::object>()["records"].get<picojson::array>();
 
     Map<String, NDArray> result;
+    std::string raw_data;
+    Optional<NDArray> staging_buffer;
+
+    auto fcopy_param_from_bytes = [&](NDArray param, void* data, size_t 
nbytes) {
+      if (device_type != kDLOpenCL) {
+        param.CopyFromBytes(data, nbytes);
+      }
+      // special handle OpenCL
+      // OpenCL runtime can create a host side memory mirror
+      // for every cl_mem that tries to copy data from host
+      // which can cause memory issue.
+      // We use a single staging buffer here
+      // that get de-allocated later
+      if (staging_buffer.defined()) {
+        size_t curr_size = 
runtime::GetDataSize(*(staging_buffer.value().operator->()));
+        if (curr_size < nbytes) {
+          staging_buffer = NullOpt;
+        }
+      }
+      if (!staging_buffer.defined()) {
+        staging_buffer = NDArray::Empty(param.Shape(), param->dtype, 
param->device);
+      }
+      NDArray staging_view = staging_buffer.value().CreateView(param.Shape(), 
param->dtype);
+      staging_view.CopyFromBytes(data, nbytes);
+      param.CopyFrom(staging_view);
+      TVMSynchronize(device_type, device_id, nullptr);
+    };
 
     for (auto shard_item : shard_records) {
       auto shard_rec = shard_item.get<picojson::object>();
       ICHECK(shard_rec["dataPath"].is<std::string>());
       std::string data_path = shard_rec["dataPath"].get<std::string>();
 
-      std::string raw_data;
       LoadBinaryFromFile(cache_path + "/" + data_path, &raw_data);
       CHECK_EQ(shard_rec["format"].get<std::string>(), "raw-shard");
       int64_t raw_nbytes = shard_rec["nbytes"].get<int64_t>();
@@ -138,9 +164,9 @@ class NDArrayCache {
           for (size_t i = 0; i < buffer.size(); ++i) {
             decoded[i] = static_cast<uint32_t>(buffer[i]) << 16;
           }
-          arr.CopyFromBytes(decoded.data(), decoded.size() * sizeof(uint32_t));
+          fcopy_param_from_bytes(arr, decoded.data(), decoded.size() * 
sizeof(uint32_t));
         } else {
-          arr.CopyFromBytes(raw_data.data() + offset, nbytes);
+          fcopy_param_from_bytes(arr, raw_data.data() + offset, nbytes);
         }
         Update(name, arr, true);
       }

Reply via email to