inline bool operator !=(const CG<Base>& left, const CG<Base>& right) { if (left.isParameter() && right.isParameter()) { return left.getValue() != right.getValue(); } else if (left.isParameter() || right.isParameter()) { return true; } else { return left.getOperationNode() != right.getOperationNode(); } }
int main(int argc, char* argv[]) { init_paralution(); info_paralution(); LocalVector<double> x; LocalVector<double> rhs; LocalStencil<double> stencil(Laplace2D); stencil.SetGrid(100); // 100x100 x.Allocate("x", stencil.get_nrow()); rhs.Allocate("rhs", stencil.get_nrow()); // Linear Solver CG<LocalStencil<double>, LocalVector<double>, double > ls; rhs.Ones(); x.Zeros(); ls.SetOperator(stencil); ls.Build(); stencil.info(); double tick, tack; tick = paralution_time(); ls.Solve(rhs, &x); tack = paralution_time(); std::cout << "Solver execution:" << (tack-tick)/1000000 << " sec" << std::endl; ls.Clear(); stop_paralution(); return 0; }
extern "C" __declspec(dllexport) void CPUsolveCSRDouble(int *row_offset, int *col, double *val, const int nnz, const int N, double *_rhs, double *_x) { std::string name = "s"; LocalVector<double> x; LocalVector<double> rhs; LocalMatrix<double> mat; x.Allocate(name, N); x.Zeros(); rhs.Allocate(name, N); mat.AllocateCSR(name, nnz, N, N); mat.CopyFromCSR(row_offset, col, val); rhs.CopyFromData(_rhs); CG<LocalMatrix<double>, LocalVector<double>, double> ls; Jacobi<LocalMatrix<double>, LocalVector<double>, double> p; ls.SetOperator(mat); ls.SetPreconditioner(p); ls.Build(); ls.Solve(rhs, &x); x.CopyToData(_x); mat.Clear(); x.Clear(); rhs.Clear(); ls.Clear(); }
inline CG<Base>& CG<Base>::operator*=(const CG<Base> &right) { if (isParameter() && right.isParameter()) { *value_ *= *right.value_; } else { CodeHandler<Base>* handler; if (isParameter()) { if (isIdenticalZero()) { return *this; // nothing to do (does not consider that right might be infinity) } else if (isIdenticalOne()) { *this = right; return *this; } handler = right.getCodeHandler(); } else if (right.isParameter()) { if (right.isIdenticalZero()) { makeParameter(Base(0.0)); // does not consider that left might be infinity return *this; } else if (right.isIdenticalOne()) { return *this; // nothing to do } handler = getCodeHandler(); } else { CPPADCG_ASSERT_UNKNOWN(getCodeHandler() == right.getCodeHandler()); handler = getCodeHandler(); } std::unique_ptr<Base> value; if (isValueDefined() && right.isValueDefined()) { value.reset(new Base(getValue() * right.getValue())); } makeVariable(*handler, new OperationNode<Base>(CGOpCode::Mul,{argument(), right.argument()}), value); } return *this; }
extern "C" __declspec(dllexport) void solveCSRSingle(int *row_offset, int *col, float *val, const int nnz, const int N, float *_rhs, float *_x) { std::string name = "s"; LocalVector<float> x; LocalVector<float> rhs; LocalMatrix<float> mat; x.Allocate(name, N); x.Zeros(); rhs.Allocate(name, N); mat.AllocateCSR(name, nnz, N, N); mat.CopyFromCSR(row_offset, col, val); rhs.CopyFromData(_rhs); // mat.Check(); /* rhs.SetDataPtr(&_rhs, name, N); x.SetDataPtr(&_x, name, N); mat.SetDataPtrCSR(&row_offset, &col, &val, name, nnz, N, N); */ mat.MoveToAccelerator(); x.MoveToAccelerator(); rhs.MoveToAccelerator(); CG<LocalMatrix<float>, LocalVector<float>, float> ls; MultiColoredILU<LocalMatrix<float>, LocalVector<float>, float> p; ls.SetOperator(mat); ls.SetPreconditioner(p); ls.Build(); ls.Solve(rhs, &x); mat.MoveToHost(); x.MoveToHost(); rhs.MoveToHost(); /* mat.LeaveDataPtrCSR(&row_offset, &col, &val); rhs.LeaveDataPtr(&_rhs); x.LeaveDataPtr(&_x); */ x.CopyToData(_x); mat.Clear(); x.Clear(); rhs.Clear(); ls.Clear(); }
inline CG<Base>& CG<Base>::operator+=(const CG<Base> &right) { if (isParameter() && right.isParameter()) { *value_ += *right.value_; } else { CodeHandler<Base>* handler; if (isParameter()) { if (isIdenticalZero()) { *this = right; return *this; } handler = right.getCodeHandler(); } else if (right.isParameter()) { if (right.isIdenticalZero()) { return *this; // nothing to do } handler = getCodeHandler(); } else { CPPADCG_ASSERT_UNKNOWN(getCodeHandler() == right.getCodeHandler()); handler = getCodeHandler(); } std::unique_ptr<Base> value; if (isValueDefined() && right.isValueDefined()) { value.reset(new Base(getValue() + right.getValue())); } makeVariable(*handler, new OperationNode<Base>(CGOpCode::Add,{argument(), right.argument()}), value); } return *this; }
int main(int argc, char* argv[]) { if (argc == 1) { std::cerr << argv[0] << " <matrix> [Num threads]" << std::endl; exit(1); } init_paralution(); if (argc > 2) { set_omp_threads_paralution(atoi(argv[2])); } info_paralution(); LocalVector<double> x; LocalVector<double> rhs; LocalMatrix<double> mat; mat.ReadFileMTX(std::string(argv[1])); // Compute and apply (R)CMK ordering LocalVector<int> cmk; // mat.CMK(&cmk); mat.RCMK(&cmk); mat.Permute(cmk); mat.MoveToAccelerator(); x.MoveToAccelerator(); rhs.MoveToAccelerator(); x.Allocate("x", mat.get_nrow()); rhs.Allocate("rhs", mat.get_nrow()); // Linear Solver CG<LocalMatrix<double>, LocalVector<double>, double > ls; // Preconditioner ILU<LocalMatrix<double>, LocalVector<double>, double > p; double tick, tack; rhs.Ones(); x.Zeros(); ls.SetOperator(mat); ls.SetPreconditioner(p); ls.Build(); mat.info(); tick = paralution_time(); ls.Solve(rhs, &x); tack = paralution_time(); std::cout << "Solver execution:" << (tack-tick)/1000000 << " sec" << std::endl; // Revert CMK ordering on solution vector x.PermuteBackward(cmk); stop_paralution(); return 0; }
void AMG<OperatorType, VectorType, ValueType>::Build(void) { if (this->build_ == true) this->Clear(); assert(this->build_ == false); this->BuildHierarchy(); this->build_ = true; this->d_level_ = new VectorType*[this->levels_]; this->r_level_ = new VectorType*[this->levels_]; this->t_level_ = new VectorType*[this->levels_]; this->s_level_ = new VectorType*[this->levels_]; for (int i=0; i<this->levels_; ++i) { this->r_level_[i] = new VectorType; this->t_level_[i] = new VectorType; this->s_level_[i] = new VectorType; this->r_level_[i]->CloneBackend(*this->op_); this->t_level_[i]->CloneBackend(*this->op_); this->s_level_[i]->CloneBackend(*this->op_); if (i > 0) { this->d_level_[i] = new VectorType; this->d_level_[i]->CloneBackend(*this->op_); } } // Allocate temporary vectors for cycles for (int level=0; level<this->levels_; ++level) { if (level > 0) { this->d_level_[level]->Allocate("defect correction", this->op_level_[level-1]->get_nrow()); this->r_level_[level]->Allocate("residual", this->op_level_[level-1]->get_nrow()); this->t_level_[level]->Allocate("temporary", this->op_level_[level-1]->get_nrow()); this->s_level_[level]->Allocate("temporary", this->op_level_[level-1]->get_nrow()); } else { this->r_level_[level]->Allocate("residual", this->op_->get_nrow()); this->t_level_[level]->Allocate("temporary", this->op_->get_nrow()); this->s_level_[level]->Allocate("temporary", this->op_->get_nrow()); } } // Setup and build smoothers if (this->set_sm_ == false) { // Smoother for each level FixedPoint<OperatorType, VectorType, ValueType > **sm = NULL; sm = new FixedPoint<OperatorType, VectorType, ValueType >* [this->levels_-1]; MultiColoredGS<OperatorType, VectorType, ValueType > **gs = NULL; gs = new MultiColoredGS<OperatorType, VectorType, ValueType >* [this->levels_-1]; this->smoother_level_ = new IterativeLinearSolver<OperatorType, VectorType, ValueType>*[this->levels_-1]; this->sm_default_ = new Solver<OperatorType, VectorType, ValueType>*[this->levels_-1]; for (int i=0; i<this->levels_-1; ++i) { sm[i] = new FixedPoint<OperatorType, VectorType, ValueType >; gs[i] = new MultiColoredGS<OperatorType, VectorType, ValueType >; gs[i]->SetPrecondMatrixFormat(this->sm_format_); // relxation sm[i]->SetRelaxation(1.3); sm[i]->SetPreconditioner(*gs[i]); // be quite sm[i]->Verbose(0); this->smoother_level_[i] = sm[i]; // pass pointer to class so we can free it when clearing this->sm_default_[i] = gs[i]; } delete[] sm; delete[] gs; } for (int i=0; i<this->levels_-1; ++i) { if (i > 0) this->smoother_level_[i]->SetOperator(*this->op_level_[i-1]); else this->smoother_level_[i]->SetOperator(*this->op_); this->smoother_level_[i]->Build(); } // Setup and build coarse grid solver if (this->set_s_ == false) { // Coarse Grid Solver CG<OperatorType, VectorType, ValueType > *cgs = new CG<OperatorType, VectorType, ValueType >; // be quite cgs->Verbose(0); this->solver_coarse_ = cgs; } this->solver_coarse_->SetOperator(*this->op_level_[this->levels_-2]); this->solver_coarse_->Build(); // Convert operator to op_format if (this->op_format_ != CSR) for (int i=0; i<this->levels_-1;++i) this->op_level_[i]->ConvertTo(this->op_format_); }
int main(int argc, char* argv[]) { if (argc == 1) { std::cerr << argv[0] << " <matrix> [Num threads]" << std::endl; exit(1); } init_paralution(); if (argc > 2) { set_omp_threads_paralution(atoi(argv[2])); } info_paralution(); LocalVector<double> b, b_old, *b_k, *b_k1, *b_tmp; LocalMatrix<double> mat; mat.ReadFileMTX(std::string(argv[1])); // Gershgorin spectrum approximation double glambda_min, glambda_max; // Power method spectrum approximation double plambda_min, plambda_max; // Maximum number of iteration for the power method int iter_max = 10000; double tick, tack; // Gershgorin approximation of the eigenvalues mat.Gershgorin(glambda_min, glambda_max); std::cout << "Gershgorin : Lambda min = " << glambda_min << "; Lambda max = " << glambda_max << std::endl; mat.MoveToAccelerator(); b.MoveToAccelerator(); b_old.MoveToAccelerator(); b.Allocate("b_k+1", mat.get_nrow()); b_k1 = &b; b_old.Allocate("b_k", mat.get_nrow()); b_k = &b_old; b_k->Ones(); mat.info(); tick = paralution_time(); // compute lambda max for (int i=0; i<=iter_max; ++i) { mat.Apply(*b_k, b_k1); // std::cout << b_k1->Dot(*b_k) << std::endl; b_k1->Scale(double(1.0)/b_k1->Norm()); b_tmp = b_k1; b_k1 = b_k; b_k = b_tmp; } // get lambda max (Rayleigh quotient) mat.Apply(*b_k, b_k1); plambda_max = b_k1->Dot(*b_k) ; tack = paralution_time(); std::cout << "Power method (lambda max) execution:" << (tack-tick)/1000000 << " sec" << std::endl; mat.AddScalarDiagonal(double(-1.0)*plambda_max); b_k->Ones(); tick = paralution_time(); // compute lambda min for (int i=0; i<=iter_max; ++i) { mat.Apply(*b_k, b_k1); // std::cout << b_k1->Dot(*b_k) + plambda_max << std::endl; b_k1->Scale(double(1.0)/b_k1->Norm()); b_tmp = b_k1; b_k1 = b_k; b_k = b_tmp; } // get lambda min (Rayleigh quotient) mat.Apply(*b_k, b_k1); plambda_min = (b_k1->Dot(*b_k) + plambda_max); // back to the original matrix mat.AddScalarDiagonal(plambda_max); tack = paralution_time(); std::cout << "Power method (lambda min) execution:" << (tack-tick)/1000000 << " sec" << std::endl; std::cout << "Power method Lambda min = " << plambda_min << "; Lambda max = " << plambda_max << "; iter=2x" << iter_max << std::endl; LocalVector<double> x; LocalVector<double> rhs; x.CloneBackend(mat); rhs.CloneBackend(mat); x.Allocate("x", mat.get_nrow()); rhs.Allocate("rhs", mat.get_nrow()); // Chebyshev iteration Chebyshev<LocalMatrix<double>, LocalVector<double>, double > ls; rhs.Ones(); x.Zeros(); ls.SetOperator(mat); ls.Set(plambda_min, plambda_max); ls.Build(); tick = paralution_time(); ls.Solve(rhs, &x); tack = paralution_time(); std::cout << "Solver execution:" << (tack-tick)/1000000 << " sec" << std::endl; // PCG + Chebyshev polynomial CG<LocalMatrix<double>, LocalVector<double>, double > cg; AIChebyshev<LocalMatrix<double>, LocalVector<double>, double > p; // damping factor plambda_min = plambda_max / 7; p.Set(3, plambda_min, plambda_max); rhs.Ones(); x.Zeros(); cg.SetOperator(mat); cg.SetPreconditioner(p); cg.Build(); tick = paralution_time(); cg.Solve(rhs, &x); tack = paralution_time(); std::cout << "Solver execution:" << (tack-tick)/1000000 << " sec" << std::endl; stop_paralution(); return 0; }