[arrayfire] 51/284: Enables use of ArrayFire with external context & command queue

Ghislain Vaillant ghisvail-guest at moszumanska.debian.org
Sun Feb 7 18:59:18 UTC 2016


This is an automated email from the git hooks/post-receive script.

ghisvail-guest pushed a commit to branch debian/experimental
in repository arrayfire.

commit ce2d6a6c5d2fa20478f701aedd31ea291f3356f6
Author: pradeep <pradeep at arrayfire.com>
Date:   Thu Dec 3 16:03:09 2015 -0500

    Enables use of ArrayFire with external context & command queue
---
 include/af/opencl.h             |  47 ++++++++++++++++++
 src/backend/opencl/platform.cpp | 103 +++++++++++++++++++++++++++++++++++++++-
 src/backend/opencl/platform.hpp |  17 ++++++-
 3 files changed, 164 insertions(+), 3 deletions(-)

diff --git a/include/af/opencl.h b/include/af/opencl.h
index 271879f..99080a5 100644
--- a/include/af/opencl.h
+++ b/include/af/opencl.h
@@ -63,6 +63,53 @@ AFAPI af_err afcl_get_device_id(cl_device_id *id);
 AFAPI af_err afcl_set_device_id(cl_device_id id);
 #endif
 
+#if AF_API_VERSION >= 33
+/**
+   Push user provided device control constructs into the ArrayFire device manager pool
+
+   This function should be used only when the user would like ArrayFire to use an
+   user generated OpenCL context and related objects for ArrayFire operations.
+
+   \param[in] dev is the OpenCL device for which user provided context will be used by ArrayFire
+   \param[in] ctx is the user provided OpenCL cl_context to be used by ArrayFire
+   \param[in] que is the user provided OpenCL cl_command_queue to be used by ArrayFire. If this
+                  parameter is NULL, then we create a command queue for the user using the OpenCL
+                  context they provided us.
+
+   \note The cl_* objects are passed onto c++ objects (cl::Device, cl::Context & cl::CommandQueue)
+   that are defined in the `cl.hpp` OpenCL c++ header provided by Khronos Group Inc. Therefore, please
+   be aware of the lifetime of the cl_* objects before passing them to ArrayFire.
+*/
+AFAPI af_err afcl_push_device_context(cl_device_id dev, cl_context ctx, cl_command_queue que);
+#endif
+
+#if AF_API_VERSION >= 33
+/**
+   Set active device using cl_context and cl_device_id
+
+   \param[in] dev is the OpenCL device id that is to be set as Active device inside ArrayFire
+   \param[in] ctx is the OpenCL cl_context being used by ArrayFire
+*/
+AFAPI af_err afcl_set_device_context(cl_device_id dev, cl_context ctx);
+#endif
+
+#if AF_API_VERSION >= 33
+/**
+   Remove the user provided device control constructs from the ArrayFire device manager pool
+
+   This function should be used only when the user would like ArrayFire to remove an already
+   pushed user generated OpenCL context and related objects.
+
+   \param[in] dev is the OpenCL device id that has to be popped
+   \param[in] ctx is the cl_context object to be removed from ArrayFire pool
+
+   \note Any reference counts incremented for cl_* objects by ArrayFire internally are decremented
+   by this func call and you won't be able to call `afcl_set_device_context` on these objects after
+   this function has been called.
+*/
+AFAPI af_err afcl_pop_device_context(cl_device_id dev, cl_context ctx);
+#endif
+
 /**
   @}
 */
diff --git a/src/backend/opencl/platform.cpp b/src/backend/opencl/platform.cpp
index 6f9ae99..32ba72d 100644
--- a/src/backend/opencl/platform.cpp
+++ b/src/backend/opencl/platform.cpp
@@ -108,7 +108,7 @@ void DeviceManager::setContext(int device)
 }
 
 DeviceManager::DeviceManager()
-    : mActiveCtxId(0), mActiveQId(0)
+    : mUserDeviceOffset(0), mActiveCtxId(0), mActiveQId(0)
 {
     try {
         std::vector<cl::Platform>   platforms;
@@ -181,6 +181,7 @@ DeviceManager::DeviceManager()
         }
     }
 #endif
+    mUserDeviceOffset = mDevices.size();
 }
 
 
@@ -472,6 +473,88 @@ void DeviceManager::markDeviceForInterop(const int device, const fg::Window* wHa
 }
 #endif
 
