62 auto name = appendName<T>(
"obj_");
66 py::class_<Class>(mod,
name.data(), py::buffer_protocol())
68 const py::array_t<T, py::array::f_style |
69 py::array::forcecast> &data) {
70 int ndim =
data.ndim() + 1;
71 std::vector<long> data_dims(ndim);
72 data_dims[0] =
data.ndim();
74 begin(data_dims) + 1);
75 return std::unique_ptr<Class>(
76 new Class(&c, data_dims.data(), (
const T *)
data.data()));
79 py::arg(
"context").none(
false), py::arg(
"h_data").none(
false))
82 return std::unique_ptr<Class>(
new Class(&c, &data));
85 py::arg(
"context").none(
false), py::arg(
"d_data").none(
false))
87 .def_buffer([](Class &frame) -> py::buffer_info {
90 const long *dims =
frame.get_dims();
91 std::vector<ssize_t> shape(dims[0]);
92 std::vector<ssize_t> strides(dims[0]);
93 ssize_t stride =
sizeof(T);
104 for (ssize_t dim(0); dim < dims[0]; ++dim) {
105 shape[dim] = dims[dim + 1];
106 strides[dim] = stride;
107 stride *= shape[dim];
110 return py::buffer_info(
frame.get_h_data(),
sizeof(T),
111 py::format_descriptor<T>::format(), dims[0],
118 .def_property_readonly(
"nb_streams", &Class::get_nb_streams,
121 .def(
"add_stream", (
int (Class::*)()) & Class::add_stream,
124 .def(
"add_stream", (
int (Class::*)(
int)) & Class::add_stream,
"TODO",
127 .def(
"del_stream", (
int (Class::*)()) & Class::del_stream,
130 .def(
"del_stream", (
int (Class::*)(
int)) & Class::del_stream,
"TODO",
133 .def(
"wait_stream", &Class::wait_stream,
"TODO",
135 .def(
"swap_ptr", [](Class &obj, Class &obj2){
136 obj.swap_ptr(obj2.get_data());
141 .def(
"swap_ptr", [](Class &obj, ipc::Cacao<T> &obj2){
142 obj.swap_ptr(obj2.inputPtr());
147 .def(
"wait_all_streams", &Class::wait_all_streams,
151 .def_property_readonly(
"shape",
152 [](Class &frame) -> py::array_t<long> {
153 long nb_dim =
frame.get_dims(0);
154 const long *c_dim =
frame.get_dims() + 1;
155 return py::array_t<long>(nb_dim, c_dim);
160 .def_property_readonly(
"nbElem", &Class::get_nb_elements,
163 .def_property_readonly(
"context", &Class::get_context,
166 .def_property_readonly(
"device", &Class::get_device,
169 .def_property_readonly(
"o_data", &Class::get_o_data_value,
175 py::array_t<T, py::array::f_style | py::array::forcecast>
176 &data) {
c.host2device((
const T *)
data.data()); },
178 py::arg(
"data").none(
false))
182 py::array_t<T, py::array::f_style | py::array::forcecast>
183 &data) {
c.device2host((T *)
data.mutable_data()); },
185 py::arg(
"data").none(
false))
189 [](Class &src, Class &dest,
long nb_elem) {
191 nb_elem = src.get_nb_elements();
193 src.copy_into(dest, nb_elem);
195 "TODO", py::arg(
"dest"),
196 py::arg(
"nb_elem") = -1)
199 [](Class &dest, Class &src,
long nb_elem) {
201 nb_elem = dest.get_nb_elements();
203 dest.copy_from(src, nb_elem);
205 "TODO", py::arg(
"data"),
206 py::arg(
"nb_elem") = -1)
208 .def(
"copy_into",(
int (Class::*)(ipc::Cacao<T>*))&Class::copy_into)
209 .def(
"copy_from",(
int (Class::*)(ipc::Cacao<T>*))&Class::copy_from)
212 .def(
"reset", &Class::reset,
"TODO")
216 .def(
"sum", &Class::sum,
"TODO")
218 .def(
"init_reduceCub", &Class::init_reduceCub,
221 .def(
"reduceCub", &Class::reduceCub,
224 .def(
"clip", &Class::clip,
"TODO", py::arg(
"data_min").none(
false),
225 py::arg(
"data_max").none(
false))
229 .def(
"transpose", &Class::transpose,
"TODO",
230 py::arg(
"source").none(
false))
235 .def(
"aimax", &Class::aimax,
"TODO",
238 .def(
"aimin", &Class::aimin,
"TODO",
241 .def(
"asum", &Class::asum,
"TODO",
244 .def(
"nrm2", &Class::nrm2,
"TODO",
247 .def(
"dot", &Class::dot,
"TODO", py::arg(
"source").none(
false),
251 .def(
"scale", &Class::scale,
"TODO", py::arg(
"scale").none(
false),
254 .def(
"swap", &Class::swap,
"TODO", py::arg(
"source").none(
false),
258 .def(
"copy", &Class::copy,
"TODO")
261 .def(
"axpy", &Class::axpy,
"TODO", py::arg(
"alpha"),
262 py::arg(
"source").none(
false), py::arg(
"incx") = 1,
263 py::arg(
"incy") = 1, py::arg(
"offset") = 0)
266 .def(
"rot", &Class::rot,
"TODO")
271 [](Class &mat, Class &vectx, T alpha,
char op, Class *vecty,
273 if (vecty ==
nullptr) {
274 long dims[] = {1, 0};
275 if (op ==
'N' || op ==
'n') {
276 dims[1] = mat.get_dims(1);
278 dims[1] = mat.get_dims(2);
280 vecty =
new Class(mat.get_context(), dims);
283 carma_magma_gemv(op, mat.get_dims(1), mat.get_dims(2), alpha, mat.get_data(), mat.get_dims(1), vectx.get_data(), 1, beta, vecty->get_data(), 1);
286 "this method performs one of the matrix‐vector operations vecty = "
287 "alpha * op(mat) * vectx + beta * vecty",
288 py::arg(
"vectx"), py::arg(
"alpha") = 1, py::arg(
"op") =
'N',
289 py::arg(
"vecty") =
nullptr, py::arg(
"beta") = 0)
291 [](Class &mat, Class &vectx, T alpha,
char op, Class *vecty,
293 if (vecty ==
nullptr) {
294 long dims[] = {1, 0};
295 if (op ==
'N' || op ==
'n') {
296 dims[1] = mat.get_dims(1);
298 dims[1] = mat.get_dims(2);
300 vecty =
new Class(mat.get_context(), dims);
303 vecty->gemv(op, alpha, &mat, mat.get_dims(1), &vectx, 1, beta, 1);
306 "this method performs one of the matrix‐vector operations vecty = "
307 "alpha * op(mat) * vectx + beta * vecty",
308 py::arg(
"vectx"), py::arg(
"alpha") = 1, py::arg(
"op") =
'N',
309 py::arg(
"vecty") =
nullptr, py::arg(
"beta") = 0)
316 if (vecty ==
nullptr) {
317 long dims[] = {1, 0, 1};
318 if (op ==
'N' || op ==
'n') {
326 vecty->
gemv(op, __float2half(alpha), &mat, mat.
get_dims(1),
327 &vectx, 1, __float2half(beta), 1);
330 "this method performs one of the matrix‐vector operations vecty = "
331 "alpha * op(mat) * vectx + beta * vecty",
332 py::arg(
"vectx"), py::arg(
"alpha") = 1, py::arg(
"op") =
'N',
333 py::arg(
"vecty") =
nullptr, py::arg(
"beta") = 0)
338 [](Class &vectx, Class &vecty, Class *mat, T alpha) {
339 std::unique_ptr<Class> ptr_res;
340 if (mat ==
nullptr) {
341 long dims[] = {2, vectx.get_nb_elements(), vecty.get_nb_elements()};
342 mat =
new Class(vectx.get_context(), dims);
345 mat->ger(alpha, &vectx, 1, &vecty, 1, vectx.get_nb_elements());
348 "this method performs the symmetric rank 1 operation A = alpha * "
350 py::arg(
"vecty"), py::arg(
"mat") =
nullptr,
351 py::arg(
"alpha") = 1)
356 [](Class &mat, Class &vectx, T alpha,
char uplo, Class *vecty,
358 int lda = mat.get_dims(2);
359 if (vecty ==
nullptr) {
360 long dims[] = {1, lda};
361 vecty =
new Class(mat.get_context(), dims);
364 vecty->symv(uplo, alpha, &mat, lda, &vectx, 1, beta, 1);
367 "this method performs one of the matrix‐vector operations vecty = "
368 "alpha * mat * vectx + beta * vecty",
369 py::arg(
"vectx"), py::arg(
"alpha") = 1, py::arg(
"uplo") =
'l',
370 py::arg(
"vecty") =
nullptr, py::arg(
"beta") = 0)
376 [](Class &matA, Class &matB,
char op_a,
char op_b, T alpha,
377 Class *matC, T beta) {
378 int lda, ldb, ldc,
m,
n,
k;
379 if (op_a ==
'N' || op_a ==
'n') {
380 m = matA.get_dims(1);
381 k = matA.get_dims(2);
383 m = matA.get_dims(2);
384 k = matA.get_dims(1);
387 if (op_b ==
'N' || op_b ==
'n') {
388 k = matB.get_dims(1);
389 n = matB.get_dims(2);
391 k = matB.get_dims(2);
392 n = matB.get_dims(1);
395 if (matC ==
nullptr) {
396 long dims[] = {2,
m,
n};
397 matC =
new Class(matA.get_context(), dims);
401 carma_gemm<T>(matA.get_context()->get_cublas_handle(), op_a, op_b,
402 m, n, k, alpha, matA, matA.get_dims(1), matB,
403 matB.get_dims(1), beta, *matC, matC->get_dims(1));
406 "this method performs one of the matrix‐marix operations matC = "
407 "alpha * op_a(matA) * op_b(matB) + beta * matC",
408 py::arg(
"matB"), py::arg(
"op_a") =
'N', py::arg(
"op_b") =
"N",
409 py::arg(
"alpha") = 1, py::arg(
"matC") =
nullptr,
416 [](Class &matA, Class &matB, T alpha, Class *matC, T beta,
417 char side,
char uplo) {
418 if (matC ==
nullptr) {
419 long dims[] = {2, matB.get_dims(1), matB.get_dims(2)};
420 matC =
new Class(matA.get_context(), dims);
422 carma_symm<T>(matA.get_context()->get_cublas_handle(), side, uplo,
423 matB.get_dims(1), matB.get_dims(2), alpha, matA,
424 matA.get_dims(1), matB, matB.get_dims(1), beta,
425 *matC, matC->get_dims(1));
429 "this method performs one of the matrix‐marix operations matC = "
430 "alpha * matA * matB + beta * C",
431 py::arg(
"matB"), py::arg(
"alpha") = 1, py::arg(
"matC") =
nullptr,
432 py::arg(
"beta") = 0, py::arg(
"side") =
"l", py::arg(
"uplo") =
"u")
445 [](Class &matA,
char fill,
char op, T alpha, Class *matC, T beta) {
447 if (op ==
'N' || op ==
'n') {
448 n = matA.get_dims(1);
449 k = matA.get_dims(2);
451 n = matA.get_dims(2);
452 k = matA.get_dims(1);
454 if (matC ==
nullptr) {
455 long dims[] = {2,
n,
n};
456 matC =
new Class(matA.get_context(), dims);
459 carma_syrk<T>(matA.get_context()->get_cublas_handle(), fill, op, n,
460 k, alpha, matA, matA.get_dims(1), beta, *matC,
464 "this method performs the symmetric rank- k update",
465 py::arg(
"fill") =
"U", py::arg(
"op") =
'N', py::arg(
"alpha") = 1,
466 py::arg(
"matC") =
nullptr, py::arg(
"beta") = 0)
471 [](Class &matA, Class &matB,
char fill,
char op, T alpha,
472 Class *matC, T beta) {
474 if (op ==
'N' || op ==
'n') {
475 n = matA.get_dims(1);
476 k = matA.get_dims(2);
478 n = matA.get_dims(2);
479 k = matA.get_dims(1);
481 if (matC ==
nullptr) {
482 long dims[] = {2,
n,
n};
483 matC =
new Class(matA.get_context(), dims);
486 carma_syrkx<T>(matA.get_context()->get_cublas_handle(), fill, op,
487 n, k, alpha, matA, matA.get_dims(1), matB,
488 matB.get_dims(1), beta, *matC, matC->get_dims(1));
491 "this method performs the symmetric rank- k update",
492 py::arg(
"matB"), py::arg(
"fill") =
"U", py::arg(
"op") =
'N',
493 py::arg(
"alpha") = 1, py::arg(
"matC") =
nullptr,
500 [](Class &matA, Class &matB,
char opA,
char opB, T alpha,
501 Class *matC, T beta) {
503 if (opA ==
'N' || opA ==
'n') {
504 m = matA.get_dims(1);
505 n = matA.get_dims(2);
507 m = matA.get_dims(2);
508 n = matA.get_dims(1);
510 if (matC ==
nullptr) {
511 long dims[] = {2,
m,
n};
512 matC =
new Class(matA.get_context(), dims);
515 carma_geam<T>(matA.get_context()->get_cublas_handle(), opA, opB, m,
516 n, alpha, matA, matA.get_dims(1), beta, matB,
517 matB.get_dims(1), *matC, matC->get_dims(1));
520 "this method performs the symmetric rank- k update",
521 py::arg(
"matB"), py::arg(
"opA") =
'N', py::arg(
"opB") =
'N',
522 py::arg(
"alpha") = 1, py::arg(
"matC") =
nullptr,
525 [](Class &matA, Class &vectX, T alpha,
char side, Class *matC,
527 if (matC ==
nullptr) {
528 long dims[] = {2, matA.get_dims(1), matA.get_dims(2)};
529 matC =
new Class(matA.get_context(), dims);
532 carma_dgmm<T>(matA.get_context()->get_cublas_handle(), side,
533 matA.get_dims(1), matA.get_dims(2), matA,
534 matA.get_dims(1), vectX, incx, *matC,
538 "this method performs one of the matrix‐marix operations matC = "
539 "diag(vectX)*matA if side='l'",
540 py::arg(
"vectX"), py::arg(
"alpha") = 1, py::arg(
"side") =
"r",
541 py::arg(
"matC") =
nullptr, py::arg(
"incx") = 1)
544 .def(
"is_rng_init", &Class::is_rng_init)
546 .def(
"init_prng", (
int (Class::*)()) & Class::init_prng)
548 .def(
"init_prng", (
int (Class::*)(
long)) & Class::init_prng)
550 .def(
"destroy_prng", &Class::destroy_prng)
552 .def(
"prng", (
int (Class::*)(T *,
char,
float,
float)) & Class::prng)
554 .def(
"prng", (
int (Class::*)(T *,
char,
float)) & Class::prng)
556 .def(
"prng", (
int (Class::*)(
char,
float,
float)) & Class::prng)
558 .def(
"prng", (
int (Class::*)(
char,
float)) & Class::prng)
560 .def(
"prng", (
int (Class::*)(
char)) & Class::prng)
563 [](Class &data,
int seed,
char gtype) {
564 data.init_prng(seed);
567 py::arg(
"seed") = 1234, py::arg(
"j") =
'U')
570 [](Class &data,
int seed,
char gtype) {
571 data.init_prng_host(seed);
572 data.prng_host(gtype);
574 py::arg(
"seed") = 1234, py::arg(
"j") =
'U')
577 .def(
"prng_montagn", &Class::prng_montagn)
580 .def(
"init_prng_host", (
int (Class::*)(
int)) & Class::init_prng_host)
582 .def(
"prng_host", (
int (Class::*)(
char)) & Class::prng_host)
584 .def(
"prng_host", (
int (Class::*)(
char, T)) & Class::prng_host)
586 .def(
"prng_host", (
int (Class::*)(
char, T, T)) & Class::prng_host)
588 .def(
"destroy_prng_host", &Class::destroy_prng_host)
591 [](Class &data, Class &dest,
int direction) {
592 throw std::runtime_error(
"not implemented");
601 py::arg(
"dest") =
nullptr, py::arg(
"direction") = 1);
695 appendName<T>(
"magma_syevd_").data(),
696 [](Class &d_mat_a, ClassHost &eigenvals, Class *d_U,
bool computeU) {
697 if (d_U ==
nullptr) {
704 d_U->copy_from(d_mat_a, d_mat_a.get_nb_elements());
712 py::arg(
"d_mat_a"), py::arg(
"eigenvals"), py::arg(
"d_U") =
nullptr,
713 py::arg(
"computeU") =
true);
716 appendName<T>(
"syevd_").data(),
717 [](Class &d_mat_a, Class &eigenvals, Class *d_U,
bool computeU) {
718 if (d_U ==
nullptr) {
720 carma_syevd(CUSOLVER_EIG_MODE_VECTOR, &d_mat_a, &eigenvals);
722 carma_syevd(CUSOLVER_EIG_MODE_NOVECTOR, &d_mat_a, &eigenvals);
725 d_U->copy_from(d_mat_a, d_mat_a.get_nb_elements());
727 carma_syevd(CUSOLVER_EIG_MODE_VECTOR, d_U, &eigenvals);
729 carma_syevd(CUSOLVER_EIG_MODE_NOVECTOR, d_U, &eigenvals);
733 py::arg(
"d_mat_a"), py::arg(
"eigenvals"), py::arg(
"d_U") =
nullptr,
734 py::arg(
"computeU") =
true);
746 mod.def(appendName<T>(
"magma_getri_").data(), &carma_magma_getri<T>);
750 mod.def(appendName<T>(
"magma_potri_").data(), &carma_magma_potri<T>);