<commit_before>/**
 * @file constrained_ik.cpp
 * @brief Basic low-level kinematics functions.
 *
 * Typically, just wrappers around the equivalent KDL calls.
 *
 * @author dsolomon
 * @date Sep 15, 2013
 * @version TODO
 * @bug No known bugs
 *
 * @copyright Copyright (c) 2013, Southwest Research Institute
 *
 * @license Software License Agreement (Apache License)\n
 * \n
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at\n
 * \n
 * http://www.apache.org/licenses/LICENSE-2.0\n
 * \n
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "constrained_ik/constrained_ik.h"
#include "constrained_ik/constraint_group.h"
#include <boost/make_shared.hpp>
//#include <moveit/collision_detection_fcl/collision_common.h>
#include <constrained_ik/collision_robot_fcl_detailed.h>
#include <constrained_ik/constraint_results.h>
#include <ros/ros.h>

namespace constrained_ik
{
using Eigen::MatrixXd;
using Eigen::VectorXd;
using Eigen::Affine3d;

Constrained_IK::Constrained_IK()
{
  initialized_ = false;
  max_iter_ = 500;                  //default max_iter
  joint_convergence_tol_ = 0.0001;   //default convergence tolerance
  debug_ = false;
  kpp_ = 1.0;// default primary proportional gain
  kpa_ = 0.5;// default auxillary proportional gain
}

constrained_ik::ConstraintResults Constrained_IK::evalConstraint(constraint_types::ConstraintType constraint_type, const constrained_ik::SolverState &state) const
{
  switch(constraint_type)
  {
    case constraint_types::Primary:
      return primary_constraints_.evalConstraint(state);
    case constraint_types::Auxiliary:
      return auxiliary_constraints_.evalConstraint(state);
  }
}

Eigen::MatrixXd Constrained_IK::calcNullspaceProjection(const Eigen::MatrixXd &J) const
{
  MatrixXd J_pinv = calcDampedPseudoinverse(J);
  MatrixXd JplusJ = J_pinv * J;
  int mn = JplusJ.rows();
  MatrixXd P = MatrixXd::Identity(mn,mn)-JplusJ;
  return (P);
}

Eigen::MatrixXd Constrained_IK::calcNullspaceProjectionTheRightWay(const Eigen::MatrixXd &A) const
{
  Eigen::JacobiSVD<MatrixXd> svd(A, Eigen::ComputeFullV);
  MatrixXd V(svd.matrixV());

  // determine rank using same algorithym as latest Eigen
  // TODO replace next 10 lines of code with rnk = svd.rank(); once eigen3 is updated
  int rnk = 0;
  if(svd.singularValues().size()==0)
  {
    rnk = 0;
  }
  else
  {
    double threshold = std::min(A.rows(),A.cols())*Eigen::NumTraits<double>::epsilon();
    double premultiplied_threshold = svd.singularValues().coeff(0) * threshold;
    rnk = svd.nonzeroSingularValues()-1;
    while(rnk>=0 && svd.singularValues().coeff(rnk) < premultiplied_threshold) --rnk;
    rnk++;
  }

  // zero singular vectors in the range of A
  for(int i=0; i<rnk; ++i)
  {
    for(int j=0; j<A.cols(); j++) V(j,i) = 0;
  }

  MatrixXd P = V *  V.transpose();
  return(P);
}

Eigen::MatrixXd Constrained_IK::calcDampedPseudoinverse(const Eigen::MatrixXd &J) const
{
  MatrixXd J_pinv;

  if (basic_kin::BasicKin::dampedPInv(J,J_pinv))
  {
    return J_pinv;
  }
  else
  {
    ROS_ERROR_STREAM("Not able to calculate damped pseudoinverse!");
    throw std::runtime_error("Not able to calculate damped pseudoinverse!  IK solution may be invalid.");
  }
}

void Constrained_IK::calcInvKin(const Eigen::Affine3d &goal,
                                const Eigen::VectorXd &joint_seed,
                                Eigen::VectorXd &joint_angles,
                                int min_updates) const
{
  calcInvKin(goal,joint_seed, planning_scene::PlanningSceneConstPtr(), joint_angles, min_updates);
}

void Constrained_IK::calcInvKin(const Eigen::Affine3d &goal,
                                const Eigen::VectorXd &joint_seed,
                                const planning_scene::PlanningSceneConstPtr planning_scene,
                                Eigen::VectorXd &joint_angles,
                                int min_updates) const
{
  // initialize state
  joint_angles = joint_seed;  // initialize result to seed value
  constrained_ik::SolverState state = getState(goal, joint_seed); // create state vars for this IK solve
  state.condition = checkInitialized();
  state.planning_scene = planning_scene;
  if(planning_scene)
  {
    state.robot_state = robot_state::RobotStatePtr(new moveit::core::RobotState(planning_scene->getCurrentState()));
    state.collision_robot = CollisionRobotFCLDetailed::CollisionRobotFCLDetailedPtr(new CollisionRobotFCLDetailed(planning_scene->getRobotModel()));
  }

  if (state.condition == initialization_state::NothingInitialized || state.condition == initialization_state::AuxiliaryOnly)
    throw std::runtime_error("Must call init() before using Constrained_IK and have a primary constraint.");

  //Cache the joint angles to return if max iteration is reached.
  Eigen::VectorXd cached_joint_angles = joint_seed;

  // iterate until solution converges (or aborted)
  bool status = false;
  while (true)
  {
    // re-update internal state variables
    updateState(state, joint_angles);

    // calculate a Jacobian (relating joint-space updates/deltas to cartesian-space errors/deltas)
    // and the associated cartesian-space error/delta vector
    // Primary Constraints
    constrained_ik::ConstraintResults primary = evalConstraint(constraint_types::Primary, state);
    // TODO since we already have J_p = USV, use that to get null-projection too.
    // otherwise, we are repeating the expensive calculation of the SVD
    MatrixXd Ji_p = calcDampedPseudoinverse(primary.jacobian);
    VectorXd dJoint_p = kpp_*(Ji_p*primary.error);
    if(dJoint_p.norm() > 1.0)// limit maximum update to unit size 1 radian /meter
    {
      dJoint_p = dJoint_p/dJoint_p.norm();
    }
    ROS_DEBUG("theta_p = %f ep = %f",dJoint_p.norm(), primary.error.norm());

    // Auxiliary Constraints
    VectorXd dJoint_a;
    constrained_ik::ConstraintResults auxiliary;
    dJoint_a.setZero(dJoint_p.size());
    if (state.condition == initialization_state::PrimaryAndAuxiliary)
    {
      auxiliary = evalConstraint(constraint_types::Auxiliary, state);
      MatrixXd N_p = calcNullspaceProjectionTheRightWay(auxiliary.jacobian);
      MatrixXd Jnull_a = calcDampedPseudoinverse(auxiliary.jacobian*N_p);
      dJoint_a = kpa_*Jnull_a*(auxiliary.error-auxiliary.jacobian*dJoint_p);
    }

    // Check the status of convergence
    if(state.condition = initialization_state::PrimaryAndAuxiliary)
    {
      status = checkStatus(state, primary, auxiliary);

      if(state.iter > max_iter_*.9)
        ROS_ERROR("theta_p = %f theta_a = %f ep = %f ea = %f", dJoint_p.norm(), dJoint_a.norm(), primary.error.norm(), auxiliary.error.norm());
    }
    else if(state.condition = initialization_state::PrimaryOnly)
    {
      status = checkStatus(state, primary);

      if(state.iter > max_iter_*.9)
        ROS_ERROR("theta_p = %f ep = %f ", dJoint_p.norm(),  primary.error.norm());
    }

    if(status && min_updates<=0)
    {
      break;
    }
    else
    {
      // update joint solution by the calculated update (or a partial fraction)
      joint_angles += (dJoint_p + dJoint_a);
      clipToJointLimits(joint_angles);
      min_updates--;
    }
  }

  if (state.iter == max_iter_)
    joint_angles = cached_joint_angles;

  // checking for collision on a valid planning scene
  if(planning_scene && collision_checks_required())
  {
    moveit::core::RobotStatePtr robot_state(new moveit::core::RobotState(planning_scene->getCurrentState()));
    robot_state->setJointGroupPositions(kin_.getJointModelGroup()->getName(),joint_angles);
    robot_state->update();
    if(planning_scene->isStateColliding(*robot_state,kin_.getJointModelGroup()->getName()))
    {
      ROS_ERROR("Robot is in collision at this pose");
    }
  }

  ROS_INFO_STREAM("IK solution: " << joint_angles.transpose());
}

bool Constrained_IK::checkStatus(const constrained_ik::SolverState &state, const constrained_ik::ConstraintResults &primary) const
{
  if (primary.status)
    return true;

  // check maximum iterations
  if (state.iter > max_iter_)
    throw std::runtime_error("Maximum iterations reached.  IK solution may be invalid.");

  // check for joint convergence
  //   - this is an error: joints stabilize, but goal pose not reached
  if (state.joints_delta.cwiseAbs().maxCoeff() < joint_convergence_tol_)
  {
    ROS_WARN_STREAM("Reached " << state.iter << " / " << max_iter_ << " iterations before convergence.");
    return true;
  }

  return false;
}

bool Constrained_IK::checkStatus(const constrained_ik::SolverState &state, const constrained_ik::ConstraintResults &primary, const constrained_ik::ConstraintResults &auxiliary) const
{
  if (primary.status && auxiliary.status)
    return true;

  // check maximum iterations
  if (state.iter > max_iter_)
    throw std::runtime_error("Maximum iterations reached.  IK solution may be invalid.");

  // check for joint convergence
  //   - this is an error: joints stabilize, but goal pose not reached
  if (state.joints_delta.cwiseAbs().maxCoeff() < joint_convergence_tol_)
  {
    ROS_WARN_STREAM("Reached " << state.iter << " / " << max_iter_ << " iterations before convergence.");
    return true;
  }

  return false;
}

void Constrained_IK::clearConstraintList()
{
  primary_constraints_.clear();
  auxiliary_constraints_.clear();
}

void Constrained_IK::clipToJointLimits(Eigen::VectorXd &joints) const
{
  const MatrixXd limits = kin_.getLimits();
  const VectorXd orig_joints(joints);

  if (joints.size() != limits.rows())
    throw std::invalid_argument("clipToJointLimits: Unexpected number of joints");

  for (size_t i=0; i<limits.rows(); ++i)
  {
    joints[i] = std::max(limits(i,0), std::min(limits(i,1), joints[i]));
  }
  if (debug_ && !joints.isApprox(orig_joints))
      ROS_WARN("Joints have been clipped");
}

void Constrained_IK::init(const basic_kin::BasicKin &kin)
{
  if (!kin.checkInitialized())
    throw std::invalid_argument("Input argument 'BasicKin' must be initialized");

  ros::NodeHandle pnh("~");
  pnh.getParam("primary_kp", kpp_);
  pnh.getParam("auxiliary_kp", kpa_);
  ROS_INFO("using primary kp=%f and auxiliary kp=%f", kpp_, kpa_);
  kin_ = kin;
  initialized_ = true;
  primary_constraints_.init(this);
  auxiliary_constraints_.init(this);

}

double Constrained_IK::rangedAngle(double angle)
{
    angle = copysign(fmod(fabs(angle),2.0*M_PI), angle);
    if (angle < -M_PI) return angle+2.*M_PI;
    if (angle > M_PI)  return angle-2.*M_PI;
    return angle;
}

constrained_ik::SolverState Constrained_IK::getState(const Eigen::Affine3d &goal, const Eigen::VectorXd &joint_seed) const
{
  if (!kin_.checkJoints(joint_seed))
    throw std::invalid_argument("Seed doesn't match kinematic model");

  if (!goal.matrix().block(0,0,3,3).isUnitary(1e-6))
        throw std::invalid_argument("Goal pose not proper affine");

  return constrained_ik::SolverState(goal, joint_seed);
}

void Constrained_IK::updateState(constrained_ik::SolverState &state, const Eigen::VectorXd &joints) const
{
  // update maximum iterations
  state.iter++;

  // update joint convergence
  state.joints_delta = joints - state.joints;
  state.joints = joints;
  kin_.calcFwdKin(joints, state.pose_estimate);

  if(state.planning_scene && state.robot_state)
  {
    state.robot_state->setJointGroupPositions(kin_.getJointModelGroup()->getName(), joints);
    state.robot_state->update();
  }

  if (debug_)
      state.iteration_path.push_back(joints);

}

bool Constrained_IK::collision_checks_required() const
{
  return( primary_constraints_.collision_checks_required() | auxiliary_constraints_.collision_checks_required());
}

} // namespace constrained_ik

<commit_msg>Fix syntax error in constrained_ik.cpp<commit_after>/**
 * @file constrained_ik.cpp
 * @brief Basic low-level kinematics functions.
 *
 * Typically, just wrappers around the equivalent KDL calls.
 *
 * @author dsolomon
 * @date Sep 15, 2013
 * @version TODO
 * @bug No known bugs
 *
 * @copyright Copyright (c) 2013, Southwest Research Institute
 *
 * @license Software License Agreement (Apache License)\n
 * \n
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at\n
 * \n
 * http://www.apache.org/licenses/LICENSE-2.0\n
 * \n
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "constrained_ik/constrained_ik.h"
#include "constrained_ik/constraint_group.h"
#include <boost/make_shared.hpp>
//#include <moveit/collision_detection_fcl/collision_common.h>
#include <constrained_ik/collision_robot_fcl_detailed.h>
#include <constrained_ik/constraint_results.h>
#include <ros/ros.h>

namespace constrained_ik
{
using Eigen::MatrixXd;
using Eigen::VectorXd;
using Eigen::Affine3d;

Constrained_IK::Constrained_IK()
{
  initialized_ = false;
  max_iter_ = 500;                  //default max_iter
  joint_convergence_tol_ = 0.0001;   //default convergence tolerance
  debug_ = false;
  kpp_ = 1.0;// default primary proportional gain
  kpa_ = 0.5;// default auxillary proportional gain
}

constrained_ik::ConstraintResults Constrained_IK::evalConstraint(constraint_types::ConstraintType constraint_type, const constrained_ik::SolverState &state) const
{
  switch(constraint_type)
  {
    case constraint_types::Primary:
      return primary_constraints_.evalConstraint(state);
    case constraint_types::Auxiliary:
      return auxiliary_constraints_.evalConstraint(state);
  }
}

Eigen::MatrixXd Constrained_IK::calcNullspaceProjection(const Eigen::MatrixXd &J) const
{
  MatrixXd J_pinv = calcDampedPseudoinverse(J);
  MatrixXd JplusJ = J_pinv * J;
  int mn = JplusJ.rows();
  MatrixXd P = MatrixXd::Identity(mn,mn)-JplusJ;
  return (P);
}

Eigen::MatrixXd Constrained_IK::calcNullspaceProjectionTheRightWay(const Eigen::MatrixXd &A) const
{
  Eigen::JacobiSVD<MatrixXd> svd(A, Eigen::ComputeFullV);
  MatrixXd V(svd.matrixV());

  // determine rank using same algorithym as latest Eigen
  // TODO replace next 10 lines of code with rnk = svd.rank(); once eigen3 is updated
  int rnk = 0;
  if(svd.singularValues().size()==0)
  {
    rnk = 0;
  }
  else
  {
    double threshold = std::min(A.rows(),A.cols())*Eigen::NumTraits<double>::epsilon();
    double premultiplied_threshold = svd.singularValues().coeff(0) * threshold;
    rnk = svd.nonzeroSingularValues()-1;
    while(rnk>=0 && svd.singularValues().coeff(rnk) < premultiplied_threshold) --rnk;
    rnk++;
  }

  // zero singular vectors in the range of A
  for(int i=0; i<rnk; ++i)
  {
    for(int j=0; j<A.cols(); j++) V(j,i) = 0;
  }

  MatrixXd P = V *  V.transpose();
  return(P);
}

Eigen::MatrixXd Constrained_IK::calcDampedPseudoinverse(const Eigen::MatrixXd &J) const
{
  MatrixXd J_pinv;

  if (basic_kin::BasicKin::dampedPInv(J,J_pinv))
  {
    return J_pinv;
  }
  else
  {
    ROS_ERROR_STREAM("Not able to calculate damped pseudoinverse!");
    throw std::runtime_error("Not able to calculate damped pseudoinverse!  IK solution may be invalid.");
  }
}

void Constrained_IK::calcInvKin(const Eigen::Affine3d &goal,
                                const Eigen::VectorXd &joint_seed,
                                Eigen::VectorXd &joint_angles,
                                int min_updates) const
{
  calcInvKin(goal,joint_seed, planning_scene::PlanningSceneConstPtr(), joint_angles, min_updates);
}

void Constrained_IK::calcInvKin(const Eigen::Affine3d &goal,
                                const Eigen::VectorXd &joint_seed,
                                const planning_scene::PlanningSceneConstPtr planning_scene,
                                Eigen::VectorXd &joint_angles,
                                int min_updates) const
{
  // initialize state
  joint_angles = joint_seed;  // initialize result to seed value
  constrained_ik::SolverState state = getState(goal, joint_seed); // create state vars for this IK solve
  state.condition = checkInitialized();
  state.planning_scene = planning_scene;
  if(planning_scene)
  {
    state.robot_state = robot_state::RobotStatePtr(new moveit::core::RobotState(planning_scene->getCurrentState()));
    state.collision_robot = CollisionRobotFCLDetailed::CollisionRobotFCLDetailedPtr(new CollisionRobotFCLDetailed(planning_scene->getRobotModel()));
  }

  if (state.condition == initialization_state::NothingInitialized || state.condition == initialization_state::AuxiliaryOnly)
    throw std::runtime_error("Must call init() before using Constrained_IK and have a primary constraint.");

  //Cache the joint angles to return if max iteration is reached.
  Eigen::VectorXd cached_joint_angles = joint_seed;

  // iterate until solution converges (or aborted)
  bool status = false;
  while (true)
  {
    // re-update internal state variables
    updateState(state, joint_angles);

    // calculate a Jacobian (relating joint-space updates/deltas to cartesian-space errors/deltas)
    // and the associated cartesian-space error/delta vector
    // Primary Constraints
    constrained_ik::ConstraintResults primary = evalConstraint(constraint_types::Primary, state);
    // TODO since we already have J_p = USV, use that to get null-projection too.
    // otherwise, we are repeating the expensive calculation of the SVD
    MatrixXd Ji_p = calcDampedPseudoinverse(primary.jacobian);
    VectorXd dJoint_p = kpp_*(Ji_p*primary.error);
    if(dJoint_p.norm() > 1.0)// limit maximum update to unit size 1 radian /meter
    {
      dJoint_p = dJoint_p/dJoint_p.norm();
    }
    ROS_DEBUG("theta_p = %f ep = %f",dJoint_p.norm(), primary.error.norm());

    // Auxiliary Constraints
    VectorXd dJoint_a;
    constrained_ik::ConstraintResults auxiliary;
    dJoint_a.setZero(dJoint_p.size());
    if (state.condition == initialization_state::PrimaryAndAuxiliary)
    {
      auxiliary = evalConstraint(constraint_types::Auxiliary, state);
      MatrixXd N_p = calcNullspaceProjectionTheRightWay(auxiliary.jacobian);
      MatrixXd Jnull_a = calcDampedPseudoinverse(auxiliary.jacobian*N_p);
      dJoint_a = kpa_*Jnull_a*(auxiliary.error-auxiliary.jacobian*dJoint_p);
    }

    // Check the status of convergence
    if(state.condition == initialization_state::PrimaryAndAuxiliary)
    {
      status = checkStatus(state, primary, auxiliary);

      if(state.iter > max_iter_*.9)
        ROS_ERROR("theta_p = %f theta_a = %f ep = %f ea = %f", dJoint_p.norm(), dJoint_a.norm(), primary.error.norm(), auxiliary.error.norm());
    }
    else if(state.condition == initialization_state::PrimaryOnly)
    {
      status = checkStatus(state, primary);

      if(state.iter > max_iter_*.9)
        ROS_ERROR("theta_p = %f ep = %f ", dJoint_p.norm(),  primary.error.norm());
    }

    if(status && min_updates<=0)
    {
      break;
    }
    else
    {
      // update joint solution by the calculated update (or a partial fraction)
      joint_angles += (dJoint_p + dJoint_a);
      clipToJointLimits(joint_angles);
      min_updates--;
    }
  }

  if (state.iter == max_iter_)
    joint_angles = cached_joint_angles;

  // checking for collision on a valid planning scene
  if(planning_scene && collision_checks_required())
  {
    moveit::core::RobotStatePtr robot_state(new moveit::core::RobotState(planning_scene->getCurrentState()));
    robot_state->setJointGroupPositions(kin_.getJointModelGroup()->getName(),joint_angles);
    robot_state->update();
    if(planning_scene->isStateColliding(*robot_state,kin_.getJointModelGroup()->getName()))
    {
      ROS_ERROR("Robot is in collision at this pose");
    }
  }

  ROS_INFO_STREAM("IK solution: " << joint_angles.transpose());
}

bool Constrained_IK::checkStatus(const constrained_ik::SolverState &state, const constrained_ik::ConstraintResults &primary) const
{
  if (primary.status)
    return true;

  // check maximum iterations
  if (state.iter > max_iter_)
    throw std::runtime_error("Maximum iterations reached.  IK solution may be invalid.");

  // check for joint convergence
  //   - this is an error: joints stabilize, but goal pose not reached
  if (state.joints_delta.cwiseAbs().maxCoeff() < joint_convergence_tol_)
  {
    ROS_WARN_STREAM("Reached " << state.iter << " / " << max_iter_ << " iterations before convergence.");
    return true;
  }

  return false;
}

bool Constrained_IK::checkStatus(const constrained_ik::SolverState &state, const constrained_ik::ConstraintResults &primary, const constrained_ik::ConstraintResults &auxiliary) const
{
  if (primary.status && auxiliary.status)
    return true;

  // check maximum iterations
  if (state.iter > max_iter_)
    throw std::runtime_error("Maximum iterations reached.  IK solution may be invalid.");

  // check for joint convergence
  //   - this is an error: joints stabilize, but goal pose not reached
  if (state.joints_delta.cwiseAbs().maxCoeff() < joint_convergence_tol_)
  {
    ROS_WARN_STREAM("Reached " << state.iter << " / " << max_iter_ << " iterations before convergence.");
    return true;
  }

  return false;
}

void Constrained_IK::clearConstraintList()
{
  primary_constraints_.clear();
  auxiliary_constraints_.clear();
}

void Constrained_IK::clipToJointLimits(Eigen::VectorXd &joints) const
{
  const MatrixXd limits = kin_.getLimits();
  const VectorXd orig_joints(joints);

  if (joints.size() != limits.rows())
    throw std::invalid_argument("clipToJointLimits: Unexpected number of joints");

  for (size_t i=0; i<limits.rows(); ++i)
  {
    joints[i] = std::max(limits(i,0), std::min(limits(i,1), joints[i]));
  }
  if (debug_ && !joints.isApprox(orig_joints))
      ROS_WARN("Joints have been clipped");
}

void Constrained_IK::init(const basic_kin::BasicKin &kin)
{
  if (!kin.checkInitialized())
    throw std::invalid_argument("Input argument 'BasicKin' must be initialized");

  ros::NodeHandle pnh("~");
  pnh.getParam("primary_kp", kpp_);
  pnh.getParam("auxiliary_kp", kpa_);
  ROS_INFO("using primary kp=%f and auxiliary kp=%f", kpp_, kpa_);
  kin_ = kin;
  initialized_ = true;
  primary_constraints_.init(this);
  auxiliary_constraints_.init(this);

}

double Constrained_IK::rangedAngle(double angle)
{
    angle = copysign(fmod(fabs(angle),2.0*M_PI), angle);
    if (angle < -M_PI) return angle+2.*M_PI;
    if (angle > M_PI)  return angle-2.*M_PI;
    return angle;
}

constrained_ik::SolverState Constrained_IK::getState(const Eigen::Affine3d &goal, const Eigen::VectorXd &joint_seed) const
{
  if (!kin_.checkJoints(joint_seed))
    throw std::invalid_argument("Seed doesn't match kinematic model");

  if (!goal.matrix().block(0,0,3,3).isUnitary(1e-6))
        throw std::invalid_argument("Goal pose not proper affine");

  return constrained_ik::SolverState(goal, joint_seed);
}

void Constrained_IK::updateState(constrained_ik::SolverState &state, const Eigen::VectorXd &joints) const
{
  // update maximum iterations
  state.iter++;

  // update joint convergence
  state.joints_delta = joints - state.joints;
  state.joints = joints;
  kin_.calcFwdKin(joints, state.pose_estimate);

  if(state.planning_scene && state.robot_state)
  {
    state.robot_state->setJointGroupPositions(kin_.getJointModelGroup()->getName(), joints);
    state.robot_state->update();
  }

  if (debug_)
      state.iteration_path.push_back(joints);

}

bool Constrained_IK::collision_checks_required() const
{
  return( primary_constraints_.collision_checks_required() | auxiliary_constraints_.collision_checks_required());
}

} // namespace constrained_ik

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: unodoc.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: kz $ $Date: 2004-02-25 17:23:08 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

// System - Includes -----------------------------------------------------

#include <tools/string.hxx>
#include <sfx2/docfac.hxx>

#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif

#include "scmod.hxx"

#ifndef _VOS_MUTEX_HXX_
#include <vos/mutex.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

#include "docsh.hxx"

using namespace ::com::sun::star;

::rtl::OUString SAL_CALL ScDocument_getImplementationName() throw()
{
    return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.SpreadsheetDocument" ) );
}

uno::Sequence< rtl::OUString > SAL_CALL ScDocument_getSupportedServiceNames() throw()
{
    uno::Sequence< rtl::OUString > aSeq( 1 );
    aSeq[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.SpreadsheetDocument" ));
    return aSeq;
}

uno::Reference< uno::XInterface > SAL_CALL ScDocument_createInstance(
                const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
{
    ::vos::OGuard aGuard( Application::GetSolarMutex() );
    ScDLL::Init();
    SfxObjectShell* pShell = new ScDocShell( SFX_CREATE_MODE_STANDARD );
    return uno::Reference< uno::XInterface >( pShell->GetModel() );
}

<commit_msg>INTEGRATION: CWS ooo19126 (1.6.520); FILE MERGED 2005/09/05 15:09:03 rt 1.6.520.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: unodoc.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 22:51:24 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/

// System - Includes -----------------------------------------------------

#include <tools/string.hxx>
#include <sfx2/docfac.hxx>

#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif

#include "scmod.hxx"

#ifndef _VOS_MUTEX_HXX_
#include <vos/mutex.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

#include "docsh.hxx"

using namespace ::com::sun::star;

::rtl::OUString SAL_CALL ScDocument_getImplementationName() throw()
{
    return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Calc.SpreadsheetDocument" ) );
}

uno::Sequence< rtl::OUString > SAL_CALL ScDocument_getSupportedServiceNames() throw()
{
    uno::Sequence< rtl::OUString > aSeq( 1 );
    aSeq[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.SpreadsheetDocument" ));
    return aSeq;
}

uno::Reference< uno::XInterface > SAL_CALL ScDocument_createInstance(
                const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
{
    ::vos::OGuard aGuard( Application::GetSolarMutex() );
    ScDLL::Init();
    SfxObjectShell* pShell = new ScDocShell( SFX_CREATE_MODE_STANDARD );
    return uno::Reference< uno::XInterface >( pShell->GetModel() );
}

<|endoftext|>


<commit_before>/*
* Pedis is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* You may obtain a copy of the License at
*
*     http://www.gnu.org/licenses
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*
*  Copyright (c) 2016-2026, Peng Jian, pstack@163.com. All rights reserved.
*
*/
#pragma once
#include "redis.hh"
#include "db.hh"
#include "redis.hh"
#include "redis_protocol.hh"
#include "core/metrics_registration.hh"
#include "core/thread.hh"
namespace redis {
class server {
private:
    lw_shared_ptr<server_socket> _listener;
    redis_service& _redis;
    uint16_t _port;
    struct connection {
        connected_socket _socket;
        socket_address _addr;
        input_stream<char> _in;
        output_stream<char> _out;
        redis_protocol _proto;
        connection(connected_socket&& socket, socket_address addr, redis_service& redis)
            : _socket(std::move(socket))
              , _addr(addr)
              , _in(_socket.input())
              , _out(_socket.output())
              , _proto(redis)
        {
        }
        ~connection() {
        }
    };
    seastar::metrics::metric_groups _metrics;
    void setup_metrics();
    struct connection_stats {
        uint64_t _new_connection_count = 0;
        uint64_t _alived_connection_count = 0;
    };
    connection_stats _stats;
public:
    server(redis_service& db, uint16_t port = 6379)
        : _redis(db)
        , _port(port)
    {
        setup_metrics();
    }

