<commit_before>//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

// moose includes
#include "NonlinearSystem.h"
#include "FEProblem.h"
#include "DisplacedProblem.h"
#include "TimeIntegrator.h"
#include "FiniteDifferencePreconditioner.h"
#include "PetscSupport.h"
#include "ComputeResidualFunctor.h"
#include "ComputeFDResidualFunctor.h"
#include "MooseVariableScalar.h"
#include "MooseTypes.h"

#include "libmesh/nonlinear_solver.h"
#include "libmesh/petsc_nonlinear_solver.h"
#include "libmesh/sparse_matrix.h"
#include "libmesh/petsc_matrix.h"
#include "libmesh/diagonal_matrix.h"
#include "libmesh/default_coupling.h"

namespace Moose
{
void
compute_jacobian(const NumericVector<Number> & soln,
                 SparseMatrix<Number> & jacobian,
                 NonlinearImplicitSystem & sys)
{
  FEProblemBase * p =
      sys.get_equation_systems().parameters.get<FEProblemBase *>("_fe_problem_base");
  p->computeJacobianSys(sys, soln, jacobian);
}

void
compute_bounds(NumericVector<Number> & lower,
               NumericVector<Number> & upper,
               NonlinearImplicitSystem & sys)
{
  FEProblemBase * p =
      sys.get_equation_systems().parameters.get<FEProblemBase *>("_fe_problem_base");
  p->computeBounds(sys, lower, upper);
}

void
compute_nullspace(std::vector<NumericVector<Number> *> & sp, NonlinearImplicitSystem & sys)
{
  FEProblemBase * p =
      sys.get_equation_systems().parameters.get<FEProblemBase *>("_fe_problem_base");
  p->computeNullSpace(sys, sp);
}

void
compute_transpose_nullspace(std::vector<NumericVector<Number> *> & sp,
                            NonlinearImplicitSystem & sys)
{
  FEProblemBase * p =
      sys.get_equation_systems().parameters.get<FEProblemBase *>("_fe_problem_base");
  p->computeTransposeNullSpace(sys, sp);
}

void
compute_nearnullspace(std::vector<NumericVector<Number> *> & sp, NonlinearImplicitSystem & sys)
{
  FEProblemBase * p =
      sys.get_equation_systems().parameters.get<FEProblemBase *>("_fe_problem_base");
  p->computeNearNullSpace(sys, sp);
}

void
compute_postcheck(const NumericVector<Number> & old_soln,
                  NumericVector<Number> & search_direction,
                  NumericVector<Number> & new_soln,
                  bool & changed_search_direction,
                  bool & changed_new_soln,
                  NonlinearImplicitSystem & sys)
{
  FEProblemBase * p =
      sys.get_equation_systems().parameters.get<FEProblemBase *>("_fe_problem_base");
  p->computePostCheck(
      sys, old_soln, search_direction, new_soln, changed_search_direction, changed_new_soln);
}
} // namespace Moose

NonlinearSystem::NonlinearSystem(FEProblemBase & fe_problem, const std::string & name)
  : NonlinearSystemBase(
        fe_problem, fe_problem.es().add_system<NonlinearImplicitSystem>(name), name),
    _nl_implicit_sys(fe_problem.es().get_system<NonlinearImplicitSystem>(name)),
    _nl_residual_functor(_fe_problem),
    _fd_residual_functor(_fe_problem),
    _resid_and_jac_functor(_fe_problem),
    _use_coloring_finite_difference(false)
{
}

NonlinearSystem::~NonlinearSystem() {}

void
NonlinearSystem::init()
{
  NonlinearSystemBase::init();

  if (_resid_and_jacobian_together)
    nonlinearSolver()->residual_and_jacobian_object = &_resid_and_jac_functor;
  else
  {
    nonlinearSolver()->residual_object = &_nl_residual_functor;
    nonlinearSolver()->jacobian = Moose::compute_jacobian;
  }
  nonlinearSolver()->bounds = Moose::compute_bounds;
  nonlinearSolver()->nullspace = Moose::compute_nullspace;
  nonlinearSolver()->transpose_nullspace = Moose::compute_transpose_nullspace;
  nonlinearSolver()->nearnullspace = Moose::compute_nearnullspace;

  PetscNonlinearSolver<Real> * petsc_solver =
      static_cast<PetscNonlinearSolver<Real> *>(_nl_implicit_sys.nonlinear_solver.get());
  if (petsc_solver)
  {
    petsc_solver->set_residual_zero_out(false);
    petsc_solver->set_jacobian_zero_out(false);
    petsc_solver->use_default_monitor(false);
  }

  if (_automatic_scaling && _resid_vs_jac_scaling_param < 1. - TOLERANCE)
    // Add diagonal matrix that will be used for computing scaling factors
    _nl_implicit_sys.add_matrix<DiagonalMatrix>("scaling_matrix");
}

void
NonlinearSystem::solve()
{
  // Only attach the postcheck function to the solver if we actually
  // have dampers or if the FEProblemBase needs to update the solution,
  // which is also done during the linesearch postcheck.  It doesn't
  // hurt to do this multiple times, it is just setting a pointer.
  if (_fe_problem.hasDampers() || _fe_problem.shouldUpdateSolution() ||
      _fe_problem.needsPreviousNewtonIteration())
    _nl_implicit_sys.nonlinear_solver->postcheck = Moose::compute_postcheck;

  if (_fe_problem.solverParams()._type != Moose::ST_LINEAR)
  {
    TIME_SECTION("nlInitialResidual", 3, "Computing Initial Residual");
    // Calculate the initial residual for use in the convergence criterion.
    _computing_initial_residual = true;
    _fe_problem.computeResidualSys(_nl_implicit_sys, *_current_solution, *_nl_implicit_sys.rhs);
    _computing_initial_residual = false;
    _nl_implicit_sys.rhs->close();
    _initial_residual_before_preset_bcs = _nl_implicit_sys.rhs->l2_norm();
    if (_compute_initial_residual_before_preset_bcs)
      _console << "Initial residual before setting preset BCs: "
               << _initial_residual_before_preset_bcs << std::endl;
  }

  // Clear the iteration counters
  _current_l_its.clear();
  _current_nl_its = 0;

  // Initialize the solution vector using a predictor and known values from nodal bcs
  setInitialSolution();

  // Now that the initial solution has ben set, potentially perform a residual/Jacobian evaluation
  // to determine variable scaling factors
  if (_automatic_scaling)
  {
    if (_compute_scaling_once)
    {
      if (!_computed_scaling)
      {
        computeScaling();
        _computed_scaling = true;
      }
    }
    else
      computeScaling();
  }
#ifdef MOOSE_GLOBAL_AD_INDEXING
  // We do not know a priori what variable a global degree of freedom corresponds to, so we need a
  // map from global dof to scaling factor. We just use a ghosted NumericVector for that mapping
  assembleScalingVector();
#endif

  if (_use_finite_differenced_preconditioner)
  {
    _nl_implicit_sys.nonlinear_solver->fd_residual_object = &_fd_residual_functor;
    setupFiniteDifferencedPreconditioner();
  }

  PetscNonlinearSolver<Real> & solver =
      static_cast<PetscNonlinearSolver<Real> &>(*_nl_implicit_sys.nonlinear_solver);
  solver.mffd_residual_object = &_fd_residual_functor;

  solver.set_snesmf_reuse_base(_fe_problem.useSNESMFReuseBase());

  if (_time_integrator)
  {
    _time_integrator->solve();
    _time_integrator->postSolve();
    _n_iters = _time_integrator->getNumNonlinearIterations();
    _n_linear_iters = _time_integrator->getNumLinearIterations();
  }
  else
  {
    system().solve();
    _n_iters = _nl_implicit_sys.n_nonlinear_iterations();
    _n_linear_iters = solver.get_total_linear_iterations();
  }

  // store info about the solve
  _final_residual = _nl_implicit_sys.final_nonlinear_residual();

  if (_use_coloring_finite_difference)
    MatFDColoringDestroy(&_fdcoloring);
}

void
NonlinearSystem::stopSolve()
{
  PetscNonlinearSolver<Real> & solver =
      static_cast<PetscNonlinearSolver<Real> &>(*sys().nonlinear_solver);
  SNESSetFunctionDomainError(solver.snes());

  // Insert a NaN into the residual vector.  As of PETSc-3.6, this
  // should make PETSc return DIVERGED_NANORINF the next time it does
  // a reduction.  We'll write to the first local dof on every
  // processor that has any dofs.
  _nl_implicit_sys.rhs->close();

  if (_nl_implicit_sys.rhs->local_size())
    _nl_implicit_sys.rhs->set(_nl_implicit_sys.rhs->first_local_index(),
                              std::numeric_limits<Real>::quiet_NaN());
  _nl_implicit_sys.rhs->close();

  // Clean up by getting other vectors into a valid state for a
  // (possible) subsequent solve.  There may be more than just
  // these...
  if (_Re_time)
    _Re_time->close();
  _Re_non_time->close();
}

void
NonlinearSystem::setupFiniteDifferencedPreconditioner()
{
  std::shared_ptr<FiniteDifferencePreconditioner> fdp =
      std::dynamic_pointer_cast<FiniteDifferencePreconditioner>(_preconditioner);
  if (!fdp)
    mooseError("Did not setup finite difference preconditioner, and please add a preconditioning "
               "block with type = fdp");

  if (fdp->finiteDifferenceType() == "coloring")
  {
    setupColoringFiniteDifferencedPreconditioner();
    _use_coloring_finite_difference = true;
  }

  else if (fdp->finiteDifferenceType() == "standard")
  {
    setupStandardFiniteDifferencedPreconditioner();
    _use_coloring_finite_difference = false;
  }
  else
    mooseError("Unknown finite difference type");
}

void
NonlinearSystem::setupStandardFiniteDifferencedPreconditioner()
{
  // Make sure that libMesh isn't going to override our preconditioner
  _nl_implicit_sys.nonlinear_solver->jacobian = nullptr;

  PetscNonlinearSolver<Number> * petsc_nonlinear_solver =
      static_cast<PetscNonlinearSolver<Number> *>(_nl_implicit_sys.nonlinear_solver.get());

  PetscMatrix<Number> * petsc_mat =
      static_cast<PetscMatrix<Number> *>(&_nl_implicit_sys.get_system_matrix());

  SNESSetJacobian(petsc_nonlinear_solver->snes(),
                  petsc_mat->mat(),
                  petsc_mat->mat(),
                  SNESComputeJacobianDefault,
                  nullptr);
}

void
NonlinearSystem::setupColoringFiniteDifferencedPreconditioner()
{
  // Make sure that libMesh isn't going to override our preconditioner
  _nl_implicit_sys.nonlinear_solver->jacobian = nullptr;

  PetscNonlinearSolver<Number> & petsc_nonlinear_solver =
      dynamic_cast<PetscNonlinearSolver<Number> &>(*_nl_implicit_sys.nonlinear_solver);

  // Pointer to underlying PetscMatrix type
  PetscMatrix<Number> * petsc_mat =
      dynamic_cast<PetscMatrix<Number> *>(&_nl_implicit_sys.get_system_matrix());

  Moose::compute_jacobian(*_nl_implicit_sys.current_local_solution, *petsc_mat, _nl_implicit_sys);

  if (!petsc_mat)
    mooseError("Could not convert to Petsc matrix.");

  petsc_mat->close();

  PetscErrorCode ierr = 0;
  ISColoring iscoloring;

  // PETSc 3.5.x
  MatColoring matcoloring;
  ierr = MatColoringCreate(petsc_mat->mat(), &matcoloring);
  CHKERRABORT(_communicator.get(), ierr);
  ierr = MatColoringSetType(matcoloring, MATCOLORINGLF);
  CHKERRABORT(_communicator.get(), ierr);
  ierr = MatColoringSetFromOptions(matcoloring);
  CHKERRABORT(_communicator.get(), ierr);
  ierr = MatColoringApply(matcoloring, &iscoloring);
  CHKERRABORT(_communicator.get(), ierr);
  ierr = MatColoringDestroy(&matcoloring);
  CHKERRABORT(_communicator.get(), ierr);

  MatFDColoringCreate(petsc_mat->mat(), iscoloring, &_fdcoloring);
  MatFDColoringSetFromOptions(_fdcoloring);
  // clang-format off
  MatFDColoringSetFunction(_fdcoloring,
                           (PetscErrorCode(*)(void))(void (*)(void)) &
                               libMesh::libmesh_petsc_snes_fd_residual,
                           &petsc_nonlinear_solver);
  // clang-format on
  MatFDColoringSetUp(petsc_mat->mat(), iscoloring, _fdcoloring);
  SNESSetJacobian(petsc_nonlinear_solver.snes(),
                  petsc_mat->mat(),
                  petsc_mat->mat(),
                  SNESComputeJacobianDefaultColor,
                  _fdcoloring);
  // PETSc >=3.3.0
  ISColoringDestroy(&iscoloring);
}

bool
NonlinearSystem::converged()
{
  if (_fe_problem.hasException())
    return false;

  return _nl_implicit_sys.nonlinear_solver->converged;
}

void
NonlinearSystem::attachPreconditioner(Preconditioner<Number> * preconditioner)
{
  nonlinearSolver()->attach_preconditioner(preconditioner);
}

void
NonlinearSystem::computeScalingJacobian()
{
  _fe_problem.computeJacobianSys(_nl_implicit_sys, *_current_solution, *_scaling_matrix);
}

void
NonlinearSystem::computeScalingResidual()
{
  _fe_problem.computeResidualSys(_nl_implicit_sys, *_current_solution, RHS());
}

