[arrayfire] 175/284: Add OpenCL-CPU fallback for SVD

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 59a9df0957537e4933c145482034704d68915c1b
Author: Shehzan Mohammed <shehzan at arrayfire.com>
Date:   Fri Jan 8 12:48:30 2016 -0500

    Add OpenCL-CPU fallback for SVD
---
 src/backend/opencl/cpu/cpu_svd.cpp | 103 +++++++++++++++++++++++++++++++++++++
 src/backend/opencl/cpu/cpu_svd.hpp |  22 ++++++++
 src/backend/opencl/svd.cpp         |  10 ++++
 3 files changed, 135 insertions(+)

diff --git a/src/backend/opencl/cpu/cpu_svd.cpp b/src/backend/opencl/cpu/cpu_svd.cpp
new file mode 100644
index 0000000..85b9ee8
--- /dev/null
+++ b/src/backend/opencl/cpu/cpu_svd.cpp
@@ -0,0 +1,103 @@
+/*******************************************************
+ * 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_svd.hpp>
+#include <err_common.hpp>
+
+#include <copy.hpp>
+
+namespace opencl
+{
+namespace cpu
+{
+
+#define SVD_FUNC_DEF( FUNC )                                            \
+    template<typename T,typename Tr> svd_func_def<T, Tr> svd_func();
+
+#define SVD_FUNC( FUNC, T, Tr, PREFIX )                     \
+    template<> svd_func_def<T, Tr>     svd_func<T, Tr>()    \
+    { return & LAPACK_NAME(PREFIX##FUNC); }
+
+#if defined(USE_MKL) || defined(__APPLE__)
+
+    template<typename T, typename Tr>
+    using svd_func_def = int (*)(ORDER_TYPE,
+                                 char jobz,
+                                 int m, int n,
+                                 T* in, int ldin,
+                                 Tr* s,
+                                 T* u, int ldu,
+                                 T* vt, int ldvt);
+
+    SVD_FUNC_DEF( gesdd )
+    SVD_FUNC(gesdd, float  , float , s)
+    SVD_FUNC(gesdd, double , double, d)
+    SVD_FUNC(gesdd, cfloat , float , c)
+    SVD_FUNC(gesdd, cdouble, double, z)
+
+#else   // Atlas causes memory freeing issues with using gesdd
+
+    template<typename T, typename Tr>
+    using svd_func_def = int (*)(ORDER_TYPE,
+                                 char jobu, char jobvt,
+                                 int m, int n,
+                                 T* in, int ldin,
+                                 Tr* s,
+                                 T* u, int ldu,
+                                 T* vt, int ldvt,
+                                 Tr *superb);
+
+    SVD_FUNC_DEF( gesvd )
+    SVD_FUNC(gesvd, float  , float , s)
+    SVD_FUNC(gesvd, double , double, d)
+    SVD_FUNC(gesvd, cfloat , float , c)
+    SVD_FUNC(gesvd, cdouble, double, z)
+
+#endif
+
+    template <typename T, typename Tr>
+    void svdInPlace(Array<Tr> &s, Array<T> &u, Array<T> &vt, Array<T> &in)
+    {
+        dim4 iDims = in.dims();
+        int M = iDims[0];
+        int N = iDims[1];
+
+        Tr *sPtr = getMappedPtr<Tr>(s.get());
+        T  *uPtr = getMappedPtr<T >(u.get());
+        T  *vPtr = getMappedPtr<T >(vt.get());
+        T  *iPtr = getMappedPtr<T >(in.get());
+
+#if defined(USE_MKL) || defined(__APPLE__)
+        svd_func<T, Tr>()(AF_LAPACK_COL_MAJOR, 'A', M, N, iPtr, in.strides()[1],
+                          sPtr, uPtr, u.strides()[1], vPtr, vt.strides()[1]);
+#else
+        std::vector<Tr> superb(std::min(M, N));
+        svd_func<T, Tr>()(AF_LAPACK_COL_MAJOR, 'A', 'A', M, N, iPtr, in.strides()[1],
+                          sPtr, uPtr, u.strides()[1], vPtr, vt.strides()[1], &superb[0]);
+#endif
+    }
+
+    template <typename T, typename Tr>
+    void svd(Array<Tr> &s, Array<T> &u, Array<T> &vt, const Array<T> &in)
+    {
+        Array<T> in_copy = copyArray<T>(in);
+        svdInPlace(s, u, vt, in_copy);
+    }
+
+#define INSTANTIATE_SVD(T, Tr)                                          \
+    template void svd<T, Tr>(Array<Tr> & s, Array<T> & u, Array<T> & vt, const Array<T> &in); \
+    template void svdInPlace<T, Tr>(Array<Tr> & s, Array<T> & u, Array<T> & vt, Array<T> &in);
+
+    INSTANTIATE_SVD(float  , float )
+    INSTANTIATE_SVD(double , double)
+    INSTANTIATE_SVD(cfloat , float )
+    INSTANTIATE_SVD(cdouble, double)
+}
+}
diff --git a/src/backend/opencl/cpu/cpu_svd.hpp b/src/backend/opencl/cpu/cpu_svd.hpp
new file mode 100644
index 0000000..4f271af
--- /dev/null
+++ b/src/backend/opencl/cpu/cpu_svd.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, typename Tr>
+    void svd(Array<Tr> &s, Array<T> &u, Array<T> &vt, const Array<T> &in);
+
+    template<typename T, typename Tr>
+    void svdInPlace(Array<Tr> &s, Array<T> &u, Array<T> &vt, Array<T> &in);
+}
+}
diff --git a/src/backend/opencl/svd.cpp b/src/backend/opencl/svd.cpp
index 77f7c8a..61da27b 100644
--- a/src/backend/opencl/svd.cpp
+++ b/src/backend/opencl/svd.cpp
@@ -20,6 +20,8 @@
 #include <magma/magma.h>
 #include <magma/magma_cpu_lapack.h>
 #include <magma/magma_helper.h>
+#include <platform.hpp>
+#include <cpu/cpu_svd.hpp>
 
 namespace opencl
 {
@@ -196,6 +198,10 @@ void svd(Array<T > &arrU,
 template<typename T, typename Tr>
 void svdInPlace(Array<Tr> &s, Array<T> &u, Array<T> &vt, Array<T> &in)
 {
+    if(OpenCLCPUOffload()) {
+        return cpu::svdInPlace(s, u, vt, in);
+    }
+
     initBlas();
     svd<T, Tr>(u, s, vt, in, true);
 }
@@ -203,6 +209,10 @@ void svdInPlace(Array<Tr> &s, Array<T> &u, Array<T> &vt, Array<T> &in)
 template<typename T, typename Tr>
 void svd(Array<Tr> &s, Array<T> &u, Array<T> &vt, const Array<T> &in)
 {
+    if(OpenCLCPUOffload()) {
+        return cpu::svd(s, u, vt, in);
+    }
+
     dim4 iDims = in.dims();
     int M = iDims[0];
     int N = iDims[1];

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