    void start() {
        listen_options lo;
        lo.reuse_address = true;
        _listener = engine().listen(make_ipv4_address({_port}), lo);
        keep_doing([this] {
           return _listener->accept().then([this] (connected_socket fd, socket_address addr) mutable {
               return seastar::async([this, &fd, addr] {
               ++_stats._new_connection_count;
               ++_stats._alived_connection_count;
               auto conn = make_lw_shared<connection>(std::move(fd), addr, _redis);
               do_until([conn] { return conn->_in.eof(); }, [this, conn] {
                   return conn->_proto.handle(conn->_in, conn->_out).then([conn] {
                       return conn->_out.flush();
                   });
               }).finally([this, conn] {
                   --_stats._alived_connection_count;
                   return conn->_out.close().finally([conn]{});
               });
               });
           });
       }).or_terminate();
    }
    future<> stop() {
        return make_ready_future<>();
    }
};
} /* namespace redis */
<commit_msg>not to process request in the seastar thread code<commit_after>/*
* Pedis is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* You may obtain a copy of the License at
*
*     http://www.gnu.org/licenses
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*
*  Copyright (c) 2016-2026, Peng Jian, pstack@163.com. All rights reserved.
*
*/
#pragma once
#include "redis.hh"
#include "db.hh"
#include "redis.hh"
#include "redis_protocol.hh"
#include "core/metrics_registration.hh"
#include "core/thread.hh"
namespace redis {
class server {
private:
    lw_shared_ptr<server_socket> _listener;
    redis_service& _redis;
    uint16_t _port;
    struct connection {
        connected_socket _socket;
        socket_address _addr;
        input_stream<char> _in;
        output_stream<char> _out;
        redis_protocol _proto;
        connection(connected_socket&& socket, socket_address addr, redis_service& redis)
            : _socket(std::move(socket))
              , _addr(addr)
              , _in(_socket.input())
              , _out(_socket.output())
              , _proto(redis)
        {
        }
        ~connection() {
        }
    };
    seastar::metrics::metric_groups _metrics;
    void setup_metrics();
    struct connection_stats {
        uint64_t _new_connection_count = 0;
        uint64_t _alived_connection_count = 0;
    };
    connection_stats _stats;
public:
    server(redis_service& db, uint16_t port = 6379)
        : _redis(db)
        , _port(port)
    {
        setup_metrics();
    }