SNES
NonlinearSystem::getSNES()
{
  PetscNonlinearSolver<Number> * petsc_solver =
      dynamic_cast<PetscNonlinearSolver<Number> *>(nonlinearSolver());

  if (petsc_solver)
    return petsc_solver->snes();
  else
    mooseError("It is not a petsc nonlinear solver");
}
<commit_msg>Move residual and jac initialization back to constructor<commit_after>//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

// moose includes
#include "NonlinearSystem.h"
#include "FEProblem.h"
#include "DisplacedProblem.h"
#include "TimeIntegrator.h"
#include "FiniteDifferencePreconditioner.h"
#include "PetscSupport.h"
#include "ComputeResidualFunctor.h"
#include "ComputeFDResidualFunctor.h"
#include "MooseVariableScalar.h"
#include "MooseTypes.h"

#include "libmesh/nonlinear_solver.h"
#include "libmesh/petsc_nonlinear_solver.h"
#include "libmesh/sparse_matrix.h"
#include "libmesh/petsc_matrix.h"
#include "libmesh/diagonal_matrix.h"
#include "libmesh/default_coupling.h"

namespace Moose
{
void
compute_jacobian(const NumericVector<Number> & soln,
                 SparseMatrix<Number> & jacobian,
                 NonlinearImplicitSystem & sys)
{
  FEProblemBase * p =
      sys.get_equation_systems().parameters.get<FEProblemBase *>("_fe_problem_base");
  p->computeJacobianSys(sys, soln, jacobian);
}

void
compute_bounds(NumericVector<Number> & lower,
               NumericVector<Number> & upper,
               NonlinearImplicitSystem & sys)
{
  FEProblemBase * p =
      sys.get_equation_systems().parameters.get<FEProblemBase *>("_fe_problem_base");
  p->computeBounds(sys, lower, upper);
}

void
compute_nullspace(std::vector<NumericVector<Number> *> & sp, NonlinearImplicitSystem & sys)
{
  FEProblemBase * p =
      sys.get_equation_systems().parameters.get<FEProblemBase *>("_fe_problem_base");
  p->computeNullSpace(sys, sp);
}

void
compute_transpose_nullspace(std::vector<NumericVector<Number> *> & sp,
                            NonlinearImplicitSystem & sys)
{
  FEProblemBase * p =
      sys.get_equation_systems().parameters.get<FEProblemBase *>("_fe_problem_base");
  p->computeTransposeNullSpace(sys, sp);
}

void
compute_nearnullspace(std::vector<NumericVector<Number> *> & sp, NonlinearImplicitSystem & sys)
{
  FEProblemBase * p =
      sys.get_equation_systems().parameters.get<FEProblemBase *>("_fe_problem_base");
  p->computeNearNullSpace(sys, sp);
}

void
compute_postcheck(const NumericVector<Number> & old_soln,
                  NumericVector<Number> & search_direction,
                  NumericVector<Number> & new_soln,
                  bool & changed_search_direction,
                  bool & changed_new_soln,
                  NonlinearImplicitSystem & sys)
{
  FEProblemBase * p =
      sys.get_equation_systems().parameters.get<FEProblemBase *>("_fe_problem_base");
  p->computePostCheck(
      sys, old_soln, search_direction, new_soln, changed_search_direction, changed_new_soln);
}
} // namespace Moose

NonlinearSystem::NonlinearSystem(FEProblemBase & fe_problem, const std::string & name)
  : NonlinearSystemBase(
        fe_problem, fe_problem.es().add_system<NonlinearImplicitSystem>(name), name),
    _nl_implicit_sys(fe_problem.es().get_system<NonlinearImplicitSystem>(name)),
    _nl_residual_functor(_fe_problem),
    _fd_residual_functor(_fe_problem),
    _resid_and_jac_functor(_fe_problem),
    _use_coloring_finite_difference(false)
{
  if (_resid_and_jacobian_together)
    nonlinearSolver()->residual_and_jacobian_object = &_resid_and_jac_functor;
  else
  {
    nonlinearSolver()->residual_object = &_nl_residual_functor;
    nonlinearSolver()->jacobian = Moose::compute_jacobian;
  }
  nonlinearSolver()->bounds = Moose::compute_bounds;
  nonlinearSolver()->nullspace = Moose::compute_nullspace;
  nonlinearSolver()->transpose_nullspace = Moose::compute_transpose_nullspace;
  nonlinearSolver()->nearnullspace = Moose::compute_nearnullspace;

  PetscNonlinearSolver<Real> * petsc_solver =
      static_cast<PetscNonlinearSolver<Real> *>(_nl_implicit_sys.nonlinear_solver.get());
  if (petsc_solver)
  {
    petsc_solver->set_residual_zero_out(false);
    petsc_solver->set_jacobian_zero_out(false);
    petsc_solver->use_default_monitor(false);
  }
}

NonlinearSystem::~NonlinearSystem() {}

void
NonlinearSystem::init()
{
  NonlinearSystemBase::init();

  if (_automatic_scaling && _resid_vs_jac_scaling_param < 1. - TOLERANCE)
    // Add diagonal matrix that will be used for computing scaling factors
    _nl_implicit_sys.add_matrix<DiagonalMatrix>("scaling_matrix");
}

void
NonlinearSystem::solve()
{
  // Only attach the postcheck function to the solver if we actually
  // have dampers or if the FEProblemBase needs to update the solution,
  // which is also done during the linesearch postcheck.  It doesn't
  // hurt to do this multiple times, it is just setting a pointer.
  if (_fe_problem.hasDampers() || _fe_problem.shouldUpdateSolution() ||
      _fe_problem.needsPreviousNewtonIteration())
    _nl_implicit_sys.nonlinear_solver->postcheck = Moose::compute_postcheck;

  if (_fe_problem.solverParams()._type != Moose::ST_LINEAR)
  {
    TIME_SECTION("nlInitialResidual", 3, "Computing Initial Residual");
    // Calculate the initial residual for use in the convergence criterion.
    _computing_initial_residual = true;
    _fe_problem.computeResidualSys(_nl_implicit_sys, *_current_solution, *_nl_implicit_sys.rhs);
    _computing_initial_residual = false;
    _nl_implicit_sys.rhs->close();
    _initial_residual_before_preset_bcs = _nl_implicit_sys.rhs->l2_norm();
    if (_compute_initial_residual_before_preset_bcs)
      _console << "Initial residual before setting preset BCs: "
               << _initial_residual_before_preset_bcs << std::endl;
  }

  // Clear the iteration counters
  _current_l_its.clear();
  _current_nl_its = 0;

  // Initialize the solution vector using a predictor and known values from nodal bcs
  setInitialSolution();

  // Now that the initial solution has ben set, potentially perform a residual/Jacobian evaluation
  // to determine variable scaling factors
  if (_automatic_scaling)
  {
    if (_compute_scaling_once)
    {
      if (!_computed_scaling)
      {
        computeScaling();
        _computed_scaling = true;
      }
    }
    else
      computeScaling();
  }
#ifdef MOOSE_GLOBAL_AD_INDEXING
  // We do not know a priori what variable a global degree of freedom corresponds to, so we need a
  // map from global dof to scaling factor. We just use a ghosted NumericVector for that mapping
  assembleScalingVector();
#endif

  if (_use_finite_differenced_preconditioner)
  {
    _nl_implicit_sys.nonlinear_solver->fd_residual_object = &_fd_residual_functor;
    setupFiniteDifferencedPreconditioner();
  }

  PetscNonlinearSolver<Real> & solver =
      static_cast<PetscNonlinearSolver<Real> &>(*_nl_implicit_sys.nonlinear_solver);
  solver.mffd_residual_object = &_fd_residual_functor;

  solver.set_snesmf_reuse_base(_fe_problem.useSNESMFReuseBase());

  if (_time_integrator)
  {
    _time_integrator->solve();
    _time_integrator->postSolve();
    _n_iters = _time_integrator->getNumNonlinearIterations();
    _n_linear_iters = _time_integrator->getNumLinearIterations();
  }
  else
  {
    system().solve();
    _n_iters = _nl_implicit_sys.n_nonlinear_iterations();
    _n_linear_iters = solver.get_total_linear_iterations();
  }

  // store info about the solve
  _final_residual = _nl_implicit_sys.final_nonlinear_residual();

  if (_use_coloring_finite_difference)
    MatFDColoringDestroy(&_fdcoloring);
}

void
NonlinearSystem::stopSolve()
{
  PetscNonlinearSolver<Real> & solver =
      static_cast<PetscNonlinearSolver<Real> &>(*sys().nonlinear_solver);
  SNESSetFunctionDomainError(solver.snes());

  // Insert a NaN into the residual vector.  As of PETSc-3.6, this
  // should make PETSc return DIVERGED_NANORINF the next time it does
  // a reduction.  We'll write to the first local dof on every
  // processor that has any dofs.
  _nl_implicit_sys.rhs->close();

  if (_nl_implicit_sys.rhs->local_size())
    _nl_implicit_sys.rhs->set(_nl_implicit_sys.rhs->first_local_index(),
                              std::numeric_limits<Real>::quiet_NaN());
  _nl_implicit_sys.rhs->close();

  // Clean up by getting other vectors into a valid state for a
  // (possible) subsequent solve.  There may be more than just
  // these...
  if (_Re_time)
    _Re_time->close();
  _Re_non_time->close();
}

void
NonlinearSystem::setupFiniteDifferencedPreconditioner()
{
  std::shared_ptr<FiniteDifferencePreconditioner> fdp =
      std::dynamic_pointer_cast<FiniteDifferencePreconditioner>(_preconditioner);
  if (!fdp)
    mooseError("Did not setup finite difference preconditioner, and please add a preconditioning "
               "block with type = fdp");

  if (fdp->finiteDifferenceType() == "coloring")
  {
    setupColoringFiniteDifferencedPreconditioner();
    _use_coloring_finite_difference = true;
  }

  else if (fdp->finiteDifferenceType() == "standard")
  {
    setupStandardFiniteDifferencedPreconditioner();
    _use_coloring_finite_difference = false;
  }
  else
    mooseError("Unknown finite difference type");
}

void
NonlinearSystem::setupStandardFiniteDifferencedPreconditioner()
{
  // Make sure that libMesh isn't going to override our preconditioner
  _nl_implicit_sys.nonlinear_solver->jacobian = nullptr;

  PetscNonlinearSolver<Number> * petsc_nonlinear_solver =
      static_cast<PetscNonlinearSolver<Number> *>(_nl_implicit_sys.nonlinear_solver.get());

  PetscMatrix<Number> * petsc_mat =
      static_cast<PetscMatrix<Number> *>(&_nl_implicit_sys.get_system_matrix());

  SNESSetJacobian(petsc_nonlinear_solver->snes(),
                  petsc_mat->mat(),
                  petsc_mat->mat(),
                  SNESComputeJacobianDefault,
                  nullptr);
}

void
NonlinearSystem::setupColoringFiniteDifferencedPreconditioner()
{
  // Make sure that libMesh isn't going to override our preconditioner
  _nl_implicit_sys.nonlinear_solver->jacobian = nullptr;

  PetscNonlinearSolver<Number> & petsc_nonlinear_solver =
      dynamic_cast<PetscNonlinearSolver<Number> &>(*_nl_implicit_sys.nonlinear_solver);

  // Pointer to underlying PetscMatrix type
  PetscMatrix<Number> * petsc_mat =
      dynamic_cast<PetscMatrix<Number> *>(&_nl_implicit_sys.get_system_matrix());

  Moose::compute_jacobian(*_nl_implicit_sys.current_local_solution, *petsc_mat, _nl_implicit_sys);

  if (!petsc_mat)
    mooseError("Could not convert to Petsc matrix.");

  petsc_mat->close();

  PetscErrorCode ierr = 0;
  ISColoring iscoloring;

  // PETSc 3.5.x
  MatColoring matcoloring;
  ierr = MatColoringCreate(petsc_mat->mat(), &matcoloring);
  CHKERRABORT(_communicator.get(), ierr);
  ierr = MatColoringSetType(matcoloring, MATCOLORINGLF);
  CHKERRABORT(_communicator.get(), ierr);
  ierr = MatColoringSetFromOptions(matcoloring);
  CHKERRABORT(_communicator.get(), ierr);
  ierr = MatColoringApply(matcoloring, &iscoloring);
  CHKERRABORT(_communicator.get(), ierr);
  ierr = MatColoringDestroy(&matcoloring);
  CHKERRABORT(_communicator.get(), ierr);

  MatFDColoringCreate(petsc_mat->mat(), iscoloring, &_fdcoloring);
  MatFDColoringSetFromOptions(_fdcoloring);
  // clang-format off
  MatFDColoringSetFunction(_fdcoloring,
                           (PetscErrorCode(*)(void))(void (*)(void)) &
                               libMesh::libmesh_petsc_snes_fd_residual,
                           &petsc_nonlinear_solver);
  // clang-format on
  MatFDColoringSetUp(petsc_mat->mat(), iscoloring, _fdcoloring);
  SNESSetJacobian(petsc_nonlinear_solver.snes(),
                  petsc_mat->mat(),
                  petsc_mat->mat(),
                  SNESComputeJacobianDefaultColor,
                  _fdcoloring);
  // PETSc >=3.3.0
  ISColoringDestroy(&iscoloring);
}

bool
NonlinearSystem::converged()
{
  if (_fe_problem.hasException())
    return false;

  return _nl_implicit_sys.nonlinear_solver->converged;
}

