示例#1
0
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();
    }
}
示例#2
0
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;
}
示例#7
0
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;
}
示例#8
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;
}