|
1 | 1 | #include "LinSolverDirectKLU.hpp" |
2 | 2 |
|
3 | | -#include <cstring> // includes memcpy |
| 3 | +#include <cassert> |
| 4 | +#include <cstring> |
4 | 5 |
|
5 | 6 | #include <resolve/matrix/Csc.hpp> |
6 | 7 | #include <resolve/matrix/Csr.hpp> |
@@ -166,6 +167,13 @@ namespace ReSolve |
166 | 167 | { |
167 | 168 | return 1; |
168 | 169 | } |
| 170 | + else |
| 171 | + { |
| 172 | + if (Numeric_->nzoff != 0) |
| 173 | + { |
| 174 | + assert(0 && "Numeric_->nzoff != 0, this is not supported by ReSolve!"); |
| 175 | + } |
| 176 | + } |
169 | 177 | return 0; |
170 | 178 | } |
171 | 179 |
|
@@ -253,22 +261,12 @@ namespace ReSolve |
253 | 261 | } |
254 | 262 |
|
255 | 263 | /** |
256 | | - * @brief Get the L factor of the matrix A in compressed sparse row format. |
257 | | - * |
258 | | - * This function extracts the lower triangular factor L from the |
259 | | - * KLU solver's numeric factorization. If the factors have not been |
260 | | - * extracted yet, it allocates memory for L and U factors, |
261 | | - * extracts them from the numeric factorization, |
262 | | - * and sets the updated flag for both factors. |
263 | | - * Otherwise, it returns the already extracted L factor. |
264 | | - * This is because the input matrix is CSR and interpreted as CSC. |
265 | | - * Then the CSC U extraced from klu is actually an L factor of the original matrix, |
266 | | - * if interprted as CSR. The reverse is true for the CSC L being a U factor of the original matrix. |
267 | | - * Note that in this factorization, the scaling is in the L factor, unlike convention. |
| 264 | + * @brief Extracts L and U factors from the KLU solver in CSR format, if they have not already been extracted. |
268 | 265 | * |
269 | | - * @return L factor in compressed sparse row format |
| 266 | + * It extracts the factors as $A = U^T L^T$, |
| 267 | + * where U^T is the reinterpretation of the CSC U factor as CSR and L^T is the reinterpretation of the CSC L factor as CSR. |
270 | 268 | */ |
271 | | - matrix::Sparse* LinSolverDirectKLU::getLFactorCsr() |
| 269 | + void LinSolverDirectKLU::extractFactorsCsr() |
272 | 270 | { |
273 | 271 | if (!factors_extracted_) |
274 | 272 | { |
@@ -303,69 +301,35 @@ namespace ReSolve |
303 | 301 | (void) ok; // TODO: Check status in ok before setting `factors_extracted_` |
304 | 302 | factors_extracted_ = true; |
305 | 303 | } |
| 304 | + return; |
| 305 | + } |
| 306 | + |
| 307 | + /** |
| 308 | + * @brief Gets an L factor of the matrix A in compressed sparse row format. |
| 309 | + * |
| 310 | + * @return L factor in compressed sparse row format |
| 311 | + */ |
| 312 | + matrix::Sparse* LinSolverDirectKLU::getLFactorCsr() |
| 313 | + { |
| 314 | + extractFactorsCsr(); |
306 | 315 | return L_; |
307 | 316 | } |
308 | 317 |
|
309 | 318 | /** |
310 | | - * @brief Get the U factor of the matrix A in compressed sparse row format. |
311 | | - * |
312 | | - * This function extracts the upper triangular factor U from the |
313 | | - * KLU solver's numeric factorization. If the factors have not been |
314 | | - * extracted yet, it allocates memory for L and U factors, |
315 | | - * extracts them from the numeric factorization, |
316 | | - * and sets the updated flag for both factors. |
317 | | - * Otherwise, it returns the already extracted U factor. |
318 | | - * This is because the input matrix is CSR and interpreted as CSC. |
319 | | - * Then the CSC U extraced from klu is actually an L factor of the original matrix, |
320 | | - * if interprted as CSR. The reverse is true for the CSC L being a U factor of the original matrix. |
321 | | - * Note that in this factorization, the scaling is in the L factor, unlike convention. |
| 319 | + * @brief Gets a U factor of the matrix A in compressed sparse row format. |
322 | 320 | * |
323 | 321 | * @return U factor in compressed sparse row format |
324 | 322 | */ |
325 | 323 | matrix::Sparse* LinSolverDirectKLU::getUFactorCsr() |
326 | 324 | { |
327 | | - if (!factors_extracted_) |
328 | | - { |
329 | | - const int nnzL = Numeric_->lnz; |
330 | | - const int nnzU = Numeric_->unz; |
331 | | - |
332 | | - // Create CSR matrices - L gets U's data, U gets L's data |
333 | | - L_ = new matrix::Csr(A_->getNumRows(), A_->getNumColumns(), nnzU); |
334 | | - U_ = new matrix::Csr(A_->getNumRows(), A_->getNumColumns(), nnzL); |
335 | | - L_->allocateMatrixData(memory::HOST); |
336 | | - U_->allocateMatrixData(memory::HOST); |
337 | | - |
338 | | - int ok = klu_extract(Numeric_, |
339 | | - Symbolic_, |
340 | | - U_->getRowData(memory::HOST), // L CSC colptr -> U CSR rowptr |
341 | | - U_->getColData(memory::HOST), // L CSC rowidx -> U CSR colidx |
342 | | - U_->getValues(memory::HOST), // L CSC values -> U CSR values |
343 | | - L_->getRowData(memory::HOST), // U CSC colptr -> L CSR rowptr |
344 | | - L_->getColData(memory::HOST), // U CSC rowidx -> L CSR colidx |
345 | | - L_->getValues(memory::HOST), // U CSC values -> L CSR values |
346 | | - nullptr, |
347 | | - nullptr, |
348 | | - nullptr, |
349 | | - nullptr, |
350 | | - nullptr, |
351 | | - nullptr, |
352 | | - nullptr, |
353 | | - &Common_); |
354 | | - |
355 | | - L_->setUpdated(memory::HOST); |
356 | | - U_->setUpdated(memory::HOST); |
357 | | - (void) ok; // TODO: Check status in ok before setting `factors_extracted_` |
358 | | - factors_extracted_ = true; |
359 | | - } |
| 325 | + extractFactorsCsr(); |
360 | 326 | return U_; |
361 | 327 | } |
362 | 328 |
|
363 | 329 | /** |
364 | | - * @brief Get the lower triangular factor L. |
365 | | - * |
366 | | - * @return L factor |
| 330 | + * @brief Extract L and U factors from the KLU solver in compressed sparse column format. |
367 | 331 | */ |
368 | | - matrix::Sparse* LinSolverDirectKLU::getLFactor() |
| 332 | + void LinSolverDirectKLU::extractFactors() |
369 | 333 | { |
370 | 334 | if (!factors_extracted_) |
371 | 335 | { |
@@ -399,48 +363,27 @@ namespace ReSolve |
399 | 363 | (void) ok; // TODO: Check status in ok before setting `factors_extracted_` |
400 | 364 | factors_extracted_ = true; |
401 | 365 | } |
| 366 | + } |
| 367 | + |
| 368 | + /** |
| 369 | + * @brief Get the lower triangular factor L of the matrix A in compressed sparse column format. |
| 370 | + * |
| 371 | + * @return L factor in compressed sparse column format |
| 372 | + */ |
| 373 | + matrix::Sparse* LinSolverDirectKLU::getLFactor() |
| 374 | + { |
| 375 | + extractFactors(); |
402 | 376 | return L_; |
403 | 377 | } |
404 | 378 |
|
405 | 379 | /** |
406 | | - * @brief Get the upper triangular factor U. |
| 380 | + * @brief Get the upper triangular factor U of the matrix A in compressed sparse column format. |
407 | 381 | * |
408 | 382 | * @return U factor |
409 | 383 | */ |
410 | 384 | matrix::Sparse* LinSolverDirectKLU::getUFactor() |
411 | 385 | { |
412 | | - if (!factors_extracted_) |
413 | | - { |
414 | | - const int nnzL = Numeric_->lnz; |
415 | | - const int nnzU = Numeric_->unz; |
416 | | - |
417 | | - L_ = new matrix::Csc(A_->getNumRows(), A_->getNumColumns(), nnzL); |
418 | | - U_ = new matrix::Csc(A_->getNumRows(), A_->getNumColumns(), nnzU); |
419 | | - L_->allocateMatrixData(memory::HOST); |
420 | | - U_->allocateMatrixData(memory::HOST); |
421 | | - int ok = klu_extract(Numeric_, |
422 | | - Symbolic_, |
423 | | - L_->getColData(memory::HOST), |
424 | | - L_->getRowData(memory::HOST), |
425 | | - L_->getValues(memory::HOST), |
426 | | - U_->getColData(memory::HOST), |
427 | | - U_->getRowData(memory::HOST), |
428 | | - U_->getValues(memory::HOST), |
429 | | - nullptr, |
430 | | - nullptr, |
431 | | - nullptr, |
432 | | - nullptr, |
433 | | - nullptr, |
434 | | - nullptr, |
435 | | - nullptr, |
436 | | - &Common_); |
437 | | - |
438 | | - L_->setUpdated(memory::HOST); |
439 | | - U_->setUpdated(memory::HOST); |
440 | | - |
441 | | - (void) ok; // TODO: Check status in ok before setting `factors_extracted_` |
442 | | - factors_extracted_ = true; |
443 | | - } |
| 386 | + extractFactors(); |
444 | 387 | return U_; |
445 | 388 | } |
446 | 389 |
|
|
0 commit comments