void
NonlinearSystem::attachPreconditioner(Preconditioner<Number> * preconditioner)
{
  nonlinearSolver()->attach_preconditioner(preconditioner);
}

void
NonlinearSystem::computeScalingJacobian()
{
  _fe_problem.computeJacobianSys(_nl_implicit_sys, *_current_solution, *_scaling_matrix);
}

void
NonlinearSystem::computeScalingResidual()
{
  _fe_problem.computeResidualSys(_nl_implicit_sys, *_current_solution, RHS());
}

SNES
NonlinearSystem::getSNES()
{
  PetscNonlinearSolver<Number> * petsc_solver =
      dynamic_cast<PetscNonlinearSolver<Number> *>(nonlinearSolver());

  if (petsc_solver)
    return petsc_solver->snes();
  else
    mooseError("It is not a petsc nonlinear solver");
}
<|endoftext|>


<commit_before>void testBench(const G1& P, const G2& Q)
{
	G1 Pa;
	G2 Qa;
	Fp12 e1, e2;
	pairing(e1, P, Q);
	Fp12::pow(e2, e1, 12345);
	const int C = 500;
	const int C2 = 1000;
	Fp x, y;
	x.setHashOf("abc");
	y.setHashOf("xyz");
	mpz_class z = 3;
	mpz_class a = x.getMpz();
	CYBOZU_BENCH_C("G1::mulCT     ", C, G1::mulCT, Pa, P, a);
//	CYBOZU_BENCH_C("G1::mulCTsmall", C, G1::mulCT, Pa, P, z);
	CYBOZU_BENCH_C("G1::mul       ", C, G1::mul, Pa, Pa, a);
//	CYBOZU_BENCH_C("G1::mulsmall  ", C, G1::mul, Pa, Pa, z);
	CYBOZU_BENCH_C("G1::add       ", C, G1::add, Pa, Pa, P);
	CYBOZU_BENCH_C("G1::dbl       ", C, G1::dbl, Pa, Pa);
	CYBOZU_BENCH_C("G2::mulCT     ", C, G2::mulCT, Qa, Q, a);
//	CYBOZU_BENCH_C("G2::mulCTsmall", C, G2::mulCT, Qa, Q, z);
	CYBOZU_BENCH_C("G2::mul       ", C, G2::mul, Qa, Qa, a);
//	CYBOZU_BENCH_C("G2::mulsmall  ", C, G2::mul, Qa, Qa, z);
	CYBOZU_BENCH_C("G2::add       ", C, G2::add, Qa, Qa, Q);
	CYBOZU_BENCH_C("G2::dbl       ", C, G2::dbl, Qa, Qa);
	CYBOZU_BENCH_C("GT::pow       ", C, GT::pow, e1, e1, a);
//	CYBOZU_BENCH_C("GT::powGLV    ", C, BN::param.glv2.pow, e1, e1, a);
	G1 PP;
	G2 QQ;
	std::string s;
	s = P.getStr();
	CYBOZU_BENCH_C("G1::setStr chk", C, PP.setStr, s);
	verifyOrderG1(false);
	CYBOZU_BENCH_C("G1::setStr    ", C, PP.setStr, s);
	verifyOrderG1(true);
	s = Q.getStr();
	CYBOZU_BENCH_C("G2::setStr chk", C, QQ.setStr, s);
	verifyOrderG2(false);
	CYBOZU_BENCH_C("G2::setStr    ", C, QQ.setStr, s);
	verifyOrderG2(true);
	CYBOZU_BENCH_C("hashAndMapToG1", C, hashAndMapToG1, PP, "abc", 3);
	CYBOZU_BENCH_C("hashAndMapToG2", C, hashAndMapToG2, QQ, "abc", 3);
	CYBOZU_BENCH_C("Fp::add       ", C2, Fp::add, x, x, y);
	CYBOZU_BENCH_C("Fp::mul       ", C2, Fp::mul, x, x, y);
	CYBOZU_BENCH_C("Fp::sqr       ", C2, Fp::sqr, x, x);
	CYBOZU_BENCH_C("Fp::inv       ", C2, Fp::inv, x, x);

	CYBOZU_BENCH_C("GT::add       ", C2, GT::add, e1, e1, e2);
	CYBOZU_BENCH_C("GT::mul       ", C2, GT::mul, e1, e1, e2);
	CYBOZU_BENCH_C("GT::sqr       ", C2, GT::sqr, e1, e1);
	CYBOZU_BENCH_C("GT::inv       ", C2, GT::inv, e1, e1);
	CYBOZU_BENCH_C("pairing       ", C, pairing, e1, P, Q);
	CYBOZU_BENCH_C("millerLoop    ", C, millerLoop, e1, P, Q);
	CYBOZU_BENCH_C("finalExp      ", C, finalExp, e1, e1);
	std::vector<Fp6> Qcoeff;
	precomputeG2(Qcoeff, Q);
	CYBOZU_BENCH_C("precomputedML ", C, precomputedMillerLoop, e2, P, Qcoeff);
}
<commit_msg>add bench of FpDbl<commit_after>void testBench(const G1& P, const G2& Q)
{
	G1 Pa;
	G2 Qa;
	Fp12 e1, e2;
	pairing(e1, P, Q);
	Fp12::pow(e2, e1, 12345);
	const int C = 500;
	const int C2 = 1000;
	const int C3 = 10000;
	Fp x, y;
	x.setHashOf("abc");
	y.setHashOf("xyz");
	mpz_class z = 3;
	mpz_class a = x.getMpz();
	CYBOZU_BENCH_C("G1::mulCT     ", C, G1::mulCT, Pa, P, a);
//	CYBOZU_BENCH_C("G1::mulCTsmall", C, G1::mulCT, Pa, P, z);
	CYBOZU_BENCH_C("G1::mul       ", C, G1::mul, Pa, Pa, a);
//	CYBOZU_BENCH_C("G1::mulsmall  ", C, G1::mul, Pa, Pa, z);
	CYBOZU_BENCH_C("G1::add       ", C, G1::add, Pa, Pa, P);
	CYBOZU_BENCH_C("G1::dbl       ", C, G1::dbl, Pa, Pa);
	CYBOZU_BENCH_C("G2::mulCT     ", C, G2::mulCT, Qa, Q, a);
//	CYBOZU_BENCH_C("G2::mulCTsmall", C, G2::mulCT, Qa, Q, z);
	CYBOZU_BENCH_C("G2::mul       ", C, G2::mul, Qa, Qa, a);
//	CYBOZU_BENCH_C("G2::mulsmall  ", C, G2::mul, Qa, Qa, z);
	CYBOZU_BENCH_C("G2::add       ", C, G2::add, Qa, Qa, Q);
	CYBOZU_BENCH_C("G2::dbl       ", C, G2::dbl, Qa, Qa);
	CYBOZU_BENCH_C("GT::pow       ", C, GT::pow, e1, e1, a);
//	CYBOZU_BENCH_C("GT::powGLV    ", C, BN::param.glv2.pow, e1, e1, a);
	G1 PP;
	G2 QQ;
	std::string s;
	s = P.getStr();
	CYBOZU_BENCH_C("G1::setStr chk", C, PP.setStr, s);
	verifyOrderG1(false);
	CYBOZU_BENCH_C("G1::setStr    ", C, PP.setStr, s);
	verifyOrderG1(true);
	s = Q.getStr();
	CYBOZU_BENCH_C("G2::setStr chk", C, QQ.setStr, s);
	verifyOrderG2(false);
	CYBOZU_BENCH_C("G2::setStr    ", C, QQ.setStr, s);
	verifyOrderG2(true);
	CYBOZU_BENCH_C("hashAndMapToG1", C, hashAndMapToG1, PP, "abc", 3);
	CYBOZU_BENCH_C("hashAndMapToG2", C, hashAndMapToG2, QQ, "abc", 3);
	CYBOZU_BENCH_C("Fp::add       ", C3, Fp::add, x, x, y);
	CYBOZU_BENCH_C("Fp::mul       ", C3, Fp::mul, x, x, y);
	CYBOZU_BENCH_C("Fp::sqr       ", C3, Fp::sqr, x, x);
	CYBOZU_BENCH_C("Fp::inv       ", C3, Fp::inv, x, x);
	Fp2 xx, yy;
	xx.a = x;
	xx.b = 3;
	yy.a = y;
	yy.b = -5;
	CYBOZU_BENCH_C("Fp2::add      ", C3, Fp2::add, xx, xx, yy);
	CYBOZU_BENCH_C("Fp2::mul      ", C3, Fp2::mul, xx, xx, yy);
	CYBOZU_BENCH_C("Fp2::sqr      ", C3, Fp2::sqr, xx, xx);
	CYBOZU_BENCH_C("Fp2::inv      ", C3, Fp2::inv, xx, xx);
	FpDbl d0, d1;
	x = 9;
	y = 3;
	CYBOZU_BENCH_C("FpDbl::mulPre ", C3, FpDbl::mulPre, d0, x, y);
	CYBOZU_BENCH_C("FpDbl::sqrPre ", C3, FpDbl::sqrPre, d1, x);
	CYBOZU_BENCH_C("FpDbl::add    ", C3, FpDbl::add, d1, d1, d0);
	CYBOZU_BENCH_C("FpDbl::sub    ", C3, FpDbl::sub, d1, d1, d0);
	CYBOZU_BENCH_C("FpDbl::addPre ", C3, FpDbl::addPre, d1, d1, d0);
	CYBOZU_BENCH_C("FpDbl::subPre ", C3, FpDbl::subPre, d1, d1, d0);
	CYBOZU_BENCH_C("FpDbl::mod    ", C3, FpDbl::mod, x, d0);

	CYBOZU_BENCH_C("GT::add       ", C2, GT::add, e1, e1, e2);
	CYBOZU_BENCH_C("GT::mul       ", C2, GT::mul, e1, e1, e2);
	CYBOZU_BENCH_C("GT::sqr       ", C2, GT::sqr, e1, e1);
	CYBOZU_BENCH_C("GT::inv       ", C2, GT::inv, e1, e1);
	CYBOZU_BENCH_C("pairing       ", C, pairing, e1, P, Q);
	CYBOZU_BENCH_C("millerLoop    ", C, millerLoop, e1, P, Q);
	CYBOZU_BENCH_C("finalExp      ", C, finalExp, e1, e1);
	std::vector<Fp6> Qcoeff;
	precomputeG2(Qcoeff, Q);
	CYBOZU_BENCH_C("precomputedML ", C, precomputedMillerLoop, e2, P, Qcoeff);
}
<|endoftext|>


<commit_before>#include <mcl/lagrange.hpp>

void benchAddDblG1()
{
	puts("benchAddDblG1");
	const int C = 100000;
	G1 P1, P2, P3;
	hashAndMapToG1(P1, "a");
	hashAndMapToG1(P2, "b");
	P1 += P2;
	P2 += P1;
	printf("z.isOne()=%d %d\n", P1.z.isOne(), P2.z.isOne());
	CYBOZU_BENCH_C("G1::add(1)", C, G1::add, P3, P1, P2);
	P1.normalize();
	printf("z.isOne()=%d %d\n", P1.z.isOne(), P2.z.isOne());
	CYBOZU_BENCH_C("G1::add(2)", C, G1::add, P3, P1, P2);
	CYBOZU_BENCH_C("G1::add(3)", C, G1::add, P3, P2, P1);
	P2.normalize();
	printf("z.isOne()=%d %d\n", P1.z.isOne(), P2.z.isOne());
	CYBOZU_BENCH_C("G1::add(4)", C, G1::add, P3, P1, P2);
	P1 = P3;
	printf("z.isOne()=%d\n", P1.z.isOne());
	CYBOZU_BENCH_C("G1::dbl(1)", C, G1::dbl, P3, P1);
	P1.normalize();
	printf("z.isOne()=%d\n", P1.z.isOne());
	CYBOZU_BENCH_C("G1::dbl(2)", C, G1::dbl, P3, P1);
}

void benchAddDblG2()
{
	puts("benchAddDblG2");
	const int C = 100000;
	G2 P1, P2, P3;
	hashAndMapToG2(P1, "a");
	hashAndMapToG2(P2, "b");
	P1 += P2;
	P2 += P1;
	printf("z.isOne()=%d %d\n", P1.z.isOne(), P2.z.isOne());
	CYBOZU_BENCH_C("G2::add(1)", C, G2::add, P3, P1, P2);
	P1.normalize();
	printf("z.isOne()=%d %d\n", P1.z.isOne(), P2.z.isOne());
	CYBOZU_BENCH_C("G2::add(2)", C, G2::add, P3, P1, P2);
	CYBOZU_BENCH_C("G2::add(3)", C, G2::add, P3, P2, P1);
	P2.normalize();
	printf("z.isOne()=%d %d\n", P1.z.isOne(), P2.z.isOne());
	CYBOZU_BENCH_C("G2::add(4)", C, G2::add, P3, P1, P2);
	P1 = P3;
	printf("z.isOne()=%d\n", P1.z.isOne());
	CYBOZU_BENCH_C("G2::dbl(1)", C, G2::dbl, P3, P1);
	P1.normalize();
	printf("z.isOne()=%d\n", P1.z.isOne());
	CYBOZU_BENCH_C("G2::dbl(2)", C, G2::dbl, P3, P1);
}

