static void PruneInductionCandidate(int tnum, LOOP *l) { if (tempInfo[tnum]->size >= ISZ_FLOAT) { briggsReset(candidates, tnum); } else { QUAD *I = tempInfo[tnum]->instructionDefines; switch(I->dc.opcode) { case i_phi: { PHIDATA *pd = I->dc.v.phi; struct _phiblock *pb = pd->temps; while (pb) { if (!briggsTest(candidates, pb->Tn) && !isInvariant(pb->Tn, l)) { briggsReset(candidates, tnum); break; } pb = pb->next; } } break; case i_add: case i_sub: if (I->temps & TEMP_RIGHT) { int tn2 = I->dc.right->offset->v.sp->value.i; if (!briggsTest(candidates, tn2)) briggsReset(candidates, tnum); } /* FALLTHROUGH */ case i_neg: case i_assn: if (I->temps & TEMP_LEFT) { int tn2 = I->dc.left->offset->v.sp->value.i; if (!briggsTest(candidates, tn2)) briggsReset(candidates, tnum); } break; default: diag("PruneInductionCandidate: invalid form"); break; } } }
// // Find loop invariant instructions in a given block. // We can do this block by block because we are traversing the dominator // tree in pre-order, which accumulating invariants in our set. // void LicmPass::inspectBlock(const Loop* loop, BasicBlock* block, Invariants& invariants) { // No need to iterate over subloops because they will already have their // instructions hoisted. Skip if we are in the subloop. bool top_level = isTopLevel(loop, block); if (!top_level) { return; } // Iterate through all the intructions. for (BasicBlock::iterator J = block->begin(), JE = block->end(); J != JE; ++J) { Instruction& instr = *J; bool invariant = isInvariant(loop, invariants, &instr); if (invariant) { invariants.insert(&instr); } } }
// // Check if instruction is invariant. // bool LicmPass::isInvariant(const Loop* loop, Invariants& invariants, Instruction* instr) { // Must also satisfy these conditions to ensure safety of movement. if (!isSafeToSpeculativelyExecute(instr) || instr->mayReadFromMemory() || isa<LandingPadInst>(instr)) { return false; } // See if all operands are invariant. for (User::op_iterator OI = instr->op_begin(), OE = instr->op_end(); OI != OE; ++OI) { Value *operand = *OI; if (!isInvariant(loop, invariants, operand)) { return false; } } // Satisfies all conditions. return true; }
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); }