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)