void testBench(const G1& P, const G2& Q)
{
	G1 Pa;
	G2 Qa;
	Fp12 e1, e2;
	pairing(e1, P, Q);
	Fp12::pow(e2, e1, 12345);
	Fp x, y;
	x.setHashOf("abc");
	y.setHashOf("xyz");
	const int C = 1000;
	const int C3 = 100000;
#if 1
	const int C2 = 3000;
	mpz_class a = x.getMpz();
	CYBOZU_BENCH_C("G1::mulCT     ", C, G1::mulCT, Pa, P, a);
	CYBOZU_BENCH_C("G1::mul       ", C, G1::mul, Pa, Pa, a);
	CYBOZU_BENCH_C("G1::add       ", C, G1::add, Pa, Pa, P);
	CYBOZU_BENCH_C("G1::dbl       ", C, G1::dbl, Pa, Pa);
	CYBOZU_BENCH_C("G2::mulCT     ", C, G2::mulCT, Qa, Q, a);
	CYBOZU_BENCH_C("G2::mul       ", C, G2::mul, Qa, Qa, a);
	CYBOZU_BENCH_C("G2::add       ", C, G2::add, Qa, Qa, Q);
	CYBOZU_BENCH_C("G2::dbl       ", C, G2::dbl, Qa, Qa);
	CYBOZU_BENCH_C("GT::pow       ", C, GT::pow, e1, e1, a);
//	CYBOZU_BENCH_C("GT::powGLV    ", C, BN::param.glv2.pow, e1, e1, a);
	G1 PP;
	G2 QQ;
	std::string s;
	s = P.getStr();
	verifyOrderG1(true);
	CYBOZU_BENCH_C("G1::setStr chk", C, PP.setStr, s);
	verifyOrderG1(false);
	CYBOZU_BENCH_C("G1::setStr    ", C, PP.setStr, s);
	s = Q.getStr();
	verifyOrderG2(true);
	CYBOZU_BENCH_C("G2::setStr chk", C, QQ.setStr, s);
	verifyOrderG2(false);
	CYBOZU_BENCH_C("G2::setStr    ", C, QQ.setStr, s);
	CYBOZU_BENCH_C("hashAndMapToG1", C, hashAndMapToG1, PP, "abc", 3);
	CYBOZU_BENCH_C("hashAndMapToG2", C, hashAndMapToG2, QQ, "abc", 3);
#endif
	CYBOZU_BENCH_C("Fp::add       ", C3, Fp::add, x, x, y);
	CYBOZU_BENCH_C("Fp::sub       ", C3, Fp::sub, x, x, y);
	CYBOZU_BENCH_C("Fp::neg       ", C3, Fp::neg, x, x);
	CYBOZU_BENCH_C("Fp::mul       ", C3, Fp::mul, x, x, y);
	CYBOZU_BENCH_C("Fp::sqr       ", C3, Fp::sqr, x, x);
	CYBOZU_BENCH_C("Fp::inv       ", C3, Fp::inv, x, x);
	CYBOZU_BENCH_C("Fp::pow       ", C3, Fp::pow, x, x, y);
	{
		Fr a, b, c;
		a.setHashOf("abc", 3);
		b.setHashOf("123", 3);
		CYBOZU_BENCH_C("Fr::add       ", C3, Fr::add, a, a, b);
		CYBOZU_BENCH_C("Fr::sub       ", C3, Fr::sub, a, a, b);
		CYBOZU_BENCH_C("Fr::neg       ", C3, Fr::neg, a, a);
		CYBOZU_BENCH_C("Fr::mul       ", C3, Fr::mul, a, a, b);
		CYBOZU_BENCH_C("Fr::sqr       ", C3, Fr::sqr, a, a);
		CYBOZU_BENCH_C("Fr::inv       ", C3, Fr::inv, a, a);
		CYBOZU_BENCH_C("Fr::pow       ", C3, Fr::pow, a, a, b);
	}
	Fp2 xx, yy;
	xx.a = x;
	xx.b = 3;
	yy.a = y;
	yy.b = -5;
	FpDbl d0, d1;
	x = 9;
	y = 3;
#if 1
	CYBOZU_BENCH_C("Fp2::add      ", C3, Fp2::add, xx, xx, yy);
	CYBOZU_BENCH_C("Fp2::sub      ", C3, Fp2::sub, xx, xx, yy);
	CYBOZU_BENCH_C("Fp2::neg      ", C3, Fp2::neg, xx, xx);
	CYBOZU_BENCH_C("Fp2::mul      ", C3, Fp2::mul, xx, xx, yy);
	CYBOZU_BENCH_C("Fp2::mul_xi   ", C3, Fp2::mul_xi, xx, xx);
	CYBOZU_BENCH_C("Fp2::sqr      ", C3, Fp2::sqr, xx, xx);
	CYBOZU_BENCH_C("Fp2::inv      ", C3, Fp2::inv, xx, xx);
	CYBOZU_BENCH_C("FpDbl::addPre ", C3, FpDbl::addPre, d1, d1, d0);
	CYBOZU_BENCH_C("FpDbl::subPre ", C3, FpDbl::subPre, d1, d1, d0);
	CYBOZU_BENCH_C("FpDbl::add    ", C3, FpDbl::add, d1, d1, d0);
	CYBOZU_BENCH_C("FpDbl::sub    ", C3, FpDbl::sub, d1, d1, d0);
	CYBOZU_BENCH_C("FpDbl::mulPre ", C3, FpDbl::mulPre, d0, x, y);
	CYBOZU_BENCH_C("FpDbl::sqrPre ", C3, FpDbl::sqrPre, d1, x);
	CYBOZU_BENCH_C("FpDbl::mod    ", C3, FpDbl::mod, x, d0);
	Fp2Dbl D;
	CYBOZU_BENCH_C("Fp2Dbl::mulPre ", C3, Fp2Dbl::mulPre, D, xx, yy);
	CYBOZU_BENCH_C("Fp2Dbl::sqrPre ", C3, Fp2Dbl::sqrPre, D, xx);

	CYBOZU_BENCH_C("GT::add       ", C2, GT::add, e1, e1, e2);
	CYBOZU_BENCH_C("GT::mul       ", C2, GT::mul, e1, e1, e2);
	CYBOZU_BENCH_C("GT::sqr       ", C2, GT::sqr, e1, e1);
	CYBOZU_BENCH_C("GT::inv       ", C2, GT::inv, e1, e1);
#endif
	CYBOZU_BENCH_C("FpDbl::mulPre ", C3, FpDbl::mulPre, d0, x, y);
	CYBOZU_BENCH_C("pairing       ", 3000, pairing, e1, P, Q);
	CYBOZU_BENCH_C("millerLoop    ", 3000, millerLoop, e1, P, Q);
	CYBOZU_BENCH_C("finalExp      ", 3000, finalExp, e1, e1);
//exit(1);
	std::vector<Fp6> Qcoeff;
	CYBOZU_BENCH_C("precomputeG2  ", C, precomputeG2, Qcoeff, Q);
	precomputeG2(Qcoeff, Q);
	CYBOZU_BENCH_C("precomputedML ", C, precomputedMillerLoop, e2, P, Qcoeff);
	const size_t n = 7;
	G1 Pvec[n];
	G2 Qvec[n];
	for (size_t i = 0; i < n; i++) {
		char d = (char)(i + 1);
		hashAndMapToG1(Pvec[i], &d, 1);
		hashAndMapToG2(Qvec[i], &d, 1);
	}
	e2 = 1;
	for (size_t i = 0; i < n; i++) {
		millerLoop(e1, Pvec[i], Qvec[i]);
		e2 *= e1;
	}
	CYBOZU_BENCH_C("millerLoopVec ", 3000, millerLoopVec, e1, Pvec, Qvec, n);
	CYBOZU_TEST_EQUAL(e1, e2);
}

inline void SquareRootPrecomputeTest(const mpz_class& p)
{
	mcl::SquareRoot sq1, sq2;
	bool b;
	sq1.set(&b, p, true);
	CYBOZU_TEST_ASSERT(b);
	CYBOZU_TEST_ASSERT(sq1.isPrecomputed());
	sq2.set(&b, p, false);
	CYBOZU_TEST_ASSERT(sq1 == sq2);
	if (sq1 != sq2) {
		puts("dump");
		puts("sq1");
		sq1.dump();
		puts("sq2");
		sq2.dump();
		puts("---");
	}
}

void testSquareRoot()
{
	if (BN::param.cp == mcl::BN254 || BN::param.cp == mcl::BLS12_381) {
		SquareRootPrecomputeTest(BN::param.p);
		SquareRootPrecomputeTest(BN::param.r);
	}
}

void testLagrange()
{
	puts("testLagrange");
	const int k = 7;
	Fr c[k], x[k], y[k];
	for (size_t i = 0; i < k; i++) {
		c[i].setByCSPRNG();
		x[i].setByCSPRNG();
	}
	for (size_t i = 0; i < k; i++) {
		mcl::evaluatePolynomial(y[i], c, k, x[i]);
	}
	Fr s;
	mcl::LagrangeInterpolation(s, x, y, k);
	CYBOZU_TEST_EQUAL(s, c[0]);
	mcl::LagrangeInterpolation(s, x, y, 1);
	CYBOZU_TEST_EQUAL(s, y[0]);
	mcl::evaluatePolynomial(y[0], c, 1, x[0]);
	CYBOZU_TEST_EQUAL(y[0], c[0]);
}
<commit_msg>bench of inv<commit_after>#include <mcl/lagrange.hpp>

void benchAddDblG1()
{
	puts("benchAddDblG1");
	const int C = 100000;
	G1 P1, P2, P3;
	hashAndMapToG1(P1, "a");
	hashAndMapToG1(P2, "b");
	P1 += P2;
	P2 += P1;
	printf("z.isOne()=%d %d\n", P1.z.isOne(), P2.z.isOne());
	CYBOZU_BENCH_C("G1::add(1)", C, G1::add, P3, P1, P2);
	P1.normalize();
	printf("z.isOne()=%d %d\n", P1.z.isOne(), P2.z.isOne());
	CYBOZU_BENCH_C("G1::add(2)", C, G1::add, P3, P1, P2);
	CYBOZU_BENCH_C("G1::add(3)", C, G1::add, P3, P2, P1);
	P2.normalize();
	printf("z.isOne()=%d %d\n", P1.z.isOne(), P2.z.isOne());
	CYBOZU_BENCH_C("G1::add(4)", C, G1::add, P3, P1, P2);
	P1 = P3;
	printf("z.isOne()=%d\n", P1.z.isOne());
	CYBOZU_BENCH_C("G1::dbl(1)", C, G1::dbl, P3, P1);
	P1.normalize();
	printf("z.isOne()=%d\n", P1.z.isOne());
	CYBOZU_BENCH_C("G1::dbl(2)", C, G1::dbl, P3, P1);
}

void benchAddDblG2()
{
	puts("benchAddDblG2");
	const int C = 100000;
	G2 P1, P2, P3;
	hashAndMapToG2(P1, "a");
	hashAndMapToG2(P2, "b");
	P1 += P2;
	P2 += P1;
	printf("z.isOne()=%d %d\n", P1.z.isOne(), P2.z.isOne());
	CYBOZU_BENCH_C("G2::add(1)", C, G2::add, P3, P1, P2);
	P1.normalize();
	printf("z.isOne()=%d %d\n", P1.z.isOne(), P2.z.isOne());
	CYBOZU_BENCH_C("G2::add(2)", C, G2::add, P3, P1, P2);
	CYBOZU_BENCH_C("G2::add(3)", C, G2::add, P3, P2, P1);
	P2.normalize();
	printf("z.isOne()=%d %d\n", P1.z.isOne(), P2.z.isOne());
	CYBOZU_BENCH_C("G2::add(4)", C, G2::add, P3, P1, P2);
	P1 = P3;
	printf("z.isOne()=%d\n", P1.z.isOne());
	CYBOZU_BENCH_C("G2::dbl(1)", C, G2::dbl, P3, P1);
	P1.normalize();
	printf("z.isOne()=%d\n", P1.z.isOne());
	CYBOZU_BENCH_C("G2::dbl(2)", C, G2::dbl, P3, P1);
}

template<class T>
void invAdd(T& out, const T& x, const T& y)
{
	T::inv(out, x);
	out += y;
}

