[arrayfire] 173/284: Add OpenCL-CPU fallback for Cholesky

Ghislain Vaillant ghisvail-guest at moszumanska.debian.org
Sun Feb 7 18:59:30 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 88e910d9a9e91dc38b888fabd70a3a307e79307c
Author: Shehzan Mohammed <shehzan at arrayfire.com>
Date:   Fri Jan 8 11:21:01 2016 -0500

    Add OpenCL-CPU fallback for Cholesky
---
 src/backend/opencl/cholesky.cpp         | 13 ++++-
 src/backend/opencl/cpu/cpu_cholesky.cpp | 88 +++++++++++++++++++++++++++++++++
 src/backend/opencl/cpu/cpu_cholesky.hpp | 22 +++++++++
 src/backend/opencl/cpu/cpu_triangle.hpp | 52 +++++++++++++++++++
 4 files changed, 173 insertions(+), 2 deletions(-)

diff --git a/src/backend/opencl/cholesky.cpp b/src/backend/opencl/cholesky.cpp
index 78fe999..a2034a3 100644
--- a/src/backend/opencl/cholesky.cpp
+++ b/src/backend/opencl/cholesky.cpp
@@ -8,14 +8,16 @@
  ********************************************************/
 
 #include <cholesky.hpp>
-#include <copy.hpp>
 #include <err_common.hpp>
-#include <blas.hpp>
 #include <err_opencl.hpp>
+#include <blas.hpp>
+#include <copy.hpp>
 
 #if defined(WITH_OPENCL_LINEAR_ALGEBRA)
 #include <magma/magma.h>
 #include <triangle.hpp>
