void nlVectorToVariables() { NLuint i ; nl_assert(nlCurrentContext->alloc_x) ; nl_assert(nlCurrentContext->alloc_variable) ; for(i=0; i<nlCurrentContext->nb_variables; i++) { NLVariable* v = &(nlCurrentContext->variable[i]) ; if(!v->locked) { nl_assert(v->index < nlCurrentContext->n) ; v->value = nlCurrentContext->x[v->index] ; } } }
ATTR_HOT void net_t::inc_active(core_terminal_t &term) { m_active++; m_list_active.insert(term); nl_assert(m_active <= num_cons()); if (m_active == 1) { if (netlist().use_deactivate()) { railterminal().device().inc_active(); //m_cur_Q = m_new_Q; } if (m_in_queue == 0) { if (m_time > netlist().time()) { m_in_queue = 1; /* pending */ netlist().push_to_queue(*this, m_time); } else { m_cur_Q = m_new_Q; m_in_queue = 2; } } //else if (netlist().use_deactivate()) // m_cur_Q = m_new_Q; } }
void detail::net_t::update_devs() { //assert(m_num_cons != 0); nl_assert(this->isRailNet()); static const unsigned masks[4] = { 0, core_terminal_t::STATE_INP_LH | core_terminal_t::STATE_INP_ACTIVE, core_terminal_t::STATE_INP_HL | core_terminal_t::STATE_INP_ACTIVE, 0 }; const unsigned mask = masks[ m_cur_Q * 2 + m_new_Q ]; m_in_queue = 2; /* mark as taken ... */ m_cur_Q = m_new_Q; for (auto & p : m_list_active) { p.device().m_stat_call_count.inc(); if ((p.state() & mask) != 0) p.device().update_dev(); } }
void nlEndMatrix() { nlTransition(NL_STATE_MATRIX, NL_STATE_MATRIX_CONSTRUCTED) ; nlRowColumnDestroy(&nlCurrentContext->af) ; nlCurrentContext->alloc_af = NL_FALSE ; nlRowColumnDestroy(&nlCurrentContext->al) ; nlCurrentContext->alloc_al = NL_FALSE ; nlRowColumnDestroy(&nlCurrentContext->xl) ; nlCurrentContext->alloc_al = NL_FALSE ; if(!nlCurrentContext->least_squares) { nl_assert( nlCurrentContext->current_row == nlCurrentContext->n ) ; } if((nlCurrentContext->solver == NL_CHOLMOD_EXT || // or any other direct solver nlCurrentContext->solver == NL_SUPERLU_EXT || nlCurrentContext->solver == NL_PERM_SUPERLU_EXT || nlCurrentContext->solver == NL_SYMMETRIC_SUPERLU_EXT) && nlCurrentContext->direct_solver_context == NULL) { nlCurrentContext->factorize_func() ; } }
void detail::net_t::dec_active(core_terminal_t &term) { --m_active; nl_assert(m_active >= 0); m_list_active.remove(&term); if (m_active == 0) railterminal().device().do_dec_active(); }
void nlBeginSystem() { nlTransition(NL_STATE_INITIAL, NL_STATE_SYSTEM) ; nl_assert(nlCurrentContext->nb_variables > 0) ; nlCurrentContext->variable = NL_NEW_ARRAY( NLVariable, nlCurrentContext->nb_variables ) ; nlCurrentContext->alloc_variable = NL_TRUE ; }
ATTR_HOT void net_t::dec_active(core_terminal_t &term) { m_active--; nl_assert(m_active >= 0); m_list_active.remove(term); if (m_active == 0 && netlist().use_deactivate()) railterminal().device().dec_active(); }
void nlSolverParameterd(NLenum pname, NLdouble param) { nlCheckState(NL_STATE_INITIAL) ; switch(pname) { case NL_SOLVER: { nlCurrentContext->solver = (NLenum)param ; } break ; case NL_NB_VARIABLES: { nl_assert(param > 0) ; nlCurrentContext->nb_variables = (NLuint)param ; } break ; case NL_LEAST_SQUARES: { nlCurrentContext->least_squares = (NLboolean)param ; } break ; case NL_MAX_ITERATIONS: { nl_assert(param > 0) ; nlCurrentContext->max_iterations = (NLuint)param ; } break ; case NL_THRESHOLD: { nl_assert(param >= 0) ; nlCurrentContext->threshold = (NLdouble)param ; } break ; case NL_OMEGA: { nl_range_assert(param,1.0,2.0) ; nlCurrentContext->omega = (NLdouble)param ; } break ; case NL_SYMMETRIC: { nlCurrentContext->symmetric = (NLboolean)param ; } case NL_INNER_ITERATIONS: { nl_assert(param > 0) ; nlCurrentContext->inner_iterations = (NLuint)param ; } break ; case NL_PRECONDITIONER: { nlCurrentContext->preconditioner = (NLuint)param ; } break ; case NL_MATRIX_STORE: { nlCurrentContext->matrix_store = (NLenum)param ; } break ; default: { nl_assert_not_reached ; } break ; } }
void nlDisable(NLenum pname) { switch(pname) { case NL_NORMALIZE_ROWS: { nl_assert(nlCurrentContext->state != NL_STATE_ROW) ; nlCurrentContext->normalize_rows = NL_FALSE ; } break ; default: { nl_assert_not_reached ; } } }
void nlEndMatrix() { nlTransition(NL_STATE_MATRIX, NL_STATE_MATRIX_CONSTRUCTED) ; nlRowColumnDestroy(&nlCurrentContext->af) ; nlCurrentContext->alloc_af = NL_FALSE ; nlRowColumnDestroy(&nlCurrentContext->al) ; nlCurrentContext->alloc_al = NL_FALSE ; nlRowColumnDestroy(&nlCurrentContext->xl) ; nlCurrentContext->alloc_al = NL_FALSE ; if(!nlCurrentContext->least_squares) { nl_assert( nlCurrentContext->current_row == nlCurrentContext->n ) ; } }
ATTR_HOT /* inline */ void net_t::update_devs() { //assert(m_num_cons != 0); nl_assert(this->isRailNet()); const int masks[4] = { 1, 5, 3, 1 }; const int mask = masks[ (m_cur_Q << 1) | m_new_Q ]; m_in_queue = 2; /* mark as taken ... */ m_cur_Q = m_new_Q; for (core_terminal_t *p = m_list_active.first(); p != nullptr; p = p->next()) { inc_stat(p->netdev().stat_call_count); if ((p->state() & mask) != 0) p->device().update_dev(); } }
ATTR_HOT /* inline */ void net_t::update_devs() { //assert(m_num_cons != 0); nl_assert(this->isRailNet()); const UINT32 masks[4] = { 1, 5, 3, 1 }; const UINT32 mask = masks[ (m_cur_Q << 1) | m_new_Q ]; m_in_queue = 2; /* mark as taken ... */ m_cur_Q = m_new_Q; #if 0 core_terminal_t * t[256]; core_terminal_t *p = m_list_active.first(); int cnt = 0; while (p != NULL) { if ((p->state() & mask) != 0) t[cnt++] = p; p = m_list_active.next(p); } for (int i=0; i<cnt; i++) t[i]->netdev().update_dev(); core_terminal_t *p = m_list_active.first(); while (p != NULL) { p->update_dev(mask); p = m_list_active.next(p); } #else core_terminal_t *p = m_list_active.first(); while (p != NULL) { p->update_dev(mask); p = p->m_next; } #endif }
ATTR_HOT /*ATTR_ALIGN*/ inline void netlist_net_t::update_devs() { //assert(m_num_cons != 0); nl_assert(this->isRailNet()); const int masks[4] = { 1, 5, 3, 1 }; const UINT32 mask = masks[ (m_cur_Q << 1) | m_new_Q ]; m_in_queue = 2; /* mark as taken ... */ m_cur_Q = m_new_Q; netlist_core_terminal_t *p = m_list_active.first(); #if 0 switch (m_active) { case 2: p->update_dev(mask); p = m_list_active.next(p); case 1: p->update_dev(mask); break; default: while (p != NULL) { p->update_dev(mask); p = m_list_active.next(p); } break; } #else while (p != NULL) { p->update_dev(mask); p = m_list_active.next(p); } #endif }
void detail::net_t::inc_active(core_terminal_t &term) { m_active++; m_list_active.push_front(&term); nl_assert(m_active <= static_cast<int>(num_cons())); if (m_active == 1) { railterminal().device().do_inc_active(); if (m_in_queue == 0) { if (m_time > netlist().time()) { m_in_queue = 1; /* pending */ netlist().push_to_queue(*this, m_time); } else { m_cur_Q = m_new_Q; m_in_queue = 2; } } } }
NLboolean nlSolve_SUPERLU() { /* OpenNL Context */ NLdouble* b = nlCurrentContext->b ; NLdouble* x = nlCurrentContext->x ; NLuint n = nlCurrentContext->n ; superlu_context* context = (superlu_context*)(nlCurrentContext->direct_solver_context) ; nl_assert(context != NULL) ; /* SUPERLU variables */ SuperMatrix B ; DNformat *vals = NULL ; /* access to result */ double *rvals = NULL ; /* access to result */ /* Temporary variables */ NLuint i ; NLint info ; StatInit(&(context->stat)) ; /* * Step 1: convert right-hand side into SUPERLU representation * ----------------------------------------------------------- */ dCreate_Dense_Matrix( &B, n, 1, b, n, SLU_DN, /* Fortran-type column-wise storage */ SLU_D, /* doubles */ SLU_GE /* general storage */ ); /* * Step 2: solve * ------------- */ dgstrs(NOTRANS, &(context->L), &(context->U), context->perm_c, context->perm_r, &B, &(context->stat), &info) ; /* * Step 3: get the solution * ------------------------ */ vals = (DNformat*)B.Store; rvals = (double*)(vals->nzval); for(i = 0; i < n; i++) x[i] = rvals[i]; /* * Step 4: cleanup * --------------- */ Destroy_SuperMatrix_Store(&B); StatFree(&(context->stat)); return NL_TRUE ; }
void nlBeginMatrix() { NLuint i ; NLuint n = 0 ; NLenum storage = NL_MATRIX_STORE_ROWS ; nlTransition(NL_STATE_SYSTEM, NL_STATE_MATRIX) ; if(!nlCurrentContext->matrix_already_set) { for(i=0; i<nlCurrentContext->nb_variables; i++) { if(!nlCurrentContext->variable[i].locked) { nlCurrentContext->variable[i].index = n ; n++ ; } else { nlCurrentContext->variable[i].index = ~0 ; } } nlCurrentContext->n = n ; /* SSOR preconditioner requires rows and columns */ if(nlCurrentContext->preconditioner == NL_PRECOND_SSOR) { storage = (storage | NL_MATRIX_STORE_COLUMNS) ; } /* a least squares problem results in a symmetric matrix */ if(nlCurrentContext->least_squares && !nlSolverIsCNC(nlCurrentContext->solver)) { nlCurrentContext->symmetric = NL_TRUE ; } if(nlCurrentContext->symmetric) { storage = (storage | NL_MATRIX_STORE_SYMMETRIC) ; } /* SuperLU storage does not support symmetric storage */ if( nlCurrentContext->solver == NL_SUPERLU_EXT || nlCurrentContext->solver == NL_PERM_SUPERLU_EXT || nlCurrentContext->solver == NL_SYMMETRIC_SUPERLU_EXT ) { storage = (storage & ~NL_MATRIX_STORE_SYMMETRIC) ; } /* CHOLMOD storage requires columns */ if(nlCurrentContext->solver == NL_CHOLMOD_EXT) { storage = (storage & ~NL_MATRIX_STORE_ROWS) ; storage = (storage | NL_MATRIX_STORE_COLUMNS) ; } nlSparseMatrixConstruct(&nlCurrentContext->M, n, n, storage) ; nlCurrentContext->alloc_M = NL_TRUE ; nlCurrentContext->x = NL_NEW_ARRAY(NLdouble, n) ; nlCurrentContext->alloc_x = NL_TRUE ; nlCurrentContext->b = NL_NEW_ARRAY(NLdouble, n) ; nlCurrentContext->alloc_b = NL_TRUE ; nlVariablesToVector() ; nlRowColumnConstruct(&nlCurrentContext->af) ; nlCurrentContext->alloc_af = NL_TRUE ; nlRowColumnConstruct(&nlCurrentContext->al) ; nlCurrentContext->alloc_al = NL_TRUE ; nlRowColumnConstruct(&nlCurrentContext->xl) ; nlCurrentContext->alloc_xl = NL_TRUE ; nlCurrentContext->current_row = 0 ; } else { nl_assert(nlCurrentContext->alloc_M) ; nl_assert(nlCurrentContext->alloc_x) ; nl_assert(nlCurrentContext->alloc_b) ; nlRowColumnConstruct(&nlCurrentContext->af) ; nlCurrentContext->alloc_af = NL_TRUE ; nlRowColumnConstruct(&nlCurrentContext->al) ; nlCurrentContext->alloc_al = NL_TRUE ; nlRowColumnConstruct(&nlCurrentContext->xl) ; nlCurrentContext->alloc_xl = NL_TRUE ; nlCurrentContext->current_row = 0 ; } }
NLboolean nlVariableIsLocked(NLuint index) { nl_assert(nlCurrentContext->state != NL_STATE_INITIAL) ; nl_debug_range_assert(index, 0, nlCurrentContext->nb_variables - 1) ; return nlCurrentContext->variable[index].locked ; }
NLdouble nlGetVariable(NLuint index) { nl_assert(nlCurrentContext->state != NL_STATE_INITIAL) ; nl_debug_range_assert(index, 0, nlCurrentContext->nb_variables - 1) ; return nlCurrentContext->variable[index].value ; }
ATTR_COLD void netlist_net_t::register_railterminal(netlist_output_t &mr) { nl_assert(m_railterminal == NULL); m_railterminal = &mr; }
NLuint nlSolve_BICGSTAB_precond() { NLdouble* b = nlCurrentContext->b ; NLdouble* x = nlCurrentContext->x ; NLdouble eps = nlCurrentContext->threshold ; NLuint max_iter = nlCurrentContext->max_iterations ; NLint N = nlCurrentContext->n ; NLint i; NLdouble *rT = NL_NEW_ARRAY(NLdouble, N) ; NLdouble *d = NL_NEW_ARRAY(NLdouble, N) ; NLdouble *h = NL_NEW_ARRAY(NLdouble, N) ; NLdouble *u = NL_NEW_ARRAY(NLdouble, N) ; NLdouble *Sd = NL_NEW_ARRAY(NLdouble, N) ; NLdouble *t = NL_NEW_ARRAY(NLdouble, N) ; NLdouble *aux = NL_NEW_ARRAY(NLdouble, N) ; NLdouble *s = h; NLdouble rTh, rTSd, rTr, alpha, beta, omega, st, tt; NLuint its=0; NLdouble b_square = ddot(N,b,1,b,1); NLdouble err = eps*eps*b_square; NLdouble *r = NL_NEW_ARRAY(NLdouble, N); NLdouble * Ax = NL_NEW_ARRAY(NLdouble,nlCurrentContext->n); NLdouble accu =0.0; nlCurrentContext->matrix_vector_prod(x,r); daxpy(N,-1.,b,1,r,1); nlCurrentContext->precond_vector_prod(r,d); dcopy(N,d,1,h,1); dcopy(N,h,1,rT,1); nl_assert( ddot(N,rT,1,rT,1)>1e-40 ); rTh=ddot(N,rT,1,h,1); rTr=ddot(N,r,1,r,1); while ( rTr>err && its < max_iter) { if(!(its % 100)) { printf ( "%d : %.10e -- %.10e\n", its, rTr, err ) ; } nlCurrentContext->matrix_vector_prod(d,aux); nlCurrentContext->precond_vector_prod(aux,Sd); rTSd=ddot(N,rT,1,Sd,1); nl_assert( fabs(rTSd)>1e-40 ); alpha=rTh/rTSd; daxpy(N,-alpha,aux,1,r,1); dcopy(N,h,1,s,1); daxpy(N,-alpha,Sd,1,s,1); nlCurrentContext->matrix_vector_prod(s,aux); nlCurrentContext->precond_vector_prod(aux,t); daxpy(N,1.,t,1,u,1); dscal(N,alpha,u,1); st=ddot(N,s,1,t,1); tt=ddot(N,t,1,t,1); if ( fabs(st)<1e-40 || fabs(tt)<1e-40 ) { omega = 0.; } else { omega = st/tt; } daxpy(N,-omega,aux,1,r,1); daxpy(N,-alpha,d,1,x,1); daxpy(N,-omega,s,1,x,1); dcopy(N,s,1,h,1); daxpy(N,-omega,t,1,h,1); beta=(alpha/omega)/rTh; rTh=ddot(N,rT,1,h,1); beta*=rTh; dscal(N,beta,d,1); daxpy(N,1.,h,1,d,1); daxpy(N,-beta*omega,Sd,1,d,1); rTr=ddot(N,r,1,r,1); ++its; } nlCurrentContext->matrix_vector_prod(x,Ax); for(i = 0 ; i < N ; ++i){ accu+=(Ax[i]-b[i])*(Ax[i]-b[i]); } printf("in OpenNL : ||Ax-b||/||b|| = %e\n",sqrt(accu)/sqrt(b_square)); NL_DELETE_ARRAY(Ax); NL_DELETE_ARRAY(r); NL_DELETE_ARRAY(rT); NL_DELETE_ARRAY(d); NL_DELETE_ARRAY(h); NL_DELETE_ARRAY(u); NL_DELETE_ARRAY(Sd); NL_DELETE_ARRAY(t); NL_DELETE_ARRAY(aux); return its; }
NLboolean nlFactorize_SUPERLU() { /* OpenNL Context */ NLSparseMatrix* M = &(nlCurrentContext->M) ; NLuint n = nlCurrentContext->n ; NLuint nnz = nlSparseMatrixNNZ(M) ; /* Number of Non-Zero coeffs */ superlu_context* context = (superlu_context*)(nlCurrentContext->direct_solver_context) ; if(context == NULL) { nlCurrentContext->direct_solver_context = malloc(sizeof(superlu_context)) ; context = (superlu_context*)(nlCurrentContext->direct_solver_context) ; } /* SUPERLU variables */ NLint info ; SuperMatrix A, AC ; /* Temporary variables */ NLRowColumn* Ci = NULL ; NLuint i,j,count ; /* Sanity checks */ nl_assert(!(M->storage & NL_MATRIX_STORE_SYMMETRIC)) ; nl_assert(M->storage & NL_MATRIX_STORE_ROWS) ; nl_assert(M->m == M->n) ; set_default_options(&(context->options)) ; switch(nlCurrentContext->solver) { case NL_SUPERLU_EXT: { context->options.ColPerm = NATURAL ; } break ; case NL_PERM_SUPERLU_EXT: { context->options.ColPerm = COLAMD ; } break ; case NL_SYMMETRIC_SUPERLU_EXT: { context->options.ColPerm = MMD_AT_PLUS_A ; context->options.SymmetricMode = YES ; } break ; default: { nl_assert_not_reached ; } break ; } StatInit(&(context->stat)) ; /* * Step 1: convert matrix M into SUPERLU compressed column representation * ---------------------------------------------------------------------- */ NLint* xa = NL_NEW_ARRAY(NLint, n+1) ; NLdouble* a = NL_NEW_ARRAY(NLdouble, nnz) ; NLint* asub = NL_NEW_ARRAY(NLint, nnz) ; count = 0 ; for(i = 0; i < n; i++) { Ci = &(M->row[i]) ; xa[i] = count ; for(j = 0; j < Ci->size; j++) { a[count] = Ci->coeff[j].value ; asub[count] = Ci->coeff[j].index ; count++ ; } } xa[n] = nnz ; dCreate_CompCol_Matrix( &A, n, n, nnz, a, asub, xa, SLU_NR, /* Row wise */ SLU_D, /* doubles */ SLU_GE /* general storage */ ); /* * Step 2: factorize matrix * ------------------------ */ context->perm_c = NL_NEW_ARRAY(NLint, n) ; context->perm_r = NL_NEW_ARRAY(NLint, n) ; NLint* etree = NL_NEW_ARRAY(NLint, n) ; get_perm_c(context->options.ColPerm, &A, context->perm_c) ; sp_preorder(&(context->options), &A, context->perm_c, etree, &AC) ; int panel_size = sp_ienv(1) ; int relax = sp_ienv(2) ; dgstrf(&(context->options), &AC, relax, panel_size, etree, NULL, 0, context->perm_c, context->perm_r, &(context->L), &(context->U), &(context->stat), &info) ; /* * Step 3: cleanup * --------------- */ NL_DELETE_ARRAY(xa) ; NL_DELETE_ARRAY(a) ; NL_DELETE_ARRAY(asub) ; NL_DELETE_ARRAY(etree) ; Destroy_SuperMatrix_Store(&A); Destroy_CompCol_Permuted(&AC); StatFree(&(context->stat)); return NL_TRUE ; }
ATTR_COLD void net_t::register_railterminal(core_terminal_t &mr) { nl_assert(m_railterminal == nullptr); m_railterminal = &mr; }