[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