    void start() {
        listen_options lo;
        lo.reuse_address = true;
        _listener = engine().listen(make_ipv4_address({_port}), lo);
        keep_doing([this] {
           return _listener->accept().then([this] (connected_socket fd, socket_address addr) mutable {
               ++_stats._new_connection_count;
               ++_stats._alived_connection_count;
               auto conn = make_lw_shared<connection>(std::move(fd), addr, _redis);
               do_until([conn] { return conn->_in.eof(); }, [this, conn] {
                   return conn->_proto.handle(conn->_in, conn->_out).then([conn] {
                       return conn->_out.flush();
                   });
               }).finally([this, conn] {
                   --_stats._alived_connection_count;
                   return conn->_out.close().finally([conn]{});
               });
           });
       }).or_terminate();
    }
    future<> stop() {
        return make_ready_future<>();
    }
};
} /* namespace redis */
<|endoftext|>


<commit_before>#include "rpcruntime_decoded_param.h"
#include "rpcruntime_paramter_description.h"

#include <algorithm>
#include <cassert>
#include <iterator>
#include <sstream>

template <class Container>
struct Reverse_container {
    Reverse_container(Container &container)
        : container(container) {}
    auto begin() {
        return container.rbegin();
    }

    auto end() {
        return container.rend();
    }

    private:
    Container &container;
};

template <class Container>
Reverse_container<Container> reverse_view(Container &container) {
    return {container};
}

RPCRuntimeDecodedParam::RPCRuntimeDecodedParam(const RPCRuntimeParameterDescription &parameter_description, std::string field_id)
    : parameter_description(&parameter_description) {
    this->field_id = field_id;
}

template <class T>
T parse_signed_int(const std::vector<unsigned char> &data) {
    T retval = 0;
    for (auto &chr : reverse_view(data)) {
        retval <<= 8;
        retval |= chr;
    }
    return retval;
}

template <>
uint8_t parse_signed_int<uint8_t>(const std::vector<unsigned char> &data) {
    return data[0];
}

template <>
int8_t parse_signed_int<int8_t>(const std::vector<unsigned char> &data) {
    return data[0];
}

uint64_t RPCRuntimeDecodedParam::as_unsigned_integer() const {
    assert(parameter_description->get_type() == RPCRuntimeParameterDescription::Type::integer);
    assert(parameter_description->as_integer().is_signed == false);
    return parse_signed_int<uint64_t>(data);
}

int64_t RPCRuntimeDecodedParam::as_signed_integer() const {
    assert(parameter_description->get_type() == RPCRuntimeParameterDescription::Type::integer);
    assert(parameter_description->as_integer().is_signed == true);
    switch (data.size()) {
        case 1:
            return parse_signed_int<int8_t>(data);
        case 2:
            return parse_signed_int<int16_t>(data);
        case 4:
            return parse_signed_int<int32_t>(data);
        case 8:
            return parse_signed_int<int64_t>(data);
    }
    throw std::domain_error("RPC: Invalid amount of data to parse signed integer");
}

int64_t RPCRuntimeDecodedParam::as_integer() const {
    assert(parameter_description->get_type() == RPCRuntimeParameterDescription::Type::integer);
    if (parameter_description->as_integer().is_signed == true) {
        return as_signed_integer();
    }
    assert(parameter_description->get_bit_size() < 64); //make sure we don't have a uint64_t, because we cannot represent it fully in an int64_t
    return as_unsigned_integer();
}

Decoded_enum RPCRuntimeDecodedParam::as_enum() const {
    int value = parse_signed_int<int>(data);
    std::string name;
    for (auto &enum_value : parameter_description->as_enumeration().values) {
        if (enum_value.is_int()) {
            if (enum_value.to_int() == value) {
                name = enum_value.name;
                break;
            }
        }
    }
    return {name, value};
}

std::vector<Decoded_struct> RPCRuntimeDecodedParam::as_struct() const {
    std::vector<Decoded_struct> retval;
    assert(parameter_description->get_type() == RPCRuntimeParameterDescription::Type::structure);
    int current_data_position = 0;
    for (auto &member : parameter_description->as_structure().members) {
        retval.push_back({member.get_parameter_name(), {member, field_id + "." + member.get_parameter_name()}});
        auto data_size = member.get_bit_size() / 8;
        retval.back().type.set_data(data.data() + current_data_position, data_size);
        current_data_position += data_size;
    }
    assert(current_data_position == static_cast<int>(data.size()));
    return retval;
}

