[arrayfire] 184/284: Add the ability to sort OpenCL devices Using the following criterion

Ghislain Vaillant ghisvail-guest at moszumanska.debian.org
Sun Feb 7 18:59:31 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 3047acd599e86136578e80f5f35ca706456ffe7a
Author: Pavan Yalamanchili <pavan at arrayfire.com>
Date:   Sat Jan 9 04:59:39 2016 -0500

    Add the ability to sort OpenCL devices Using the following criterion
    
    1. GPUs > Accelerators > CPUs.
    
    2. IN GPUs:
       a. Discreet preferred to integrated
       b. AMD > NVIDIA > APPLE > Intel / BEIGNET
    
    3. IN CPUs Intel > AMD > POCL > other
    
    4. While everything above is the same:
       a. Higher OpenCL compute version preferred
       b. Higher amount of memory preferred
---
 src/backend/opencl/platform.cpp | 215 +++++++++++++++++++++++++++++-----------
 1 file changed, 155 insertions(+), 60 deletions(-)

diff --git a/src/backend/opencl/platform.cpp b/src/backend/opencl/platform.cpp
index 0cd46d2..3bf13c0 100644
--- a/src/backend/opencl/platform.cpp
+++ b/src/backend/opencl/platform.cpp
@@ -110,6 +110,94 @@ void DeviceManager::setContext(int device)
     mActiveCtxId = device;
 }
 