void testBench(const G1& P, const G2& Q)
{
	G1 Pa;
	G2 Qa;
	Fp12 e1, e2;
	pairing(e1, P, Q);
	Fp12::pow(e2, e1, 12345);
	Fp x, y;
	x.setHashOf("abc");
	y.setHashOf("xyz");
	const int C = 1000;
	const int C3 = 100000;
#if 1
	const int C2 = 3000;
	mpz_class a = x.getMpz();
	CYBOZU_BENCH_C("G1::mulCT     ", C, G1::mulCT, Pa, P, a);
	CYBOZU_BENCH_C("G1::mul       ", C, G1::mul, Pa, Pa, a);
	CYBOZU_BENCH_C("G1::add       ", C, G1::add, Pa, Pa, P);
	CYBOZU_BENCH_C("G1::dbl       ", C, G1::dbl, Pa, Pa);
	CYBOZU_BENCH_C("G2::mulCT     ", C, G2::mulCT, Qa, Q, a);
	CYBOZU_BENCH_C("G2::mul       ", C, G2::mul, Qa, Qa, a);
	CYBOZU_BENCH_C("G2::add       ", C, G2::add, Qa, Qa, Q);
	CYBOZU_BENCH_C("G2::dbl       ", C, G2::dbl, Qa, Qa);
	CYBOZU_BENCH_C("GT::pow       ", C, GT::pow, e1, e1, a);
//	CYBOZU_BENCH_C("GT::powGLV    ", C, BN::param.glv2.pow, e1, e1, a);
	G1 PP;
	G2 QQ;
	std::string s;
	s = P.getStr();
	verifyOrderG1(true);
	CYBOZU_BENCH_C("G1::setStr chk", C, PP.setStr, s);
	verifyOrderG1(false);
	CYBOZU_BENCH_C("G1::setStr    ", C, PP.setStr, s);
	s = Q.getStr();
	verifyOrderG2(true);
	CYBOZU_BENCH_C("G2::setStr chk", C, QQ.setStr, s);
	verifyOrderG2(false);
	CYBOZU_BENCH_C("G2::setStr    ", C, QQ.setStr, s);
	CYBOZU_BENCH_C("hashAndMapToG1", C, hashAndMapToG1, PP, "abc", 3);
	CYBOZU_BENCH_C("hashAndMapToG2", C, hashAndMapToG2, QQ, "abc", 3);
#endif
	CYBOZU_BENCH_C("Fp::add       ", C3, Fp::add, x, x, y);
	CYBOZU_BENCH_C("Fp::sub       ", C3, Fp::sub, x, x, y);
	CYBOZU_BENCH_C("Fp::neg       ", C3, Fp::neg, x, x);
	CYBOZU_BENCH_C("Fp::mul       ", C3, Fp::mul, x, x, y);
	CYBOZU_BENCH_C("Fp::sqr       ", C3, Fp::sqr, x, x);
	CYBOZU_BENCH_C("Fp::inv       ", C3, invAdd, x, x, y);
	CYBOZU_BENCH_C("Fp::pow       ", C3, Fp::pow, x, x, y);
	{
		Fr a, b, c;
		a.setHashOf("abc", 3);
		b.setHashOf("123", 3);
		CYBOZU_BENCH_C("Fr::add       ", C3, Fr::add, a, a, b);
		CYBOZU_BENCH_C("Fr::sub       ", C3, Fr::sub, a, a, b);
		CYBOZU_BENCH_C("Fr::neg       ", C3, Fr::neg, a, a);
		CYBOZU_BENCH_C("Fr::mul       ", C3, Fr::mul, a, a, b);
		CYBOZU_BENCH_C("Fr::sqr       ", C3, Fr::sqr, a, a);
		CYBOZU_BENCH_C("Fr::inv       ", C3, invAdd, a, a, b);
		CYBOZU_BENCH_C("Fr::pow       ", C3, Fr::pow, a, a, b);
	}
	Fp2 xx, yy;
	xx.a = x;
	xx.b = 3;
	yy.a = y;
	yy.b = -5;
	FpDbl d0, d1;
	x = 9;
	y = 3;
#if 1
	CYBOZU_BENCH_C("Fp2::add      ", C3, Fp2::add, xx, xx, yy);
	CYBOZU_BENCH_C("Fp2::sub      ", C3, Fp2::sub, xx, xx, yy);
	CYBOZU_BENCH_C("Fp2::neg      ", C3, Fp2::neg, xx, xx);
	CYBOZU_BENCH_C("Fp2::mul      ", C3, Fp2::mul, xx, xx, yy);
	CYBOZU_BENCH_C("Fp2::mul_xi   ", C3, Fp2::mul_xi, xx, xx);
	CYBOZU_BENCH_C("Fp2::sqr      ", C3, Fp2::sqr, xx, xx);
	CYBOZU_BENCH_C("Fp2::inv      ", C3, invAdd, xx, xx, yy);
	CYBOZU_BENCH_C("FpDbl::addPre ", C3, FpDbl::addPre, d1, d1, d0);
	CYBOZU_BENCH_C("FpDbl::subPre ", C3, FpDbl::subPre, d1, d1, d0);
	CYBOZU_BENCH_C("FpDbl::add    ", C3, FpDbl::add, d1, d1, d0);
	CYBOZU_BENCH_C("FpDbl::sub    ", C3, FpDbl::sub, d1, d1, d0);
	CYBOZU_BENCH_C("FpDbl::mulPre ", C3, FpDbl::mulPre, d0, x, y);
	CYBOZU_BENCH_C("FpDbl::sqrPre ", C3, FpDbl::sqrPre, d1, x);
	CYBOZU_BENCH_C("FpDbl::mod    ", C3, FpDbl::mod, x, d0);
	Fp2Dbl D;
	CYBOZU_BENCH_C("Fp2Dbl::mulPre ", C3, Fp2Dbl::mulPre, D, xx, yy);
	CYBOZU_BENCH_C("Fp2Dbl::sqrPre ", C3, Fp2Dbl::sqrPre, D, xx);

	CYBOZU_BENCH_C("GT::add       ", C2, GT::add, e1, e1, e2);
	CYBOZU_BENCH_C("GT::mul       ", C2, GT::mul, e1, e1, e2);
	CYBOZU_BENCH_C("GT::sqr       ", C2, GT::sqr, e1, e1);
	CYBOZU_BENCH_C("GT::inv       ", C2, GT::inv, e1, e1);
#endif
	CYBOZU_BENCH_C("FpDbl::mulPre ", C3, FpDbl::mulPre, d0, x, y);
	CYBOZU_BENCH_C("pairing       ", 3000, pairing, e1, P, Q);
	CYBOZU_BENCH_C("millerLoop    ", 3000, millerLoop, e1, P, Q);
	CYBOZU_BENCH_C("finalExp      ", 3000, finalExp, e1, e1);
//exit(1);
	std::vector<Fp6> Qcoeff;
	CYBOZU_BENCH_C("precomputeG2  ", C, precomputeG2, Qcoeff, Q);
	precomputeG2(Qcoeff, Q);
	CYBOZU_BENCH_C("precomputedML ", C, precomputedMillerLoop, e2, P, Qcoeff);
	const size_t n = 7;
	G1 Pvec[n];
	G2 Qvec[n];
	for (size_t i = 0; i < n; i++) {
		char d = (char)(i + 1);
		hashAndMapToG1(Pvec[i], &d, 1);
		hashAndMapToG2(Qvec[i], &d, 1);
	}
	e2 = 1;
	for (size_t i = 0; i < n; i++) {
		millerLoop(e1, Pvec[i], Qvec[i]);
		e2 *= e1;
	}
	CYBOZU_BENCH_C("millerLoopVec ", 3000, millerLoopVec, e1, Pvec, Qvec, n);
	CYBOZU_TEST_EQUAL(e1, e2);
}

inline void SquareRootPrecomputeTest(const mpz_class& p)
{
	mcl::SquareRoot sq1, sq2;
	bool b;
	sq1.set(&b, p, true);
	CYBOZU_TEST_ASSERT(b);
	CYBOZU_TEST_ASSERT(sq1.isPrecomputed());
	sq2.set(&b, p, false);
	CYBOZU_TEST_ASSERT(sq1 == sq2);
	if (sq1 != sq2) {
		puts("dump");
		puts("sq1");
		sq1.dump();
		puts("sq2");
		sq2.dump();
		puts("---");
	}
}

void testSquareRoot()
{
	if (BN::param.cp == mcl::BN254 || BN::param.cp == mcl::BLS12_381) {
		SquareRootPrecomputeTest(BN::param.p);
		SquareRootPrecomputeTest(BN::param.r);
	}
}

void testLagrange()
{
	puts("testLagrange");
	const int k = 7;
	Fr c[k], x[k], y[k];
	for (size_t i = 0; i < k; i++) {
		c[i].setByCSPRNG();
		x[i].setByCSPRNG();
	}
	for (size_t i = 0; i < k; i++) {
		mcl::evaluatePolynomial(y[i], c, k, x[i]);
	}
	Fr s;
	mcl::LagrangeInterpolation(s, x, y, k);
	CYBOZU_TEST_EQUAL(s, c[0]);
	mcl::LagrangeInterpolation(s, x, y, 1);
	CYBOZU_TEST_EQUAL(s, y[0]);
	mcl::evaluatePolynomial(y[0], c, 1, x[0]);
	CYBOZU_TEST_EQUAL(y[0], c[0]);
}
<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// This is the source code of the clang-check tool, taken directly from the
// Clang repository (tools/clang-check/ClangCheck.cpp) to serve as a canary for
// linking with Clang libraries properly.
//
// See below for the (LLVM) license of this file.
// Eli Bendersky (eliben@gmail.com)
//------------------------------------------------------------------------------

//===--- tools/clang-check/ClangCheck.cpp - Clang check tool --------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file implements a clang-check tool that runs clang based on the info
//  stored in a compilation database.
//
//  This tool uses the Clang Tooling infrastructure, see
//    http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
//  for details on setting it up with LLVM source tree.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/ASTConsumer.h"
#include "clang/Driver/Options.h"
#include "clang/Frontend/ASTConsumers.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Rewrite/Frontend/FixItRewriter.h"
#include "clang/Rewrite/Frontend/FrontendActions.h"
#include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/Option/OptTable.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Signals.h"
#include "llvm/ADT/STLExtras.h"

using namespace clang::driver;
using namespace clang::tooling;
using namespace llvm;

static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
static cl::extrahelp MoreHelp(
    "\tFor example, to run clang-check on all files in a subtree of the\n"
    "\tsource tree, use:\n"
    "\n"
    "\t  find path/in/subtree -name '*.cpp'|xargs clang-check\n"
    "\n"
    "\tor using a specific build path:\n"
    "\n"
    "\t  find path/in/subtree -name '*.cpp'|xargs clang-check -p build/path\n"
    "\n"
    "\tNote, that path/in/subtree and current directory should follow the\n"
    "\trules described above.\n"
    "\n"
);

static cl::OptionCategory ClangCheckCategory("clang-check options");
static std::unique_ptr<opt::OptTable> Options(createDriverOptTable());
static cl::opt<bool>
ASTDump("ast-dump", cl::desc(Options->getOptionHelpText(options::OPT_ast_dump)),
        cl::cat(ClangCheckCategory));
static cl::opt<bool>
ASTList("ast-list", cl::desc(Options->getOptionHelpText(options::OPT_ast_list)),
        cl::cat(ClangCheckCategory));
static cl::opt<bool>
ASTPrint("ast-print",
         cl::desc(Options->getOptionHelpText(options::OPT_ast_print)),
         cl::cat(ClangCheckCategory));
static cl::opt<std::string> ASTDumpFilter(
    "ast-dump-filter",
    cl::desc(Options->getOptionHelpText(options::OPT_ast_dump_filter)),
    cl::cat(ClangCheckCategory));
static cl::opt<bool>
Analyze("analyze", cl::desc(Options->getOptionHelpText(options::OPT_analyze)),
        cl::cat(ClangCheckCategory));

static cl::opt<bool>
Fixit("fixit", cl::desc(Options->getOptionHelpText(options::OPT_fixit)),
      cl::cat(ClangCheckCategory));
static cl::opt<bool> FixWhatYouCan(
    "fix-what-you-can",
    cl::desc(Options->getOptionHelpText(options::OPT_fix_what_you_can)),
    cl::cat(ClangCheckCategory));

namespace {

// FIXME: Move FixItRewriteInPlace from lib/Rewrite/Frontend/FrontendActions.cpp
// into a header file and reuse that.
class FixItOptions : public clang::FixItOptions {
public:
  FixItOptions() {
    FixWhatYouCan = ::FixWhatYouCan;
  }

  std::string RewriteFilename(const std::string& filename, int &fd) override {
    assert(llvm::sys::path::is_absolute(filename) &&
           "clang-fixit expects absolute paths only.");

    // We don't need to do permission checking here since clang will diagnose
    // any I/O errors itself.

    fd = -1;  // No file descriptor for file.

    return filename;
  }
};

/// \brief Subclasses \c clang::FixItRewriter to not count fixed errors/warnings
/// in the final error counts.
///
/// This has the side-effect that clang-check -fixit exits with code 0 on
/// successfully fixing all errors.
class FixItRewriter : public clang::FixItRewriter {
public:
  FixItRewriter(clang::DiagnosticsEngine& Diags,
                clang::SourceManager& SourceMgr,
                const clang::LangOptions& LangOpts,
                clang::FixItOptions* FixItOpts)
      : clang::FixItRewriter(Diags, SourceMgr, LangOpts, FixItOpts) {
  }

  bool IncludeInDiagnosticCounts() const override { return false; }
};

/// \brief Subclasses \c clang::FixItAction so that we can install the custom
/// \c FixItRewriter.
class FixItAction : public clang::FixItAction {
public:
  bool BeginSourceFileAction(clang::CompilerInstance& CI,
                             StringRef Filename) override {
    FixItOpts.reset(new FixItOptions);
    Rewriter.reset(new FixItRewriter(CI.getDiagnostics(), CI.getSourceManager(),
                                     CI.getLangOpts(), FixItOpts.get()));
    return true;
  }
};

class ClangCheckActionFactory {
public:
  std::unique_ptr<clang::ASTConsumer> newASTConsumer() {
    if (ASTList)
      return clang::CreateASTDeclNodeLister();
    if (ASTDump)
      return clang::CreateASTDumper(ASTDumpFilter, /*DumpDecls=*/true,
                                    /*DumpLookups=*/false);
    if (ASTPrint)
      return clang::CreateASTPrinter(&llvm::outs(), ASTDumpFilter);
    return llvm::make_unique<clang::ASTConsumer>();
  }
};

} // namespace