std::vector<RPCRuntimeDecodedParam> RPCRuntimeDecodedParam::as_array() const {
    std::vector<RPCRuntimeDecodedParam> retval;
    assert(parameter_description->get_type() == RPCRuntimeParameterDescription::Type::array);
    for (int i = 0; i < parameter_description->as_array().number_of_elements; i++) {
        retval.emplace_back(parameter_description->as_array().type, field_id + "." + std::to_string(i));
        retval.back().set_data(data.data() + i * parameter_description->as_array().type.get_bit_size() / 8,
                               parameter_description->as_array().type.get_bit_size() / 8);
    }
    return retval;
}

std::string RPCRuntimeDecodedParam::as_full_string() const {
    std::string retval;
    retval.resize(data.size());
    std::copy(std::begin(data), std::end(data), std::begin(retval));
    return retval;
}

std::string RPCRuntimeDecodedParam::as_string() const {
    std::string retval;
    retval.reserve(data.size());
    for (auto &c : data) {
        if (c == '\0') {
            break;
        }
        retval.push_back(c);
    }
    return retval;
}

std::string RPCRuntimeDecodedParam::get_field_id() const {
    return field_id;
}

const RPCRuntimeParameterDescription *RPCRuntimeDecodedParam::get_desciption() const {
    return parameter_description;
}

void RPCRuntimeDecodedParam::set_data(std::vector<unsigned char> data) {
    this->data = std::move(data);
}

void RPCRuntimeDecodedParam::set_data(const unsigned char *begin, int size) {
    data.resize(size);
    std::copy(begin, begin + size, std::begin(data));
}

std::istream &operator>>(std::istream &is, RPCRuntimeDecodedParam &param) {
    const auto byte_size = param.get_desciption()->get_bit_size() / 8;
    std::vector<unsigned char> data;
    data.resize(byte_size);
    is.read(reinterpret_cast<char *>(data.data()), byte_size);
    if (is) {
        param.set_data(std::move(data));
    }
    return is;
}
<commit_msg>if struct size is not generated correctly in xml, it will be a thrown exception now rather than a failing assert<commit_after>#include "rpcruntime_decoded_param.h"
#include "rpcruntime_paramter_description.h"

#include <algorithm>
#include <cassert>
#include <iterator>
#include <sstream>

template <class Container>
struct Reverse_container {
    Reverse_container(Container &container)
        : container(container) {}
    auto begin() {
        return container.rbegin();
    }

    auto end() {
        return container.rend();
    }

    private:
    Container &container;
};

template <class Container>
Reverse_container<Container> reverse_view(Container &container) {
    return {container};
}

RPCRuntimeDecodedParam::RPCRuntimeDecodedParam(const RPCRuntimeParameterDescription &parameter_description, std::string field_id)
    : parameter_description(&parameter_description) {
    this->field_id = field_id;
}

template <class T>
T parse_signed_int(const std::vector<unsigned char> &data) {
    T retval = 0;
    for (auto &chr : reverse_view(data)) {
        retval <<= 8;
        retval |= chr;
    }
    return retval;
}

template <>
uint8_t parse_signed_int<uint8_t>(const std::vector<unsigned char> &data) {
    return data[0];
}

template <>
int8_t parse_signed_int<int8_t>(const std::vector<unsigned char> &data) {
    return data[0];
}

uint64_t RPCRuntimeDecodedParam::as_unsigned_integer() const {
    assert(parameter_description->get_type() == RPCRuntimeParameterDescription::Type::integer);
    assert(parameter_description->as_integer().is_signed == false);
    return parse_signed_int<uint64_t>(data);
}

int64_t RPCRuntimeDecodedParam::as_signed_integer() const {
    assert(parameter_description->get_type() == RPCRuntimeParameterDescription::Type::integer);
    assert(parameter_description->as_integer().is_signed == true);
    switch (data.size()) {
        case 1:
            return parse_signed_int<int8_t>(data);
        case 2:
            return parse_signed_int<int16_t>(data);
        case 4:
            return parse_signed_int<int32_t>(data);
        case 8:
            return parse_signed_int<int64_t>(data);
    }
    throw std::domain_error("RPC: Invalid amount of data to parse signed integer");
}

int64_t RPCRuntimeDecodedParam::as_integer() const {
    assert(parameter_description->get_type() == RPCRuntimeParameterDescription::Type::integer);
    if (parameter_description->as_integer().is_signed == true) {
        return as_signed_integer();
    }
    assert(parameter_description->get_bit_size() < 64); //make sure we don't have a uint64_t, because we cannot represent it fully in an int64_t
    return as_unsigned_integer();
}

Decoded_enum RPCRuntimeDecodedParam::as_enum() const {
    int value = parse_signed_int<int>(data);
    std::string name;
    for (auto &enum_value : parameter_description->as_enumeration().values) {
        if (enum_value.is_int()) {
            if (enum_value.to_int() == value) {
                name = enum_value.name;
                break;
            }
        }
    }
    return {name, value};
}

std::vector<Decoded_struct> RPCRuntimeDecodedParam::as_struct() const {
    std::vector<Decoded_struct> retval;
    assert(parameter_description->get_type() == RPCRuntimeParameterDescription::Type::structure);
    int current_data_position = 0;
    for (auto &member : parameter_description->as_structure().members) {
        retval.push_back({member.get_parameter_name(), {member, field_id + "." + member.get_parameter_name()}});
        auto data_size = member.get_bit_size() / 8;
        retval.back().type.set_data(data.data() + current_data_position, data_size);
        current_data_position += data_size;
    }
    if (current_data_position != static_cast<int>(data.size())) {
        throw std::runtime_error("RPC struct size messed up. Typename: " + parameter_description->get_parameter_type());
    }
    assert(current_data_position == static_cast<int>(data.size()));
    return retval;
}

std::vector<RPCRuntimeDecodedParam> RPCRuntimeDecodedParam::as_array() const {
    std::vector<RPCRuntimeDecodedParam> retval;
    assert(parameter_description->get_type() == RPCRuntimeParameterDescription::Type::array);
    for (int i = 0; i < parameter_description->as_array().number_of_elements; i++) {
        retval.emplace_back(parameter_description->as_array().type, field_id + "." + std::to_string(i));
        retval.back().set_data(data.data() + i * parameter_description->as_array().type.get_bit_size() / 8,
                               parameter_description->as_array().type.get_bit_size() / 8);
    }
    return retval;
}

std::string RPCRuntimeDecodedParam::as_full_string() const {
    std::string retval;
    retval.resize(data.size());
    std::copy(std::begin(data), std::end(data), std::begin(retval));
    return retval;
}

std::string RPCRuntimeDecodedParam::as_string() const {
    std::string retval;
    retval.reserve(data.size());
    for (auto &c : data) {
        if (c == '\0') {
            break;
        }
        retval.push_back(c);
    }
    return retval;
}

std::string RPCRuntimeDecodedParam::get_field_id() const {
    return field_id;
}

const RPCRuntimeParameterDescription *RPCRuntimeDecodedParam::get_desciption() const {
    return parameter_description;
}

void RPCRuntimeDecodedParam::set_data(std::vector<unsigned char> data) {
    this->data = std::move(data);
}

void RPCRuntimeDecodedParam::set_data(const unsigned char *begin, int size) {
    data.resize(size);
    std::copy(begin, begin + size, std::begin(data));
}

std::istream &operator>>(std::istream &is, RPCRuntimeDecodedParam &param) {
    const auto byte_size = param.get_desciption()->get_bit_size() / 8;
    std::vector<unsigned char> data;
    data.resize(byte_size);
    is.read(reinterpret_cast<char *>(data.data()), byte_size);
    if (is) {
        param.set_data(std::move(data));
    }
    return is;
}
<|endoftext|>


<commit_before>// Copyright (c) 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/third_party/quiche/src/quic/core/frames/quic_new_token_frame.h"
#include "net/third_party/quiche/src/quic/core/quic_constants.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"

namespace quic {

QuicNewTokenFrame::QuicNewTokenFrame()
    : control_frame_id(kInvalidControlFrameId) {}

QuicNewTokenFrame::QuicNewTokenFrame(QuicControlFrameId control_frame_id,
                                     std::string token)
    : control_frame_id(control_frame_id), token(token) {}

std::ostream& operator<<(std::ostream& os, const QuicNewTokenFrame& s) {
  os << "{ control_frame_id: " << s.control_frame_id << ", token: " << s.token
     << " }\n";
  return os;
}

}  // namespace quic
<commit_msg>Fix logging of QuicNewTokenFrame<commit_after>// Copyright (c) 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/third_party/quiche/src/quic/core/frames/quic_new_token_frame.h"

#include "net/third_party/quiche/src/quic/core/quic_constants.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_text_utils.h"

namespace quic {

QuicNewTokenFrame::QuicNewTokenFrame()
    : control_frame_id(kInvalidControlFrameId) {}

QuicNewTokenFrame::QuicNewTokenFrame(QuicControlFrameId control_frame_id,
                                     std::string token)
    : control_frame_id(control_frame_id), token(token) {}

std::ostream& operator<<(std::ostream& os, const QuicNewTokenFrame& s) {
  os << "{ control_frame_id: " << s.control_frame_id
     << ", token: " << QuicTextUtils::HexEncode(s.token) << " }\n";
  return os;
}

}  // namespace quic
<|endoftext|>


<commit_before>/*
 * OSPRayPKDGeometry.cpp
 * Copyright (C) 2009-2017 by MegaMol Team
 * Alle Rechte vorbehalten.
 */

#include "stdafx.h"
#include "OSPRayPKDGeometry.h"
#include "mmcore/Call.h"
#include "mmcore/moldyn/MultiParticleDataCall.h"
#include "mmcore/param/EnumParam.h"
#include "mmcore/param/FloatParam.h"
#include "mmcore/param/IntParam.h"
#include "mmcore/param/Vector3fParam.h"
#include "vislib/forceinline.h"
#include "vislib/sys/Log.h"

#include "mmcore/view/CallClipPlane.h"
#include "mmcore/view/CallGetTransferFunction.h"
#include <ospray.h>
#include "OSPRay_plugin/CallOSPRayAPIObject.h"