+static inline bool verify_present(std::string pname, const char *ref)
+{
+    return pname.find(ref) != std::string::npos;
+}
+
+static inline bool compare_default(const Device *ldev, const Device *rdev)
+{
+    const cl_device_type device_types[] = {CL_DEVICE_TYPE_GPU,
+                                           CL_DEVICE_TYPE_ACCELERATOR};
+
+    auto l_dev_type = ldev->getInfo<CL_DEVICE_TYPE>();
+    auto r_dev_type = rdev->getInfo<CL_DEVICE_TYPE>();
+
+    // This ensures GPU > ACCELERATOR > CPU
+    for (auto current_type : device_types) {
+        auto is_l_curr_type = l_dev_type == current_type;
+        auto is_r_curr_type = r_dev_type == current_type;
+
+        if ( is_l_curr_type && !is_r_curr_type) return true;
+        if (!is_l_curr_type &&  is_r_curr_type) return false;
+    }
+
+    // For GPUs, this ensures discreet > integrated
+    auto is_l_integrared = ldev->getInfo<CL_DEVICE_HOST_UNIFIED_MEMORY>();
+    auto is_r_integrared = rdev->getInfo<CL_DEVICE_HOST_UNIFIED_MEMORY>();
+
+    if (!is_l_integrared &&  is_r_integrared) return true;
+    if ( is_l_integrared && !is_r_integrared) return false;
+
+    // At this point, the devices are of same type.
+    // Sort based on emperical evidence of preferred platforms
+
+    // Prefer AMD first
+    std::string lPlatName = getPlatformName(*ldev);
+    std::string rPlatName = getPlatformName(*rdev);
+
+    if (l_dev_type == CL_DEVICE_TYPE_GPU &&
+        r_dev_type == CL_DEVICE_TYPE_GPU ) {
+        // If GPU, prefer AMD > NVIDIA > Beignet / Intel > APPLE
+        const char *platforms[] = {"AMD", "NVIDIA", "APPLE", "INTEL", "BEIGNET"};
+
+        for (auto ref_name : platforms) {
+            if ( verify_present(lPlatName, ref_name) &&
+                !verify_present(rPlatName, ref_name)) return true;
+
+            if (!verify_present(lPlatName, ref_name) &&
+                 verify_present(rPlatName, ref_name)) return false;
+        }
+
+        // Intel falls back to compare based on memory
+    } else {
+        // If CPU, prefer Intel > AMD > POCL > APPLE
+        const char *platforms[] = {"INTEL", "AMD", "POCL", "APPLE"};
+
+        for (auto ref_name : platforms) {
+            if ( verify_present(lPlatName, ref_name) &&
+                !verify_present(rPlatName, ref_name)) return true;
+
+            if (!verify_present(lPlatName, ref_name) &&
+                 verify_present(rPlatName, ref_name)) return false;
+        }
+    }
+
+
+    // Compare device compute versions
+
+    {
+        // Check Device OpenCL Version
+        auto lversion =  ldev->getInfo<CL_DEVICE_VERSION>();
+        auto rversion =  rdev->getInfo<CL_DEVICE_VERSION>();
+
+        auto lres = (lversion[7] > rversion[7]) ||
+            ((lversion[7] == rversion[7]) && (lversion[9] > rversion[9]));
+
+        auto rres = (lversion[7] < rversion[7]) ||
+            ((lversion[7] == rversion[7]) && (lversion[9] < rversion[9]));
+
+        if (lres > 0) return true;
+        if (rres < 0) return false;
+    }
+
+    // Default crietria, sort based on memory
+    // Sort based on memory
+    auto l_mem = ldev->getInfo<CL_DEVICE_GLOBAL_MEM_SIZE>();
+    auto r_mem = rdev->getInfo<CL_DEVICE_GLOBAL_MEM_SIZE>();
+    return l_mem >= r_mem;
+}
+
 DeviceManager::DeviceManager()
     : mUserDeviceOffset(0), mActiveCtxId(0), mActiveQId(0)
 {
@@ -117,41 +205,46 @@ DeviceManager::DeviceManager()
         std::vector<cl::Platform>   platforms;
         Platform::get(&platforms);
 
-        cl_device_type DEVC_TYPES[] = {
-            CL_DEVICE_TYPE_GPU,
-#ifndef OS_MAC
-            CL_DEVICE_TYPE_ACCELERATOR,
-            CL_DEVICE_TYPE_CPU
+        // This is all we need because the sort takes care of the order of devices
+#ifdef OS_MAC
+        cl_device_type DEVICE_TYPES = CL_DEVICE_TYPE_GPU;
+#else
+        cl_device_type DEVICE_TYPES = CL_DEVICE_TYPE_ALL;
 #endif
-        };
-
-        unsigned nDevices = 0;
-        for (auto devType : DEVC_TYPES) {
-            for (auto &platform : platforms) {
-
-                cl_context_properties cps[3] = {CL_CONTEXT_PLATFORM,
-                    (cl_context_properties)(platform()),
-                    0};
-
-                std::vector<Device> devs;
-                try {
-                    platform.getDevices(devType, &devs);
-                } catch(const cl::Error &err) {
-                    if (err.err() != CL_DEVICE_NOT_FOUND) {
-                        throw;
-                    }
-                }
 
-                for (auto dev : devs) {
-                    nDevices++;
-                    Context *ctx = new Context(dev, cps);
-                    CommandQueue *cq = new CommandQueue(*ctx, dev);
-                    mDevices.push_back(new Device(dev));
-                    mContexts.push_back(ctx);
-                    mQueues.push_back(cq);
-                    mIsGLSharingOn.push_back(false);
+        // Iterate through platforms, get all available devices and store them
+        for (auto &platform : platforms) {
+            std::vector<Device> current_devices;
+
+            try {
+                platform.getDevices(DEVICE_TYPES, &current_devices);
+            } catch(const cl::Error &err) {
+                if (err.err() != CL_DEVICE_NOT_FOUND) {
+                    throw;
                 }
             }
+
+            for (auto dev : current_devices) {
+                mDevices.push_back(new Device(dev));
+            }
+        }
+
+        // Sort OpenCL devices based on default criteria
+        std::stable_sort(mDevices.begin(), mDevices.end(), compare_default);
+
+        // Create contexts and queues once the sort is done
+        int nDevices = mDevices.size();
+        for (int i = 0; i < nDevices; i++) {
+            cl_platform_id device_platform = mDevices[i]->getInfo<CL_DEVICE_PLATFORM>();
+            cl_context_properties cps[3] = {CL_CONTEXT_PLATFORM,
+                                            (cl_context_properties)(device_platform),
+                                            0};
+
+            Context *ctx = new Context(*mDevices[i], cps);
+            CommandQueue *cq = new CommandQueue(*ctx, *mDevices[i]);
+            mContexts.push_back(ctx);
+            mQueues.push_back(cq);
+            mIsGLSharingOn.push_back(false);
         }
 
         std::string deviceENV = getEnvVar("AF_OPENCL_DEFAULT_DEVICE");
@@ -204,11 +297,12 @@ static std::string platformMap(std::string &platStr)
     typedef std::map<std::string, std::string> strmap_t;
     static strmap_t platMap;
     if (isFirst) {
-        platMap["NVIDIA CUDA"] = "NVIDIA  ";
-        platMap["Intel(R) OpenCL"] = "INTEL   ";
+        platMap["NVIDIA CUDA"]                         = "NVIDIA  ";
+        platMap["Intel(R) OpenCL"]                     = "INTEL   ";
         platMap["AMD Accelerated Parallel Processing"] = "AMD     ";
-        platMap["Intel Gen OCL Driver"] = "BEIGNET ";
-        platMap["Apple"] = "APPLE   ";
+        platMap["Intel Gen OCL Driver"]                = "BEIGNET ";
+        platMap["Apple"]                               = "APPLE   ";
+        platMap["Portable Computing Language"]         = "POCL    ";
         isFirst = false;
     }
 
@@ -228,38 +322,37 @@ std::string getInfo()
          << " (OpenCL, " << get_system() << ", build " << AF_REVISION << ")" << std::endl;
 
     unsigned nDevices = 0;
-    for (auto context : DeviceManager::getInstance().mContexts) {
-        vector<Device> devices = context->getInfo<CL_CONTEXT_DEVICES>();
+    for(auto &device: DeviceManager::getInstance().mDevices) {
+        const Platform platform(device->getInfo<CL_DEVICE_PLATFORM>());
 
-        for(auto &device:devices) {
-            const Platform platform(device.getInfo<CL_DEVICE_PLATFORM>());
+        string dstr = device->getInfo<CL_DEVICE_NAME>();
 
-            string platStr = platform.getInfo<CL_PLATFORM_NAME>();
-            string dstr = device.getInfo<CL_DEVICE_NAME>();
+        // Remove null termination character from the strings
+        dstr.pop_back();
+
+        bool show_braces = ((unsigned)getActiveDeviceId() == nDevices);
 
-            // Remove null termination character from the strings
-            platStr.pop_back();
-            dstr.pop_back();
+        string id =
+            (show_braces ? string("[") : "-") +
+            std::to_string(nDevices) +
+            (show_braces ? string("]") : "-");
 
-            bool show_braces = ((unsigned)getActiveDeviceId() == nDevices);
-            string id = (show_braces ? string("[") : "-") + std::to_string(nDevices) +
-                        (show_braces ? string("]") : "-");
-            info << id << " " << platformMap(platStr) << ": " << ltrim(dstr) << " ";
+        info << id << " " << getPlatformName(*device) << ": " << ltrim(dstr);
 #ifndef NDEBUG
-            string devVersion = device.getInfo<CL_DEVICE_VERSION>();
-            string driVersion = device.getInfo<CL_DRIVER_VERSION>();
-            devVersion.pop_back();
-            driVersion.pop_back();
-            info << devVersion;
-            info << " Device driver " << driVersion;
-            info << " FP64 Support("
-                 << (device.getInfo<CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE>()>0 ? "True" : "False")
-                 << ")";
+        info << " -- ";
+        string devVersion = device->getInfo<CL_DEVICE_VERSION>();
+        string driVersion = device->getInfo<CL_DRIVER_VERSION>();
+        devVersion.pop_back();
+        driVersion.pop_back();
+        info << devVersion;
+        info << " -- Device driver " << driVersion;
+        info << " -- FP64 Support: "
+             << (device->getInfo<CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE>()>0 ? "True" : "False")
+             << "";
 #endif
-            info << std::endl;
+        info << std::endl;
 
-            nDevices++;
-        }
+        nDevices++;
     }
     return info.str();
 }
@@ -268,6 +361,8 @@ std::string getPlatformName(const cl::Device &device)
 {
     const Platform platform(device.getInfo<CL_DEVICE_PLATFORM>());
     std::string platStr = platform.getInfo<CL_PLATFORM_NAME>();
+    // Remove null termination character from the strings
+    platStr.pop_back();
     return platformMap(platStr);
 }
 

-- 
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