int main(int argc, const char **argv) {
  llvm::sys::PrintStackTraceOnErrorSignal();
  CommonOptionsParser OptionsParser(argc, argv, ClangCheckCategory);
  ClangTool Tool(OptionsParser.getCompilations(),
                 OptionsParser.getSourcePathList());

  // Clear adjusters because -fsyntax-only is inserted by the default chain.
  Tool.clearArgumentsAdjusters();
  Tool.appendArgumentsAdjuster(new ClangStripOutputAdjuster());

  // Running the analyzer requires --analyze. Other modes can work with the
  // -fsyntax-only option.
  Tool.appendArgumentsAdjuster(new InsertArgumentAdjuster(
      Analyze ? "--analyze" : "-fsyntax-only", InsertArgumentAdjuster::BEGIN));

  ClangCheckActionFactory CheckFactory;
  std::unique_ptr<FrontendActionFactory> FrontendFactory;

  // Choose the correct factory based on the selected mode.
  if (Analyze)
    FrontendFactory = newFrontendActionFactory<clang::ento::AnalysisAction>();
  else if (Fixit)
    FrontendFactory = newFrontendActionFactory<FixItAction>();
  else
    FrontendFactory = newFrontendActionFactory(&CheckFactory);

  return Tool.run(FrontendFactory.get());
}
<commit_msg>Refresh the ClangCheck file from clang/tools<commit_after>//------------------------------------------------------------------------------
// This is the source code of the clang-check tool, taken directly from the
// Clang repository (tools/clang-check/ClangCheck.cpp) to serve as a canary for
// linking with Clang libraries properly.
//
// See below for the (LLVM) license of this file.
// Eli Bendersky (eliben@gmail.com)
//------------------------------------------------------------------------------

//===--- tools/clang-check/ClangCheck.cpp - Clang check tool --------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file implements a clang-check tool that runs clang based on the info
//  stored in a compilation database.
//
//  This tool uses the Clang Tooling infrastructure, see
//    http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
//  for details on setting it up with LLVM source tree.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/ASTConsumer.h"
#include "clang/Driver/Options.h"
#include "clang/Frontend/ASTConsumers.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Rewrite/Frontend/FixItRewriter.h"
#include "clang/Rewrite/Frontend/FrontendActions.h"
#include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/Option/OptTable.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Signals.h"
#include "llvm/ADT/STLExtras.h"

using namespace clang::driver;
using namespace clang::tooling;
using namespace llvm;

static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
static cl::extrahelp MoreHelp(
    "\tFor example, to run clang-check on all files in a subtree of the\n"
    "\tsource tree, use:\n"
    "\n"
    "\t  find path/in/subtree -name '*.cpp'|xargs clang-check\n"
    "\n"
    "\tor using a specific build path:\n"
    "\n"
    "\t  find path/in/subtree -name '*.cpp'|xargs clang-check -p build/path\n"
    "\n"
    "\tNote, that path/in/subtree and current directory should follow the\n"
    "\trules described above.\n"
    "\n"
);

static cl::OptionCategory ClangCheckCategory("clang-check options");
static std::unique_ptr<opt::OptTable> Options(createDriverOptTable());
static cl::opt<bool>
ASTDump("ast-dump", cl::desc(Options->getOptionHelpText(options::OPT_ast_dump)),
        cl::cat(ClangCheckCategory));
static cl::opt<bool>
ASTList("ast-list", cl::desc(Options->getOptionHelpText(options::OPT_ast_list)),
        cl::cat(ClangCheckCategory));
static cl::opt<bool>
ASTPrint("ast-print",
         cl::desc(Options->getOptionHelpText(options::OPT_ast_print)),
         cl::cat(ClangCheckCategory));
static cl::opt<std::string> ASTDumpFilter(
    "ast-dump-filter",
    cl::desc(Options->getOptionHelpText(options::OPT_ast_dump_filter)),
    cl::cat(ClangCheckCategory));
static cl::opt<bool>
Analyze("analyze", cl::desc(Options->getOptionHelpText(options::OPT_analyze)),
        cl::cat(ClangCheckCategory));

static cl::opt<bool>
Fixit("fixit", cl::desc(Options->getOptionHelpText(options::OPT_fixit)),
      cl::cat(ClangCheckCategory));
static cl::opt<bool> FixWhatYouCan(
    "fix-what-you-can",
    cl::desc(Options->getOptionHelpText(options::OPT_fix_what_you_can)),
    cl::cat(ClangCheckCategory));

namespace {

// FIXME: Move FixItRewriteInPlace from lib/Rewrite/Frontend/FrontendActions.cpp
// into a header file and reuse that.
class FixItOptions : public clang::FixItOptions {
public:
  FixItOptions() {
    FixWhatYouCan = ::FixWhatYouCan;
  }

  std::string RewriteFilename(const std::string& filename, int &fd) override {
    assert(llvm::sys::path::is_absolute(filename) &&
           "clang-fixit expects absolute paths only.");

    // We don't need to do permission checking here since clang will diagnose
    // any I/O errors itself.

    fd = -1;  // No file descriptor for file.

    return filename;
  }
};

/// \brief Subclasses \c clang::FixItRewriter to not count fixed errors/warnings
/// in the final error counts.
///
/// This has the side-effect that clang-check -fixit exits with code 0 on
/// successfully fixing all errors.
class FixItRewriter : public clang::FixItRewriter {
public:
  FixItRewriter(clang::DiagnosticsEngine& Diags,
                clang::SourceManager& SourceMgr,
                const clang::LangOptions& LangOpts,
                clang::FixItOptions* FixItOpts)
      : clang::FixItRewriter(Diags, SourceMgr, LangOpts, FixItOpts) {
  }

  bool IncludeInDiagnosticCounts() const override { return false; }
};

/// \brief Subclasses \c clang::FixItAction so that we can install the custom
/// \c FixItRewriter.
class FixItAction : public clang::FixItAction {
public:
  bool BeginSourceFileAction(clang::CompilerInstance& CI,
                             StringRef Filename) override {
    FixItOpts.reset(new FixItOptions);
    Rewriter.reset(new FixItRewriter(CI.getDiagnostics(), CI.getSourceManager(),
                                     CI.getLangOpts(), FixItOpts.get()));
    return true;
  }
};

class ClangCheckActionFactory {
public:
  std::unique_ptr<clang::ASTConsumer> newASTConsumer() {
    if (ASTList)
      return clang::CreateASTDeclNodeLister();
    if (ASTDump)
      return clang::CreateASTDumper(ASTDumpFilter, /*DumpDecls=*/true,
                                    /*DumpLookups=*/false);
    if (ASTPrint)
      return clang::CreateASTPrinter(&llvm::outs(), ASTDumpFilter);
    return llvm::make_unique<clang::ASTConsumer>();
  }
};

} // namespace