+void pushDeviceContext(cl_device_id dev, cl_context ctx, cl_command_queue que)
+{
+    try {
+        DeviceManager& devMngr   = DeviceManager::getInstance();
+        cl::Device* tDevice      = new cl::Device(dev);
+        cl::Context* tContext    = new cl::Context(ctx);
+        cl::CommandQueue* tQueue = (que==NULL ?
+                new cl::CommandQueue(*tContext, *tDevice) : new cl::CommandQueue(que));
+        devMngr.mDevices.push_back(tDevice);
+        devMngr.mContexts.push_back(tContext);
+        devMngr.mQueues.push_back(tQueue);
+        // FIXME: add OpenGL Interop for user provided contexts later
+        devMngr.mIsGLSharingOn.push_back(false);
+    } catch (const cl::Error &ex) {
+        CL_TO_AF_ERROR(ex);
+    }
+}
+
+void setDeviceContext(cl_device_id dev, cl_context ctx)
+{
+    // FIXME: add OpenGL Interop for user provided contexts later
+    try {
+        DeviceManager& devMngr = DeviceManager::getInstance();
+        const int dCount = devMngr.mDevices.size();
+        for (int i=0; i<dCount; ++i) {
+            if(devMngr.mDevices[i]->operator()()==dev &&
+                    devMngr.mContexts[i]->operator()()==ctx) {
+                setDevice(i);
+                return;
+            }
+        }
+    } catch (const cl::Error &ex) {
+        CL_TO_AF_ERROR(ex);
+    }
+    AF_ERROR("No matching device found", AF_ERR_ARG);
+}
+
+void popDeviceContext(cl_device_id dev, cl_context ctx)
+{
+    try {
+        if (getDevice()() == dev && getContext()()==ctx) {
+            AF_ERROR("Cannot pop the device currently in use", AF_ERR_ARG);
+        }
+
+        DeviceManager& devMngr = DeviceManager::getInstance();
+        const int dCount = devMngr.mDevices.size();
+        int deleteIdx = -1;
+        for (int i = 0; i<dCount; ++i) {
+            if(devMngr.mDevices[i]->operator()()==dev &&
+                    devMngr.mContexts[i]->operator()()==ctx) {
+                deleteIdx = i;
+                break;
+            }
+        }
+        if (deleteIdx < (int)devMngr.mUserDeviceOffset) {
+            AF_ERROR("Cannot pop ArrayFire internal devices", AF_ERR_ARG);
+        } else if (deleteIdx == -1) {
+            AF_ERROR("No matching device found", AF_ERR_ARG);
+        } else {
+            // FIXME: this case can potentially cause issues due to the
+            // modification of the device pool stl containers.
+
+            // IF the current active device is enumerated at a position
+            // that lies ahead of the device that has been requested
+            // to be removed. We just pop the entries from pool since it
+            // has no side effects.
+            devMngr.mDevices.erase(devMngr.mDevices.begin()+deleteIdx);
+            devMngr.mContexts.erase(devMngr.mContexts.begin()+deleteIdx);
+            devMngr.mQueues.erase(devMngr.mQueues.begin()+deleteIdx);
+            // FIXME: add OpenGL Interop for user provided contexts later
+            devMngr.mIsGLSharingOn.erase(devMngr.mIsGLSharingOn.begin()+deleteIdx);
+            // OTHERWISE, update(decrement) the `mActive*Id` variables
+            if (deleteIdx < (int)devMngr.mActiveCtxId) {
+                --devMngr.mActiveCtxId;
+                --devMngr.mActiveQId;
+            }
+        }
+    } catch (const cl::Error &ex) {
+        CL_TO_AF_ERROR(ex);
+    }
+}
+
 }
 
 using namespace opencl;
@@ -502,3 +585,21 @@ af_err afcl_set_device_id(cl_device_id id)
     setDevice(getDeviceIdFromNativeId(id));
     return AF_SUCCESS;
 }
+
+af_err afcl_push_device_context(cl_device_id dev, cl_context ctx, cl_command_queue que)
+{
+    pushDeviceContext(dev, ctx, que);
+    return AF_SUCCESS;
+}
+
+af_err afcl_set_device_context(cl_device_id dev, cl_context ctx)
+{
+    setDeviceContext(dev, ctx);
+    return AF_SUCCESS;
+}
+
+af_err afcl_pop_device_context(cl_device_id dev, cl_context ctx)
+{
+    popDeviceContext(dev, ctx);
+    return AF_SUCCESS;
+}
diff --git a/src/backend/opencl/platform.hpp b/src/backend/opencl/platform.hpp
index 7f0dab6..022cd7e 100644
--- a/src/backend/opencl/platform.hpp
+++ b/src/backend/opencl/platform.hpp
@@ -43,8 +43,14 @@ class DeviceManager
 
     friend int setDevice(int device);
 
+    friend void pushDeviceContext(cl_device_id dev, cl_context cxt, cl_command_queue que);
+
+    friend void setDeviceContext(cl_device_id dev, cl_context cxt);
+
+    friend void popDeviceContext(cl_device_id dev, cl_context ctx);
+
     public:
-        static const unsigned MAX_DEVICES = 16;
+        static const unsigned MAX_DEVICES = 32;
 
         static DeviceManager& getInstance();
 
@@ -67,10 +73,11 @@ class DeviceManager
 
     private:
         // Attributes
-        std::vector<cl::CommandQueue*>  mQueues;
         std::vector<cl::Device*>       mDevices;
         std::vector<cl::Context*>     mContexts;
+        std::vector<cl::CommandQueue*>  mQueues;
         std::vector<bool>        mIsGLSharingOn;
+        unsigned mUserDeviceOffset;
 
         unsigned mActiveCtxId;
         unsigned mActiveQId;
@@ -100,6 +107,12 @@ std::string getPlatformName(const cl::Device &device);
 
 int setDevice(int device);
 
+void pushDeviceContext(cl_device_id dev, cl_context cxt, cl_command_queue que);
+
+void setDeviceContext(cl_device_id dev, cl_context cxt);
+
+void popDeviceContext(cl_device_id dev, cl_context ctx);
+
 void sync(int device);
 
 }

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/arrayfire.git



More information about the debian-science-commits mailing list