45 #ifdef USE_NAIVE_MULTITHREAD
50 #include <sys/types.h>
53 #include <sys/ioctl.h>
68 ParNaiveSolver::ParNaiveSolver(
unsigned nt,
const integer &size,
85 row_locks.resize(iSize + 2);
86 col_locks.resize(iSize, AO_TS_INITIALIZER);
88 pthread_mutex_init(&thread_mutex, NULL);
89 pthread_cond_init(&thread_cond, NULL);
94 for (
integer i = 1; i < iSize; i++) {
95 ppril[i] = ppril[i - 1] + iSize;
99 memset(pnril, 0,
sizeof(
integer)*iSize);
101 for (
integer row = 0; row < iSize; row++) {
111 for (
unsigned t = 0; t < nThreads; t++) {
112 thread_data[t].pSLUS =
this;
113 thread_data[t].threadNumber = t;
114 thread_data[t].retval = 0;
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(
"ParNaiveSolver: pthread_create() failed "
120 <<
" of " << nThreads << std::endl);
127 ParNaiveSolver::~ParNaiveSolver(
void)
130 thread_operation = ParNaiveSolver::EXIT;
131 thread_count = nThreads;
133 for (
unsigned i = 0; i < nThreads; i++) {
134 sem_post(&thread_data[i].sem);
139 pthread_mutex_lock(&thread_mutex);
140 if (thread_count > 0) {
141 pthread_cond_wait(&thread_cond, &thread_mutex);
143 pthread_mutex_unlock(&thread_mutex);
145 for (
unsigned i = 1; i < nThreads; i++) {
146 sem_destroy(&thread_data[i].sem);
149 pthread_mutex_destroy(&thread_mutex);
150 pthread_cond_destroy(&thread_cond);
166 ParNaiveSolver::thread_op(
void *arg)
168 thread_data_t *td = (thread_data_t *)arg;
170 silent_cout(
"ParNaiveSolver: thread " << td->threadNumber
171 <<
" [self=" << pthread_self()
172 <<
",pid=" << getpid() <<
"]"
173 <<
" starting..." << std::endl);
177 sigemptyset(&newset);
178 sigaddset(&newset, SIGTERM);
179 sigaddset(&newset, SIGINT);
180 sigaddset(&newset, SIGHUP);
181 pthread_sigmask(SIG_BLOCK, &newset, NULL);
185 bool bKeepGoing(
true);
190 switch (td->pSLUS->thread_operation) {
191 case ParNaiveSolver::FACTOR:
192 td->retval = pnaivfct(td->pSLUS->A->ppdRows,
195 td->pSLUS->A->ppiRows,
197 td->pSLUS->A->ppiCols,
200 td->pSLUS->A->ppnonzero,
204 &td->pSLUS->row_locks[0],
205 &td->pSLUS->col_locks[0],
212 silent_cerr(
"NaiveSolver: NAIVE_ENULCOL("
218 silent_cerr(
"NaiveSolver: NAIVE_ENOPIV("
228 case ParNaiveSolver::SOLVE:
229 pnaivslv(td->pSLUS->A->ppdRows,
232 td->pSLUS->A->ppiCols,
233 td->pSLUS->LinearSolver::pdRhs,
236 td->pSLUS->LinearSolver::pdSol,
237 &td->pSLUS->row_locks[0],
243 case ParNaiveSolver::EXIT:
248 silent_cerr(
"ParNaiveSolver: unhandled op"
253 td->pSLUS->EndOfOp();
260 ParNaiveSolver::EndOfOp(
void)
265 pthread_mutex_lock(&thread_mutex);
267 last = (thread_count == 0);
272 pthread_cond_broadcast(&thread_cond);
274 pthread_cond_signal(&thread_cond);
277 pthread_mutex_unlock(&thread_mutex);
282 ParNaiveSolver::IsValid(
void)
const
293 ParNaiveSolver::Factor(
void)
301 thread_operation = ParNaiveSolver::FACTOR;
302 thread_count = nThreads;
304 for (
int i = 0; i < iSize; i++) {
313 row_locks[iSize] = 0;
314 row_locks[iSize + 1] = 0;
319 for (
unsigned t = 0; t < nThreads; t++) {
320 thread_data[t].retval = 0;
321 sem_post(&thread_data[t].sem);
324 pthread_mutex_lock(&thread_mutex);
325 if (thread_count > 0) {
326 pthread_cond_wait(&thread_cond, &thread_mutex);
328 pthread_mutex_unlock(&thread_mutex);
334 ParNaiveSolver::Solve(
void)
const
341 const_cast<ParNaiveSolver *
>(
this)->
Factor();
342 bHasBeenReset =
false;
345 for (
int i = 0; i < iSize + 2; i++) {
349 thread_operation = ParNaiveSolver::SOLVE;
350 thread_count = nThreads;
352 for (
unsigned t = 0; t < nThreads; t++) {
353 thread_data[t].retval = 0;
354 sem_post(&thread_data[t].sem);
358 pthread_mutex_lock(&thread_mutex);
359 if (thread_count > 0) {
360 pthread_cond_wait(&thread_cond, &thread_mutex);
362 pthread_mutex_unlock(&thread_mutex);
377 ParNaiveSparseSolutionManager::ParNaiveSparseSolutionManager(
unsigned nt,
384 ASSERT((dMP >= 0.0) && (dMP <= 1.0));
389 ParNaiveSolver(nt, Dim, dMP, A));
391 pLS->pdSetResVec(VH.pdGetVec());
392 pLS->pdSetSolVec(XH.pdGetVec());
393 pLS->SetSolutionManager(
this);
402 ParNaiveSparseSolutionManager::~ParNaiveSparseSolutionManager(
void)
420 ParNaiveSparseSolutionManager::IsValid(
void)
const
424 #ifdef DEBUG_MEMMANAGER
430 ASSERT((VH.IsValid(), 1));
431 ASSERT((XH.IsValid(), 1));
432 ASSERT((pLS->IsValid(), 1));
438 ParNaiveSparseSolutionManager::MatrReset(
void)
450 ParNaiveSparseSolutionManager::Solve(
void)
463 ParNaiveSparseSolutionManager::pMatHdl(
void)
const
469 ParNaiveSparseSolutionManager::pResHdl(
void)
const
479 ParNaiveSparseSolutionManager::pSolHdl(
void)
const
496 ParNaiveSparsePermSolutionManager::ParNaiveSparsePermSolutionManager(
500 : ParNaiveSparseSolutionManager(nt, Dim, dMP),
505 invperm.resize(Dim, 0);
511 dynamic_cast<ParNaiveSolver *
>(pLS)->SetMat(A);
516 ParNaiveSparsePermSolutionManager::~ParNaiveSparsePermSolutionManager(
void)
522 ParNaiveSparsePermSolutionManager::MatrReset(
void)
524 if (ePermState == PERM_INTERMEDIATE) {
525 ePermState = PERM_READY;
527 pLS->pdSetResVec(VH.pdGetVec());
528 pLS->pdSetSolVec(XH.pdGetVec());
530 pLS->SetSolutionManager(
this);
537 ParNaiveSparsePermSolutionManager::ComputePermutation(
void)
539 std::vector<integer> Ai;
540 A->MakeCCStructure(Ai, invperm);
546 if (!
mbdyn_colamd(A->iGetNumRows(), A->iGetNumCols(), Alen,
547 &(Ai[0]), &(invperm[0]), knobs, stats)) {
548 silent_cerr(
"colamd permutation failed" << std::endl);
551 for (
integer i = 0; i < A->iGetNumRows(); i++) {
552 perm[invperm[i]] = i;
554 ePermState = PERM_INTERMEDIATE;
558 ParNaiveSparsePermSolutionManager::BackPerm(
void)
560 for (
integer i = 0; i < A->iGetNumCols(); i++) {
561 XH(invperm[i] + 1) = VH(i + 1);
568 ParNaiveSparsePermSolutionManager::Solve(
void)
570 if (ePermState == PERM_NO) {
571 ComputePermutation();
574 pLS->pdSetSolVec(VH.pdGetVec());
579 if (ePermState == PERM_READY) {
581 pLS->pdSetSolVec(XH.pdGetVec());
587 ParNaiveSparsePermSolutionManager::MatrInitialize()
589 ePermState = PERM_NO;
591 for (
integer i = 0; i < A->iGetNumRows(); i++) {
#define MBDYN_EXCEPT_ARGS
#define SAFEDELETEARR(pnt)
void mbdyn_colamd_set_defaults(double knobs[20])
int mbdyn_task2cpu(int cpu)
integer mbdyn_colamd_recommended(integer nnz, integer n_row, integer n_col)
integer mbdyn_colamd(integer n_row, integer n_col, integer Alen, integer A[], integer p[], double knobs[20], integer stats[20])
#define ASSERT(expression)
#define SAFENEWWITHCONSTRUCTOR(pnt, item, constructor)
#define defaultMemoryManager
#define SAFENEWARRNOFILL(pnt, item, sz)
#define SAFENEWARR(pnt, item, sz)
static const doublereal a