+#include <platform.hpp>
+#include <cpu/cpu_cholesky.hpp>
 
 namespace opencl
 {
@@ -24,6 +26,10 @@ template<typename T>
 int cholesky_inplace(Array<T> &in, const bool is_upper)
 {
     try {
+        if(OpenCLCPUOffload()) {
+            return cpu::cholesky_inplace(in, is_upper);
+        }
+
         initBlas();
 
         dim4 iDims = in.dims();
@@ -46,6 +52,9 @@ template<typename T>
 Array<T> cholesky(int *info, const Array<T> &in, const bool is_upper)
 {
     try {
+        if(OpenCLCPUOffload()) {
+            return cpu::cholesky(info, in, is_upper);
+        }
 
         Array<T> out = copyArray<T>(in);
         *info = cholesky_inplace(out, is_upper);
diff --git a/src/backend/opencl/cpu/cpu_cholesky.cpp b/src/backend/opencl/cpu/cpu_cholesky.cpp
new file mode 100644
index 0000000..234df2b
--- /dev/null
+++ b/src/backend/opencl/cpu/cpu_cholesky.cpp
@@ -0,0 +1,88 @@
+/*******************************************************
+ * Copyright (c) 2014, ArrayFire
+ * All rights reserved.
+ *
+ * This file is distributed under 3-clause BSD license.
+ * The complete license agreement can be obtained at:
+ * http://arrayfire.com/licenses/BSD-3-Clause
+ ********************************************************/
+
+#include <cpu/cpu_lapack_helper.hpp>
+#include <cpu/cpu_cholesky.hpp>
+#include <err_common.hpp>
+
+#include <af/dim4.hpp>
+#include <handle.hpp>
+#include <iostream>
+#include <cassert>
+
+#include <cpu/cpu_triangle.hpp>
+
+namespace opencl
+{
+namespace cpu
+{
+
+template<typename T>
+using potrf_func_def = int (*)(ORDER_TYPE, char,
+                               int,
+                               T*, int);
+
+#define CH_FUNC_DEF( FUNC )                                     \
+template<typename T> FUNC##_func_def<T> FUNC##_func();
+
+
+#define CH_FUNC( FUNC, TYPE, PREFIX )                           \
+template<> FUNC##_func_def<TYPE>     FUNC##_func<TYPE>()        \
+{ return & LAPACK_NAME(PREFIX##FUNC); }
+
+CH_FUNC_DEF( potrf )
+CH_FUNC(potrf , float  , s)
+CH_FUNC(potrf , double , d)
+CH_FUNC(potrf , cfloat , c)
+CH_FUNC(potrf , cdouble, z)
+
+template<typename T>
+Array<T> cholesky(int *info, const Array<T> &in, const bool is_upper)
+{
+    Array<T> out = copyArray<T>(in);
+    *info = cholesky_inplace(out, is_upper);
+
+    T* oPtr = getMappedPtr<T>(out.get());
+    if (is_upper) triangle<T, true , false>(oPtr, oPtr, out.dims(), out.strides(), out.strides());
+    else          triangle<T, false, false>(oPtr, oPtr, out.dims(), out.strides(), out.strides());
+    unmapPtr(out.get(), oPtr);
+
+    return out;
+}
+
+template<typename T>
+int cholesky_inplace(Array<T> &in, const bool is_upper)
+{
+    dim4 iDims = in.dims();
+    int N = iDims[0];
+
+    char uplo = 'L';
+    if(is_upper)
+        uplo = 'U';
+
+    T* inPtr = getMappedPtr<T>(in.get());
+    int info = potrf_func<T>()(AF_LAPACK_COL_MAJOR, uplo,
+                               N, inPtr, in.strides()[1]);
+    unmapPtr(in.get(), inPtr);
+
+    return info;
+}
+
+#define INSTANTIATE_CH(T)                                                                   \
+    template int cholesky_inplace<T>(Array<T> &in, const bool is_upper);                    \
+    template Array<T> cholesky<T>   (int *info, const Array<T> &in, const bool is_upper);   \
+
+
+INSTANTIATE_CH(float)
+INSTANTIATE_CH(cfloat)
+INSTANTIATE_CH(double)
+INSTANTIATE_CH(cdouble)
+
+}
+}
diff --git a/src/backend/opencl/cpu/cpu_cholesky.hpp b/src/backend/opencl/cpu/cpu_cholesky.hpp
new file mode 100644
index 0000000..041e939
--- /dev/null
+++ b/src/backend/opencl/cpu/cpu_cholesky.hpp
@@ -0,0 +1,22 @@
+/*******************************************************
+ * Copyright (c) 2014, ArrayFire
+ * All rights reserved.
+ *
+ * This file is distributed under 3-clause BSD license.
+ * The complete license agreement can be obtained at:
+ * http://arrayfire.com/licenses/BSD-3-Clause
+ ********************************************************/
+
+#include <Array.hpp>
+
+namespace opencl
+{
+namespace cpu
+{
+    template<typename T>
+    Array<T> cholesky(int *info, const Array<T> &in, const bool is_upper);
+
+    template<typename T>
+    int cholesky_inplace(Array<T> &in, const bool is_upper);
+}
+}
diff --git a/src/backend/opencl/cpu/cpu_triangle.hpp b/src/backend/opencl/cpu/cpu_triangle.hpp
new file mode 100644
index 0000000..5e40f92
--- /dev/null
+++ b/src/backend/opencl/cpu/cpu_triangle.hpp
@@ -0,0 +1,52 @@
+/*******************************************************
+ * Copyright (c) 2014, ArrayFire
+ * All rights reserved.
+ *
+ * This file is distributed under 3-clause BSD license.
+ * The complete license agreement can be obtained at:
+ * http://arrayfire.com/licenses/BSD-3-Clause
+ ********************************************************/
+
+#ifndef CPU_LAPACK_TRIANGLE
+#define CPU_LAPACK_TRIANGLE
+namespace opencl
+{
+namespace cpu
+{
+
+template<typename T, bool is_upper, bool is_unit_diag>
+void triangle(T *o, const T *i, const dim4 odm, const dim4 ost, const dim4 ist)
+{
+    for(dim_t ow = 0; ow < odm[3]; ow++) {
+        const dim_t oW = ow * ost[3];
+        const dim_t iW = ow * ist[3];
+
+        for(dim_t oz = 0; oz < odm[2]; oz++) {
+            const dim_t oZW = oW + oz * ost[2];
+            const dim_t iZW = iW + oz * ist[2];
+
+            for(dim_t oy = 0; oy < odm[1]; oy++) {
+                const dim_t oYZW = oZW + oy * ost[1];
+                const dim_t iYZW = iZW + oy * ist[1];
+
+                for(dim_t ox = 0; ox < odm[0]; ox++) {
+                    const dim_t oMem = oYZW + ox;
+                    const dim_t iMem = iYZW + ox;
+
+                    bool cond = is_upper ? (oy >= ox) : (oy <= ox);
+                    bool do_unit_diag = (is_unit_diag && ox == oy);
+                    if(cond) {
+                        o[oMem] = do_unit_diag ? scalar<T>(1) : i[iMem];
+                    } else {
+                        o[oMem] = scalar<T>(0);
+                    }
+                }
+            }
+        }
+    }
+}
+
+}
+}
+
+#endif

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