DPsim
Loading...
Searching...
No Matches
magma.c
1#include <dpsim/MNASolverDynInterface.h>
2
3#include <stdio.h>
4#include <string.h>
5
6#include <cusolverSp.h>
7#include <magma_types.h>
8#include <magma_v2.h>
9#include <magmasparse.h>
10
11int dps_magma_init(struct dpsim_csr_matrix *matrix);
12int dps_magma_decomp(struct dpsim_csr_matrix *matrix);
13int dps_magma_solve(double *rhs_values, double *lhs_values);
14void dps_magma_log(const char *str);
15void dps_magma_cleanup(void);
16
18 int size;
19 int nnz;
20 int *perm_map;
21 double *rhs_buffer;
23 magma_dopts mMagmaOpts;
24 magma_queue_t mMagmaQueue;
25
27 magma_d_matrix mHostSysMat;
28 magma_d_matrix mDevSysMat;
29
31 magma_d_matrix mHostRhsVec;
32 magma_d_matrix mDevRhsVec;
34 magma_d_matrix mHostLhsVec;
35 magma_d_matrix mDevLhsVec;
36} data;
37
38static const char *PLUGIN_NAME = "libdps_magma";
39static struct dpsim_mna_plugin dps_magma_plugin = {
40 .log =
41 dps_magma_log, //a properly working dpsim will override this with the spdlog logger
42 .init = dps_magma_init,
43 .lu_decomp = dps_magma_decomp,
44 .solve = dps_magma_solve,
45 .cleanup = dps_magma_cleanup,
46};
47
48struct dpsim_mna_plugin *get_mna_plugin(const char *name) {
49 if (name == NULL || strcmp(name, PLUGIN_NAME) != 0) {
50 printf("error: name mismatch\n");
51 return NULL;
52 }
53 return &dps_magma_plugin;
54}
55
56int dps_magma_init(struct dpsim_csr_matrix *matrix) {
57 dps_magma_plugin.log("initialize");
58 magma_init();
59 magma_queue_create(0, &data.mMagmaQueue);
60 data.mHostSysMat.storage_type = Magma_CSR;
61 data.mDevSysMat.storage_type = Magma_CSR;
62 data.mHostRhsVec.storage_type = Magma_CSR;
63 data.mDevRhsVec.storage_type = Magma_CSR;
64 data.mHostLhsVec.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);
68
69 return dps_magma_decomp(matrix);
70}
71
72int dps_magma_decomp(struct dpsim_csr_matrix *matrix) {
73 int perm_size = 0;
74 data.size = matrix->row_number;
75 data.nnz = matrix->nnz;
76 dps_magma_plugin.log("decomp");
77 cusparseMatDescr_t descr_M = 0;
78
79 cusolverSpHandle_t mCusolverhandle;
80 if (cusolverSpCreate(&mCusolverhandle) != CUSOLVER_STATUS_SUCCESS) {
81 dps_magma_plugin.log("cusolverSpCreate returend an error");
82 return 1;
83 }
84 if (cusparseCreateMatDescr(&descr_M) != CUSPARSE_STATUS_SUCCESS) {
85 dps_magma_plugin.log("returend an error");
86 return 1;
87 }
88
89 if (cusparseSetMatIndexBase(descr_M, CUSPARSE_INDEX_BASE_ZERO) !=
90 CUSPARSE_STATUS_SUCCESS) {
91 dps_magma_plugin.log("cusolver returend an error");
92 return 1;
93 }
94 if (cusparseSetMatType(descr_M, CUSPARSE_MATRIX_TYPE_GENERAL) !=
95 CUSPARSE_STATUS_SUCCESS) {
96 dps_magma_plugin.log("cusolver returend an error");
97 return 1;
98 }
99
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");
105 return 1;
106 }
107
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) {
113 q[i] = i;
114 }
115 for (int i = 0; i <= matrix->nnz; ++i) {
116 map[i] = i;
117 old_values[i] = matrix->values[i];
118 }
119
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");
125 return 1;
126 }
127
128 void *buffer = malloc(bufferSize);
129
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");
135 return 1;
136 }
137
138 for (int i = 0; i <= matrix->nnz; ++i) {
139 matrix->values[i] = old_values[map[i]];
140 }
141
142 magma_dcsrset(matrix->row_number, matrix->row_number, matrix->rowIndex,
143 matrix->colIndex, matrix->values, &data.mHostSysMat,
144 data.mMagmaQueue);
145
146 data.mMagmaOpts.solver_par.solver = Magma_PIDRMERGE;
147 data.mMagmaOpts.solver_par.restart = 8;
148 data.mMagmaOpts.solver_par.maxiter = 1000;
149 data.mMagmaOpts.solver_par.rtol = 1e-10;
150 data.mMagmaOpts.solver_par.maxiter = 1000;
151 data.mMagmaOpts.precond_par.solver = Magma_ILU;
152 data.mMagmaOpts.precond_par.levels = 0;
153 data.mMagmaOpts.precond_par.trisolver = Magma_CUSOLVE;
154
155 magma_dsolverinfo_init(&data.mMagmaOpts.solver_par,
156 &data.mMagmaOpts.precond_par, data.mMagmaQueue);
157
158 magma_dvinit(&data.mDevRhsVec, Magma_DEV, matrix->row_number, 1, 0.0,
159 data.mMagmaQueue);
160 magma_dmtransfer(data.mHostSysMat, &data.mDevSysMat, Magma_CPU, Magma_DEV,
161 data.mMagmaQueue);
162 magma_d_precondsetup(data.mDevSysMat, data.mDevRhsVec,
163 &data.mMagmaOpts.solver_par,
164 &data.mMagmaOpts.precond_par, data.mMagmaQueue);
165
166 free(buffer);
167 free(q);
168 free(map);
169 free(old_values);
170 cusparseDestroyMatDescr(descr_M);
171 cusolverSpDestroy(mCusolverhandle);
172
173 return 0;
174}
175
176int dps_magma_solve(double *rhs_values, double *lhs_values) {
177 int one = 0;
178 dps_magma_plugin.log("solve");
179
180 for (int i = 0; i <= data.size; ++i) {
181 data.rhs_buffer[i] = rhs_values[data.perm_map[i]];
182 }
183 //
184 //Copy right vector to device
185 magma_dvset(data.size, 1, data.rhs_buffer, &data.mHostRhsVec,
186 data.mMagmaQueue);
187 magma_dmtransfer(data.mHostRhsVec, &data.mDevRhsVec, Magma_CPU, Magma_DEV,
188 data.mMagmaQueue);
189 magma_dvinit(&data.mDevLhsVec, Magma_DEV, data.mHostRhsVec.num_rows,
190 data.mHostRhsVec.num_cols, 0.0, data.mMagmaQueue);
191
192 // Solve
193 magma_d_solver(data.mDevSysMat, data.mDevRhsVec, &data.mDevLhsVec,
194 &data.mMagmaOpts, data.mMagmaQueue);
195
196 //Copy Solution back
197 magma_dmtransfer(data.mDevLhsVec, &data.mHostLhsVec, Magma_DEV, Magma_CPU,
198 data.mMagmaQueue);
199 magma_dvcopy(data.mDevLhsVec, &data.size, &one, lhs_values, data.mMagmaQueue);
200
201 //Apply inverse Permutation: TODO: This seems to be wrong, but why?
202 //this->mLeftSideVector = mTransp->inverse() * this->mLeftSideVector;
203
204 // Components' states will be updated by the post-step tasks
205 return 0;
206}
207
208void 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);
213
214 magma_queue_destroy(data.mMagmaQueue);
215 magma_finalize();
216 free(data.perm_map);
217 free(data.rhs_buffer);
218}
219
220void dps_magma_log(const char *str) { puts(str); }
magma_d_matrix mHostLhsVec
LHS-Vector.
Definition magma.c:34
magma_dopts mMagmaOpts
Solver-Handle.
Definition magma.c:23
magma_d_matrix mHostRhsVec
RHS-Vector.
Definition magma.c:31
magma_d_matrix mHostSysMat
Systemmatrix.
Definition magma.c:27