namespace megamol {
namespace ospray {

OSPRayPKDGeometry::OSPRayPKDGeometry(void)
    : getDataSlot("getdata", "Connects to the data source")
    , deployStructureSlot("deployStructureSlot", "Connects to an OSPRayAPIStructure")
    , colorTypeSlot("colorType", "Set the type of encoded color") {

    this->getDataSlot.SetCompatibleCall<core::moldyn::MultiParticleDataCallDescription>();
    this->MakeSlotAvailable(&this->getDataSlot);

    auto ep = new megamol::core::param::EnumParam(0);
    ep->SetTypePair(0, "none");
    ep->SetTypePair(1, "RGBu8");
    ep->SetTypePair(2, "RGBAu8");
    ep->SetTypePair(3, "RGBf");
    ep->SetTypePair(4, "RGBAf");
    ep->SetTypePair(5, "I");
    this->colorTypeSlot << ep;
    this->MakeSlotAvailable(&this->colorTypeSlot);

    this->deployStructureSlot.SetCallback(CallOSPRayAPIObject::ClassName(), CallOSPRayAPIObject::FunctionName(0), &OSPRayPKDGeometry::getDataCallback);
    this->deployStructureSlot.SetCallback(CallOSPRayAPIObject::ClassName(), CallOSPRayAPIObject::FunctionName(1), &OSPRayPKDGeometry::getExtendsCallback);
    this->deployStructureSlot.SetCallback(CallOSPRayAPIObject::ClassName(), CallOSPRayAPIObject::FunctionName(2), &OSPRayPKDGeometry::getDirtyCallback);
    this->MakeSlotAvailable(&this->deployStructureSlot);
}

bool OSPRayPKDGeometry::getDataCallback(megamol::core::Call& call) {

    // read Data, calculate  shape parameters, fill data vectors
    auto os = dynamic_cast<CallOSPRayAPIObject*>(&call);
    megamol::core::moldyn::MultiParticleDataCall* cd =
        this->getDataSlot.CallAs<megamol::core::moldyn::MultiParticleDataCall>();

    if (!(*cd)(1)) return false;

    auto const minFrameCount = cd->FrameCount();

    if (minFrameCount == 0) return false;

    auto frameTime = 0;

    if (os->FrameID() >= minFrameCount) {
        cd->SetFrameID(minFrameCount - 1, true); // isTimeForced flag set to true
        frameTime = minFrameCount - 1;
    } else {
        cd->SetFrameID(os->FrameID(), true); // isTimeForced flag set to true
        frameTime = os->FrameID();
    }

    if (this->datahash != cd->DataHash() || this->time != frameTime || this->InterfaceIsDirty()) {
        this->datahash = cd->DataHash();
        this->time = frameTime;
    } else {
        return true;
    }

    if (!(*cd)(1)) return false;
    if (!(*cd)(0)) return false;

    size_t listCount = cd->GetParticleListCount();
    std::vector<OSPGeometry> geo;
    for (size_t i = 0; i < listCount; i++) {

        core::moldyn::MultiParticleDataCall::Particles& parts = cd->AccessParticles(i);

        auto partCount = parts.GetCount();
        auto globalRadius = parts.GetGlobalRadius();
        auto raw = parts.GetVertexData();
        auto boundingBox = parts.GetBBox();

        size_t vertexLength = 3;
        size_t colorLength = 0;

        auto colorType = this->colorTypeSlot.Param<megamol::core::param::EnumParam>()->Value();
        if (colorType != 0) {
            colorLength = 1;
        }

        geo.push_back(ospNewGeometry("pkd_geometry"));

        auto vertexData = ospNewData(partCount, OSP_FLOAT4, raw, OSP_DATA_SHARED_BUFFER);
        ospCommit(vertexData);

        // set bbox
        auto bboxData = ospNewData(6, OSP_FLOAT, boundingBox.PeekBounds(), OSP_DATA_SHARED_BUFFER);
        ospCommit(bboxData);

        ospSet1f(geo.back(), "radius", globalRadius);
        ospSet1i(geo.back(), "colorType", colorType);
        ospSetData(geo.back(), "position", vertexData);
        ospSetData(geo.back(), "bbox", bboxData);
        ospCommit(geo.back());

        // TODO: implement distributed stuff
        // if (this->rd_type.Param<megamol::core::param::EnumParam>()->Value() == MPI_RAYCAST) {
        //    auto const half_radius = element.globalRadius * 0.5f;

        //    auto const bbox = element.boundingBox->ObjectSpaceBBox().PeekBounds(); //< TODO Not all geometries expose
        //    bbox ospcommon::vec3f lower{bbox[0] - half_radius, bbox[1] - half_radius,
        //        bbox[2] - half_radius}; //< TODO The bbox needs to include complete sphere bound
        //    ospcommon::vec3f upper{bbox[3] + half_radius, bbox[4] + half_radius, bbox[5] + half_radius};
        //    // ghostRegions.emplace_back(lower, upper);
        //    worldBounds.extend({lower, upper}); //< TODO Possible hazard if bbox is not centered
        //    regions.emplace_back(lower, upper);
        //}
    }

    std::vector<void*> geo_transfer(geo.size());
    for (auto i = 0; i < geo.size(); i++) {
        geo_transfer[i] = reinterpret_cast<void*>(geo[i]);
    }
    os->setStructureType(GEOMETRY);
    os->setAPIObjects(std::move(geo_transfer));

    return true;
}

OSPRayPKDGeometry::~OSPRayPKDGeometry() { this->Release(); }

bool OSPRayPKDGeometry::create() {
    auto error = ospLoadModule("pkd");
    if (error != OSPError::OSP_NO_ERROR) {
        vislib::sys::Log::DefaultLog.WriteError(
            "Unable to load OSPRay module: PKD. Error occured in %s:%d", __FILE__, __LINE__);
    }
    return true;
}

void OSPRayPKDGeometry::release() {}

/*
ospray::OSPRayPKDGeometry::InterfaceIsDirty()
*/
bool OSPRayPKDGeometry::InterfaceIsDirty() {
    if (this->colorTypeSlot.IsDirty()) {
        this->colorTypeSlot.ResetDirty();
        return true;
    } else {
        return false;
    }
}

bool OSPRayPKDGeometry::InterfaceIsDirtyNoReset() const { return this->colorTypeSlot.IsDirty(); }

bool OSPRayPKDGeometry::getExtendsCallback(core::Call &call) {
    auto os = dynamic_cast<CallOSPRayAPIObject*>(&call);
    core::moldyn::MultiParticleDataCall* cd = this->getDataSlot.CallAs<core::moldyn::MultiParticleDataCall>();

    if (cd == NULL) return false;
    cd->SetFrameID(os->FrameID(), true); // isTimeForced flag set to true
    // if (!(*cd)(1)) return false; // floattable returns flase at first attempt and breaks everything
    (*cd)(1);

    os->SetExtent(cd->FrameCount(), cd->AccessBoundingBoxes());

    return true;
}

bool OSPRayPKDGeometry::getDirtyCallback(core::Call& call) {
    auto os = dynamic_cast<CallOSPRayAPIObject*>(&call);
    auto cd = this->getDataSlot.CallAs<megamol::core::moldyn::MultiParticleDataCall>();

    if (cd == nullptr) return false;
    if (this->InterfaceIsDirtyNoReset()) {
        os->setDirty();
    }
    if (this->datahash != cd->DataHash()) {
        os->SetDataHash(cd->DataHash());
    }
    return true;
}

} // namespace ospray
} // namespace megamol<commit_msg>some cleaning<commit_after>/*
 * OSPRayPKDGeometry.cpp
 * Copyright (C) 2009-2017 by MegaMol Team
 * Alle Rechte vorbehalten.
 */

#include "stdafx.h"
#include "OSPRayPKDGeometry.h"
#include "mmcore/Call.h"
#include "mmcore/moldyn/MultiParticleDataCall.h"
#include "mmcore/param/EnumParam.h"
#include "mmcore/param/FloatParam.h"
#include "mmcore/param/IntParam.h"
#include "mmcore/param/Vector3fParam.h"
#include "vislib/forceinline.h"
#include "vislib/sys/Log.h"

#include <ospray.h>
#include "OSPRay_plugin/CallOSPRayAPIObject.h"
#include "mmcore/view/CallClipPlane.h"
#include "mmcore/view/CallGetTransferFunction.h"

namespace megamol {
namespace ospray {

OSPRayPKDGeometry::OSPRayPKDGeometry(void)
    : getDataSlot("getdata", "Connects to the data source")
    , deployStructureSlot("deployStructureSlot", "Connects to an OSPRayAPIStructure")
    , colorTypeSlot("colorType", "Set the type of encoded color") {

    this->getDataSlot.SetCompatibleCall<core::moldyn::MultiParticleDataCallDescription>();
    this->MakeSlotAvailable(&this->getDataSlot);

    auto ep = new megamol::core::param::EnumParam(0);
    ep->SetTypePair(0, "none");
    ep->SetTypePair(1, "RGBu8");
    ep->SetTypePair(2, "RGBAu8");
    ep->SetTypePair(3, "RGBf");
    ep->SetTypePair(4, "RGBAf");
    ep->SetTypePair(5, "I");
    this->colorTypeSlot << ep;
    this->MakeSlotAvailable(&this->colorTypeSlot);

    this->deployStructureSlot.SetCallback(
        CallOSPRayAPIObject::ClassName(), CallOSPRayAPIObject::FunctionName(0), &OSPRayPKDGeometry::getDataCallback);
    this->deployStructureSlot.SetCallback(
        CallOSPRayAPIObject::ClassName(), CallOSPRayAPIObject::FunctionName(1), &OSPRayPKDGeometry::getExtendsCallback);
    this->deployStructureSlot.SetCallback(
        CallOSPRayAPIObject::ClassName(), CallOSPRayAPIObject::FunctionName(2), &OSPRayPKDGeometry::getDirtyCallback);
    this->MakeSlotAvailable(&this->deployStructureSlot);
}

bool OSPRayPKDGeometry::getDataCallback(megamol::core::Call& call) {

    // read Data, calculate  shape parameters, fill data vectors
    auto os = dynamic_cast<CallOSPRayAPIObject*>(&call);
    megamol::core::moldyn::MultiParticleDataCall* cd =
        this->getDataSlot.CallAs<megamol::core::moldyn::MultiParticleDataCall>();

    if (!(*cd)(1)) return false;

    auto const minFrameCount = cd->FrameCount();

    if (minFrameCount == 0) return false;

    auto frameTime = 0;

    if (os->FrameID() >= minFrameCount) {
        cd->SetFrameID(minFrameCount - 1, true); // isTimeForced flag set to true
        frameTime = minFrameCount - 1;
    } else {
        cd->SetFrameID(os->FrameID(), true); // isTimeForced flag set to true
        frameTime = os->FrameID();
    }

    if (this->datahash != cd->DataHash() || this->time != frameTime || this->InterfaceIsDirty()) {
        this->datahash = cd->DataHash();
        this->time = frameTime;
    } else {
        return true;
    }

    if (!(*cd)(0)) return false;

    size_t listCount = cd->GetParticleListCount();
    std::vector<OSPGeometry> geo;
    for (size_t i = 0; i < listCount; i++) {

        core::moldyn::MultiParticleDataCall::Particles& parts = cd->AccessParticles(i);

        auto colorType = this->colorTypeSlot.Param<megamol::core::param::EnumParam>()->Value();

        geo.push_back(ospNewGeometry("pkd_geometry"));

        auto vertexData = ospNewData(parts.GetCount(), OSP_FLOAT4, parts.GetVertexData(), OSP_DATA_SHARED_BUFFER);
        ospCommit(vertexData);

        // set bbox
        auto bboxData = ospNewData(6, OSP_FLOAT, parts.GetBBox().PeekBounds(), OSP_DATA_SHARED_BUFFER);
        ospCommit(bboxData);

        ospSet1f(geo.back(), "radius", parts.GetGlobalRadius());
        ospSet1i(geo.back(), "colorType", colorType);
        ospSetData(geo.back(), "position", vertexData);
        // ospSetData(geo.back(), "bbox", bboxData);
        ospSetData(geo.back(), "bbox", nullptr);
        ospCommit(geo.back());

        // TODO: implement distributed stuff
        // if (this->rd_type.Param<megamol::core::param::EnumParam>()->Value() == MPI_RAYCAST) {
        //    auto const half_radius = element.globalRadius * 0.5f;

        //    auto const bbox = element.boundingBox->ObjectSpaceBBox().PeekBounds(); //< TODO Not all geometries expose
        //    bbox ospcommon::vec3f lower{bbox[0] - half_radius, bbox[1] - half_radius,
        //        bbox[2] - half_radius}; //< TODO The bbox needs to include complete sphere bound
        //    ospcommon::vec3f upper{bbox[3] + half_radius, bbox[4] + half_radius, bbox[5] + half_radius};
        //    // ghostRegions.emplace_back(lower, upper);
        //    worldBounds.extend({lower, upper}); //< TODO Possible hazard if bbox is not centered
        //    regions.emplace_back(lower, upper);
        //}
    }

    std::vector<void*> geo_transfer(geo.size());
    for (auto i = 0; i < geo.size(); i++) {
        geo_transfer[i] = reinterpret_cast<void*>(geo[i]);
    }
    os->setStructureType(GEOMETRY);
    os->setAPIObjects(std::move(geo_transfer));

    return true;
}

OSPRayPKDGeometry::~OSPRayPKDGeometry() { this->Release(); }

bool OSPRayPKDGeometry::create() {
    auto error = ospLoadModule("pkd");
    if (error != OSPError::OSP_NO_ERROR) {
        vislib::sys::Log::DefaultLog.WriteError(
            "Unable to load OSPRay module: PKD. Error occured in %s:%d", __FILE__, __LINE__);
    }
    return true;
}

void OSPRayPKDGeometry::release() {}

/*
ospray::OSPRayPKDGeometry::InterfaceIsDirty()
*/
bool OSPRayPKDGeometry::InterfaceIsDirty() {
    if (this->colorTypeSlot.IsDirty()) {
        this->colorTypeSlot.ResetDirty();
        return true;
    } else {
        return false;
    }
}

bool OSPRayPKDGeometry::InterfaceIsDirtyNoReset() const { return this->colorTypeSlot.IsDirty(); }

bool OSPRayPKDGeometry::getExtendsCallback(core::Call& call) {
    auto os = dynamic_cast<CallOSPRayAPIObject*>(&call);
    core::moldyn::MultiParticleDataCall* cd = this->getDataSlot.CallAs<core::moldyn::MultiParticleDataCall>();

    if (cd == NULL) return false;
    cd->SetFrameID(os->FrameID(), true); // isTimeForced flag set to true
    // if (!(*cd)(1)) return false; // floattable returns flase at first attempt and breaks everything
    (*cd)(1);

    os->SetExtent(cd->FrameCount(), cd->AccessBoundingBoxes());

    return true;
}

bool OSPRayPKDGeometry::getDirtyCallback(core::Call& call) {
    auto os = dynamic_cast<CallOSPRayAPIObject*>(&call);
    auto cd = this->getDataSlot.CallAs<megamol::core::moldyn::MultiParticleDataCall>();

    if (cd == nullptr) return false;
    if (this->InterfaceIsDirtyNoReset()) {
        os->setDirty();
    }
    if (this->datahash != cd->DataHash()) {
        os->SetDataHash(cd->DataHash());
    }
    return true;
}

} // namespace ospray
} // namespace megamol<|endoftext|>


