Mesa (master): clover: implement clEnqueueSVMMigrateMem

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Feb 2 16:33:05 UTC 2021


Module: Mesa
Branch: master
Commit: f7616c89a4af756cefc865970509f0a184a0d787
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=f7616c89a4af756cefc865970509f0a184a0d787

Author: Jérôme Glisse <jglisse at redhat.com>
Date:   Wed Aug  8 19:16:06 2018 -0400

clover: implement clEnqueueSVMMigrateMem

Memory migration for SVM (share virtual memory). This allow to migrate
a range of virtual address of the process to device memory to speed up
device processing when that memory is in use by the device.

v2 (Karol): use tracked SVM allocation in order to support cases where
            the size of the migration is not specified

Signed-off-by: Jérôme Glisse <jglisse at redhat.com>
Signed-off-by: Karol Herbst <kherbst at redhat.com>
Reviewed-by: Francisco Jerez <currojerez at riseup.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6401>

---

 src/gallium/frontends/clover/api/transfer.cpp | 60 ++++++++++++++++++++++++---
 src/gallium/frontends/clover/core/queue.cpp   | 13 ++++++
 src/gallium/frontends/clover/core/queue.hpp   |  2 +
 3 files changed, 70 insertions(+), 5 deletions(-)

diff --git a/src/gallium/frontends/clover/api/transfer.cpp b/src/gallium/frontends/clover/api/transfer.cpp
index ff2043136b6..7468bd612c0 100644
--- a/src/gallium/frontends/clover/api/transfer.cpp
+++ b/src/gallium/frontends/clover/api/transfer.cpp
@@ -217,6 +217,19 @@ namespace {
          validate_object_access(mem, CL_MEM_HOST_WRITE_ONLY);
    }
 
+   ///
+   /// Checks that the memory migration flags are correct.
+   ///
+   void
+   validate_mem_migration_flags(const cl_mem_migration_flags flags) {
+      const cl_mem_migration_flags valid =
+         CL_MIGRATE_MEM_OBJECT_HOST |
+         CL_MIGRATE_MEM_OBJECT_CONTENT_UNDEFINED;
+
+      if (flags & ~valid)
+         throw error(CL_INVALID_VALUE);
+   }
+
    ///
    /// Class that encapsulates the task of mapping an object of type
    /// \a T.  The return value of get() should be implicitly
@@ -1239,14 +1252,51 @@ clEnqueueSVMMigrateMem(cl_command_queue d_q,
                        const void **svm_pointers,
                        const size_t *sizes,
                        const cl_mem_migration_flags flags,
-                       cl_uint  num_events_in_wait_list,
-                       const cl_event *event_wait_list,
-                       cl_event *event) {
+                       cl_uint num_deps,
+                       const cl_event *d_deps,
+                       cl_event *rd_ev) try {
    auto &q = obj(d_q);
+   auto deps = objs<wait_list_tag>(d_deps, num_deps);
+
+   validate_common(q, deps);
+   validate_mem_migration_flags(flags);
 
    if (!q.device().svm_support())
       return CL_INVALID_OPERATION;
 
-   CLOVER_NOT_SUPPORTED_UNTIL("2.1");
-   return CL_INVALID_VALUE;
+   if (!num_svm_pointers || !svm_pointers)
+      return CL_INVALID_VALUE;
+
+   std::vector<size_t> sizes_copy(num_svm_pointers);
+   std::vector<const void*>  ptrs(num_svm_pointers);
+
+   for (unsigned i = 0; i < num_svm_pointers; ++i) {
+      const void *ptr = svm_pointers[i];
+      size_t size = sizes ? sizes[i] : 0;
+      if (!ptr)
+         return CL_INVALID_VALUE;
+
+      auto p = q.context().find_svm_allocation(ptr);
+      if (!p.first)
+         return CL_INVALID_VALUE;
+
+      std::ptrdiff_t pdiff = (uint8_t*)ptr - (uint8_t*)p.first;
+      if (size && size + pdiff > p.second)
+         return CL_INVALID_VALUE;
+
+      sizes_copy[i] = size ? size : p.second;
+      ptrs[i] = size ? svm_pointers[i] : p.first;
+   }
+
+   auto hev = create<hard_event>(
+      q, CL_COMMAND_MIGRATE_MEM_OBJECTS, deps,
+      [=, &q](event &) {
+         q.svm_migrate(ptrs, sizes_copy, flags);
+      });
+
+   ret_object(rd_ev, hev);
+   return CL_SUCCESS;
+
+} catch (error &e) {
+   return e.get();
 }
diff --git a/src/gallium/frontends/clover/core/queue.cpp b/src/gallium/frontends/clover/core/queue.cpp
index 0b14706c4d2..a81ef3ab42f 100644
--- a/src/gallium/frontends/clover/core/queue.cpp
+++ b/src/gallium/frontends/clover/core/queue.cpp
@@ -113,6 +113,19 @@ command_queue::flush_unlocked() {
    }
 }
 
+void
+command_queue::svm_migrate(const std::vector<void const*> &svm_pointers,
+                           const std::vector<size_t> &sizes,
+                           cl_mem_migration_flags flags) {
+   if (!pipe->svm_migrate)
+      return;
+
+   bool to_device = !(flags & CL_MIGRATE_MEM_OBJECT_HOST);
+   bool mem_undefined = flags & CL_MIGRATE_MEM_OBJECT_CONTENT_UNDEFINED;
+   pipe->svm_migrate(pipe, svm_pointers.size(), svm_pointers.data(),
+                     sizes.data(), to_device, mem_undefined);
+}
+
 cl_command_queue_properties
 command_queue::props() const {
    return _props;
diff --git a/src/gallium/frontends/clover/core/queue.hpp b/src/gallium/frontends/clover/core/queue.hpp
index 579bba8f7a5..b132cd7ad0f 100644
--- a/src/gallium/frontends/clover/core/queue.hpp
+++ b/src/gallium/frontends/clover/core/queue.hpp
@@ -49,6 +49,8 @@ namespace clover {
       operator=(const command_queue &q) = delete;
 
       void flush();
+      void svm_migrate(const std::vector<void const *> &svm_pointers,
+                       const std::vector<size_t> &sizes, cl_mem_migration_flags flags);
 
       cl_command_queue_properties props() const;
 



More information about the mesa-commit mailing list