MCPcopy Create free account
hub / github.com/arrayfire/arrayfire / svd

Function svd

src/backend/opencl/svd.cpp:65–195  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

63
64template<typename T, typename Tr>
65void svd(Array<T> &arrU, Array<Tr> &arrS, Array<T> &arrVT, Array<T> &arrA,
66 bool want_vectors = true) {
67 dim4 idims = arrA.dims();
68 dim4 istrides = arrA.strides();
69
70 const int m = static_cast<int>(idims[0]);
71 const int n = static_cast<int>(idims[1]);
72 const int ldda = static_cast<int>(istrides[1]);
73 const int lda = m;
74 const int min_mn = std::min(m, n);
75 const int ldu = m;
76 const int ldvt = n;
77
78 const int nb = magma_get_gebrd_nb<T>(n);
79 const int lwork = (m + n) * nb;
80
81 cpu_lapack_lacpy_func<T> cpu_lapack_lacpy;
82 cpu_lapack_bdsqr_work_func<T> cpu_lapack_bdsqr_work;
83 cpu_lapack_ungbr_work_func<T> cpu_lapack_ungbr_work;
84 cpu_lapack_lamch_func<Tr> cpu_lapack_lamch;
85
86 // Get machine constants
87 static const double eps = cpu_lapack_lamch('P');
88 static const double smlnum = std::sqrt(cpu_lapack_lamch('S')) / eps;
89 static const double bignum = 1. / smlnum;
90
91 Tr anrm = abs(getScalar<T>(reduce_all<af_max_t, T, T>(arrA)));
92
93 T scale = scalar<T>(1);
94 static const int ione = 1;
95 static const int izero = 0;
96
97 bool iscl = false;
98 if (anrm > 0. && anrm < smlnum) {
99 iscl = true;
100 scale = scalar<T>(calc_scale<Tr>(anrm, smlnum));
101 } else if (anrm > bignum) {
102 iscl = true;
103 scale = scalar<T>(calc_scale<Tr>(anrm, bignum));
104 }
105
106 if (iscl == 1) { multiply_inplace(arrA, abs(scale)); }
107
108 int nru = 0;
109 int ncvt = 0;
110
111 // Instead of copying U, S, VT, and A to the host and copying the results
112 // back to the device, create a pointer that's mapped to device memory where
113 // the computation can directly happen
114 T *mappedA = static_cast<T *>(getQueue().enqueueMapBuffer(
115 *arrA.get(), CL_FALSE, CL_MAP_READ, sizeof(T) * arrA.getOffset(),
116 sizeof(T) * arrA.elements()));
117 std::vector<T> tauq(min_mn), taup(min_mn);
118 std::vector<T> work(lwork);
119 Tr *mappedS0 = (Tr *)getQueue().enqueueMapBuffer(
120 *arrS.get(), CL_TRUE, CL_MAP_WRITE, sizeof(Tr) * arrS.getOffset(),
121 sizeof(Tr) * arrS.elements());
122 std::vector<Tr> s1(min_mn - 1);

Callers

nothing calls this directly

Calls 15

sqrtFunction · 0.85
OpenCLCPUOffloadFunction · 0.85
minFunction · 0.70
absFunction · 0.70
multiply_inplaceFunction · 0.70
copyArrayFunction · 0.70
svdInPlaceFunction · 0.70
transposeFunction · 0.70
transpose_inplaceFunction · 0.70
getQueueFunction · 0.50
dimsMethod · 0.45
stridesMethod · 0.45

Tested by

no test coverage detected