42 #include <sys/types.h>
52 #include <pdsp_defs.h>
55 extern void *pdgstrf_thread(
void *);
56 extern void pdgstrf_finalize(pdgstrf_options_t *, SuperMatrix*);
62 struct ParSuperLUSolverData {
69 std::vector<int> perm_c,
71 pdgstrf_options_t pdgstrf_options;
72 pxgstrf_shared_t pxgstrf_shared;
73 pdgstrf_threadarg_t *pdgstrf_threadarg;
79 ParSuperLUSolver::ParSuperLUSolver(
unsigned nt,
integer iMatOrd,
88 bRegenerateMatrix(
true),
95 SAFENEW(sld, ParSuperLUSolverData);
103 pthread_mutex_init(&thread_mutex, NULL);
104 pthread_cond_init(&thread_cond, NULL);
108 for (
unsigned t = 0; t < nThreads; t++) {
109 thread_data[t].pSLUS =
this;
110 thread_data[t].threadNumber = t;
116 sem_init(&thread_data[t].sem, 0, 0);
117 if (pthread_create(&thread_data[t].thread, NULL, thread_op, &thread_data[t]) != 0) {
118 silent_cerr(
"ParSuperLUSolver: pthread_create() failed "
120 <<
" of " << nThreads << std::endl);
127 ParSuperLUSolver::~ParSuperLUSolver(
void)
133 pdgstrf_thread_finalize(sld->pdgstrf_threadarg, &sld->pxgstrf_shared,
134 &sld->A, &sld->perm_r[0], &sld->L, &sld->U);
139 pdgstrf_finalize(&sld->pdgstrf_options, &sld->AC);
142 thread_operation = ParSuperLUSolver::EXIT;
143 thread_count = nThreads - 1;
145 for (
unsigned i = 1; i < nThreads; i++) {
146 sem_post(&thread_data[i].sem);
151 pthread_mutex_lock(&thread_mutex);
152 if (thread_count > 0) {
153 pthread_cond_wait(&thread_cond, &thread_mutex);
155 pthread_mutex_unlock(&thread_mutex);
157 for (
unsigned i = 1; i < nThreads; i++) {
158 sem_destroy(&thread_data[i].sem);
161 pthread_mutex_destroy(&thread_mutex);
162 pthread_cond_destroy(&thread_cond);
168 ParSuperLUSolver::thread_op(
void *arg)
170 thread_data_t *td = (thread_data_t *)arg;
172 silent_cout(
"ParSuperLUSolver: thread " << td->threadNumber
173 <<
" [self=" << pthread_self()
174 <<
",pid=" << getpid() <<
"]"
175 <<
" starting..." << std::endl);
179 sigemptyset(&newset);
180 sigaddset(&newset, SIGTERM);
181 sigaddset(&newset, SIGINT);
182 sigaddset(&newset, SIGHUP);
183 pthread_sigmask(SIG_BLOCK, &newset, NULL);
185 bool bKeepGoing(
true);
190 switch (td->pSLUS->thread_operation) {
191 case ParSuperLUSolver::FACTOR:
192 (void)pdgstrf_thread(td->pdgstrf_threadarg);
195 case ParSuperLUSolver::EXIT:
200 silent_cerr(
"ParSuperLUSolver: unhandled op"
205 td->pSLUS->EndOfOp();
212 ParSuperLUSolver::EndOfOp(
void)
217 pthread_mutex_lock(&thread_mutex);
219 last = (thread_count == 0);
224 pthread_cond_broadcast(&thread_cond);
226 pthread_cond_signal(&thread_cond);
229 pthread_mutex_unlock(&thread_mutex);
234 ParSuperLUSolver::IsValid(
void)
const
245 ParSuperLUSolver::Factor(
void)
253 yes_no_t refact = YES,
258 int info = 0, lwork = 0;
259 int panel_size = sp_ienv(1),
262 if (bRegenerateMatrix) {
273 dCreate_Dense_Matrix(&sld->B, iN, 1,
278 dCreate_CompCol_Matrix(&sld->A, iN, iN, iNonZeroes,
279 Axp, Aip, App, NC, _D, GE);
281 StatAlloc(iN, nThreads, panel_size, relax, &sld->Gstat);
282 StatInit(iN, nThreads, &sld->Gstat);
284 sld->perm_c.resize(iN);
285 sld->perm_r.resize(iN);
290 NCformat *Astore = (NCformat *) sld->A.Store;
294 Astore->nnz = iNonZeroes;
296 Astore->rowind = Aip;
297 Astore->colptr = App;
325 int *pc = &(sld->perm_c[0]);
326 get_perm_c(permc_spec, &sld->A, pc);
328 bRegenerateMatrix =
false;
331 int *pr = &(sld->perm_r[0]),
332 *pc = &(sld->perm_c[0]);
339 pdgstrf_init(nThreads, refact, panel_size, relax,
340 u, usepr, drop_tol, pc, pr,
341 work, lwork, &sld->A, &sld->AC,
342 &sld->pdgstrf_options, &sld->Gstat);
348 sld->pdgstrf_threadarg = pdgstrf_thread_init(&sld->AC,
349 &sld->L, &sld->U, &sld->pdgstrf_options,
350 &sld->pxgstrf_shared, &sld->Gstat, &info);
353 silent_cerr(
"ParSuperLUSolver::Factor: pdgstrf_thread_init failed"
357 for (
unsigned t = 0; t < nThreads; t++) {
358 thread_data[t].pdgstrf_threadarg = &sld->pdgstrf_threadarg[t];
361 thread_operation = ParSuperLUSolver::FACTOR;
362 thread_count = nThreads - 1;
364 for (
unsigned t = 1; t < nThreads; t++) {
365 sem_post(&thread_data[t].sem);
368 (void)pdgstrf_thread(thread_data[0].pdgstrf_threadarg);
370 pthread_mutex_lock(&thread_mutex);
371 if (thread_count > 0) {
372 pthread_cond_wait(&thread_cond, &thread_mutex);
374 pthread_mutex_unlock(&thread_mutex);
379 pdgstrf_thread_finalize(sld->pdgstrf_threadarg, &sld->pxgstrf_shared,
380 &sld->A, pr, &sld->L, &sld->U);
385 ParSuperLUSolver::Solve(
void)
const
392 const_cast<ParSuperLUSolver *
>(
this)->
Factor();
393 bHasBeenReset =
false;
399 trans_t trans = NOTRANS;
402 int *pr = &(sld->perm_r[0]),
403 *pc = &(sld->perm_c[0]);
405 dgstrs(trans, &sld->L, &sld->U, pr, pc,
406 &sld->B, &sld->Gstat, &info);
412 std::vector<doublereal>& Ax,
413 std::vector<integer>& Ar, std::vector<integer>& Ac,
414 std::vector<integer>& Ap)
const
417 if (!bHasBeenReset) {
429 bRegenerateMatrix =
true;
432 Destroy_CompCol_Matrix(&sld->A);
442 ParSuperLUSparseSolutionManager::ParSuperLUSparseSolutionManager(
unsigned nt,
451 ASSERT((dPivotFactor >= 0.0) && (dPivotFactor <= 1.0));
455 ParSuperLUSolver(nt, iMatSize, dPivotFactor));
457 pLS->pdSetResVec(&(xb[0]));
458 pLS->pdSetSolVec(&(xb[0]));
459 pLS->SetSolutionManager(
this);
468 ParSuperLUSparseSolutionManager::~ParSuperLUSparseSolutionManager(
void)
480 ParSuperLUSparseSolutionManager::IsValid(
void)
const
484 #ifdef DEBUG_MEMMANAGER
489 ASSERT((VH.IsValid(), 1));
490 ASSERT((pLS->IsValid(), 1));
496 ParSuperLUSparseSolutionManager::MatrReset(
void)
506 ParSuperLUSparseSolutionManager::MakeCompressedColumnForm(
void)
513 pLS->MakeCompactForm(MH, Ax, Ai, Adummy, Ap);
518 ParSuperLUSparseSolutionManager::Solve(
void)
525 MakeCompressedColumnForm();
528 std::cerr <<
"### after MakeIndexForm:" << std::endl
529 <<
"{col Ap[col]}={" << std::endl;
530 for (
unsigned i = 0; i < Ap.size(); i++) {
531 std::cerr << i <<
" " << Ap[i] << std::endl;
533 std::cerr <<
"}" << std::endl;
535 std::cerr <<
"{idx Ai[idx] col Ax[idx]}={" << std::endl;
537 for (
unsigned i = 0; i < Ax.size(); i++) {
538 std::cerr << i <<
" " << Ai[i] <<
" " << c <<
" " << Ax[i] << std::endl;
543 std::cerr <<
"}" << std::endl;
549 std::cerr <<
"### after Solve:" << std::endl
550 <<
"{col Ap[col]}={" << std::endl;
551 for (
unsigned i = 0; i < Ap.size(); i++) {
552 std::cerr << i <<
" " << Ap[i] << std::endl;
554 std::cerr <<
"}" << std::endl;
556 std::cerr <<
"{idx Ai[idx] col Ax[idx]}={" << std::endl;
558 for (
unsigned i = 0; i < Ax.size(); i++) {
559 std::cerr << i <<
" " << Ai[i] <<
" " << c <<
" " << Ax[i] << std::endl;
564 std::cerr <<
"}" << std::endl;
573 ParSuperLUSparseCCSolutionManager<CC>::ParSuperLUSparseCCSolutionManager(
unsigned nt,
575 : ParSuperLUSparseSolutionManager(nt, Dim, dPivot),
583 ParSuperLUSparseCCSolutionManager<CC>::~ParSuperLUSparseCCSolutionManager(
void)
592 ParSuperLUSparseCCSolutionManager<CC>::MatrReset(
void)
600 ParSuperLUSparseCCSolutionManager<CC>::MakeCompressedColumnForm(
void)
603 pLS->MakeCompactForm(MH, Ax, Ai, Adummy, Ap);
616 ParSuperLUSparseCCSolutionManager<CC>::MatrInitialize()
626 ParSuperLUSparseCCSolutionManager<CC>::pMatHdl(
void)
const
636 template class ParSuperLUSparseCCSolutionManager<CColMatrixHandler<0> >;
637 template class ParSuperLUSparseCCSolutionManager<DirCColMatrixHandler<0> >;
virtual integer MakeCompressedColumnForm(doublereal *const Ax, integer *const Ai, integer *const Ap, int offset=0) const =0
#define MBDYN_EXCEPT_ARGS
#define SAFENEW(pnt, item)
#define ASSERT(expression)
#define SAFENEWWITHCONSTRUCTOR(pnt, item, constructor)
#define defaultMemoryManager
static std::stack< cleanup * > c
#define SAFENEWARRNOFILL(pnt, item, sz)