int main(int argc, const char **argv) {
  llvm::sys::PrintStackTraceOnErrorSignal();
  CommonOptionsParser OptionsParser(argc, argv, ClangCheckCategory);
  ClangTool Tool(OptionsParser.getCompilations(),
                 OptionsParser.getSourcePathList());

  // Clear adjusters because -fsyntax-only is inserted by the default chain.
  Tool.clearArgumentsAdjusters();
  Tool.appendArgumentsAdjuster(getClangStripOutputAdjuster());

  // Running the analyzer requires --analyze. Other modes can work with the
  // -fsyntax-only option.
  Tool.appendArgumentsAdjuster(getInsertArgumentAdjuster(
      Analyze ? "--analyze" : "-fsyntax-only", ArgumentInsertPosition::BEGIN));

  ClangCheckActionFactory CheckFactory;
  std::unique_ptr<FrontendActionFactory> FrontendFactory;

  // Choose the correct factory based on the selected mode.
  if (Analyze)
    FrontendFactory = newFrontendActionFactory<clang::ento::AnalysisAction>();
  else if (Fixit)
    FrontendFactory = newFrontendActionFactory<FixItAction>();
  else
    FrontendFactory = newFrontendActionFactory(&CheckFactory);

  return Tool.run(FrontendFactory.get());
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: webdavcontent.hxx,v $
 *
 *  $Revision: 1.17 $
 *
 *  last change: $Author: hr $ $Date: 2003-03-27 17:27:21 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _WEBDAV_UCP_CONTENT_HXX
#define _WEBDAV_UCP_CONTENT_HXX

#include <memory>
#include <list>

#ifndef _RTL_REF_HXX_
#include <rtl/ref.hxx>
#endif

#ifndef _COM_SUN_STAR_UCB_CONTENTCREATIONEXCEPTION_HPP_
#include <com/sun/star/ucb/ContentCreationException.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_XCONTENTCREATOR_HPP_
#include <com/sun/star/ucb/XContentCreator.hpp>
#endif

#ifndef _UCBHELPER_CONTENTHELPER_HXX
#include <ucbhelper/contenthelper.hxx>
#endif

#ifndef _DAVRESOURCEACCESS_HXX_
#include "DAVResourceAccess.hxx"
#endif
#ifndef _WEBDAV_UCP_PROPERTYMAP_HXX
#include "PropertyMap.hxx"
#endif

namespace com { namespace sun { namespace star { namespace beans {
    struct Property;
    struct PropertyValue;
} } } }

namespace com { namespace sun { namespace star { namespace io {
    class XInputStream;
} } } }

namespace com { namespace sun { namespace star { namespace sdbc {
    class XRow;
} } } }

namespace com { namespace sun { namespace star { namespace ucb {
    struct TransferInfo;
} } } }

namespace webdav_ucp
{

//=========================================================================

// UNO service name for the content.
#define WEBDAV_CONTENT_SERVICE_NAME "com.sun.star.ucb.WebDAVContent"

//=========================================================================

class ContentProvider;
class ContentProperties;

class Content : public ::ucb::ContentImplHelper,
                public com::sun::star::ucb::XContentCreator
{
    enum ResourceType
    {
        UNKNOWN,
        FTP,
        NON_DAV,
        DAV
    };

    std::auto_ptr< DAVResourceAccess > m_xResAccess;
    std::auto_ptr< ContentProperties > m_xCachedProps; // locally cached props
    rtl::OUString     m_aEscapedTitle;
    ResourceType      m_eResourceType;
    ContentProvider*  m_pProvider; // No need for a ref, base class holds object
      sal_Bool        m_bTransient;
    sal_Bool          m_bCollection;

private:
    virtual com::sun::star::uno::Sequence< com::sun::star::beans::Property >
    getProperties( const com::sun::star::uno::Reference<
                    com::sun::star::ucb::XCommandEnvironment > & xEnv );
    virtual com::sun::star::uno::Sequence< com::sun::star::ucb::CommandInfo >
    getCommands( const com::sun::star::uno::Reference<
                    com::sun::star::ucb::XCommandEnvironment > & xEnv );
      virtual ::rtl::OUString getParentURL();

      sal_Bool isFolder( const ::com::sun::star::uno::Reference<
                        ::com::sun::star::ucb::XCommandEnvironment >& xEnv )
        throw ( ::com::sun::star::uno::Exception );

    void getProperties( const ::com::sun::star::uno::Reference<
                            ::com::sun::star::ucb::XCommandEnvironment >& xEnv,
                        PropertyMap & rProps );

      ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow >
      getPropertyValues( const ::com::sun::star::uno::Sequence<
                           ::com::sun::star::beans::Property >& rProperties,
                          const ::com::sun::star::uno::Reference<
                        ::com::sun::star::ucb::XCommandEnvironment >& xEnv )
        throw ( ::com::sun::star::uno::Exception );

    ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >
    setPropertyValues(
                     const ::com::sun::star::uno::Sequence<
                         ::com::sun::star::beans::PropertyValue >& rValues,
                        const ::com::sun::star::uno::Reference<
                        ::com::sun::star::ucb::XCommandEnvironment >& xEnv )
        throw ( ::com::sun::star::uno::Exception );

    typedef rtl::Reference< Content > ContentRef;
      typedef std::list< ContentRef > ContentRefList;
      void queryChildren( ContentRefList& rChildren);

      sal_Bool exchangeIdentity(
                const ::com::sun::star::uno::Reference<
                        ::com::sun::star::ucb::XContentIdentifier >& xNewId );

    const rtl::OUString getBaseURI();

    const ResourceType & getResourceType(
                    const ::com::sun::star::uno::Reference<
                        ::com::sun::star::ucb::XCommandEnvironment >& xEnv )
        throw ( ::com::sun::star::uno::Exception );

      // Command "insert"
      void insert( const ::com::sun::star::uno::Reference<
                    ::com::sun::star::io::XInputStream > & xInputStream,
                   sal_Bool bReplaceExisting,
                   const com::sun::star::uno::Reference<
                      com::sun::star::ucb::XCommandEnvironment >& Environment )
        throw( ::com::sun::star::uno::Exception );

    // Command "transfer"
    void transfer( const ::com::sun::star::ucb::TransferInfo & rArgs,
                   const com::sun::star::uno::Reference<
                      com::sun::star::ucb::XCommandEnvironment >& Environment )
        throw( ::com::sun::star::uno::Exception );

    // Command "delete"
      void destroy( sal_Bool bDeletePhysical )
        throw( ::com::sun::star::uno::Exception );

    ::com::sun::star::uno::Any MapDAVException( const DAVException & e,
                                                sal_Bool bWrite );
    void cancelCommandExecution(
                    const DAVException & e,
                    const ::com::sun::star::uno::Reference<
                        com::sun::star::ucb::XCommandEnvironment > & xEnv,
                    sal_Bool bWrite = sal_False )
        throw( ::com::sun::star::uno::Exception );

    static bool shouldAccessNetworkAfterException( const DAVException & e );

public:
      Content( const ::com::sun::star::uno::Reference<
                ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
                ContentProvider* pProvider,
                const ::com::sun::star::uno::Reference<
                ::com::sun::star::ucb::XContentIdentifier >& Identifier,
             rtl::Reference< DAVSessionFactory > const & rSessionFactory )
        throw ( ::com::sun::star::ucb::ContentCreationException );
      Content( const ::com::sun::star::uno::Reference<
                ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
                ContentProvider* pProvider,
                const ::com::sun::star::uno::Reference<
                ::com::sun::star::ucb::XContentIdentifier >& Identifier,
             rtl::Reference< DAVSessionFactory > const & rSessionFactory,
                sal_Bool isCollection )
        throw ( ::com::sun::star::ucb::ContentCreationException );
      virtual ~Content();

      // XInterface
      XINTERFACE_DECL()

    // XTypeProvider
    XTYPEPROVIDER_DECL()

    // XServiceInfo
    virtual ::rtl::OUString SAL_CALL
      getImplementationName()
        throw( ::com::sun::star::uno::RuntimeException );
      virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
      getSupportedServiceNames()
        throw( ::com::sun::star::uno::RuntimeException );

      // XContent
      virtual rtl::OUString SAL_CALL
      getContentType()
        throw( com::sun::star::uno::RuntimeException );

      // XCommandProcessor
      virtual com::sun::star::uno::Any SAL_CALL
      execute( const com::sun::star::ucb::Command& aCommand,
                sal_Int32 CommandId,
                const com::sun::star::uno::Reference<
                   com::sun::star::ucb::XCommandEnvironment >& Environment )
        throw( com::sun::star::uno::Exception,
                  com::sun::star::ucb::CommandAbortedException,
                  com::sun::star::uno::RuntimeException );
      virtual void SAL_CALL
      abort( sal_Int32 CommandId )
        throw( com::sun::star::uno::RuntimeException );

      // XPropertyContainer
    virtual void SAL_CALL
    addProperty( const rtl::OUString& Name,
                 sal_Int16 Attributes,
                 const com::sun::star::uno::Any& DefaultValue )
        throw( com::sun::star::beans::PropertyExistException,
               com::sun::star::beans::IllegalTypeException,
               com::sun::star::lang::IllegalArgumentException,
               com::sun::star::uno::RuntimeException );

    virtual void SAL_CALL
    removeProperty( const rtl::OUString& Name )
        throw( com::sun::star::beans::UnknownPropertyException,
               com::sun::star::beans::NotRemoveableException,
               com::sun::star::uno::RuntimeException );

      //////////////////////////////////////////////////////////////////////
      // Additional interfaces
      //////////////////////////////////////////////////////////////////////

      // XContentCreator
    virtual com::sun::star::uno::Sequence<
        com::sun::star::ucb::ContentInfo > SAL_CALL
      queryCreatableContentsInfo()
        throw( com::sun::star::uno::RuntimeException );
      virtual com::sun::star::uno::Reference<
          com::sun::star::ucb::XContent > SAL_CALL
      createNewContent( const com::sun::star::ucb::ContentInfo& Info )
        throw( com::sun::star::uno::RuntimeException );

      //////////////////////////////////////////////////////////////////////
      // Non-interface methods.
      //////////////////////////////////////////////////////////////////////

    DAVResourceAccess & getResourceAccess() { return *m_xResAccess; }

      // Called from resultset data supplier.
      static ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow >
      getPropertyValues( const ::com::sun::star::uno::Reference<
                              ::com::sun::star::lang::XMultiServiceFactory >& rSMgr,
                       const ::com::sun::star::uno::Sequence<
                              ::com::sun::star::beans::Property >& rProperties,
                          const ContentProperties& rData,
                       const rtl::Reference<
                           ::ucb::ContentProviderImplHelper >&  rProvider,
                          const ::rtl::OUString& rContentId );
};

};

#endif
<commit_msg>INTEGRATION: CWS indephome (1.17.116); FILE MERGED 2004/05/27 12:56:37 kso 1.17.116.1: #116677# - Multithreading issues.<commit_after>/*************************************************************************
 *
 *  $RCSfile: webdavcontent.hxx,v $
 *
 *  $Revision: 1.18 $
 *
 *  last change: $Author: rt $ $Date: 2004-07-05 10:41:17 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _WEBDAV_UCP_CONTENT_HXX
#define _WEBDAV_UCP_CONTENT_HXX

#include <memory>
#include <list>

#ifndef _RTL_REF_HXX_
#include <rtl/ref.hxx>
#endif

#ifndef _COM_SUN_STAR_UCB_CONTENTCREATIONEXCEPTION_HPP_
#include <com/sun/star/ucb/ContentCreationException.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_XCONTENTCREATOR_HPP_
#include <com/sun/star/ucb/XContentCreator.hpp>
#endif

#ifndef _UCBHELPER_CONTENTHELPER_HXX
#include <ucbhelper/contenthelper.hxx>
#endif

#ifndef _DAVRESOURCEACCESS_HXX_
#include "DAVResourceAccess.hxx"
#endif
#ifndef _WEBDAV_UCP_PROPERTYMAP_HXX
#include "PropertyMap.hxx"
#endif

namespace com { namespace sun { namespace star { namespace beans {
    struct Property;
    struct PropertyValue;
} } } }

namespace com { namespace sun { namespace star { namespace io {
    class XInputStream;
} } } }

namespace com { namespace sun { namespace star { namespace sdbc {
    class XRow;
} } } }

namespace com { namespace sun { namespace star { namespace ucb {
    struct OpenCommandArgument2;
    struct PostCommandArgument2;
    struct TransferInfo;
} } } }

namespace webdav_ucp
{

//=========================================================================

// UNO service name for the content.
#define WEBDAV_CONTENT_SERVICE_NAME "com.sun.star.ucb.WebDAVContent"

//=========================================================================

class ContentProvider;
class ContentProperties;

class Content : public ::ucb::ContentImplHelper,
                public com::sun::star::ucb::XContentCreator
{
    enum ResourceType
    {
        UNKNOWN,
        FTP,
        NON_DAV,
        DAV
    };

    std::auto_ptr< DAVResourceAccess > m_xResAccess;
    std::auto_ptr< ContentProperties > m_xCachedProps; // locally cached props
    rtl::OUString     m_aEscapedTitle;
    ResourceType      m_eResourceType;
    ContentProvider*  m_pProvider; // No need for a ref, base class holds object
      sal_Bool        m_bTransient;
    sal_Bool          m_bCollection;

private:
    virtual com::sun::star::uno::Sequence< com::sun::star::beans::Property >
    getProperties( const com::sun::star::uno::Reference<
                    com::sun::star::ucb::XCommandEnvironment > & xEnv );
    virtual com::sun::star::uno::Sequence< com::sun::star::ucb::CommandInfo >
    getCommands( const com::sun::star::uno::Reference<
                    com::sun::star::ucb::XCommandEnvironment > & xEnv );
      virtual ::rtl::OUString getParentURL();

      sal_Bool isFolder( const ::com::sun::star::uno::Reference<
                        ::com::sun::star::ucb::XCommandEnvironment >& xEnv )
        throw ( ::com::sun::star::uno::Exception );

    void getProperties( const ::com::sun::star::uno::Reference<
                            ::com::sun::star::ucb::XCommandEnvironment >& xEnv,
                        PropertyMap & rProps );

      ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow >
      getPropertyValues( const ::com::sun::star::uno::Sequence<
                           ::com::sun::star::beans::Property >& rProperties,
                          const ::com::sun::star::uno::Reference<
                        ::com::sun::star::ucb::XCommandEnvironment >& xEnv )
        throw ( ::com::sun::star::uno::Exception );

    ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >
    setPropertyValues(
                     const ::com::sun::star::uno::Sequence<
                         ::com::sun::star::beans::PropertyValue >& rValues,
                        const ::com::sun::star::uno::Reference<
                        ::com::sun::star::ucb::XCommandEnvironment >& xEnv )
        throw ( ::com::sun::star::uno::Exception );

    typedef rtl::Reference< Content > ContentRef;
      typedef std::list< ContentRef > ContentRefList;
      void queryChildren( ContentRefList& rChildren);

      sal_Bool exchangeIdentity(
                const ::com::sun::star::uno::Reference<
                        ::com::sun::star::ucb::XContentIdentifier >& xNewId );

    const rtl::OUString getBaseURI();

    const ResourceType & getResourceType(
                    const ::com::sun::star::uno::Reference<
                        ::com::sun::star::ucb::XCommandEnvironment >& xEnv )
        throw ( ::com::sun::star::uno::Exception );

    // Command "open"
    com::sun::star::uno::Any open(
                const com::sun::star::ucb::OpenCommandArgument2 & rArg,
                const com::sun::star::uno::Reference<
                        com::sun::star::ucb::XCommandEnvironment > & xEnv )
        throw( ::com::sun::star::uno::Exception );

    // Command "post"
    void post( const com::sun::star::ucb::PostCommandArgument2 & rArg,
               const com::sun::star::uno::Reference<
                        com::sun::star::ucb::XCommandEnvironment > & xEnv )
        throw( ::com::sun::star::uno::Exception );

      // Command "insert"
      void insert( const ::com::sun::star::uno::Reference<
                    ::com::sun::star::io::XInputStream > & xInputStream,
                   sal_Bool bReplaceExisting,
                   const com::sun::star::uno::Reference<
                      com::sun::star::ucb::XCommandEnvironment >& Environment )
        throw( ::com::sun::star::uno::Exception );

    // Command "transfer"
    void transfer( const ::com::sun::star::ucb::TransferInfo & rArgs,
                   const com::sun::star::uno::Reference<
                      com::sun::star::ucb::XCommandEnvironment >& Environment )
        throw( ::com::sun::star::uno::Exception );

    // Command "delete"
      void destroy( sal_Bool bDeletePhysical )
        throw( ::com::sun::star::uno::Exception );

    ::com::sun::star::uno::Any MapDAVException( const DAVException & e,
                                                sal_Bool bWrite );
    void cancelCommandExecution(
                    const DAVException & e,
                    const ::com::sun::star::uno::Reference<
                        com::sun::star::ucb::XCommandEnvironment > & xEnv,
                    sal_Bool bWrite = sal_False )
        throw( ::com::sun::star::uno::Exception );

    static bool shouldAccessNetworkAfterException( const DAVException & e );

public:
      Content( const ::com::sun::star::uno::Reference<
                ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
                ContentProvider* pProvider,
                const ::com::sun::star::uno::Reference<
                ::com::sun::star::ucb::XContentIdentifier >& Identifier,
             rtl::Reference< DAVSessionFactory > const & rSessionFactory )
        throw ( ::com::sun::star::ucb::ContentCreationException );
      Content( const ::com::sun::star::uno::Reference<
                ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
                ContentProvider* pProvider,
                const ::com::sun::star::uno::Reference<
                ::com::sun::star::ucb::XContentIdentifier >& Identifier,
             rtl::Reference< DAVSessionFactory > const & rSessionFactory,
                sal_Bool isCollection )
        throw ( ::com::sun::star::ucb::ContentCreationException );
      virtual ~Content();

      // XInterface
      XINTERFACE_DECL()

    // XTypeProvider
    XTYPEPROVIDER_DECL()

    // XServiceInfo
    virtual ::rtl::OUString SAL_CALL
      getImplementationName()
        throw( ::com::sun::star::uno::RuntimeException );
      virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
      getSupportedServiceNames()
        throw( ::com::sun::star::uno::RuntimeException );

      // XContent
      virtual rtl::OUString SAL_CALL
      getContentType()
        throw( com::sun::star::uno::RuntimeException );

      // XCommandProcessor
      virtual com::sun::star::uno::Any SAL_CALL
      execute( const com::sun::star::ucb::Command& aCommand,
                sal_Int32 CommandId,
                const com::sun::star::uno::Reference<
                   com::sun::star::ucb::XCommandEnvironment >& Environment )
        throw( com::sun::star::uno::Exception,
                  com::sun::star::ucb::CommandAbortedException,
                  com::sun::star::uno::RuntimeException );
      virtual void SAL_CALL
      abort( sal_Int32 CommandId )
        throw( com::sun::star::uno::RuntimeException );

      // XPropertyContainer
    virtual void SAL_CALL
    addProperty( const rtl::OUString& Name,
                 sal_Int16 Attributes,
                 const com::sun::star::uno::Any& DefaultValue )
        throw( com::sun::star::beans::PropertyExistException,
               com::sun::star::beans::IllegalTypeException,
               com::sun::star::lang::IllegalArgumentException,
               com::sun::star::uno::RuntimeException );

    virtual void SAL_CALL
    removeProperty( const rtl::OUString& Name )
        throw( com::sun::star::beans::UnknownPropertyException,
               com::sun::star::beans::NotRemoveableException,
               com::sun::star::uno::RuntimeException );

      //////////////////////////////////////////////////////////////////////
      // Additional interfaces
      //////////////////////////////////////////////////////////////////////

      // XContentCreator
    virtual com::sun::star::uno::Sequence<
        com::sun::star::ucb::ContentInfo > SAL_CALL
      queryCreatableContentsInfo()
        throw( com::sun::star::uno::RuntimeException );
      virtual com::sun::star::uno::Reference<
          com::sun::star::ucb::XContent > SAL_CALL
      createNewContent( const com::sun::star::ucb::ContentInfo& Info )
        throw( com::sun::star::uno::RuntimeException );

      //////////////////////////////////////////////////////////////////////
      // Non-interface methods.
      //////////////////////////////////////////////////////////////////////

    DAVResourceAccess & getResourceAccess() { return *m_xResAccess; }

      // Called from resultset data supplier.
      static ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow >
      getPropertyValues( const ::com::sun::star::uno::Reference<
                              ::com::sun::star::lang::XMultiServiceFactory >& rSMgr,
                       const ::com::sun::star::uno::Sequence<
                              ::com::sun::star::beans::Property >& rProperties,
                          const ContentProperties& rData,
                       const rtl::Reference<
                           ::ucb::ContentProviderImplHelper >&  rProvider,
                          const ::rtl::OUString& rContentId );
};

};

#endif
<|endoftext|>


<commit_before>#include "libtorrent/session.hpp"
#include "libtorrent/session_settings.hpp"
#include "libtorrent/hasher.hpp"
#include "libtorrent/alert_types.hpp"
#include <boost/thread.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/filesystem/operations.hpp>

#include "test.hpp"
#include "setup_transfer.hpp"

using boost::filesystem::remove_all;
using boost::filesystem::exists;

void test_swarm()
{
	using namespace libtorrent;

	session ses1(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48000, 49000));
	session ses2(fingerprint("LT", 0, 1, 0, 0), std::make_pair(49000, 50000));
	session ses3(fingerprint("LT", 0, 1, 0, 0), std::make_pair(50000, 51000));

	ses1.set_severity_level(alert::debug);
	ses2.set_severity_level(alert::debug);
	ses3.set_severity_level(alert::debug);

	// this is to avoid everything finish from a single peer
	// immediately. To make the swarm actually connect all
	// three peers before finishing.
	float rate_limit = 100000;
	ses1.set_upload_rate_limit(int(rate_limit));
	ses2.set_download_rate_limit(int(rate_limit));
	ses3.set_download_rate_limit(int(rate_limit));
	ses2.set_upload_rate_limit(int(rate_limit / 2));
	ses3.set_upload_rate_limit(int(rate_limit / 2));

	session_settings settings;
	settings.allow_multiple_connections_per_ip = true;
	settings.ignore_limits_on_local_network = false;
	ses1.set_settings(settings);
	ses2.set_settings(settings);
	ses3.set_settings(settings);

#ifndef TORRENT_DISABLE_ENCRYPTION
	pe_settings pes;
	pes.out_enc_policy = pe_settings::forced;
	pes.in_enc_policy = pe_settings::forced;
	ses1.set_pe_settings(pes);
	ses2.set_pe_settings(pes);
	ses3.set_pe_settings(pes);
#endif

	torrent_handle tor1;
	torrent_handle tor2;
	torrent_handle tor3;

	boost::tie(tor1, tor2, tor3) = setup_transfer(&ses1, &ses2, &ses3, true, false, true, "_swarm");

	float sum_dl_rate2 = 0.f;
	float sum_dl_rate3 = 0.f;
	int count_dl_rates2 = 0;
	int count_dl_rates3 = 0;

	for (int i = 0; i < 27; ++i)
	{
		print_alerts(ses1, "ses1");
		print_alerts(ses2, "ses2");
		print_alerts(ses3, "ses3");

		torrent_status st1 = tor1.status();
		torrent_status st2 = tor2.status();
		torrent_status st3 = tor3.status();

		if (st2.progress < 1.f && st2.progress > 0.5f)
		{
			sum_dl_rate2 += st2.download_payload_rate;
			++count_dl_rates2;
		}
		if (st3.progress < 1.f && st3.progress > 0.5f)
		{
			sum_dl_rate3 += st3.download_rate;
			++count_dl_rates3;
		}

		std::cerr
			<< "\033[33m" << int(st1.upload_payload_rate / 1000.f) << "kB/s "
			<< st1.num_peers << ": "
			<< "\033[32m" << int(st2.download_payload_rate / 1000.f) << "kB/s "
			<< "\033[31m" << int(st2.upload_payload_rate / 1000.f) << "kB/s "
			<< "\033[0m" << int(st2.progress * 100) << "% "
			<< st2.num_peers << " - "
			<< "\033[32m" << int(st3.download_payload_rate / 1000.f) << "kB/s "
			<< "\033[31m" << int(st3.upload_payload_rate / 1000.f) << "kB/s "
			<< "\033[0m" << int(st3.progress * 100) << "% "
			<< st3.num_peers
			<< std::endl;

		if (tor2.is_seed() && tor3.is_seed()) break;
		test_sleep(1000);
	}

	TEST_CHECK(tor2.is_seed());
	TEST_CHECK(tor3.is_seed());

	float average2 = sum_dl_rate2 / float(count_dl_rates2);
	float average3 = sum_dl_rate3 / float(count_dl_rates3);

	std::cerr << average2 << std::endl;
	std::cerr << "average rate: " << (average2 / 1000.f) << "kB/s - "
		<< (average3 / 1000.f) << "kB/s" << std::endl;

	TEST_CHECK(std::fabs(average2 - float(rate_limit)) < rate_limit / 11.f);
	TEST_CHECK(std::fabs(average3 - float(rate_limit)) < rate_limit / 11.f);
	if (tor2.is_seed() && tor3.is_seed()) std::cerr << "done\n";

	// make sure the files are deleted
	ses1.remove_torrent(tor1, session::delete_files);
	ses2.remove_torrent(tor2, session::delete_files);
	ses3.remove_torrent(tor3, session::delete_files);

	std::auto_ptr<alert> a = ses1.pop_alert();
	ptime end = time_now() + seconds(20);
	while (a.get() == 0 || dynamic_cast<torrent_deleted_alert*>(a.get()) == 0)
	{
		if (ses1.wait_for_alert(end - time_now()) == 0)
		{
			std::cerr << "wait_for_alert() expired" << std::endl;
			break;
		}
		a = ses1.pop_alert();
		assert(a.get());
		std::cerr << a->msg() << std::endl;
	}

	TEST_CHECK(dynamic_cast<torrent_deleted_alert*>(a.get()) != 0);

	// there shouldn't be any alerts generated from now on
	// make sure that the timer in wait_for_alert() works
	// this should time out (ret == 0) and it should take
	// about 2 seconds
	ptime start = time_now();
	alert const* ret = ses1.wait_for_alert(seconds(2));
	TEST_CHECK(ret == 0);
	if (ret != 0) std::cerr << ret->msg() << std::endl;
	TEST_CHECK(time_now() - start < seconds(3));
	TEST_CHECK(time_now() - start > seconds(2));
}