<commit_before>#include "generated_sger.o.h"

#include <Halide.h>
#include <tiramisu/tiramisu.h>
#include <tiramisu/utils.h>

#include <iostream>
#include "benchmarks.h"

#define M_DIM M
#define N_DIM N

int sger_ref(int n, int m, double alpha, double * A, double* x, double * y)
{
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < m; ++j)
            A[i * m + j] +=  alpha * x[i] * y[j];

    return 0;
}

int main(int argc, char** argv)
{
    std::vector<std::chrono::duration<double, std::milli>> duration_vector_1, duration_vector_2;

    bool run_ref = false, run_tiramisu = false;

    const char* env_ref = std::getenv("RUN_REF");
    if (env_ref != NULL && env_ref[0] == '1')
        run_ref = true;

    const char* env_tiramisu = std::getenv("RUN_TIRAMISU");
    if (env_tiramisu != NULL && env_tiramisu[0] == '1')
        run_tiramisu = true;

    // ---------------------------------------------------------------------
    // ---------------------------------------------------------------------
    // ---------------------------------------------------------------------

    double alpha = 2.0;

    Halide::Buffer<double> b_alpha(1);
    b_alpha(0) = alpha;

    // b_A and b_A_ref needs to be initialized in each iteration test
    Halide::Buffer<double> b_A(N_DIM, M_DIM), b_A_ref(N_DIM, M_DIM);

    Halide::Buffer<double> b_X(N_DIM);
    init_buffer(b_X, (double) 2);

    Halide::Buffer<double> b_Y(M_DIM);
    init_buffer(b_Y, (double) 3);

    /**
    * We have :
    *
    * alpha : equals 2
    * b_X : size N_DIM vector with all values set to 2
    * b_Y : size M_DIM vector with all values set to 3
    * b_A : N_DIM by M_DIM matrix with all values set to 1 (initialized in each loop)
    * b_A_ref : N_DIM by M_DIM matrix with all values set to 1 (initialized in each loop)
    *
    * The result must be a N_DIM by M_DIM with all values equal to 13
    */

    {
        for (int i = 0; i < NB_TESTS; ++i)
        {
            // b_A_ref initialized with 1
            init_buffer(b_A_ref, (double) 1);
            auto start = std::chrono::high_resolution_clock::now();

            if (run_ref)
	    	sger_ref(N_DIM, M_DIM, alpha, b_A_ref.data(), b_X.data(), b_Y.data() );

            auto end = std::chrono::high_resolution_clock::now();
            duration_vector_1.push_back(end - start);
        }
    }

    {
        for (int i = 0; i < NB_TESTS; ++i)
        {
            // b_A initialized with 1
            init_buffer(b_A, (double) 1);

            auto start = std::chrono::high_resolution_clock::now();

            if (run_tiramisu)
	    	sger(b_A.raw_buffer(), b_X.raw_buffer(), b_Y.raw_buffer(), b_alpha.raw_buffer());

            auto end = std::chrono::high_resolution_clock::now();
            duration_vector_2.push_back(end - start);
        }
    }

    print_time("performance_cpu.csv", "sger",
	       {"Ref", "Tiramisu"},
	       {median(duration_vector_1), median(duration_vector_2)});

    if (CHECK_CORRECTNESS && run_ref && run_tiramisu)
        compare_buffers("sger", b_A_ref, b_A);

    if (PRINT_OUTPUT)
    {
        std::cout << "Tiramisu " << std::endl;
        print_buffer(b_A);

        std::cout << "Reference " << std::endl;
        print_buffer(b_A_ref);
    }

    return 0;
}
<commit_msg>remove an extra line<commit_after>#include "generated_sger.o.h"

#include <Halide.h>
#include <tiramisu/tiramisu.h>
#include <tiramisu/utils.h>

#include <iostream>
#include "benchmarks.h"

#define M_DIM M
#define N_DIM N

int sger_ref(int n, int m, double alpha, double * A, double* x, double * y)
{
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < m; ++j)
            A[i * m + j] +=  alpha * x[i] * y[j];

    return 0;
}

int main(int argc, char** argv)
{
    std::vector<std::chrono::duration<double, std::milli>> duration_vector_1, duration_vector_2;

    bool run_ref = false, run_tiramisu = false;

    const char* env_ref = std::getenv("RUN_REF");
    if (env_ref != NULL && env_ref[0] == '1')
        run_ref = true;

    const char* env_tiramisu = std::getenv("RUN_TIRAMISU");
    if (env_tiramisu != NULL && env_tiramisu[0] == '1')
        run_tiramisu = true;

    // ---------------------------------------------------------------------
    // ---------------------------------------------------------------------
    // ---------------------------------------------------------------------

    double alpha = 2.0;

    Halide::Buffer<double> b_alpha(1);
    b_alpha(0) = alpha;

    // b_A and b_A_ref needs to be initialized in each iteration test
    Halide::Buffer<double> b_A(N_DIM, M_DIM), b_A_ref(N_DIM, M_DIM);

    Halide::Buffer<double> b_X(N_DIM);
    init_buffer(b_X, (double) 2);

    Halide::Buffer<double> b_Y(M_DIM);
    init_buffer(b_Y, (double) 3);

    /**
    * We have :
    *
    * alpha : equals 2
    * b_X : size N_DIM vector with all values set to 2
    * b_Y : size M_DIM vector with all values set to 3
    * b_A : N_DIM by M_DIM matrix with all values set to 1 (initialized in each loop)
    * b_A_ref : N_DIM by M_DIM matrix with all values set to 1 (initialized in each loop)
    *
    * The result must be a N_DIM by M_DIM with all values equal to 13
    */

    {
        for (int i = 0; i < NB_TESTS; ++i)
        {
            // b_A_ref initialized with 1
            init_buffer(b_A_ref, (double) 1);
            auto start = std::chrono::high_resolution_clock::now();

            if (run_ref)
	    	sger_ref(N_DIM, M_DIM, alpha, b_A_ref.data(), b_X.data(), b_Y.data() );

            auto end = std::chrono::high_resolution_clock::now();
            duration_vector_1.push_back(end - start);
        }
    }

    {
        for (int i = 0; i < NB_TESTS; ++i)
        {
            // b_A initialized with 1
            init_buffer(b_A, (double) 1);

            auto start = std::chrono::high_resolution_clock::now();

            if (run_tiramisu)
	    	sger(b_A.raw_buffer(), b_X.raw_buffer(), b_Y.raw_buffer(), b_alpha.raw_buffer());

            auto end = std::chrono::high_resolution_clock::now();
            duration_vector_2.push_back(end - start);
        }
    }

    print_time("performance_cpu.csv", "sger",
	       {"Ref", "Tiramisu"},
	       {median(duration_vector_1), median(duration_vector_2)});

    if (CHECK_CORRECTNESS && run_ref && run_tiramisu)
        compare_buffers("sger", b_A_ref, b_A);

    if (PRINT_OUTPUT)
    {
        std::cout << "Tiramisu " << std::endl;
        print_buffer(b_A);

        std::cout << "Reference " << std::endl;
        print_buffer(b_A_ref);
    }

    return 0;
}
<|endoftext|>


<commit_before>//===- TopDownClosure.cpp - Compute the top-down interprocedure closure ---===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the TDDataStructures class, which represents the
// Top-down Interprocedural closure of the data structure graph over the
// program.  This is useful (but not strictly necessary?) for applications
// like pointer analysis.
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/DataStructure.h"
#include "llvm/Module.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Analysis/DSGraph.h"
#include "Support/Debug.h"
#include "Support/Statistic.h"
using namespace llvm;

namespace {
  RegisterAnalysis<TDDataStructures>   // Register the pass
  Y("tddatastructure", "Top-down Data Structure Analysis");

  Statistic<> NumTDInlines("tddatastructures", "Number of graphs inlined");
}

void TDDataStructures::markReachableFunctionsExternallyAccessible(DSNode *N,
                                                   hash_set<DSNode*> &Visited) {
  if (!N || Visited.count(N)) return;
  Visited.insert(N);

  for (unsigned i = 0, e = N->getNumLinks(); i != e; ++i) {
    DSNodeHandle &NH = N->getLink(i*N->getPointerSize());
    if (DSNode *NN = NH.getNode()) {
      const std::vector<GlobalValue*> &Globals = NN->getGlobals();
      for (unsigned G = 0, e = Globals.size(); G != e; ++G)
        if (Function *F = dyn_cast<Function>(Globals[G]))
          ArgsRemainIncomplete.insert(F);

      markReachableFunctionsExternallyAccessible(NN, Visited);
    }
  }
}

// run - Calculate the top down data structure graphs for each function in the
// program.
//
bool TDDataStructures::run(Module &M) {
  BUDataStructures &BU = getAnalysis<BUDataStructures>();
  GlobalsGraph = new DSGraph(BU.getGlobalsGraph());
  GlobalsGraph->setPrintAuxCalls();

  // Figure out which functions must not mark their arguments complete because
  // they are accessible outside this compilation unit.  Currently, these
  // arguments are functions which are reachable by global variables in the
  // globals graph.
  const DSGraph::ScalarMapTy &GGSM = GlobalsGraph->getScalarMap();
  hash_set<DSNode*> Visited;
  for (DSGraph::ScalarMapTy::const_iterator I = GGSM.begin(), E = GGSM.end();
       I != E; ++I)
    if (isa<GlobalValue>(I->first))
      markReachableFunctionsExternallyAccessible(I->second.getNode(), Visited);

  // Loop over unresolved call nodes.  Any functions passed into (but not
  // returned!) from unresolvable call nodes may be invoked outside of the
  // current module.
  const std::vector<DSCallSite> &Calls = GlobalsGraph->getAuxFunctionCalls();
  for (unsigned i = 0, e = Calls.size(); i != e; ++i) {
    const DSCallSite &CS = Calls[i];
    for (unsigned arg = 0, e = CS.getNumPtrArgs(); arg != e; ++arg)
      markReachableFunctionsExternallyAccessible(CS.getPtrArg(arg).getNode(),
                                                 Visited);
  }
  Visited.clear();

  // Functions without internal linkage also have unknown incoming arguments!
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
    if (!I->isExternal() && !I->hasInternalLinkage())
      ArgsRemainIncomplete.insert(I);

  // We want to traverse the call graph in reverse post-order.  To do this, we
  // calculate a post-order traversal, then reverse it.
  hash_set<DSGraph*> VisitedGraph;
  std::vector<DSGraph*> PostOrder;
  const BUDataStructures::ActualCalleesTy &ActualCallees =
    getAnalysis<BUDataStructures>().getActualCallees();

  // Calculate top-down from main...
  if (Function *F = M.getMainFunction())
    ComputePostOrder(*F, VisitedGraph, PostOrder, ActualCallees);

  // Next calculate the graphs for each unreachable function...
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
    ComputePostOrder(*I, VisitedGraph, PostOrder, ActualCallees);

  VisitedGraph.clear();   // Release memory!

  // Visit each of the graphs in reverse post-order now!
  while (!PostOrder.empty()) {
    inlineGraphIntoCallees(*PostOrder.back());
    PostOrder.pop_back();
  }

  ArgsRemainIncomplete.clear();
  return false;
}

