示例#1
0
bool EigenLisLinearSolver::solve(EigenMatrix &A_, EigenVector& b_,
                                 EigenVector &x_)
{
    static_assert(EigenMatrix::RawMatrixType::IsRowMajor,
                  "Sparse matrix is required to be in row major storage.");
    auto &A = A_.getRawMatrix();
    auto &b = b_.getRawVector();
    auto &x = x_.getRawVector();

    if (!A.isCompressed())
        A.makeCompressed();
    int nnz = A.nonZeros();
    int* ptr = A.outerIndexPtr();
    int* col = A.innerIndexPtr();
    double* data = A.valuePtr();
    LisMatrix lisA(A_.getNumberOfRows(), nnz, ptr, col, data);
    LisVector lisb(b.rows(), b.data());
    LisVector lisx(x.rows(), x.data());

    LisLinearSolver lissol; // TODO not always creat Lis solver here
    lissol.setOption(_lis_option);
    lissol.solve(lisA, lisb, lisx);

    for (std::size_t i=0; i<lisx.size(); i++)
        x[i] = lisx[i];

    return true; // TODO implement checks
}
示例#2
0
bool EigenLinearSolver::solve(EigenMatrix &A, EigenVector& b, EigenVector &x)
{
    INFO("------------------------------------------------------------------");
    INFO("*** Eigen solver computation");

#ifdef USE_EIGEN_UNSUPPORTED
    std::unique_ptr<Eigen::IterScaling<EigenMatrix::RawMatrixType>> scal;
    if (_option.scaling)
    {
        INFO("-> scale");
        scal.reset(new Eigen::IterScaling<EigenMatrix::RawMatrixType>());
        scal->computeRef(A.getRawMatrix());
        b.getRawVector() = scal->LeftScaling().cwiseProduct(b.getRawVector());
    }
#endif
    auto const success = _solver->solve(A.getRawMatrix(), b.getRawVector(),
                                        x.getRawVector(), _option);
#ifdef USE_EIGEN_UNSUPPORTED
    if (scal)
        x.getRawVector() = scal->RightScaling().cwiseProduct(x.getRawVector());
#endif

    INFO("------------------------------------------------------------------");

    return success;
}
示例#3
0
//---------------------------------------------------------------------------
int main(int argc, char *argv[]) {
    namespace po = boost::program_options;

    try {
        std::string ifile;
        std::string ofile = "partition.mtx";

        int nparts, block_size;

        po::options_description desc("Options");

        desc.add_options()
            ("help,h", "show help")
            ("input,i",      po::value<std::string>(&ifile)->required(), "Input matrix")
            ("output,o",     po::value<std::string>(&ofile)->default_value(ofile), "Output file")
            ("nparts,n",     po::value<int>(&nparts)->required(), "Number of parts")
            ("block_size,b", po::value<int>(&block_size)->default_value(1), "Block size")
            ;

        po::positional_options_description pd;
        pd.add("input", 1);

        po::variables_map vm;
        po::store(po::command_line_parser(argc, argv).options(desc).positional(pd).run(), vm);

        if (vm.count("help")) {
            std::cout << desc << std::endl;
            return 0;
        }

        po::notify(vm);

        EigenMatrix A;
        precondition(
            Eigen::loadMarket(A, ifile),
            "Failed to load matrix file"
            );

        PartVector part = partition(A.rows(), nparts, block_size,
                A.outerIndexPtr(), A.innerIndexPtr());

        precondition(
                Eigen::saveMarketVector(part, ofile),
                "Failed to write partition data"
                );
    } catch (const std::exception &e) {
        std::cerr << "Error: " << e.what() << std::endl;
        return 1;
    }
}
示例#4
0
void addToMatrix(EigenMatrix& m,
                 std::initializer_list<double> values)
{
    auto const rows = m.getNumberOfRows();
    auto const cols = m.getNumberOfColumns();

    assert(static_cast<EigenMatrix::IndexType>(values.size()) == rows*cols);
    Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> tmp(rows, cols);

    auto it = values.begin();
    for (GlobalIndexType r=0; r<rows; ++r) {
        for (GlobalIndexType c=0; c<cols; ++c) {
            tmp(r, c) = *(it++);
        }
    }

    m.getRawMatrix() += tmp.sparseView();
}
示例#5
0
EigenLinearSolver::EigenLinearSolver(EigenMatrix &A,
                            const std::string /*solver_name*/,
                            BaseLib::ConfigTree const*const option)
{
    if (option)
        setOption(*option);

    if (!A.getRawMatrix().isCompressed())
        A.getRawMatrix().makeCompressed();
    if (_option.solver_type==EigenOption::SolverType::SparseLU) {
        using SolverType = Eigen::SparseLU<EigenMatrix::RawMatrixType, Eigen::COLAMDOrdering<int>>;
        _solver = new details::EigenDirectLinearSolver<SolverType, IEigenSolver>(A.getRawMatrix());
    } else if (_option.solver_type==EigenOption::SolverType::BiCGSTAB) {
        using SolverType = Eigen::BiCGSTAB<EigenMatrix::RawMatrixType, Eigen::DiagonalPreconditioner<double>>;
        _solver = new details::EigenIterativeLinearSolver<SolverType, IEigenSolver>(A.getRawMatrix());
    } else if (_option.solver_type==EigenOption::SolverType::CG) {
        using SolverType = Eigen::ConjugateGradient<EigenMatrix::RawMatrixType, Eigen::Lower, Eigen::DiagonalPreconditioner<double>>;
        _solver = new details::EigenIterativeLinearSolver<SolverType, IEigenSolver>(A.getRawMatrix());
    }
}
示例#6
0
bool Eigen::solve(SLE& system, base::DataMatrix& B, base::DataMatrix& X) const {
#ifdef USE_EIGEN
  Printer::getInstance().printStatusBegin("Solving linear system (Eigen)...");

  const size_t n = system.getDimension();
  EigenMatrix A = EigenMatrix::Zero(n, n);
  size_t nnz = 0;

// parallelize only if the system is cloneable
#pragma omp parallel if (system.isCloneable()) shared(system, A, nnz) default(none)
  {
    SLE* system2 = &system;
#ifdef _OPENMP
    std::unique_ptr<CloneableSLE> clonedSLE;

    if (system.isCloneable() && (omp_get_max_threads() > 1)) {
      dynamic_cast<CloneableSLE&>(system).clone(clonedSLE);
      system2 = clonedSLE.get();
    }

#endif /* _OPENMP */

// copy system matrix to Eigen matrix object
#pragma omp for ordered schedule(dynamic)

    for (size_t i = 0; i < n; i++) {
      for (size_t j = 0; j < n; j++) {
        A(i, j) = system2->getMatrixEntry(i, j);

        // count nonzero entries
        // (not necessary, you can also remove that if you like)
        if (A(i, j) != 0) {
#pragma omp atomic
          nnz++;
        }
      }

      // status message
      if (i % 100 == 0) {
#pragma omp ordered
        {
          char str[10];
          snprintf(str, sizeof(str), "%.1f%%",
                   static_cast<float_t>(i) / static_cast<float_t>(n) * 100.0);
          Printer::getInstance().printStatusUpdate("constructing matrix (" + std::string(str) +
                                                   ")");
        }
      }
    }
  }

  Printer::getInstance().printStatusUpdate("constructing matrix (100.0%)");
  Printer::getInstance().printStatusNewLine();

  // print ratio of nonzero entries
  {
    char str[10];
    float_t nnz_ratio =
        static_cast<float_t>(nnz) / (static_cast<float_t>(n) * static_cast<float_t>(n));
    snprintf(str, sizeof(str), "%.1f%%", nnz_ratio * 100.0);
    Printer::getInstance().printStatusUpdate("nnz ratio: " + std::string(str));
    Printer::getInstance().printStatusNewLine();
  }

  // calculate QR factorization of system matrix
  Printer::getInstance().printStatusUpdate("step 1: Householder QR factorization");
  ::Eigen::HouseholderQR<EigenMatrix> A_QR = A.householderQr();

  base::DataVector x(n);
  base::DataVector b(n);
  X.resize(n, B.getNcols());

  // solve system for each RHS
  for (size_t i = 0; i < B.getNcols(); i++) {
    B.getColumn(i, b);
    Printer::getInstance().printStatusNewLine();

    if (B.getNcols() == 1) {
      Printer::getInstance().printStatusUpdate("step 2: solving");
    } else {
      Printer::getInstance().printStatusUpdate("step 2: solving (RHS " + std::to_string(i + 1) +
                                               " of " + std::to_string(B.getNcols()) + ")");
    }

    if (solveInternal(A, A_QR, b, x)) {
      X.setColumn(i, x);
    } else {
      Printer::getInstance().printStatusEnd("error: Could not solve linear system!");
      return false;
    }
  }

  Printer::getInstance().printStatusEnd();
  return true;
#else
  std::cerr << "Error in sle_solver::Eigen::solve: "
            << "SG++ was compiled without Eigen support!\n";
  return false;
#endif /* USE_EIGEN */
}
示例#7
0
void setMatrix(EigenMatrix& m, Eigen::MatrixXd const& tmp)
{
    m.getRawMatrix() = tmp.sparseView();
}