int test_main()
{
	using namespace libtorrent;
	using namespace boost::filesystem;

	// in case the previous run was terminated
	try { remove_all("./tmp1_swarm"); } catch (std::exception&) {}
	try { remove_all("./tmp2_swarm"); } catch (std::exception&) {}
	try { remove_all("./tmp3_swarm"); } catch (std::exception&) {}

	test_swarm();

	test_sleep(2000);
	TEST_CHECK(!exists("./tmp1_swarm/temporary"));
	TEST_CHECK(!exists("./tmp2_swarm/temporary"));
	TEST_CHECK(!exists("./tmp3_swarm/temporary"));

	remove_all("./tmp1_swarm");
	remove_all("./tmp2_swarm");
	remove_all("./tmp3_swarm");

	return 0;
}

<commit_msg>test_swarm fix<commit_after>#include "libtorrent/session.hpp"
#include "libtorrent/session_settings.hpp"
#include "libtorrent/hasher.hpp"
#include "libtorrent/alert_types.hpp"
#include <boost/thread.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/filesystem/operations.hpp>

#include "test.hpp"
#include "setup_transfer.hpp"

using boost::filesystem::remove_all;
using boost::filesystem::exists;

void test_swarm()
{
	using namespace libtorrent;

	session ses1(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48000, 49000));
	session ses2(fingerprint("LT", 0, 1, 0, 0), std::make_pair(49000, 50000));
	session ses3(fingerprint("LT", 0, 1, 0, 0), std::make_pair(50000, 51000));

	ses1.set_severity_level(alert::debug);
	ses2.set_severity_level(alert::debug);
	ses3.set_severity_level(alert::debug);

	// this is to avoid everything finish from a single peer
	// immediately. To make the swarm actually connect all
	// three peers before finishing.
	float rate_limit = 100000;
	ses1.set_upload_rate_limit(int(rate_limit));
	ses2.set_download_rate_limit(int(rate_limit));
	ses3.set_download_rate_limit(int(rate_limit));
	ses2.set_upload_rate_limit(int(rate_limit / 2));
	ses3.set_upload_rate_limit(int(rate_limit / 2));

	session_settings settings;
	settings.allow_multiple_connections_per_ip = true;
	settings.ignore_limits_on_local_network = false;
	ses1.set_settings(settings);
	ses2.set_settings(settings);
	ses3.set_settings(settings);

#ifndef TORRENT_DISABLE_ENCRYPTION
	pe_settings pes;
	pes.out_enc_policy = pe_settings::forced;
	pes.in_enc_policy = pe_settings::forced;
	ses1.set_pe_settings(pes);
	ses2.set_pe_settings(pes);
	ses3.set_pe_settings(pes);
#endif

	torrent_handle tor1;
	torrent_handle tor2;
	torrent_handle tor3;

	boost::tie(tor1, tor2, tor3) = setup_transfer(&ses1, &ses2, &ses3, true, false, true, "_swarm");

	float sum_dl_rate2 = 0.f;
	float sum_dl_rate3 = 0.f;
	int count_dl_rates2 = 0;
	int count_dl_rates3 = 0;

	for (int i = 0; i < 30; ++i)
	{
		print_alerts(ses1, "ses1");
		print_alerts(ses2, "ses2");
		print_alerts(ses3, "ses3");

		torrent_status st1 = tor1.status();
		torrent_status st2 = tor2.status();
		torrent_status st3 = tor3.status();

		if (st2.progress < 1.f && st2.progress > 0.5f)
		{
			sum_dl_rate2 += st2.download_payload_rate;
			++count_dl_rates2;
		}
		if (st3.progress < 1.f && st3.progress > 0.5f)
		{
			sum_dl_rate3 += st3.download_rate;
			++count_dl_rates3;
		}

		std::cerr
			<< "\033[33m" << int(st1.upload_payload_rate / 1000.f) << "kB/s "
			<< st1.num_peers << ": "
			<< "\033[32m" << int(st2.download_payload_rate / 1000.f) << "kB/s "
			<< "\033[31m" << int(st2.upload_payload_rate / 1000.f) << "kB/s "
			<< "\033[0m" << int(st2.progress * 100) << "% "
			<< st2.num_peers << " - "
			<< "\033[32m" << int(st3.download_payload_rate / 1000.f) << "kB/s "
			<< "\033[31m" << int(st3.upload_payload_rate / 1000.f) << "kB/s "
			<< "\033[0m" << int(st3.progress * 100) << "% "
			<< st3.num_peers
			<< std::endl;

		if (tor2.is_seed() && tor3.is_seed()) break;
		test_sleep(1000);
	}

	TEST_CHECK(tor2.is_seed());
	TEST_CHECK(tor3.is_seed());

	float average2 = sum_dl_rate2 / float(count_dl_rates2);
	float average3 = sum_dl_rate3 / float(count_dl_rates3);

	std::cerr << average2 << std::endl;
	std::cerr << "average rate: " << (average2 / 1000.f) << "kB/s - "
		<< (average3 / 1000.f) << "kB/s" << std::endl;

	TEST_CHECK(std::fabs(average2 - float(rate_limit)) < rate_limit / 11.f);
	TEST_CHECK(std::fabs(average3 - float(rate_limit)) < rate_limit / 11.f);
	if (tor2.is_seed() && tor3.is_seed()) std::cerr << "done\n";

	// make sure the files are deleted
	ses1.remove_torrent(tor1, session::delete_files);
	ses2.remove_torrent(tor2, session::delete_files);
	ses3.remove_torrent(tor3, session::delete_files);

	std::auto_ptr<alert> a = ses1.pop_alert();
	ptime end = time_now() + seconds(20);
	while (a.get() == 0 || dynamic_cast<torrent_deleted_alert*>(a.get()) == 0)
	{
		if (ses1.wait_for_alert(end - time_now()) == 0)
		{
			std::cerr << "wait_for_alert() expired" << std::endl;
			break;
		}
		a = ses1.pop_alert();
		assert(a.get());
		std::cerr << a->msg() << std::endl;
	}

	TEST_CHECK(dynamic_cast<torrent_deleted_alert*>(a.get()) != 0);

	// there shouldn't be any alerts generated from now on
	// make sure that the timer in wait_for_alert() works
	// this should time out (ret == 0) and it should take
	// about 2 seconds
	ptime start = time_now();
	alert const* ret = ses1.wait_for_alert(seconds(2));
	TEST_CHECK(ret == 0);
	if (ret != 0) std::cerr << ret->msg() << std::endl;
	TEST_CHECK(time_now() - start < seconds(3));
	TEST_CHECK(time_now() - start > seconds(2));
}

int test_main()
{
	using namespace libtorrent;
	using namespace boost::filesystem;

	// in case the previous run was terminated
	try { remove_all("./tmp1_swarm"); } catch (std::exception&) {}
	try { remove_all("./tmp2_swarm"); } catch (std::exception&) {}
	try { remove_all("./tmp3_swarm"); } catch (std::exception&) {}

	test_swarm();

	test_sleep(2000);
	TEST_CHECK(!exists("./tmp1_swarm/temporary"));
	TEST_CHECK(!exists("./tmp2_swarm/temporary"));
	TEST_CHECK(!exists("./tmp3_swarm/temporary"));

	remove_all("./tmp1_swarm");
	remove_all("./tmp2_swarm");
	remove_all("./tmp3_swarm");

	return 0;
}

<|endoftext|>