1 #include <dpsim/MNASolverDynInterface.h>
6 #include <cusolverSp.h>
7 #include <magma_types.h>
9 #include <magmasparse.h>
13 int dps_magma_solve(
double *rhs_values,
double *lhs_values);
14 void dps_magma_log(
const char *str);
15 void dps_magma_cleanup(
void);
24 magma_queue_t mMagmaQueue;
28 magma_d_matrix mDevSysMat;
32 magma_d_matrix mDevRhsVec;
35 magma_d_matrix mDevLhsVec;
38 static const char *PLUGIN_NAME =
"libdps_magma";
42 .init = dps_magma_init,
43 .lu_decomp = dps_magma_decomp,
44 .solve = dps_magma_solve,
45 .cleanup = dps_magma_cleanup,
49 if (name == NULL || strcmp(name, PLUGIN_NAME) != 0) {
50 printf(
"error: name mismatch\n");
53 return &dps_magma_plugin;
57 dps_magma_plugin.log(
"initialize");
59 magma_queue_create(0, &data.mMagmaQueue);
61 data.mDevSysMat.storage_type = Magma_CSR;
63 data.mDevRhsVec.storage_type = Magma_CSR;
65 data.mDevLhsVec.storage_type = Magma_CSR;
66 data.rhs_buffer = (
double *)malloc(
sizeof(
double) * matrix->row_number);
67 data.perm_map = (
int *)malloc(
sizeof(
int) * matrix->row_number);
69 return dps_magma_decomp(matrix);
74 data.size = matrix->row_number;
75 data.nnz = matrix->nnz;
76 dps_magma_plugin.log(
"decomp");
77 cusparseMatDescr_t descr_M = 0;
79 cusolverSpHandle_t mCusolverhandle;
80 if (cusolverSpCreate(&mCusolverhandle) != CUSOLVER_STATUS_SUCCESS) {
81 dps_magma_plugin.log(
"cusolverSpCreate returend an error");
84 if (cusparseCreateMatDescr(&descr_M) != CUSPARSE_STATUS_SUCCESS) {
85 dps_magma_plugin.log(
"returend an error");
89 if (cusparseSetMatIndexBase(descr_M, CUSPARSE_INDEX_BASE_ZERO) !=
90 CUSPARSE_STATUS_SUCCESS) {
91 dps_magma_plugin.log(
"cusolver returend an error");
94 if (cusparseSetMatType(descr_M, CUSPARSE_MATRIX_TYPE_GENERAL) !=
95 CUSPARSE_STATUS_SUCCESS) {
96 dps_magma_plugin.log(
"cusolver returend an error");
100 if (cusolverSpDcsrzfdHost(mCusolverhandle, matrix->row_number, matrix->nnz,
101 descr_M, matrix->values, matrix->rowIndex,
102 matrix->colIndex, data.perm_map,
103 &perm_size) != CUSOLVER_STATUS_SUCCESS) {
104 dps_magma_plugin.log(
"cusolverSpDcsrzfdHost returend an error");
108 size_t bufferSize = 0;
109 int *q = (
int *)malloc(
sizeof(
int) * matrix->row_number);
110 int *map = (
int *)malloc(
sizeof(
int) * matrix->nnz);
111 double *old_values = (
double *)malloc(
sizeof(
double) * matrix->nnz);
112 for (
int i = 0; i <= matrix->row_number; ++i) {
115 for (
int i = 0; i <= matrix->nnz; ++i) {
117 old_values[i] = matrix->values[i];
120 if (cusolverSpXcsrperm_bufferSizeHost(
121 mCusolverhandle, matrix->row_number, matrix->row_number, matrix->nnz,
122 descr_M, matrix->rowIndex, matrix->colIndex, data.perm_map, q,
123 &bufferSize) != CUSOLVER_STATUS_SUCCESS) {
124 dps_magma_plugin.log(
"cusolverSpXcsrperm_bufferSizeHost returend an error");
128 void *buffer = malloc(bufferSize);
130 if (cusolverSpXcsrpermHost(mCusolverhandle, matrix->row_number,
131 matrix->row_number, matrix->nnz, descr_M,
132 matrix->rowIndex, matrix->colIndex, data.perm_map,
133 q, map, buffer) != CUSOLVER_STATUS_SUCCESS) {
134 dps_magma_plugin.log(
"cusolverSpXcsrpermHost returend an error");
138 for (
int i = 0; i <= matrix->nnz; ++i) {
139 matrix->values[i] = old_values[map[i]];
142 magma_dcsrset(matrix->row_number, matrix->row_number, matrix->rowIndex,
143 matrix->colIndex, matrix->values, &data.
mHostSysMat,
146 data.
mMagmaOpts.solver_par.solver = Magma_PIDRMERGE;
151 data.
mMagmaOpts.precond_par.solver = Magma_ILU;
153 data.
mMagmaOpts.precond_par.trisolver = Magma_CUSOLVE;
155 magma_dsolverinfo_init(&data.
mMagmaOpts.solver_par,
156 &data.
mMagmaOpts.precond_par, data.mMagmaQueue);
158 magma_dvinit(&data.mDevRhsVec, Magma_DEV, matrix->row_number, 1, 0.0,
160 magma_dmtransfer(data.
mHostSysMat, &data.mDevSysMat, Magma_CPU, Magma_DEV,
162 magma_d_precondsetup(data.mDevSysMat, data.mDevRhsVec,
164 &data.
mMagmaOpts.precond_par, data.mMagmaQueue);
170 cusparseDestroyMatDescr(descr_M);
171 cusolverSpDestroy(mCusolverhandle);
176 int dps_magma_solve(
double *rhs_values,
double *lhs_values) {
178 dps_magma_plugin.log(
"solve");
180 for (
int i = 0; i <= data.size; ++i) {
181 data.rhs_buffer[i] = rhs_values[data.perm_map[i]];
185 magma_dvset(data.size, 1, data.rhs_buffer, &data.
mHostRhsVec,
187 magma_dmtransfer(data.
mHostRhsVec, &data.mDevRhsVec, Magma_CPU, Magma_DEV,
189 magma_dvinit(&data.mDevLhsVec, Magma_DEV, data.
mHostRhsVec.num_rows,
193 magma_d_solver(data.mDevSysMat, data.mDevRhsVec, &data.mDevLhsVec,
197 magma_dmtransfer(data.mDevLhsVec, &data.
mHostLhsVec, Magma_DEV, Magma_CPU,
199 magma_dvcopy(data.mDevLhsVec, &data.size, &one, lhs_values, data.mMagmaQueue);
208 void dps_magma_cleanup(
void) {
209 dps_magma_plugin.log(
"cleanup");
210 magma_dmfree(&data.mDevSysMat, data.mMagmaQueue);
211 magma_dmfree(&data.mDevRhsVec, data.mMagmaQueue);
212 magma_dmfree(&data.mDevLhsVec, data.mMagmaQueue);
214 magma_queue_destroy(data.mMagmaQueue);
217 free(data.rhs_buffer);
220 void dps_magma_log(
const char *str) { puts(str); }
magma_d_matrix mHostLhsVec
LHS-Vector.
magma_dopts mMagmaOpts
Solver-Handle.
magma_d_matrix mHostRhsVec
RHS-Vector.
magma_d_matrix mHostSysMat
Systemmatrix.