DSGraph &TDDataStructures::getOrCreateDSGraph(Function &F) {
  DSGraph *&G = DSInfo[&F];
  if (G == 0) { // Not created yet?  Clone BU graph...
    G = new DSGraph(getAnalysis<BUDataStructures>().getDSGraph(F));
    G->getAuxFunctionCalls().clear();
    G->setPrintAuxCalls();
    G->setGlobalsGraph(GlobalsGraph);
  }
  return *G;
}

void TDDataStructures::ComputePostOrder(Function &F,hash_set<DSGraph*> &Visited,
                                        std::vector<DSGraph*> &PostOrder,
                      const BUDataStructures::ActualCalleesTy &ActualCallees) {
  if (F.isExternal()) return;
  DSGraph &G = getOrCreateDSGraph(F);
  if (Visited.count(&G)) return;
  Visited.insert(&G);

  // Recursively traverse all of the callee graphs.
  const std::vector<DSCallSite> &FunctionCalls = G.getFunctionCalls();

  for (unsigned i = 0, e = FunctionCalls.size(); i != e; ++i) {
    Instruction *CallI = FunctionCalls[i].getCallSite().getInstruction();
    std::pair<BUDataStructures::ActualCalleesTy::const_iterator,
      BUDataStructures::ActualCalleesTy::const_iterator>
         IP = ActualCallees.equal_range(CallI);

    for (BUDataStructures::ActualCalleesTy::const_iterator I = IP.first;
         I != IP.second; ++I)
      ComputePostOrder(*I->second, Visited, PostOrder, ActualCallees);
  }

  PostOrder.push_back(&G);
}

// releaseMemory - If the pass pipeline is done with this pass, we can release
// our memory... here...
//
// FIXME: This should be releaseMemory and will work fine, except that LoadVN
// has no way to extend the lifetime of the pass, which screws up ds-aa.
//
void TDDataStructures::releaseMyMemory() {
  for (hash_map<Function*, DSGraph*>::iterator I = DSInfo.begin(),
         E = DSInfo.end(); I != E; ++I) {
    I->second->getReturnNodes().erase(I->first);
    if (I->second->getReturnNodes().empty())
      delete I->second;
  }

  // Empty map so next time memory is released, data structures are not
  // re-deleted.
  DSInfo.clear();
  delete GlobalsGraph;
  GlobalsGraph = 0;
}

void TDDataStructures::inlineGraphIntoCallees(DSGraph &Graph) {
  // Recompute the Incomplete markers and eliminate unreachable nodes.
  Graph.removeTriviallyDeadNodes();
  Graph.maskIncompleteMarkers();

  // If any of the functions has incomplete incoming arguments, don't mark any
  // of them as complete.
  bool HasIncompleteArgs = false;
  const DSGraph::ReturnNodesTy &GraphReturnNodes = Graph.getReturnNodes();
  for (DSGraph::ReturnNodesTy::const_iterator I = GraphReturnNodes.begin(),
         E = GraphReturnNodes.end(); I != E; ++I)
    if (ArgsRemainIncomplete.count(I->first)) {
      HasIncompleteArgs = true;
      break;
    }

  // Now fold in the necessary globals from the GlobalsGraph.  A global G
  // must be folded in if it exists in the current graph (i.e., is not dead)
  // and it was not inlined from any of my callers.  If it was inlined from
  // a caller, it would have been fully consistent with the GlobalsGraph
  // in the caller so folding in is not necessary.  Otherwise, this node came
  // solely from this function's BU graph and so has to be made consistent.
  //
  Graph.updateFromGlobalGraph();

  // Recompute the Incomplete markers.  Depends on whether args are complete
  unsigned Flags
    = HasIncompleteArgs ? DSGraph::MarkFormalArgs : DSGraph::IgnoreFormalArgs;
  Graph.markIncompleteNodes(Flags | DSGraph::IgnoreGlobals);

  // Delete dead nodes.  Treat globals that are unreachable as dead also.
  Graph.removeDeadNodes(DSGraph::RemoveUnreachableGlobals);

  // We are done with computing the current TD Graph! Now move on to
  // inlining the current graph into the graphs for its callees, if any.
  //
  const std::vector<DSCallSite> &FunctionCalls = Graph.getFunctionCalls();
  if (FunctionCalls.empty()) {
    DEBUG(std::cerr << "  [TD] No callees for: " << Graph.getFunctionNames()
                    << "\n");
    return;
  }

  // Now that we have information about all of the callees, propagate the
  // current graph into the callees.  Clone only the reachable subgraph at
  // each call-site, not the entire graph (even though the entire graph
  // would be cloned only once, this should still be better on average).
  //
  DEBUG(std::cerr << "  [TD] Inlining '" << Graph.getFunctionNames() <<"' into "
                  << FunctionCalls.size() << " call nodes.\n");

  const BUDataStructures::ActualCalleesTy &ActualCallees =
    getAnalysis<BUDataStructures>().getActualCallees();

  // Loop over all the call sites and all the callees at each call site.  Build
  // a mapping from called DSGraph's to the call sites in this function that
  // invoke them.  This is useful because we can be more efficient if there are
  // multiple call sites to the callees in the graph from this caller.
  std::multimap<DSGraph*, std::pair<Function*, const DSCallSite*> > CallSites;

  for (unsigned i = 0, e = FunctionCalls.size(); i != e; ++i) {
    Instruction *CallI = FunctionCalls[i].getCallSite().getInstruction();
    // For each function in the invoked function list at this call site...
    std::pair<BUDataStructures::ActualCalleesTy::const_iterator,
      BUDataStructures::ActualCalleesTy::const_iterator>
          IP = ActualCallees.equal_range(CallI);
    // Loop over each actual callee at this call site
    for (BUDataStructures::ActualCalleesTy::const_iterator I = IP.first;
         I != IP.second; ++I) {
      DSGraph& CalleeGraph = getDSGraph(*I->second);
      assert(&CalleeGraph != &Graph && "TD need not inline graph into self!");

      CallSites.insert(std::make_pair(&CalleeGraph,
                           std::make_pair(I->second, &FunctionCalls[i])));
    }
  }

  // Now that we built the mapping, actually perform the inlining a callee graph
  // at a time.
  std::multimap<DSGraph*,std::pair<Function*,const DSCallSite*> >::iterator CSI;
  for (CSI = CallSites.begin(); CSI != CallSites.end(); ) {
    DSGraph &CalleeGraph = *CSI->first;
    // Iterate through all of the call sites of this graph, cloning and merging
    // any nodes required by the call.
    ReachabilityCloner RC(CalleeGraph, Graph, DSGraph::StripModRefBits);

    // Clone over any global nodes that appear in both graphs.
    for (DSGraph::ScalarMapTy::const_iterator
           SI = CalleeGraph.getScalarMap().begin(),
           SE = CalleeGraph.getScalarMap().end(); SI != SE; ++SI)
      if (GlobalValue *GV = dyn_cast<GlobalValue>(SI->first)) {
        DSGraph::ScalarMapTy::const_iterator GI = Graph.getScalarMap().find(GV);
        if (GI != Graph.getScalarMap().end())
          RC.merge(SI->second, GI->second);
      }

    // Loop over all of the distinct call sites in the caller of the callee.
    for (; CSI != CallSites.end() && CSI->first == &CalleeGraph; ++CSI) {
      Function &CF = *CSI->second.first;
      const DSCallSite &CS = *CSI->second.second;
      DEBUG(std::cerr << "     [TD] Resolving arguments for callee graph '"
            << CalleeGraph.getFunctionNames()
            << "': " << CF.getFunctionType()->getNumParams()
            << " args\n          at call site (DSCallSite*) 0x" << &CS << "\n");

      // Get the formal argument and return nodes for the called function and
      // merge them with the cloned subgraph.
      RC.mergeCallSite(CalleeGraph.getCallSiteForArguments(CF), CS);
      ++NumTDInlines;
    }
  }

  DEBUG(std::cerr << "  [TD] Done inlining into callees for: "
        << Graph.getFunctionNames() << " [" << Graph.getGraphSize() << "+"
        << Graph.getFunctionCalls().size() << "]\n");
}
<commit_msg>In the TD pass, don't iterate over the scalar map to find the globals, iterate over the globals directly.  This doesn't save any substantial time, however, because the globals graph only contains globals!<commit_after>//===- TopDownClosure.cpp - Compute the top-down interprocedure closure ---===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the TDDataStructures class, which represents the
// Top-down Interprocedural closure of the data structure graph over the
// program.  This is useful (but not strictly necessary?) for applications
// like pointer analysis.
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/DataStructure.h"
#include "llvm/Module.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Analysis/DSGraph.h"
#include "Support/Debug.h"
#include "Support/Statistic.h"
using namespace llvm;

namespace {
  RegisterAnalysis<TDDataStructures>   // Register the pass
  Y("tddatastructure", "Top-down Data Structure Analysis");

  Statistic<> NumTDInlines("tddatastructures", "Number of graphs inlined");
}

void TDDataStructures::markReachableFunctionsExternallyAccessible(DSNode *N,
                                                   hash_set<DSNode*> &Visited) {
  if (!N || Visited.count(N)) return;
  Visited.insert(N);

  for (unsigned i = 0, e = N->getNumLinks(); i != e; ++i) {
    DSNodeHandle &NH = N->getLink(i*N->getPointerSize());
    if (DSNode *NN = NH.getNode()) {
      const std::vector<GlobalValue*> &Globals = NN->getGlobals();
      for (unsigned G = 0, e = Globals.size(); G != e; ++G)
        if (Function *F = dyn_cast<Function>(Globals[G]))
          ArgsRemainIncomplete.insert(F);

      markReachableFunctionsExternallyAccessible(NN, Visited);
    }
  }
}

// run - Calculate the top down data structure graphs for each function in the
// program.
//
bool TDDataStructures::run(Module &M) {
  BUDataStructures &BU = getAnalysis<BUDataStructures>();
  GlobalsGraph = new DSGraph(BU.getGlobalsGraph());
  GlobalsGraph->setPrintAuxCalls();

  // Figure out which functions must not mark their arguments complete because
  // they are accessible outside this compilation unit.  Currently, these
  // arguments are functions which are reachable by global variables in the
  // globals graph.
  const DSGraph::ScalarMapTy &GGSM = GlobalsGraph->getScalarMap();
  hash_set<DSNode*> Visited;
  for (DSScalarMap::global_iterator I = GGSM.global_begin(), E = GGSM.global_end();
       I != E; ++I)
    markReachableFunctionsExternallyAccessible(GGSM.find(*I)->second.getNode(), Visited);

  // Loop over unresolved call nodes.  Any functions passed into (but not
  // returned!) from unresolvable call nodes may be invoked outside of the
  // current module.
  const std::vector<DSCallSite> &Calls = GlobalsGraph->getAuxFunctionCalls();
  for (unsigned i = 0, e = Calls.size(); i != e; ++i) {
    const DSCallSite &CS = Calls[i];
    for (unsigned arg = 0, e = CS.getNumPtrArgs(); arg != e; ++arg)
      markReachableFunctionsExternallyAccessible(CS.getPtrArg(arg).getNode(),
                                                 Visited);
  }
  Visited.clear();

  // Functions without internal linkage also have unknown incoming arguments!
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
    if (!I->isExternal() && !I->hasInternalLinkage())
      ArgsRemainIncomplete.insert(I);

  // We want to traverse the call graph in reverse post-order.  To do this, we
  // calculate a post-order traversal, then reverse it.
  hash_set<DSGraph*> VisitedGraph;
  std::vector<DSGraph*> PostOrder;
  const BUDataStructures::ActualCalleesTy &ActualCallees =
    getAnalysis<BUDataStructures>().getActualCallees();

  // Calculate top-down from main...
  if (Function *F = M.getMainFunction())
    ComputePostOrder(*F, VisitedGraph, PostOrder, ActualCallees);

  // Next calculate the graphs for each unreachable function...
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
    ComputePostOrder(*I, VisitedGraph, PostOrder, ActualCallees);

  VisitedGraph.clear();   // Release memory!

  // Visit each of the graphs in reverse post-order now!
  while (!PostOrder.empty()) {
    inlineGraphIntoCallees(*PostOrder.back());
    PostOrder.pop_back();
  }

  ArgsRemainIncomplete.clear();
  return false;
}

