[arrayfire] 125/408: Add SVD Cuda backend
Ghislain Vaillant
ghisvail-guest at moszumanska.debian.org
Mon Sep 21 19:11:35 UTC 2015
This is an automated email from the git hooks/post-receive script.
ghisvail-guest pushed a commit to branch debian/sid
in repository arrayfire.
commit 369013ce9af31aa1c22a7363a66ad0da74a8aa37
Author: Richard Klemm <richy at coding-reality.de>
Date: Sat Jul 4 22:39:42 2015 +0200
Add SVD Cuda backend
---
src/backend/cuda/svd.cu | 143 +++++++++++++++++++++++++++++++++++++++++++++++
src/backend/cuda/svd.hpp | 20 +++++++
2 files changed, 163 insertions(+)
diff --git a/src/backend/cuda/svd.cu b/src/backend/cuda/svd.cu
new file mode 100644
index 0000000..8e7b3ac
--- /dev/null
+++ b/src/backend/cuda/svd.cu
@@ -0,0 +1,143 @@
+/*******************************************************
+ * 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 <svd.hpp>
+#include <err_common.hpp>
+
+#if defined(WITH_CUDA_LINEAR_ALGEBRA)
+
+#include <cusolverDnManager.hpp>
+#include "transpose.hpp"
+#include <memory.hpp>
+#include <copy.hpp>
+#include <math.hpp>
+#include <err_common.hpp>
+
+namespace cuda
+{
+ using cusolver::getDnHandle;
+
+ template <typename T>
+ struct gesvd_func_def_t {
+ typedef cusolverStatus_t (*gesvd_func_def)(cusolverDnHandle_t, char, char, int,
+ int, T *, int, T *, T *, int, T *, int,
+ T *, int, T *, int *);
+ };
+
+ template<typename T>
+ struct gesvd_buf_func_def_t {
+ typedef cusolverStatus_t (*gesvd_buf_func_def)(cusolverDnHandle_t, int, int,
+ int *);
+ };
+
+#define SVD_FUNC_DEF(FUNC) \
+ template <typename T> \
+ typename FUNC##_func_def_t<T>::FUNC##_func_def FUNC##_func(); \
+ \
+ template<typename T> \
+ typename FUNC##_buf_func_def_t<T>::FUNC##_buf_func_def \
+ FUNC##_buf_func();
+
+#define SVD_FUNC(FUNC, TYPE, PREFIX) \
+ template <> \
+ typename FUNC##_func_def_t<TYPE>::FUNC##_func_def FUNC##_func<TYPE>() \
+ { \
+ return (FUNC##_func_def_t<TYPE>::FUNC##_func_def) & cusolverDn##PREFIX##FUNC; \
+ } \
+ \
+ template<> typename FUNC##_buf_func_def_t<TYPE>::FUNC##_buf_func_def \
+ FUNC##_buf_func<TYPE>() \
+ { \
+ return (FUNC##_buf_func_def_t<TYPE>::FUNC##_buf_func_def) & \
+ cusolverDn##PREFIX##FUNC##_bufferSize; \
+ }
+
+ SVD_FUNC_DEF(gesvd)
+ SVD_FUNC(gesvd, float, S)
+ SVD_FUNC(gesvd, double, D)
+//SVD_FUNC(gesvd , cfloat , C)
+//SVD_FUNC(gesvd , cdouble, Z)
+
+ template <typename T>
+ void svdInPlace(Array<T> &s, Array<T> &u, Array<T> &vt, Array<T> &in)
+ {
+ dim4 iDims = in.dims();
+ int M = iDims[0];
+ int N = iDims[1];
+
+ // cuSolver(cuda 7.0) doesn't have support for M<N
+ bool flip_and_transpose = M < N;
+
+ if (flip_and_transpose) {
+ std::swap(M, N);
+ std::swap(vt, u);
+ }
+
+ int lwork = 0;
+ CUSOLVER_CHECK(gesvd_buf_func<T>()(getDnHandle(), M, N, &lwork));
+ T *lWorkspace = memAlloc<T>(lwork);
+ //complex numbers would need rWorkspace
+ //T *rWorkspace = memAlloc<T>(lwork);
+
+ int *info = memAlloc<int>(1);
+
+ if (flip_and_transpose) {
+ transpose_inplace(in, true);
+ CUSOLVER_CHECK(gesvd_func<T>()(getDnHandle(), 'A', 'A', M, N, in.get(),
+ M, s.get(), u.get(), M, vt.get(), N,
+ lWorkspace, lwork, NULL, info));
+ std::swap(u, vt);
+ transpose_inplace(vt, true);
+ } else {
+ Array<T> inCopy = copyArray<T>(in);
+ CUSOLVER_CHECK(gesvd_func<T>()(getDnHandle(), 'A', 'A', M, N, in.get(),
+ M, s.get(), u.get(), M, vt.get(), N,
+ lWorkspace, lwork, NULL, info));
+ }
+ memFree(info);
+ memFree(lWorkspace);
+ //memFree(rWorkspace);
+ }
+
+ template <typename T>
+ void svd(Array<T> &s, Array<T> &u, Array<T> &vt, const Array<T> &in)
+ {
+ Array<T> inCopy = copyArray<T>(in);
+ svdInPlace(s, u, vt, inCopy);
+ }
+
+#define INSTANTIATE_SVD(T) \
+ template void svd<T>(Array<T> &s, Array<T> &u, Array<T> &vt, const Array<T> &in); \
+ template void svdInPlace<T>(Array<T> &s, Array<T> &u, Array<T> &vt, Array<T> &in); \
+
+ INSTANTIATE_SVD(float)
+ //INSTANTIATE_SVD(cfloat)
+ INSTANTIATE_SVD(double)
+ //INSTANTIATE_SVD(cdouble)
+}
+
+#else
+namespace cuda
+{
+ template <typename T>
+ void svd(Array<T> &s, Array<T> &u, Array<T> &vt, const Array<T> &in)
+ {
+ AF_ERROR("CUDA cusolver not available. Linear Algebra is disabled",
+ AF_ERR_NOT_CONFIGURED);
+ }
+
+#define INSTANTIATE_SVD(T) \
+ template void svd<T>(Array<T> &s, Array<T> &u, Array<T> &vt, const Array<T> &in); \
+
+ INSTANTIATE_SVD(float)
+ //INSTANTIATE_SVD(cfloat)
+ INSTANTIATE_SVD(double)
+ //INSTANTIATE_SVD(cdouble)
+}
+#endif
diff --git a/src/backend/cuda/svd.hpp b/src/backend/cuda/svd.hpp
new file mode 100644
index 0000000..44de4c2
--- /dev/null
+++ b/src/backend/cuda/svd.hpp
@@ -0,0 +1,20 @@
+/*******************************************************
+ * 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 <af/array.h>
+#include <Array.hpp>
+
+namespace cuda
+{
+ template <typename T>
+ void svd(Array<T> &s, Array<T> &u, Array<T> &vt, const Array<T> &in);
+
+ template <typename T>
+ void svdInPlace(Array<T> &s, Array<T> &u, Array<T> &vt, Array<T> &in);
+}
--
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