int get_num_invariant_accesses(Ploop *loop, PlutoProg *prog) { int i, j, ni; /* All statements under the loop, all accesses for the statement */ ni = 0; for (i=0; i<loop->nstmts; i++) { Stmt *stmt = loop->stmts[i]; for (j=0; j<stmt->nreads; j++) { ni += is_invariant(stmt, stmt->reads[j], loop->depth); } for (j=0; j<stmt->nwrites; j++) { ni += is_invariant(stmt, stmt->writes[j], loop->depth); } } return ni; }
bool binspector_parser_t::is_named_statement() { return is_invariant() || is_constant() || is_skip() || is_slot() || is_signal() || is_field(); // field should be last because atoms only // require an expression which most everything // falls into; the more explicit stuff should // come first. }
Stokhos::ProductLanczosPCEBasis<ordinal_type, value_type>:: ProductLanczosPCEBasis( ordinal_type p, const Teuchos::Array< Stokhos::OrthogPolyApprox<ordinal_type, value_type> >& pce, const Teuchos::RCP<const Stokhos::Quadrature<ordinal_type, value_type> >& quad, const Teuchos::RCP< const Stokhos::Sparse3Tensor<ordinal_type, value_type> >& Cijk, const Teuchos::ParameterList& params_) : name("Product Lanczos PCE Basis"), params(params_) { Teuchos::RCP<const Stokhos::OrthogPolyBasis<ordinal_type,value_type> > pce_basis = pce[0].basis(); ordinal_type pce_sz = pce_basis->size(); // Check if basis is a product basis Teuchos::RCP<const Stokhos::ProductBasis<ordinal_type,value_type> > prod_basis = Teuchos::rcp_dynamic_cast<const Stokhos::ProductBasis<ordinal_type,value_type> >(pce_basis); Teuchos::Array< Teuchos::RCP<const OneDOrthogPolyBasis<ordinal_type,value_type> > > coord_bases; if (prod_basis != Teuchos::null) coord_bases = prod_basis->getCoordinateBases(); // Build Lanczos basis for each pce bool project = params.get("Project", true); bool normalize = params.get("Normalize", true); bool limit_integration_order = params.get("Limit Integration Order", false); bool use_stieltjes = params.get("Use Old Stieltjes Method", false); Teuchos::Array< Teuchos::RCP<const Stokhos::OneDOrthogPolyBasis<int,double > > > coordinate_bases; Teuchos::Array<int> is_invariant(pce.size(),-2); for (ordinal_type i=0; i<pce.size(); i++) { // Check for pce's lying in invariant subspaces, which are pce's that // depend on only a single dimension. In this case use the corresponding // original coordinate basis. Convention is: -2 -- not invariant, -1 -- // constant, i >= 0 pce depends only on dimension i if (prod_basis != Teuchos::null) is_invariant[i] = isInvariant(pce[i]); if (is_invariant[i] >= 0) { coordinate_bases.push_back(coord_bases[is_invariant[i]]); } // Exclude constant pce's from the basis since they don't represent // stochastic dimensions else if (is_invariant[i] != -1) { if (use_stieltjes) { coordinate_bases.push_back( Teuchos::rcp( new Stokhos::StieltjesPCEBasis<ordinal_type,value_type>( p, Teuchos::rcp(&(pce[i]),false), quad, false, normalize, project, Cijk))); } else { if (project) coordinate_bases.push_back( Teuchos::rcp( new Stokhos::LanczosProjPCEBasis<ordinal_type,value_type>( p, Teuchos::rcp(&(pce[i]),false), Cijk, normalize, limit_integration_order))); else coordinate_bases.push_back( Teuchos::rcp( new Stokhos::LanczosPCEBasis<ordinal_type,value_type>( p, Teuchos::rcp(&(pce[i]),false), quad, normalize, limit_integration_order))); } } } ordinal_type d = coordinate_bases.size(); // Build tensor product basis tensor_lanczos_basis = Teuchos::rcp( new Stokhos::CompletePolynomialBasis<ordinal_type,value_type>( coordinate_bases, params.get("Cijk Drop Tolerance", 1.0e-15), params.get("Use Old Cijk Algorithm", false))); // Build reduced quadrature Teuchos::ParameterList sg_params; sg_params.sublist("Basis").set< Teuchos::RCP< const Stokhos::OrthogPolyBasis<ordinal_type,value_type> > >("Stochastic Galerkin Basis", tensor_lanczos_basis); sg_params.sublist("Quadrature") = params.sublist("Reduced Quadrature"); reduced_quad = Stokhos::QuadratureFactory<ordinal_type,value_type>::create(sg_params); // Build Psi matrix -- Psi_ij = Psi_i(x^j)*w_j/<Psi_i^2> const Teuchos::Array<value_type>& weights = quad->getQuadWeights(); const Teuchos::Array< Teuchos::Array<value_type> >& points = quad->getQuadPoints(); const Teuchos::Array< Teuchos::Array<value_type> >& basis_vals = quad->getBasisAtQuadPoints(); ordinal_type nqp = weights.size(); SDM Psi(pce_sz, nqp); for (ordinal_type i=0; i<pce_sz; i++) for (ordinal_type k=0; k<nqp; k++) Psi(i,k) = basis_vals[k][i]*weights[k]/pce_basis->norm_squared(i); // Build Phi matrix -- Phi_ij = Phi_i(y(x^j)) ordinal_type sz = tensor_lanczos_basis->size(); Teuchos::Array<value_type> red_basis_vals(sz); Teuchos::Array<value_type> pce_vals(d); Phi.shape(sz, nqp); for (int k=0; k<nqp; k++) { ordinal_type jdx = 0; for (int j=0; j<pce.size(); j++) { // Exclude constant pce's if (is_invariant[j] != -1) { // Use the identity mapping for invariant subspaces if (is_invariant[j] >= 0) pce_vals[jdx] = points[k][is_invariant[j]]; else pce_vals[jdx] = pce[j].evaluate(points[k], basis_vals[k]); jdx++; } } tensor_lanczos_basis->evaluateBases(pce_vals, red_basis_vals); for (int i=0; i<sz; i++) Phi(i,k) = red_basis_vals[i]; } bool verbose = params.get("Verbose", false); // Compute matrix A mapping reduced space to original A.shape(pce_sz, sz); ordinal_type ret = A.multiply(Teuchos::NO_TRANS, Teuchos::TRANS, 1.0, Psi, Phi, 0.0); TEUCHOS_ASSERT(ret == 0); //print_matlab(std::cout << "A = " << std::endl, A); // Compute pseudo-inverse of A mapping original space to reduced // A = U*S*V^T -> A^+ = V*S^+*U^T = (S^+*V^T)^T*U^T where // S^+ is a diagonal matrix comprised of the inverse of the diagonal of S // for each nonzero, and zero otherwise Teuchos::Array<value_type> sigma; SDM U, Vt; value_type rank_threshold = params.get("Rank Threshold", 1.0e-12); ordinal_type rank = svd_threshold(rank_threshold, A, sigma, U, Vt); Ainv.shape(sz, pce_sz); TEUCHOS_ASSERT(rank == Vt.numRows()); for (ordinal_type i=0; i<Vt.numRows(); i++) for (ordinal_type j=0; j<Vt.numCols(); j++) Vt(i,j) = Vt(i,j) / sigma[i]; ret = Ainv.multiply(Teuchos::TRANS, Teuchos::TRANS, 1.0, Vt, U, 0.0); TEUCHOS_ASSERT(ret == 0); //print_matlab(std::cout << "Ainv = " << std::endl, Ainv); if (verbose) { std::cout << "rank = " << rank << std::endl; std::cout << "diag(S) = ["; for (ordinal_type i=0; i<rank; i++) std::cout << sigma[i] << " "; std::cout << "]" << std::endl; // Check A = U*S*V^T SDM SVt(rank, Vt.numCols()); for (ordinal_type i=0; i<Vt.numRows(); i++) for (ordinal_type j=0; j<Vt.numCols(); j++) SVt(i,j) = Vt(i,j) * sigma[i] * sigma[i]; // since we divide by sigma // above SDM err_A(pce_sz,sz); err_A.assign(A); ret = err_A.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, -1.0, U, SVt, 1.0); TEUCHOS_ASSERT(ret == 0); std::cout << "||A - U*S*V^T||_infty = " << err_A.normInf() << std::endl; //print_matlab(std::cout << "A - U*S*V^T = " << std::endl, err_A); // Check Ainv*A == I SDM err(sz,sz); err.putScalar(0.0); for (ordinal_type i=0; i<sz; i++) err(i,i) = 1.0; ret = err.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, 1.0, Ainv, A, -1.0); TEUCHOS_ASSERT(ret == 0); std::cout << "||Ainv*A - I||_infty = " << err.normInf() << std::endl; //print_matlab(std::cout << "Ainv*A-I = " << std::endl, err); // Check A*Ainv == I SDM err2(pce_sz,pce_sz); err2.putScalar(0.0); for (ordinal_type i=0; i<pce_sz; i++) err2(i,i) = 1.0; ret = err2.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, 1.0, A, Ainv, -1.0); TEUCHOS_ASSERT(ret == 0); std::cout << "||A*Ainv - I||_infty = " << err2.normInf() << std::endl; //print_matlab(std::cout << "A*Ainv-I = " << std::endl, err2); } }
Stokhos::ProductLanczosGramSchmidtPCEBasis<ordinal_type, value_type>:: ProductLanczosGramSchmidtPCEBasis( ordinal_type max_p, const Teuchos::Array< Stokhos::OrthogPolyApprox<ordinal_type, value_type> >& pce, const Teuchos::RCP<const Stokhos::Quadrature<ordinal_type, value_type> >& quad, const Teuchos::RCP< const Stokhos::Sparse3Tensor<ordinal_type, value_type> >& Cijk, const Teuchos::ParameterList& params_) : name("Product Lanczos Gram-Schmidt PCE Basis"), params(params_), p(max_p) { Teuchos::RCP<const Stokhos::OrthogPolyBasis<ordinal_type,value_type> > pce_basis = pce[0].basis(); pce_sz = pce_basis->size(); // Check if basis is a product basis Teuchos::RCP<const Stokhos::ProductBasis<ordinal_type,value_type> > prod_basis = Teuchos::rcp_dynamic_cast<const Stokhos::ProductBasis<ordinal_type,value_type> >(pce_basis); Teuchos::Array< Teuchos::RCP<const OneDOrthogPolyBasis<ordinal_type,value_type> > > coord_bases; if (prod_basis != Teuchos::null) coord_bases = prod_basis->getCoordinateBases(); // Build Lanczos basis for each pce bool project = params.get("Project", true); bool normalize = params.get("Normalize", true); bool limit_integration_order = params.get("Limit Integration Order", false); bool use_stieltjes = params.get("Use Old Stieltjes Method", false); Teuchos::Array< Teuchos::RCP<const Stokhos::OneDOrthogPolyBasis<int,double > > > coordinate_bases; Teuchos::Array<int> is_invariant(pce.size(),-2); for (ordinal_type i=0; i<pce.size(); i++) { // Check for pce's lying in invariant subspaces, which are pce's that // depend on only a single dimension. In this case use the corresponding // original coordinate basis. Convention is: -2 -- not invariant, -1 -- // constant, i >= 0 pce depends only on dimension i if (prod_basis != Teuchos::null) is_invariant[i] = isInvariant(pce[i]); if (is_invariant[i] >= 0) { coordinate_bases.push_back(coord_bases[is_invariant[i]]); } // Exclude constant pce's from the basis since they don't represent // stochastic dimensions else if (is_invariant[i] != -1) { if (use_stieltjes) { coordinate_bases.push_back( Teuchos::rcp( new Stokhos::StieltjesPCEBasis<ordinal_type,value_type>( p, Teuchos::rcp(&(pce[i]),false), quad, false, normalize, project, Cijk))); } else { if (project) coordinate_bases.push_back( Teuchos::rcp( new Stokhos::LanczosProjPCEBasis<ordinal_type,value_type>( p, Teuchos::rcp(&(pce[i]),false), Cijk, normalize, limit_integration_order))); else coordinate_bases.push_back( Teuchos::rcp( new Stokhos::LanczosPCEBasis<ordinal_type,value_type>( p, Teuchos::rcp(&(pce[i]),false), quad, normalize, limit_integration_order))); } } } d = coordinate_bases.size(); // Build tensor product basis tensor_lanczos_basis = Teuchos::rcp( new Stokhos::CompletePolynomialBasis<ordinal_type,value_type>( coordinate_bases, params.get("Cijk Drop Tolerance", 1.0e-15), params.get("Use Old Cijk Algorithm", false))); // Build Psi matrix -- Psi_ij = Psi_i(x^j)*w_j/<Psi_i^2> const Teuchos::Array<value_type>& weights = quad->getQuadWeights(); const Teuchos::Array< Teuchos::Array<value_type> >& points = quad->getQuadPoints(); const Teuchos::Array< Teuchos::Array<value_type> >& basis_vals = quad->getBasisAtQuadPoints(); ordinal_type nqp = weights.size(); SDM Psi(pce_sz, nqp); for (ordinal_type i=0; i<pce_sz; i++) for (ordinal_type k=0; k<nqp; k++) Psi(i,k) = basis_vals[k][i]*weights[k]/pce_basis->norm_squared(i); // Build Phi matrix -- Phi_ij = Phi_i(y(x^j)) sz = tensor_lanczos_basis->size(); Teuchos::Array<value_type> red_basis_vals(sz); Teuchos::Array<value_type> pce_vals(d); SDM Phi(sz, nqp); SDM F(nqp, d); for (int k=0; k<nqp; k++) { ordinal_type jdx = 0; for (int j=0; j<pce.size(); j++) { // Exclude constant pce's if (is_invariant[j] != -1) { // Use the identity mapping for invariant subspaces if (is_invariant[j] >= 0) pce_vals[jdx] = points[k][is_invariant[j]]; else pce_vals[jdx] = pce[j].evaluate(points[k], basis_vals[k]); F(k,jdx) = pce_vals[jdx]; jdx++; } } tensor_lanczos_basis->evaluateBases(pce_vals, red_basis_vals); for (int i=0; i<sz; i++) Phi(i,k) = red_basis_vals[i]; } bool verbose = params.get("Verbose", false); // Compute matrix A mapping reduced space to original SDM A(pce_sz, sz); ordinal_type ret = A.multiply(Teuchos::NO_TRANS, Teuchos::TRANS, 1.0, Psi, Phi, 0.0); TEUCHOS_ASSERT(ret == 0); // Rescale columns of A to have unit norm const Teuchos::Array<value_type>& basis_norms = pce_basis->norm_squared(); for (ordinal_type j=0; j<sz; j++) { value_type nrm = 0.0; for (ordinal_type i=0; i<pce_sz; i++) nrm += A(i,j)*A(i,j)*basis_norms[i]; nrm = std::sqrt(nrm); for (ordinal_type i=0; i<pce_sz; i++) A(i,j) /= nrm; } // Compute our new basis -- each column of Qp is the coefficients of the // new basis in the original basis. Constraint pivoting so first d+1 // columns and included in Qp. value_type rank_threshold = params.get("Rank Threshold", 1.0e-12); std::string orthogonalization_method = params.get("Orthogonalization Method", "Householder"); Teuchos::Array<value_type> w(pce_sz, 1.0); SDM R; Teuchos::Array<ordinal_type> piv(sz); for (int i=0; i<d+1; i++) piv[i] = 1; typedef Stokhos::OrthogonalizationFactory<ordinal_type,value_type> SOF; sz = SOF::createOrthogonalBasis( orthogonalization_method, rank_threshold, verbose, A, w, Qp, R, piv); // Original basis at quadrature points -- needed to transform expansions // in this basis back to original SDM B(nqp, pce_sz); for (ordinal_type i=0; i<nqp; i++) for (ordinal_type j=0; j<pce_sz; j++) B(i,j) = basis_vals[i][j]; // Evaluate new basis at original quadrature points Q.reshape(nqp, sz); ret = Q.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, 1.0, B, Qp, 0.0); TEUCHOS_ASSERT(ret == 0); // Compute reduced quadrature rule Stokhos::ReducedQuadratureFactory<ordinal_type,value_type> quad_factory( params.sublist("Reduced Quadrature")); Teuchos::SerialDenseMatrix<ordinal_type, value_type> Q2; reduced_quad = quad_factory.createReducedQuadrature(Q, Q2, F, weights); // Basis is orthonormal by construction norms.resize(sz, 1.0); }
void LoopInvariantCodeMotion::process_block(BlockBegin* block) { TRACE_VALUE_NUMBERING(tty->print_cr("processing block B%d", block->block_id())); Instruction* prev = block; Instruction* cur = block->next(); while (cur != NULL) { // determine if cur instruction is loop invariant // only selected instruction types are processed here bool cur_invariant = false; if (cur->as_Constant() != NULL) { cur_invariant = !cur->can_trap(); } else if (cur->as_ArithmeticOp() != NULL || cur->as_LogicOp() != NULL || cur->as_ShiftOp() != NULL) { assert(cur->as_Op2() != NULL, "must be Op2"); Op2* op2 = (Op2*)cur; cur_invariant = !op2->can_trap() && is_invariant(op2->x()) && is_invariant(op2->y()); } else if (cur->as_LoadField() != NULL) { LoadField* lf = (LoadField*)cur; // deoptimizes on NullPointerException cur_invariant = !lf->needs_patching() && !lf->field()->is_volatile() && !_short_loop_optimizer->has_field_store(lf->field()->type()->basic_type()) && is_invariant(lf->obj()) && _insert_is_pred; } else if (cur->as_ArrayLength() != NULL) { ArrayLength *length = cur->as_ArrayLength(); cur_invariant = is_invariant(length->array()); } else if (cur->as_LoadIndexed() != NULL) { LoadIndexed *li = (LoadIndexed *)cur->as_LoadIndexed(); cur_invariant = !_short_loop_optimizer->has_indexed_store(as_BasicType(cur->type())) && is_invariant(li->array()) && is_invariant(li->index()) && _insert_is_pred; } if (cur_invariant) { // perform value numbering and mark instruction as loop-invariant _gvn->substitute(cur); if (cur->as_Constant() == NULL) { // ensure that code for non-constant instructions is always generated cur->pin(); } // remove cur instruction from loop block and append it to block before loop Instruction* next = cur->next(); Instruction* in = _insertion_point->next(); _insertion_point = _insertion_point->set_next(cur); cur->set_next(in); // Deoptimize on exception cur->set_flag(Instruction::DeoptimizeOnException, true); // Clear exception handlers cur->set_exception_handlers(NULL); TRACE_VALUE_NUMBERING(tty->print_cr("Instruction %c%d is loop invariant", cur->type()->tchar(), cur->id())); if (cur->state_before() != NULL) { cur->set_state_before(_state->copy()); } if (cur->exception_state() != NULL) { cur->set_exception_state(_state->copy()); } cur = prev->set_next(next); } else { prev = cur; cur = cur->next(); } } }