DSGraph &TDDataStructures::getOrCreateDSGraph(Function &F) {
  DSGraph *&G = DSInfo[&F];
  if (G == 0) { // Not created yet?  Clone BU graph...
    G = new DSGraph(getAnalysis<BUDataStructures>().getDSGraph(F));
    G->getAuxFunctionCalls().clear();
    G->setPrintAuxCalls();
    G->setGlobalsGraph(GlobalsGraph);
  }
  return *G;
}

void TDDataStructures::ComputePostOrder(Function &F,hash_set<DSGraph*> &Visited,
                                        std::vector<DSGraph*> &PostOrder,
                      const BUDataStructures::ActualCalleesTy &ActualCallees) {
  if (F.isExternal()) return;
  DSGraph &G = getOrCreateDSGraph(F);
  if (Visited.count(&G)) return;
  Visited.insert(&G);

  // Recursively traverse all of the callee graphs.
  const std::vector<DSCallSite> &FunctionCalls = G.getFunctionCalls();

  for (unsigned i = 0, e = FunctionCalls.size(); i != e; ++i) {
    Instruction *CallI = FunctionCalls[i].getCallSite().getInstruction();
    std::pair<BUDataStructures::ActualCalleesTy::const_iterator,
      BUDataStructures::ActualCalleesTy::const_iterator>
         IP = ActualCallees.equal_range(CallI);

    for (BUDataStructures::ActualCalleesTy::const_iterator I = IP.first;
         I != IP.second; ++I)
      ComputePostOrder(*I->second, Visited, PostOrder, ActualCallees);
  }

  PostOrder.push_back(&G);
}

// releaseMemory - If the pass pipeline is done with this pass, we can release
// our memory... here...
//
// FIXME: This should be releaseMemory and will work fine, except that LoadVN
// has no way to extend the lifetime of the pass, which screws up ds-aa.
//
void TDDataStructures::releaseMyMemory() {
  for (hash_map<Function*, DSGraph*>::iterator I = DSInfo.begin(),
         E = DSInfo.end(); I != E; ++I) {
    I->second->getReturnNodes().erase(I->first);
    if (I->second->getReturnNodes().empty())
      delete I->second;
  }

  // Empty map so next time memory is released, data structures are not
  // re-deleted.
  DSInfo.clear();
  delete GlobalsGraph;
  GlobalsGraph = 0;
}

void TDDataStructures::inlineGraphIntoCallees(DSGraph &Graph) {
  // Recompute the Incomplete markers and eliminate unreachable nodes.
  Graph.removeTriviallyDeadNodes();
  Graph.maskIncompleteMarkers();

  // If any of the functions has incomplete incoming arguments, don't mark any
  // of them as complete.
  bool HasIncompleteArgs = false;
  const DSGraph::ReturnNodesTy &GraphReturnNodes = Graph.getReturnNodes();
  for (DSGraph::ReturnNodesTy::const_iterator I = GraphReturnNodes.begin(),
         E = GraphReturnNodes.end(); I != E; ++I)
    if (ArgsRemainIncomplete.count(I->first)) {
      HasIncompleteArgs = true;
      break;
    }

  // Now fold in the necessary globals from the GlobalsGraph.  A global G
  // must be folded in if it exists in the current graph (i.e., is not dead)
  // and it was not inlined from any of my callers.  If it was inlined from
  // a caller, it would have been fully consistent with the GlobalsGraph
  // in the caller so folding in is not necessary.  Otherwise, this node came
  // solely from this function's BU graph and so has to be made consistent.
  //
  Graph.updateFromGlobalGraph();

  // Recompute the Incomplete markers.  Depends on whether args are complete
  unsigned Flags
    = HasIncompleteArgs ? DSGraph::MarkFormalArgs : DSGraph::IgnoreFormalArgs;
  Graph.markIncompleteNodes(Flags | DSGraph::IgnoreGlobals);

  // Delete dead nodes.  Treat globals that are unreachable as dead also.
  Graph.removeDeadNodes(DSGraph::RemoveUnreachableGlobals);

  // We are done with computing the current TD Graph! Now move on to
  // inlining the current graph into the graphs for its callees, if any.
  //
  const std::vector<DSCallSite> &FunctionCalls = Graph.getFunctionCalls();
  if (FunctionCalls.empty()) {
    DEBUG(std::cerr << "  [TD] No callees for: " << Graph.getFunctionNames()
                    << "\n");
    return;
  }

  // Now that we have information about all of the callees, propagate the
  // current graph into the callees.  Clone only the reachable subgraph at
  // each call-site, not the entire graph (even though the entire graph
  // would be cloned only once, this should still be better on average).
  //
  DEBUG(std::cerr << "  [TD] Inlining '" << Graph.getFunctionNames() <<"' into "
                  << FunctionCalls.size() << " call nodes.\n");

  const BUDataStructures::ActualCalleesTy &ActualCallees =
    getAnalysis<BUDataStructures>().getActualCallees();

  // Loop over all the call sites and all the callees at each call site.  Build
  // a mapping from called DSGraph's to the call sites in this function that
  // invoke them.  This is useful because we can be more efficient if there are
  // multiple call sites to the callees in the graph from this caller.
  std::multimap<DSGraph*, std::pair<Function*, const DSCallSite*> > CallSites;

  for (unsigned i = 0, e = FunctionCalls.size(); i != e; ++i) {
    Instruction *CallI = FunctionCalls[i].getCallSite().getInstruction();
    // For each function in the invoked function list at this call site...
    std::pair<BUDataStructures::ActualCalleesTy::const_iterator,
      BUDataStructures::ActualCalleesTy::const_iterator>
          IP = ActualCallees.equal_range(CallI);
    // Loop over each actual callee at this call site
    for (BUDataStructures::ActualCalleesTy::const_iterator I = IP.first;
         I != IP.second; ++I) {
      DSGraph& CalleeGraph = getDSGraph(*I->second);
      assert(&CalleeGraph != &Graph && "TD need not inline graph into self!");

      CallSites.insert(std::make_pair(&CalleeGraph,
                           std::make_pair(I->second, &FunctionCalls[i])));
    }
  }

  // Now that we built the mapping, actually perform the inlining a callee graph
  // at a time.
  std::multimap<DSGraph*,std::pair<Function*,const DSCallSite*> >::iterator CSI;
  for (CSI = CallSites.begin(); CSI != CallSites.end(); ) {
    DSGraph &CalleeGraph = *CSI->first;
    // Iterate through all of the call sites of this graph, cloning and merging
    // any nodes required by the call.
    ReachabilityCloner RC(CalleeGraph, Graph, DSGraph::StripModRefBits);

    // Clone over any global nodes that appear in both graphs.
    for (DSGraph::ScalarMapTy::const_iterator
           SI = CalleeGraph.getScalarMap().begin(),
           SE = CalleeGraph.getScalarMap().end(); SI != SE; ++SI)
      if (GlobalValue *GV = dyn_cast<GlobalValue>(SI->first)) {
        DSGraph::ScalarMapTy::const_iterator GI = Graph.getScalarMap().find(GV);
        if (GI != Graph.getScalarMap().end())
          RC.merge(SI->second, GI->second);
      }

    // Loop over all of the distinct call sites in the caller of the callee.
    for (; CSI != CallSites.end() && CSI->first == &CalleeGraph; ++CSI) {
      Function &CF = *CSI->second.first;
      const DSCallSite &CS = *CSI->second.second;
      DEBUG(std::cerr << "     [TD] Resolving arguments for callee graph '"
            << CalleeGraph.getFunctionNames()
            << "': " << CF.getFunctionType()->getNumParams()
            << " args\n          at call site (DSCallSite*) 0x" << &CS << "\n");

      // Get the formal argument and return nodes for the called function and
      // merge them with the cloned subgraph.
      RC.mergeCallSite(CalleeGraph.getCallSiteForArguments(CF), CS);
      ++NumTDInlines;
    }
  }

  DEBUG(std::cerr << "  [TD] Done inlining into callees for: "
        << Graph.getFunctionNames() << " [" << Graph.getGraphSize() << "+"
        << Graph.getFunctionCalls().size() << "]\n");
}
<|endoftext|>


<commit_before>#include <iostream>
#include <string>

#include "Timer.h"
#include "InputFileStream.h"
#include "LexicalReorderingTable.h"

using namespace Moses;

Timer timer;

void printHelp()
{
  std::cerr << "Usage:\n"
            "options: \n"
            "\t-in  string -- input table file name\n"
            "\t-out string -- prefix of binary table files\n"
            "If -in is not specified reads from stdin\n"
            "\n";
}

int main(int argc, char** argv)
{
  std::cerr << "processLexicalTable v0.1 by Konrad Rawlik\n";
  std::string inFilePath;
  std::string outFilePath("out");
  if(1 >= argc) {
    printHelp();
    return 1;
  }
  for(int i = 1; i < argc; ++i) {
    std::string arg(argv[i]);
    if("-in" == arg && i+1 < argc) {
      ++i;
      inFilePath = argv[i];
    } else if("-out" == arg && i+1 < argc) {
      ++i;
      outFilePath = argv[i];
    } else {
      //somethings wrong... print help
      printHelp();
      return 1;
    }
  }

  if(inFilePath.empty()) {
    std::cerr << "processing stdin to " << outFilePath << ".*\n";
    return LexicalReorderingTableTree::Create(std::cin, outFilePath);
  } else {
    std::cerr << "processing " << inFilePath<< " to " << outFilePath << ".*\n";
    InputFileStream file(inFilePath);
    return LexicalReorderingTableTree::Create(file, outFilePath);
  }
}
<commit_msg>Return 0 on success and 1 on fail. Not the other way around.<commit_after>#include <iostream>
#include <string>

#include "Timer.h"
#include "InputFileStream.h"
#include "LexicalReorderingTable.h"

using namespace Moses;

Timer timer;

void printHelp()
{
  std::cerr << "Usage:\n"
            "options: \n"
            "\t-in  string -- input table file name\n"
            "\t-out string -- prefix of binary table files\n"
            "If -in is not specified reads from stdin\n"
            "\n";
}

int main(int argc, char** argv)
{
  std::cerr << "processLexicalTable v0.1 by Konrad Rawlik\n";
  std::string inFilePath;
  std::string outFilePath("out");
  if(1 >= argc) {
    printHelp();
    return 1;
  }
  for(int i = 1; i < argc; ++i) {
    std::string arg(argv[i]);
    if("-in" == arg && i+1 < argc) {
      ++i;
      inFilePath = argv[i];
    } else if("-out" == arg && i+1 < argc) {
      ++i;
      outFilePath = argv[i];
    } else {
      //somethings wrong... print help
      printHelp();
      return 1;
    }
  }

  if(inFilePath.empty()) {
    std::cerr << "processing stdin to " << outFilePath << ".*\n";
    return LexicalReorderingTableTree::Create(std::cin, outFilePath);
  } else {
    std::cerr << "processing " << inFilePath<< " to " << outFilePath << ".*\n";
    InputFileStream file(inFilePath);
    bool success = LexicalReorderingTableTree::Create(file, outFilePath);
    return (success ? 0 : 1);
  }
}
<|endoftext|>