<commit_before>#include <iostream>
#include <stdio.h>
#include <signal.h>
#include <math.h>

#include <boost/shared_ptr.hpp>
#include <lcm/lcm-cpp.hpp>

#include <bot_core/bot_core.h>
#include <lcmtypes/bot_core.hpp>
#include <lcmtypes/drc_lcmtypes.hpp>

#include <Eigen/Dense>
#include <Eigen/StdVector>
#include <pointcloud_tools/pointcloud_math.hpp>

#include <ConciseArgs>

using namespace std;

class Pass{
  public:
    Pass(boost::shared_ptr<lcm::LCM> &lcm_, int stage_, int mode_, int footsteps_);

    ~Pass(){
    }

  private:
    int verbose_;
    boost::shared_ptr<lcm::LCM> lcm_;
    void robotStateHandler(const lcm::ReceiveBuffer* rbuf, const std::string& channel, const  drc::robot_state_t* msg);
    void candidateFootstepPlanHandler(const lcm::ReceiveBuffer* rbuf, const std::string& channel, const  drc::footstep_plan_t* msg);
    void candidateRobotPlanHandler(const lcm::ReceiveBuffer* rbuf, const std::string& channel, const  drc::robot_plan_t* msg);
    void controllerStatusHandler(const lcm::ReceiveBuffer* rbuf, const std::string& channel, const  drc::controller_status_t* msg);

    void sendDataRequests(int64_t this_utime);

    Eigen::Isometry3d getRandomGoal();
    int stage_;
    int mode_;
    std::vector<std::string> mode_names_;
    int test_counter_;

    int footsteps_;

    drc::footstep_plan_t last_footstep_msg_;

    bool was_walking_last_;
};

Pass::Pass(boost::shared_ptr<lcm::LCM> &lcm_, int stage_, int mode_, int footsteps_):
    lcm_(lcm_), stage_(stage_), mode_(mode_), footsteps_(footsteps_){

  lcm_->subscribe( "EST_ROBOT_STATE" ,&Pass::robotStateHandler,this);
  lcm_->subscribe("CANDIDATE_FOOTSTEP_PLAN",&Pass::candidateFootstepPlanHandler,this);
  lcm_->subscribe("CANDIDATE_ROBOT_PLAN",&Pass::candidateRobotPlanHandler,this);
  lcm_->subscribe("CONTROLLER_STATUS",&Pass::controllerStatusHandler,this);
  srand (time(NULL)); // random seed
  test_counter_=0;

  mode_names_.push_back("straight");
  mode_names_.push_back("left");
  mode_names_.push_back("right");

  // Initial request for height map
  sendDataRequests(0);
  sleep(1);

  was_walking_last_=false;
}

// get the robots position and rotation in rpy
Eigen::Isometry3d Pass::getRandomGoal(){
    float dx=0.0;
    float dy=0.0;
    float dyaw=0.0;

    // plus or minus
    float nx=1.0;
    float ny=1.0;
    float nyaw = 0.5;  // was 1
    if (mode_==0){
      dx = 3.0 + (float)  nx*2*( ((float) rand ()/(RAND_MAX)) -0.5);
      dy = 0.0 + (float)  ny*2*( ((float) rand ()/(RAND_MAX)) -0.5);
      dyaw = 0.0 + (float) nyaw*2*( ((float) rand ()/(RAND_MAX)) -0.5); // -/+28degrees
    }else if(mode_==1){
      dx = 3.0 + (float)  nx*2*( ((float) rand ()/(RAND_MAX)) -0.5);
      dy = 3.0 + (float)  ny*2*( ((float) rand ()/(RAND_MAX)) -0.5);
      dyaw = 0.75 + (float)  nyaw*2*( ((float) rand ()/(RAND_MAX)) -0.5);
    }else if(mode_==2){
      dx =  3.0 + (float)  nx*2*( ((float) rand ()/(RAND_MAX)) -0.5);
      dy = -3.0 + (float)  ny*2*( ((float) rand ()/(RAND_MAX)) -0.5);
      dyaw = -0.75 + (float)  nyaw*( ((float) rand ()/(RAND_MAX)) -0.5);
    }else if(mode_==3){ // this doesnt work - too random
      dx =   100.0*( ((float) rand ()/(RAND_MAX)) -0.5);
      dy =   100.0*( ((float) rand ()/(RAND_MAX)) -0.5);
      dyaw = 100.0 + (float)  nyaw*( ((float) rand ()/(RAND_MAX)) -0.5);
    }

    Eigen::Isometry3d delta_pose;
    delta_pose.setIdentity();
    delta_pose.translation()  << dx, dy, 0.0;
    delta_pose.rotate( euler_to_quat(dyaw, 0,0) );

    std::cout << "Stage 0: DX: " << dx << " DY " << dy << " DYAW: " << 180.0*dyaw/M_PI <<"\n";
    return delta_pose;
}

void Pass::robotStateHandler(const lcm::ReceiveBuffer* rbuf,
                        const std::string& channel, const  drc::robot_state_t* msg){
  if (msg->utime < 5*1E6){
    sendDataRequests(msg->utime);
  }
  if (stage_==0){
    sendDataRequests(msg->utime);

    Eigen::Isometry3d current_pose;
    current_pose.setIdentity();
    current_pose.translation()  << msg->origin_position.translation.x, msg->origin_position.translation.y, msg->origin_position.translation.z;
    Eigen::Quaterniond quat_in = Eigen::Quaterniond( msg->origin_position.rotation.w, msg->origin_position.rotation.x,
                     msg->origin_position.rotation.y, msg->origin_position.rotation.z);
    current_pose.rotate(quat_in);
    Eigen::Isometry3d goal_pose = current_pose*getRandomGoal();

    ////////////////////////////////
    drc::walking_goal_t goal;
    goal.utime  = msg->utime;
    goal.robot_name = "atlas";
    drc::position_3d_t goal_pos;
    drc::vector_3d_t trans;// = drc_vector_3d_t();
    trans.x =  goal_pose.translation().x();
    trans.y =  goal_pose.translation().y();
    trans.z = 0.0;
    goal_pos.translation = trans;
    drc::quaternion_t quat;
    Eigen::Quaterniond quat_out = Eigen::Quaterniond(goal_pose.rotation());
    quat.w = quat_out.w();
    quat.x = quat_out.x();
    quat.y = quat_out.y();
    quat.z = quat_out.z();
    goal_pos.rotation = quat;
    goal.goal_pos = goal_pos;
    goal.max_num_steps = footsteps_;
    goal.min_num_steps = 0;
    goal.timeout = 0;
    goal.step_speed = 0.5;
    goal.step_height = 0.05;
    goal.follow_spline = true;
    goal.ignore_terrain = false;
    goal.mu = 1.0;
    goal.allow_optimization = false;
    goal.is_new_goal = true;
    goal.right_foot_lead = true;
    lcm_->publish("WALKING_GOAL", &goal);

    sleep(5); // added to make sure that the footstep plane is new before accepting it, could be smaller?
    stage_=1;
    std::cout << "Stage 0: got EST_ROBOT_STATE, publishing WALKING_GOAL. Moving to Stage 1\n";
    std::cout << "         Mode: " << mode_names_[mode_] << " | Sequence: " << test_counter_ <<"\n";

    test_counter_ ++;
    // Walk 5 steps per mode:
    bool vary_mode=false;
    if (vary_mode){
      if (test_counter_ >= 5){
	test_counter_=0;
	mode_++;
	if (mode_>2){ mode_=0; }
	  std::cout << "         Next time the mode will be: " << mode_names_[mode_]  <<"\n";
      }
    }
  }
}

void Pass::candidateFootstepPlanHandler(const lcm::ReceiveBuffer* rbuf,
                             const std::string& channel, const  drc::footstep_plan_t* msg){
  if (stage_==1){
    sendDataRequests(msg->utime);
    sleep(1);
    lcm_->publish("APPROVED_FOOTSTEP_PLAN", msg );
    last_footstep_msg_ = *msg;
    stage_ =2;
    std::cout << "Stage 1: got CANDIDATE_FOOTSTEP_PLAN, republishing as COMMITTED. Moving to Stage 2\n";
  }
}

void Pass::candidateRobotPlanHandler(const lcm::ReceiveBuffer* rbuf,
                             const std::string& channel, const  drc::robot_plan_t* msg){
  if (stage_==2){
    sendDataRequests(msg->utime);
    sleep(1); // this was required as matlab was too slow to receive it immediately
    //lcm_->publish("COMMITTED_ROBOT_PLAN", msg );
    lcm_->publish("COMMITTED_FOOTSTEP_PLAN", &last_footstep_msg_ );
    stage_ =3;
    std::cout << "Stage 2: got CANDIDATE_ROBOT_PLAN, republishing as COMMITTED. Moving to Stage 3\n";
    std::cout << "         Sleeping for 45seconds until to allow walking to start\n";
    sleep(45);
    std::cout << "         Finished sleeping\n";
  }
}

void Pass::controllerStatusHandler(const lcm::ReceiveBuffer* rbuf,
                             const std::string& channel, const  drc::controller_status_t* msg){
  if (stage_==3){

    // if standing now but was walking before:
    if ((msg->state== drc::controller_status_t::STANDING)&&(was_walking_last_)){
      sendDataRequests(msg->utime);
      stage_ =0;
      std::cout << "Stage 3: controller=STANDING, restarting. Moving to Stage 0\n"
                << "===========================================================\n";
    }

    if (msg->state == drc::controller_status_t::WALKING){
      was_walking_last_ = true;
    }else{
      was_walking_last_ = false;
    }

  }
}

// Send this to make sure what we need is being published for the planner:
void Pass::sendDataRequests(int64_t this_utime){
  drc::data_request_list_t reqs;
  reqs.utime = this_utime;
  drc::data_request_t req1; //EST_ROBOT_STATE
  req1.period = 10;
  req1.type = drc::data_request_t::MINIMAL_ROBOT_STATE;
  drc::data_request_t req2; // Planning Height Map
  req2.period = 10;
  req2.type = drc::data_request_t::HEIGHT_MAP_SCENE;
  reqs.requests.push_back(req1);
  reqs.requests.push_back(req2);
  reqs.num_requests = reqs.requests.size();
  lcm_->publish("DATA_REQUEST", &reqs);
}

int main(int argc, char ** argv) {
  int verbose = 0;
  int stage = 3;
  int mode = 0;
  int footsteps = 6;
  ConciseArgs opt(argc, (char**)argv);
  opt.add(verbose, "v", "verbosity","0 none, 1 little, 2 debug");
  opt.add(stage, "s", "stage","Starting Stage");
  opt.add(mode, "m", "mode","Mode 0forward 1left 2right");// 3random");
  opt.add(footsteps, "f", "footsteps","Number of Footsteps");// 3random");
  opt.parse();
  std::cout << "verbose: " << verbose << "\n";
  std::cout << "stage: " << stage << "\n";
  std::cout << "mode: " << mode << " [where 0forward 1left 2right\n";//3random]\n";
  std::cout << "footsteps: " << footsteps << " footsteps\n";

  boost::shared_ptr<lcm::LCM> lcm(new lcm::LCM);
  if(!lcm->good()){
    std::cerr <<"ERROR: lcm is not good()" <<std::endl;
  }

  Pass app(lcm, stage, mode, footsteps);
  cout << "System Test Ready" << endl << "============================" << endl;
  while(0 == lcm->handle());
  return 0;
}
<commit_msg>adding slight sleep<commit_after>#include <iostream>
#include <stdio.h>
#include <signal.h>
#include <math.h>

#include <boost/shared_ptr.hpp>
#include <lcm/lcm-cpp.hpp>

#include <bot_core/bot_core.h>
#include <lcmtypes/bot_core.hpp>
#include <lcmtypes/drc_lcmtypes.hpp>

#include <Eigen/Dense>
#include <Eigen/StdVector>
#include <pointcloud_tools/pointcloud_math.hpp>

#include <ConciseArgs>

using namespace std;

class Pass{
  public:
    Pass(boost::shared_ptr<lcm::LCM> &lcm_, int stage_, int mode_, int footsteps_);

    ~Pass(){
    }

  private:
    int verbose_;
    boost::shared_ptr<lcm::LCM> lcm_;
    void robotStateHandler(const lcm::ReceiveBuffer* rbuf, const std::string& channel, const  drc::robot_state_t* msg);
    void candidateFootstepPlanHandler(const lcm::ReceiveBuffer* rbuf, const std::string& channel, const  drc::footstep_plan_t* msg);
    void candidateRobotPlanHandler(const lcm::ReceiveBuffer* rbuf, const std::string& channel, const  drc::robot_plan_t* msg);
    void controllerStatusHandler(const lcm::ReceiveBuffer* rbuf, const std::string& channel, const  drc::controller_status_t* msg);

    void sendDataRequests(int64_t this_utime);

    Eigen::Isometry3d getRandomGoal();
    int stage_;
    int mode_;
    std::vector<std::string> mode_names_;
    int test_counter_;

    int footsteps_;

    drc::footstep_plan_t last_footstep_msg_;

    bool was_walking_last_;
};

Pass::Pass(boost::shared_ptr<lcm::LCM> &lcm_, int stage_, int mode_, int footsteps_):
    lcm_(lcm_), stage_(stage_), mode_(mode_), footsteps_(footsteps_){

  lcm_->subscribe( "EST_ROBOT_STATE" ,&Pass::robotStateHandler,this);
  lcm_->subscribe("CANDIDATE_FOOTSTEP_PLAN",&Pass::candidateFootstepPlanHandler,this);
  lcm_->subscribe("CANDIDATE_ROBOT_PLAN",&Pass::candidateRobotPlanHandler,this);
  lcm_->subscribe("CONTROLLER_STATUS",&Pass::controllerStatusHandler,this);
  srand (time(NULL)); // random seed
  test_counter_=0;

  mode_names_.push_back("straight");
  mode_names_.push_back("left");
  mode_names_.push_back("right");

  // Initial request for height map
  sendDataRequests(0);
  sleep(1);

  was_walking_last_=false;
}

// get the robots position and rotation in rpy
Eigen::Isometry3d Pass::getRandomGoal(){
    float dx=0.0;
    float dy=0.0;
    float dyaw=0.0;

    // plus or minus
    float nx=1.0;
    float ny=1.0;
    float nyaw = 0.5;  // was 1
    if (mode_==0){
      dx = 3.0 + (float)  nx*2*( ((float) rand ()/(RAND_MAX)) -0.5);
      dy = 0.0 + (float)  ny*2*( ((float) rand ()/(RAND_MAX)) -0.5);
      dyaw = 0.0 + (float) nyaw*2*( ((float) rand ()/(RAND_MAX)) -0.5); // -/+28degrees
    }else if(mode_==1){
      dx = 3.0 + (float)  nx*2*( ((float) rand ()/(RAND_MAX)) -0.5);
      dy = 3.0 + (float)  ny*2*( ((float) rand ()/(RAND_MAX)) -0.5);
      dyaw = 0.75 + (float)  nyaw*2*( ((float) rand ()/(RAND_MAX)) -0.5);
    }else if(mode_==2){
      dx =  3.0 + (float)  nx*2*( ((float) rand ()/(RAND_MAX)) -0.5);
      dy = -3.0 + (float)  ny*2*( ((float) rand ()/(RAND_MAX)) -0.5);
      dyaw = -0.75 + (float)  nyaw*( ((float) rand ()/(RAND_MAX)) -0.5);
    }else if(mode_==3){ // this doesnt work - too random
      dx =   100.0*( ((float) rand ()/(RAND_MAX)) -0.5);
      dy =   100.0*( ((float) rand ()/(RAND_MAX)) -0.5);
      dyaw = 100.0 + (float)  nyaw*( ((float) rand ()/(RAND_MAX)) -0.5);
    }

    Eigen::Isometry3d delta_pose;
    delta_pose.setIdentity();
    delta_pose.translation()  << dx, dy, 0.0;
    delta_pose.rotate( euler_to_quat(dyaw, 0,0) );

    std::cout << "Stage 0: DX: " << dx << " DY " << dy << " DYAW: " << 180.0*dyaw/M_PI <<"\n";
    return delta_pose;
}

void Pass::robotStateHandler(const lcm::ReceiveBuffer* rbuf,
                        const std::string& channel, const  drc::robot_state_t* msg){
  if (msg->utime < 5*1E6){
    sendDataRequests(msg->utime);
  }
  if (stage_==0){
    sendDataRequests(msg->utime);
    sleep(2);

    Eigen::Isometry3d current_pose;
    current_pose.setIdentity();
    current_pose.translation()  << msg->origin_position.translation.x, msg->origin_position.translation.y, msg->origin_position.translation.z;
    Eigen::Quaterniond quat_in = Eigen::Quaterniond( msg->origin_position.rotation.w, msg->origin_position.rotation.x,
                     msg->origin_position.rotation.y, msg->origin_position.rotation.z);
    current_pose.rotate(quat_in);
    Eigen::Isometry3d goal_pose = current_pose*getRandomGoal();

    ////////////////////////////////
    drc::walking_goal_t goal;
    goal.utime  = msg->utime;
    goal.robot_name = "atlas";
    drc::position_3d_t goal_pos;
    drc::vector_3d_t trans;// = drc_vector_3d_t();
    trans.x =  goal_pose.translation().x();
    trans.y =  goal_pose.translation().y();
    trans.z = 0.0;
    goal_pos.translation = trans;
    drc::quaternion_t quat;
    Eigen::Quaterniond quat_out = Eigen::Quaterniond(goal_pose.rotation());
    quat.w = quat_out.w();
    quat.x = quat_out.x();
    quat.y = quat_out.y();
    quat.z = quat_out.z();
    goal_pos.rotation = quat;
    goal.goal_pos = goal_pos;
    goal.max_num_steps = footsteps_;
    goal.min_num_steps = 0;
    goal.timeout = 0;
    goal.step_speed = 0.5;
    goal.step_height = 0.05;
    goal.follow_spline = true;
    goal.ignore_terrain = false;
    goal.mu = 1.0;
    goal.allow_optimization = false;
    goal.is_new_goal = true;
    goal.right_foot_lead = true;
    lcm_->publish("WALKING_GOAL", &goal);

    sleep(5); // added to make sure that the footstep plane is new before accepting it, could be smaller?
    stage_=1;
    std::cout << "Stage 0: got EST_ROBOT_STATE, publishing WALKING_GOAL. Moving to Stage 1\n";
    std::cout << "         Mode: " << mode_names_[mode_] << " | Sequence: " << test_counter_ <<"\n";

    test_counter_ ++;
    // Walk 5 steps per mode:
    bool vary_mode=false;
    if (vary_mode){
      if (test_counter_ >= 5){
	test_counter_=0;
	mode_++;
	if (mode_>2){ mode_=0; }
	  std::cout << "         Next time the mode will be: " << mode_names_[mode_]  <<"\n";
      }
    }
  }
}

void Pass::candidateFootstepPlanHandler(const lcm::ReceiveBuffer* rbuf,
                             const std::string& channel, const  drc::footstep_plan_t* msg){
  if (stage_==1){
    sendDataRequests(msg->utime);
    sleep(1);
    lcm_->publish("APPROVED_FOOTSTEP_PLAN", msg );
    last_footstep_msg_ = *msg;
    stage_ =2;
    std::cout << "Stage 1: got CANDIDATE_FOOTSTEP_PLAN, republishing as COMMITTED. Moving to Stage 2\n";
  }
}

void Pass::candidateRobotPlanHandler(const lcm::ReceiveBuffer* rbuf,
                             const std::string& channel, const  drc::robot_plan_t* msg){
  if (stage_==2){
    sendDataRequests(msg->utime);
    sleep(1); // this was required as matlab was too slow to receive it immediately
    //lcm_->publish("COMMITTED_ROBOT_PLAN", msg );
    lcm_->publish("COMMITTED_FOOTSTEP_PLAN", &last_footstep_msg_ );
    stage_ =3;
    std::cout << "Stage 2: got CANDIDATE_ROBOT_PLAN, republishing as COMMITTED. Moving to Stage 3\n";
    std::cout << "         Sleeping for 45seconds until to allow walking to start\n";
    sleep(45);
    std::cout << "         Finished sleeping\n";
  }
}

void Pass::controllerStatusHandler(const lcm::ReceiveBuffer* rbuf,
                             const std::string& channel, const  drc::controller_status_t* msg){
  if (stage_==3){

    // if standing now but was walking before:
    if ((msg->state== drc::controller_status_t::STANDING)&&(was_walking_last_)){
      sendDataRequests(msg->utime);
      stage_ =0;
      std::cout << "Stage 3: controller=STANDING, restarting. Moving to Stage 0\n"
                << "===========================================================\n";
    }

    if (msg->state == drc::controller_status_t::WALKING){
      was_walking_last_ = true;
    }else{
      was_walking_last_ = false;
    }

  }
}

// Send this to make sure what we need is being published for the planner:
void Pass::sendDataRequests(int64_t this_utime){
  drc::data_request_list_t reqs;
  reqs.utime = this_utime;
  drc::data_request_t req1; //EST_ROBOT_STATE
  req1.period = 10;
  req1.type = drc::data_request_t::MINIMAL_ROBOT_STATE;
  drc::data_request_t req2; // Planning Height Map
  req2.period = 10;
  req2.type = drc::data_request_t::HEIGHT_MAP_SCENE;
  reqs.requests.push_back(req1);
  reqs.requests.push_back(req2);
  reqs.num_requests = reqs.requests.size();
  lcm_->publish("DATA_REQUEST", &reqs);
}

int main(int argc, char ** argv) {
  int verbose = 0;
  int stage = 3;
  int mode = 0;
  int footsteps = 6;
  ConciseArgs opt(argc, (char**)argv);
  opt.add(verbose, "v", "verbosity","0 none, 1 little, 2 debug");
  opt.add(stage, "s", "stage","Starting Stage");
  opt.add(mode, "m", "mode","Mode 0forward 1left 2right");// 3random");
  opt.add(footsteps, "f", "footsteps","Number of Footsteps");// 3random");
  opt.parse();
  std::cout << "verbose: " << verbose << "\n";
  std::cout << "stage: " << stage << "\n";
  std::cout << "mode: " << mode << " [where 0forward 1left 2right\n";//3random]\n";
  std::cout << "footsteps: " << footsteps << " footsteps\n";

  boost::shared_ptr<lcm::LCM> lcm(new lcm::LCM);
  if(!lcm->good()){
    std::cerr <<"ERROR: lcm is not good()" <<std::endl;
  }

  Pass app(lcm, stage, mode, footsteps);
  cout << "System Test Ready" << endl << "============================" << endl;
  while(0 == lcm->handle());
  return 0;
}
<|endoftext|>


<commit_before>#include "bgen_casa_generation.h"
#include <bgen_core.h>

#include <fstream>
#include <sstream>

using namespace std;

namespace bgen {
    namespace casa {

        namespace gen {

            string namespace_to_string (const namespace_info & info, const string & separator) {
                stringstream stream;

                size_t size = info.size ();

                if (size > 0)
                    stream << info[0];

                for (int i = 1; i < size; ++i)
                    stream << separator << info [i];

                return stream.str ();
            }

            string namespace_to_uri (const namespace_info & info) {
                return namespace_to_string (info, "/");
            }

            string namespace_to_listener (const namespace_info & info) {
                return namespace_to_string (info, "_");
            }

            string method_listener_name (const method_info & info, const string & rest_method) {
                stringstream stream;

                stream
                    << "handle_"
                    << namespace_to_listener(info.namespace_name ())
                    << "_"
                    << info.name ()
                    << "_"
                    << rest_method;

                return stream.str ();
            }

            parser_reader_pre::parser_reader_pre (const struct_info::shared & info) : _info (info) {}

            void parser_reader_pre::write (bgen::gen::output & out) const {
                out.line ()
                    << "inline bool read (const value & source, "
                    << _info->native_name ()
                    << " & dest );";
            }

            parser_reader::parser_reader (const struct_info::shared & info) : _info (info) {}

            void parser_reader::write (bgen::gen::output & out) const {
                out.line ()
                    << "inline bool read (const value & source, "
                    << _info->native_name ()
                    << " & dest ) {";

                ++out.indent;

                out.line ()
                    << "if (!source.is_object()) return false;";
                out.line ()
                    << "auto source_obj = source.as_object ();";
                out.line ();
                out.line () << "bool success = true;";

                for ( auto & f : _info->fields () ) {
                    out.line () << "success = read_field_details (source_obj, \""
                        << f.name () << "\", dest." << f.name () <<
                        ") && success;";
                }

                out.line ()
                    << "return success;";

                --out.indent;

                out.line () << "}";
                out.line ();
            }

            parser_writer::parser_writer (const struct_info::shared & info) : _info (info) {}

            void parser_writer::write (bgen::gen::output & out) const {

                out.line ()
                    << "inline value write (const "
                    << _info->native_name ()
                    << " & source ) {";

                ++out.indent;

                out.line ()
                    << "auto object = web::json::value::object ();";

                for ( auto & f : _info->fields () ) {
                    out.line ()
                        << "object [\"" << f.name () << "\"] = write (source."
                        << f.name () << ");";
                }

                out.line ()
                    << "return object;";

                --out.indent;

                out.line ()
                    << "}";
            }

            parser_writer_pre::parser_writer_pre (const struct_info::shared & info) : _info (info) {}

            void parser_writer_pre::write (bgen::gen::output & out) const {
                out.line ()
                    << "inline value write (const "
                    << _info->native_name ()
                    << " & source );";
            }

            listener_post::listener_post (const method_info & info) :
                _info (info)
            {}

            void listener_post::write (bgen::gen::output & out) const {

                out.line ()
                    << "inline void "
                    << method_listener_name(_info, "post")
                    << " (http_request request) {";

                ++out.indent;

                out.line ()
                    << "handle_post <"
                    << _info.params ()[0].type ()->native_type_name () << ", "
                    << _info.return_type ()->native_type_name() << ", "
                    << namespace_to_string (_info.namespace_name (), "::") << "::" << _info.name ()
                    << "> (request);";

                --out.indent;

                out.line ()
                    << "}";
            }

            listener_get::listener_get (const method_info & info) :
            _info (info)
            {}

            void listener_get::write (bgen::gen::output & out) const {

                out.line ()
                    << "inline void "
                    << method_listener_name(_info, "get")
                    << " (http_request request) {";

                ++out.indent;

                out.line ()
                    << "handle_get <"
                    << _info.return_type ()->native_type_name() << ", "
                    << namespace_to_string (_info.namespace_name (), "::") << "::" << _info.name ()
                    << "> (request);";

                --out.indent;

                out.line ()
                    << "}";
            }

            register_listeners::register_listeners ( const struct_info::shared & info ) : _info (info) {}

            void register_listeners::write(bgen::gen::output & out) const {

                out.line ()
                    << "inline std::vector < http_listener > register_listeners ( const std::string & address ) {";

                ++out.indent;

                out.line ()
                    << "std::vector < http_listener > lv;";

                out.line ()
                    << "lv.reserve (" << _info->methods().size() << ");";

                out.line ()
                    << "uri_builder builder (address);";

                int i = 0;

                for (auto & m : _info->methods ()) {
                    out.line ()
                        << "builder.set_path(\"" << namespace_to_uri (m.namespace_name ()) << "/" << m.name () << "\");";
                    out.line ()
                        << "lv [" << i << "] = http_listener (builder.to_uri().to_string());";

                    if (m.params ().size () == 0) {
                        out.line ()
                            << "lv [" << i << "].support(methods::GET, listeners::" << method_listener_name(m, "get") << ");";
                    } else {
                        out.line ()
                            << "lv [" << i << "].support(methods::POST, listeners::" << method_listener_name(m, "post") << ");";
                    }

                    out.line ()
                        << "lv [" << i << "].open().wait();";

                    ++i;
                }

                out.line ()
                    << "return lv;";

                --out.indent;

                out.line () << "}";
            }

            boilerplate::boilerplate ( const string & file )
            : _file_name (file) {}

            void boilerplate::write (bgen::gen::output & out) const {

                ifstream stream (_file_name);

                if (!stream) {
                    logger::write () << "failed to read resource file at " << _file_name;
                    error_status::fail();
                    return;
                }

                string line;

                while (getline (stream, line))
                    out.line () << line;
            }

        }

        const string parser_boilerplate_location = "resources/casablanca/parser_boilerplate.txt";

        const string listener_boilerplate_location = "resources/casablanca/listener_boilerplate.txt";

    }
}<commit_msg>workaround for http listener creation failure ( to be replaced with more stable solution )<commit_after>#include "bgen_casa_generation.h"
#include <bgen_core.h>

#include <fstream>
#include <sstream>

using namespace std;

namespace bgen {
    namespace casa {

        namespace gen {

            string namespace_to_string (const namespace_info & info, const string & separator) {
                stringstream stream;

                size_t size = info.size ();

                if (size > 0)
                    stream << info[0];

                for (int i = 1; i < size; ++i)
                    stream << separator << info [i];

                return stream.str ();
            }

            string namespace_to_uri (const namespace_info & info) {
                return namespace_to_string (info, "/");
            }

            string namespace_to_listener (const namespace_info & info) {
                return namespace_to_string (info, "_");
            }

            string method_listener_name (const method_info & info, const string & rest_method) {
                stringstream stream;

                stream
                    << "handle_"
                    << namespace_to_listener(info.namespace_name ())
                    << "_"
                    << info.name ()
                    << "_"
                    << rest_method;

                return stream.str ();
            }

            parser_reader_pre::parser_reader_pre (const struct_info::shared & info) : _info (info) {}

            void parser_reader_pre::write (bgen::gen::output & out) const {
                out.line ()
                    << "inline bool read (const value & source, "
                    << _info->native_name ()
                    << " & dest );";
            }

            parser_reader::parser_reader (const struct_info::shared & info) : _info (info) {}

            void parser_reader::write (bgen::gen::output & out) const {
                out.line ()
                    << "inline bool read (const value & source, "
                    << _info->native_name ()
                    << " & dest ) {";

                ++out.indent;

                out.line ()
                    << "if (!source.is_object()) return false;";
                out.line ()
                    << "auto source_obj = source.as_object ();";
                out.line ();
                out.line () << "bool success = true;";

                for ( auto & f : _info->fields () ) {
                    out.line () << "success = read_field_details (source_obj, \""
                        << f.name () << "\", dest." << f.name () <<
                        ") && success;";
                }

                out.line ()
                    << "return success;";

                --out.indent;

                out.line () << "}";
                out.line ();
            }

            parser_writer::parser_writer (const struct_info::shared & info) : _info (info) {}

            void parser_writer::write (bgen::gen::output & out) const {

                out.line ()
                    << "inline value write (const "
                    << _info->native_name ()
                    << " & source ) {";

                ++out.indent;

                out.line ()
                    << "auto object = web::json::value::object ();";

                for ( auto & f : _info->fields () ) {
                    out.line ()
                        << "object [\"" << f.name () << "\"] = write (source."
                        << f.name () << ");";
                }

                out.line ()
                    << "return object;";

                --out.indent;

                out.line ()
                    << "}";
            }

            parser_writer_pre::parser_writer_pre (const struct_info::shared & info) : _info (info) {}

            void parser_writer_pre::write (bgen::gen::output & out) const {
                out.line ()
                    << "inline value write (const "
                    << _info->native_name ()
                    << " & source );";
            }

            listener_post::listener_post (const method_info & info) :
                _info (info)
            {}

            void listener_post::write (bgen::gen::output & out) const {

                out.line ()
                    << "inline void "
                    << method_listener_name(_info, "post")
                    << " (http_request request) {";

                ++out.indent;

                out.line ()
                    << "handle_post <"
                    << _info.params ()[0].type ()->native_type_name () << ", "
                    << _info.return_type ()->native_type_name() << ", "
                    << namespace_to_string (_info.namespace_name (), "::") << "::" << _info.name ()
                    << "> (request);";

                --out.indent;

                out.line ()
                    << "}";
            }

            listener_get::listener_get (const method_info & info) :
            _info (info)
            {}

            void listener_get::write (bgen::gen::output & out) const {

                out.line ()
                    << "inline void "
                    << method_listener_name(_info, "get")
                    << " (http_request request) {";

                ++out.indent;

                out.line ()
                    << "handle_get <"
                    << _info.return_type ()->native_type_name() << ", "
                    << namespace_to_string (_info.namespace_name (), "::") << "::" << _info.name ()
                    << "> (request);";

                --out.indent;

                out.line ()
                    << "}";
            }

            register_listeners::register_listeners ( const struct_info::shared & info ) : _info (info) {}

            void register_listeners::write(bgen::gen::output & out) const {

                out.line ()
                    << "inline std::vector < http_listener > register_listeners ( const std::string & address ) {";

                ++out.indent;

                out.line ()
                    << "std::vector < http_listener > lv;";

                out.line ()
                    << "lv.reserve (" << _info->methods().size() << ");";

                out.line ()
                    << "uri_builder builder (address);";

                int i = 0;

                for (auto & m : _info->methods ()) {
                    out.line ()
                        << "builder.set_path(\"" << namespace_to_uri (m.namespace_name ()) << "/" << m.name () << "\");";
                    out.line ()
                        << "new (&lv [" << i << "]) http_listener (builder.to_uri().to_string());";

                    if (m.params ().size () == 0) {
                        out.line ()
                            << "lv [" << i << "].support(methods::GET, listeners::" << method_listener_name(m, "get") << ");";
                    } else {
                        out.line ()
                            << "lv [" << i << "].support(methods::POST, listeners::" << method_listener_name(m, "post") << ");";
                    }

                    out.line ()
                        << "lv [" << i << "].open().wait();";

                    ++i;
                }

                out.line ()
                    << "return lv;";

                --out.indent;

                out.line () << "}";
            }

            boilerplate::boilerplate ( const string & file )
            : _file_name (file) {}

            void boilerplate::write (bgen::gen::output & out) const {

                ifstream stream (_file_name);

                if (!stream) {
                    logger::write () << "failed to read resource file at " << _file_name;
                    error_status::fail();
                    return;
                }

                string line;

                while (getline (stream, line))
                    out.line () << line;
            }

        }

        const string parser_boilerplate_location = "resources/casablanca/parser_boilerplate.txt";

        const string listener_boilerplate_location = "resources/casablanca/listener_boilerplate.txt";

    }
}<|endoftext|>


<commit_before>#include "isbaseclassconstraint.h"

#include <model/devisertypes.h>

IsBaseClassConstraint::IsBaseClassConstraint(DeviserValidator* validator)
  : DeviserConstraint(validator)
{

}

int
IsBaseClassConstraint::analyzePackage(DeviserPackage *package)
{
  int result = 0;

  foreach(DeviserVersion* version, package->getVersions())
  {
    foreach (DeviserClass* current, version->getElements())
    {
      bool isAbstract = current->isBaseClass();

      int countUses = 0;
      foreach (DeviserClass* item, version->getElements())
      {
        if (item == current) continue;
        if (item->getBaseClass() == current->getName())
        {
          ++countUses;
          if (!isAbstract)
          {
            ADD_MESSAGE("Class: '" << item->getName()
                        << "' uses BaseClass '" << item->getBaseClass()
                        << "', which is not marked as 'isBaseClass'.");
          }
        }
      }

      if (isAbstract && countUses== 0)
      {
        ADD_MESSAGE("Class: '" << current->getName()
                    << "' is marked as 'isBaseClass', but not used.");
      }

    }
  }

  return result;
}

bool
IsBaseClassConstraint::fixIssue(DeviserPackage* package)
{
  bool result = false;

  foreach(DeviserVersion* version, package->getVersions())
  {
    foreach (DeviserClass* current, version->getElements())
    {
      bool isAbstract = current->isBaseClass();

      int countUses = 0;
      foreach (DeviserClass* item, version->getElements())
      {
        if (item == current) continue;
        if (item->getBaseClass() == current->getName())
        {
          ++countUses;
          if (!isAbstract)
          {
            current->setIsBaseClass(true);
          }
        }
      }

      if (isAbstract && countUses== 0)
      {
        current->setIsBaseClass(false);
      }

    }
  }

  return result;
}
<commit_msg>- issue #111044222: the issue was reported, but not counted in the results, so it would only be visible if there were other errors as well<commit_after>#include "isbaseclassconstraint.h"

#include <model/devisertypes.h>

IsBaseClassConstraint::IsBaseClassConstraint(DeviserValidator* validator)
  : DeviserConstraint(validator)
{

}

int
IsBaseClassConstraint::analyzePackage(DeviserPackage *package)
{
  int result = 0;

  foreach(DeviserVersion* version, package->getVersions())
  {
    foreach (DeviserClass* current, version->getElements())
    {
      bool isAbstract = current->isBaseClass();

      int countUses = 0;
      foreach (DeviserClass* item, version->getElements())
      {
        if (item == current) continue;
        if (item->getBaseClass() == current->getName())
        {
          ++countUses;
          if (!isAbstract)
          {
            ++result;
            ADD_MESSAGE("Class: '" << item->getName()
                        << "' uses BaseClass '" << item->getBaseClass()
                        << "', which is not marked as 'isBaseClass'.");
          }
        }
      }

      if (isAbstract && countUses== 0)
      {
        ++result;
        ADD_MESSAGE("Class: '" << current->getName()
                    << "' is marked as 'isBaseClass', but not used.");
      }

    }
  }

  return result;
}

bool
IsBaseClassConstraint::fixIssue(DeviserPackage* package)
{
  bool result = false;

  foreach(DeviserVersion* version, package->getVersions())
  {
    foreach (DeviserClass* current, version->getElements())
    {
      bool isAbstract = current->isBaseClass();

      int countUses = 0;
      foreach (DeviserClass* item, version->getElements())
      {
        if (item == current) continue;
        if (item->getBaseClass() == current->getName())
        {
          ++countUses;
          if (!isAbstract)
          {
            current->setIsBaseClass(true);
            result = true;
          }
        }
      }

      if (isAbstract && countUses== 0)
      {
        current->setIsBaseClass(false);
        result = true;
      }

    }
  }

  return result;
}
<|endoftext|>


<commit_before>{
   GeFiCa::PointContactXY *detector2 = new GeFiCa::PointContactRZ(691,505);
   detector2->XLowerBound=-3.45;
   detector2->XUpperBound=3.45;
   detector2->YUpperBound=5.05;
   detector2->PointBegin=-0.14;
   detector2->PointEnd=0.14;

   //TF2 *im=new TF2("f","-0.19175e10-0.025e10*y");
   TF2 *im=new TF2("f","-0.318e10+0.025e10*y");
   //TF1 *im1=new TF1("f","-0.318e10+0.025e10*x",0,6.9);

   detector2->MaxIterations=1e5;
   detector2->Csor=1.994;
   detector2->V0=2500*GeFiCa::volt;
   detector2->V1=0*GeFiCa::volt;

   //TF1 *im=new TF1("","pol1",-0.318e10,0.025e10)
   detector2->Impurity="-0.318e10+0.025e10*y";//-0.01e10/GeFiCa::cm3);
   //detector2->SetImpurity(0e10/GeFiCa::cm3);

   detector2->CalculateField(GeFiCa::kSOR2);
   detector2->SaveField("point2dSOR2.root");
   //detector2->LoadField("point2dSOR23.root");

/*
   // calculate fields
   GeFiCa::Planar1D *detector = new GeFiCa::Planar1D(505);
   detector->UpperBound=5.05;
   detector->V1=2500*GeFiCa::volt;
   detector->V0=0*GeFiCa::volt;
   detector->SetImpurity(-0.01e10/GeFiCa::cm3);
   detector->CalculateField(GeFiCa::kAnalytic);
   detector->SaveField("planar1dTrue.root");
*/

   TCanvas * cvs=new TCanvas();
   gStyle->SetOptTitle(kTRUE);
   gStyle->SetPadTopMargin(0.02);
   gStyle->SetPadRightMargin(0.01);
   gStyle->SetPadLeftMargin(0.0999999999);
   gStyle->SetLabelFont(22,"XY");
   gStyle->SetLabelSize(0.05,"XY");
   gStyle->SetTitleSize(0.05,"XY");
   gStyle->SetTitleFont(22,"XY");
   gStyle->SetLegendFont(22);
  /*
   TChain *ta = new TChain("t");
   ta->Add("planar1dTrue.root");
   ta->Draw("e1:c1");
   TGraph *ga = new TGraph(ta->GetSelectedRows(), ta->GetV2(), ta->GetV1());
*/

   // generate graphics
   TChain *tn = new TChain("t");
   tn->Add("point2dSOR23.root");
   tn->Draw("c2*10:e2","c1<0.01&&c1>-0.01","colz");
   TGraph *gn = new TGraph(tn->GetSelectedRows(), tn->GetV2(), tn->GetV1());

   TChain *ta = new TChain("t");
   ta->Add("point2dSOR2.root");
   ta->Draw("c2*10:e2","c1<0.01&&c1>-0.01","colz");
   TGraph *ga = new TGraph(ta->GetSelectedRows(), ta->GetV2(), ta->GetV1());

  /*
  TTree *t = new TTree("t","t");
  t->ReadFile("/home/byron/mjd_siggen/fields/p1/ev.dat", "r:z:v");
  t->Draw("z:v","r<0.01&&r>-0.01","");

   TGraph *ga = new TGraph(t->GetSelectedRows(), t->GetV2(), t->GetV1());
 */
   // make final plot
   gn->SetMarkerColor(kBlue);
   gn->SetMarkerStyle(8);
   gn->SetMarkerSize(0.3);
   ga->SetLineColor(kRed);
   gn->GetXaxis()->SetTitle("Thickness [cm]");
   gn->GetYaxis()->SetTitle("Potential [V]");
   gn->SetTitle("");

   gn->Draw("ap");
   ga->Draw("p");

   TLegend *leg = new TLegend(0.2,0.6,0.5,0.8);
   leg->SetBorderSize(0);
   leg->AddEntry(gn,"GeFiCa","p");
   leg->AddEntry(ga,"mjd","l");
   leg->SetTextSize(0.05);
   leg->Draw();

 //  cvs->SaveAs("pointContact2d.png");

}
<commit_msg>xy-rz<commit_after>{
   GeFiCa::PointContactRZ *detector2 = new GeFiCa::PointContactRZ(691,505);
   detector2->XLowerBound=-3.45;
   detector2->XUpperBound=3.45;
   detector2->YUpperBound=5.05;
   detector2->PointBegin=-0.14;
   detector2->PointEnd=0.14;

   //TF2 *im=new TF2("f","-0.19175e10-0.025e10*y");
   TF2 *im=new TF2("f","-0.318e10+0.025e10*y");
   //TF1 *im1=new TF1("f","-0.318e10+0.025e10*x",0,6.9);

   detector2->MaxIterations=1e5;
   detector2->Csor=1.994;
   detector2->V0=2500*GeFiCa::volt;
   detector2->V1=0*GeFiCa::volt;

   //TF1 *im=new TF1("","pol1",-0.318e10,0.025e10)
   detector2->Impurity="-0.318e10+0.025e10*y";//-0.01e10/GeFiCa::cm3);
   //detector2->SetImpurity(0e10/GeFiCa::cm3);

   detector2->CalculateField(GeFiCa::kSOR2);
   detector2->SaveField("point2dSOR2.root");
   //detector2->LoadField("point2dSOR23.root");

/*
   // calculate fields
   GeFiCa::Planar1D *detector = new GeFiCa::Planar1D(505);
   detector->UpperBound=5.05;
   detector->V1=2500*GeFiCa::volt;
   detector->V0=0*GeFiCa::volt;
   detector->SetImpurity(-0.01e10/GeFiCa::cm3);
   detector->CalculateField(GeFiCa::kAnalytic);
   detector->SaveField("planar1dTrue.root");
*/

   TCanvas * cvs=new TCanvas();
   gStyle->SetOptTitle(kTRUE);
   gStyle->SetPadTopMargin(0.02);
   gStyle->SetPadRightMargin(0.01);
   gStyle->SetPadLeftMargin(0.0999999999);
   gStyle->SetLabelFont(22,"XY");
   gStyle->SetLabelSize(0.05,"XY");
   gStyle->SetTitleSize(0.05,"XY");
   gStyle->SetTitleFont(22,"XY");
   gStyle->SetLegendFont(22);
  /*
   TChain *ta = new TChain("t");
   ta->Add("planar1dTrue.root");
   ta->Draw("e1:c1");
   TGraph *ga = new TGraph(ta->GetSelectedRows(), ta->GetV2(), ta->GetV1());
*/

   // generate graphics
   TChain *tn = new TChain("t");
   tn->Add("point2dSOR23.root");
   tn->Draw("c2*10:e2","c1<0.01&&c1>-0.01","colz");
   TGraph *gn = new TGraph(tn->GetSelectedRows(), tn->GetV2(), tn->GetV1());

   TChain *ta = new TChain("t");
   ta->Add("point2dSOR2.root");
   ta->Draw("c2*10:e2","c1<0.01&&c1>-0.01","colz");
   TGraph *ga = new TGraph(ta->GetSelectedRows(), ta->GetV2(), ta->GetV1());

  /*
  TTree *t = new TTree("t","t");
  t->ReadFile("/home/byron/mjd_siggen/fields/p1/ev.dat", "r:z:v");
  t->Draw("z:v","r<0.01&&r>-0.01","");

   TGraph *ga = new TGraph(t->GetSelectedRows(), t->GetV2(), t->GetV1());
 */
   // make final plot
   gn->SetMarkerColor(kBlue);
   gn->SetMarkerStyle(8);
   gn->SetMarkerSize(0.3);
   ga->SetLineColor(kRed);
   gn->GetXaxis()->SetTitle("Thickness [cm]");
   gn->GetYaxis()->SetTitle("Potential [V]");
   gn->SetTitle("");

   gn->Draw("ap");
   ga->Draw("p");

   TLegend *leg = new TLegend(0.2,0.6,0.5,0.8);
   leg->SetBorderSize(0);
   leg->AddEntry(gn,"GeFiCa","p");
   leg->AddEntry(ga,"mjd","l");
   leg->SetTextSize(0.05);
   leg->Draw();

 //  cvs->SaveAs("pointContact2d.png");

}
<|endoftext|>


<commit_before>#pragma once

#include <atomic>
#include <stdexcept>

#include "semaphore.hpp"
#include "mutex.hpp"

namespace cpl
{

const int32_t max_readers = 1 << 30;

class RWMutex
{

	RWMutex()
	: _r_sem(0), _w_sem(0), r_count(0), r_wait(0)
	{
	}

	void
	r_lock()
	{
		if (++r_count < 0) {
			// There is an active writer, so wait for it.
			_r_sem.acquire();
		}
	}

	void
	r_unlock()
	{
		int32_t r = --r_count;
		if (r < 0) {
			if (r+1 == 0 || r+1 == -max_readers) {
				throw std::runtime_error("r_unlock of unlocked RWMutex");
			}

			if (--r_wait == 0) {
				// There is a waiting writer and this
				// is the last reader.
				_w_sem.release();
			}
		}
	}

	void
	lock()
	{
		_mu.lock();
		// Announce to readers that there is a pending writer.
		int32_t r = (r_count -= max_readers) + max_readers;
		if (r != 0 && (r_wait += r) != 0) {
			// Wait for the readers.
			_w_sem.acquire();
		}
	}

	void
	unlock()
	{
		// Announce to readers that there is no active writer.
		int32_t r = (r_count += max_readers);
		if (r >= max_readers) {
			throw std::runtime_error("unlock of unlocked RWMutex");
		}
		// Unblock blocked readers.
		for (int i = 0; i < r; i++) {
			_r_sem.release();
		}
		_mu.unlock();
	}

private:
	Mutex _mu;
	Semaphore _r_sem;
	Semaphore _w_sem;
	std::atomic<int32_t> r_count;
	std::atomic<int32_t> r_wait;

}; // RWMutex

} // cpl
<commit_msg>add mention to Go's RWMutex<commit_after>// This is a reader/writer mutual exclusion lock implementation
// based on Go's RWMutex, which is available at
// https://golang.org/src/sync/rwmutex.go.
#pragma once

#include <atomic>
#include <stdexcept>

#include "semaphore.hpp"
#include "mutex.hpp"

namespace cpl
{

const int32_t max_readers = 1 << 30;

class RWMutex
{

	RWMutex()
	: _r_sem(0), _w_sem(0), r_count(0), r_wait(0)
	{
	}

	void
	r_lock()
	{
		if (++r_count < 0) {
			// There is an active writer, so wait for it.
			_r_sem.acquire();
		}
	}

	void
	r_unlock()
	{
		int32_t r = --r_count;
		if (r < 0) {
			if (r+1 == 0 || r+1 == -max_readers) {
				throw std::runtime_error("r_unlock of unlocked RWMutex");
			}

			if (--r_wait == 0) {
				// There is a waiting writer and this
				// is the last reader.
				_w_sem.release();
			}
		}
	}

	void
	lock()
	{
		_mu.lock();
		// Announce to readers that there is a pending writer.
		int32_t r = (r_count -= max_readers) + max_readers;
		if (r != 0 && (r_wait += r) != 0) {
			// Wait for the readers.
			_w_sem.acquire();
		}
	}

	void
	unlock()
	{
		// Announce to readers that there is no active writer.
		int32_t r = (r_count += max_readers);
		if (r >= max_readers) {
			throw std::runtime_error("unlock of unlocked RWMutex");
		}
		// Unblock blocked readers.
		for (int i = 0; i < r; i++) {
			_r_sem.release();
		}
		_mu.unlock();
	}

private:
	Mutex _mu;
	Semaphore _r_sem;
	Semaphore _w_sem;
	std::atomic<int32_t> r_count;
	std::atomic<int32_t> r_wait;

}; // RWMutex

} // cpl
<|endoftext|>


<commit_before>//
//  Converter.cpp
//  FormatConverter
//
//  Created by Igor Shevach on 2/29/16.
//  Copyright (c) 2016 Igor Shevach. All rights reserved.
//

#include "Converter.h"

extern "C"{
#include <libavformat/movenc.h>

    //invalid suffix on literal C++11 requires...
    // thus, some code is replicated
    //#include <libavutil/timestamp.h>
#define AV_TS_MAX_STRING_SIZE 32

#ifndef PRId64
#define PRId64 "ld"
#endif

    typedef char ts_buf[AV_TS_MAX_STRING_SIZE];
    /**
     * Fill the provided buffer with a string containing a timestamp
     * representation.
     *
     * @param buf a buffer with size in bytes of at least AV_TS_MAX_STRING_SIZE
     * @param ts the timestamp to represent
     * @return the buffer in input
     */
    static inline char *av_ts_make_string(char *buf, int64_t ts)
    {
        if (ts == AV_NOPTS_VALUE) snprintf(buf, AV_TS_MAX_STRING_SIZE, "NOPTS");
        else                      snprintf(buf, AV_TS_MAX_STRING_SIZE, "%" PRId64, ts);
        return buf;
    }

    /**
     * Fill the provided buffer with a string containing a timestamp time
     * representation.
     *
     * @param buf a buffer with size in bytes of at least AV_TS_MAX_STRING_SIZE
     * @param ts the timestamp to represent
     * @param tb the timebase of the timestamp
     * @return the buffer in input
     */
    static inline char *av_ts_make_time_string(char *buf, int64_t ts, AVRational *tb)
    {
        if (ts == AV_NOPTS_VALUE) snprintf(buf, AV_TS_MAX_STRING_SIZE, "NOPTS");
        else                      snprintf(buf, AV_TS_MAX_STRING_SIZE, "%.6g", av_q2d(*tb) * ts);
        return buf;
    }

    inline void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt, const char *tag,int avlog_level = AV_LOG_TRACE)
    {
        AVRational *time_base = &fmt_ctx->streams[pkt->stream_index]->time_base;
        ts_buf a,b,c,d,e,f;

        av_log(nullptr,avlog_level,"stm:%d sz:%d pts:%s pts_time:%s dts:%s dts_time:%s duration:%s duration_time:%s stream_index:%d\n",
               pkt->stream_index,
               pkt->size,
               av_ts_make_string(a,pkt->pts), av_ts_make_time_string(b,pkt->pts, time_base),
               av_ts_make_string(c,pkt->dts), av_ts_make_time_string(d,pkt->dts, time_base),
               av_ts_make_string(e,pkt->duration), av_ts_make_time_string(f,pkt->duration, time_base),
               pkt->stream_index);

    }
}

namespace converter{

    ConverterAppInst appInst;

    ConverterAppInst &ConverterAppInst::instance(){
        return appInst;
    }

    ConverterAppInst::ConverterAppInst()
    :STREAM_BUFFER_SIZE(1024*4),
    INPUT_FORMAT("mpegts"),
    OUTPUT_FORMAT("mp4")
    {}

    int ConverterAppInst::init(int logLevel){
        av_log_set_level(logLevel);
        av_register_all();
        return 0;
    }

    /*
     static void metadata_creation_time(AVDictionary **metadata, int64_t time)
     {
     char buffer[256];
     if (time) {
     struct tm *ptm, tmbuf;
     time_t timet;
     timet = time / 1000;
     ptm = gmtime_r(&timet, &tmbuf);
     if (!ptm) return;
     size_t n = strftime(buffer, sizeof(buffer) - 4, "%Y-%m-%d %H:%M:%S", ptm);
     if (n && sprintf(buffer+n,".%3lld",time % 1000))
     av_dict_set(metadata, "creation_time", buffer, 0);
     }
     }
     */

    Converter::Converter()
    :m_creationTime(0),
    m_hash(nullptr),
    m_minStartDTSMsec(0),
    state(CLOSED)
    {}

    Converter::~Converter(){
        close();
        if(m_hash){
            av_free(m_hash);
        }
    }

    int Converter::checkForStreams(){

        if(!input->nb_streams){
            _S(input.checkStreams());
            if(!input->nb_streams){
                return 0;
            }
        }

        _S(avformat_find_stream_info(*input,NULL));

        for( size_t i = 0 ; i < input->nb_streams; i++){
            AVStream *in_stream =input->streams[i];
            switch(in_stream->codec->codec_type){
                case AVMEDIA_TYPE_VIDEO:
                    if(in_stream->codec->width == 0 )
                        return 0;
                    break;
                case AVMEDIA_TYPE_AUDIO:
                    if(in_stream->codec->channels == 0 )
                        return 0;
                    break;
                default:
                    break;
            };
        }

        output->max_interleave_delta = 100;

        dts.resize(input->nb_streams);
        pts.resize(input->nb_streams);
        m_streamMapper.resize(input->nb_streams);

        m_minStartDTSMsec = std::numeric_limits<int64_t>::max();

        for( size_t i = 0 , output_stream = 0; i < input->nb_streams; i++){

            AVStream *in_stream =input->streams[i];

            m_minStartDTSMsec = std::min(m_minStartDTSMsec,av_rescale(in_stream->start_time,1000 * in_stream->time_base.num,in_stream->time_base.den));

            if(in_stream->codec->codec_id == AV_CODEC_ID_TIMED_ID3)
                continue;

            AVStream *out_stream = avformat_new_stream(*output, in_stream->codec->codec);

            m_streamMapper[i] = output_stream++;

            _S(avcodec_copy_context(out_stream->codec, in_stream->codec));

            out_stream->time_base           = in_stream->time_base;
            out_stream->sample_aspect_ratio = in_stream->sample_aspect_ratio;

            out_stream->codec->codec_tag = 0;
            if (output->oformat->flags & AVFMT_GLOBALHEADER) {
                out_stream->codec->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
            }
            switch(out_stream->codec->codec_type){
                case AVMEDIA_TYPE_AUDIO:
                    if(out_stream->codec->codec_id == AV_CODEC_ID_AAC){
                        _S(ff_stream_add_bitstream_filter(out_stream, "aac_adtstoasc", NULL));
                    }
                    break;
                default:
                    break;
            }
        }

        AVDictionary *opts = nullptr;
        av_dict_set(&opts, "use_editlist", "0", 0);
        int success = avformat_write_header(*output, &opts);
        av_dict_free(&opts);

        _S(success);

        state = PUSHING;

        _S(pushData());

        return 0;
    }

    int Converter::pushData(){

        while(true){

            AVPacket pkt;
            if( av_read_frame(*input,&pkt) < 0 ){
                av_log(*input,AV_LOG_TRACE,"no more frames");
                break;
            }

            av_md5_update(m_hash, (const uint8_t *)&pkt.pts, sizeof(pkt.pts));

            AVStream *in_stream  = input->streams[pkt.stream_index];

            //pkt.pts = pkt.dts;

            if(AV_NOPTS_VALUE != pkt.pts){
                m_minStartDTSMsec = std::min(m_minStartDTSMsec, pkt.pts);
                pkt.pts -= av_rescale(m_minStartDTSMsec,in_stream->time_base.den,TIMESTAMP_RESOLUTION * in_stream->time_base.num);
            } else {
                av_log(*input,AV_LOG_INFO,"Converter::pushData. stream %d. pkt with pts=AV_NOPTS_VALUE",m_streamMapper[pkt.stream_index]);
            }
            if(AV_NOPTS_VALUE != pkt.dts){
                m_minStartDTSMsec = std::min(m_minStartDTSMsec, pkt.dts);
                pkt.dts -= av_rescale(m_minStartDTSMsec,in_stream->time_base.den,TIMESTAMP_RESOLUTION * in_stream->time_base.num);
            } else {
                av_log(*input,AV_LOG_INFO,"Converter::pushData. stream %d. pkt with dts=AV_NOPTS_VALUE",m_streamMapper[pkt.stream_index]);
            }

            if(in_stream->codec->codec_id == AV_CODEC_ID_TIMED_ID3){
                if( m_creationTime ==0 ){
                    m_creationTime = extractUnixTimeMsecFromId3Tag(pkt.data,pkt.size);
                    if(m_creationTime > 0){
                        av_log(*input,AV_LOG_TRACE,"Converter::pushData. parsed id3 time %lld stream start time %lld pts %lld",
                               m_creationTime, in_stream->start_time,pkt.pts);
                        m_creationTime -= av_rescale(pkt.pts,TIMESTAMP_RESOLUTION * in_stream->time_base.num,
                                                     in_stream->time_base.den);
                        // hack for mp4
                        MOVMuxContext *mov = reinterpret_cast<MOVMuxContext*>(output->priv_data);
                        mov->time = m_creationTime / 1000 + 0x7C25B080; // 1970 based -> 1904 based
                    }
                }
            } else {

                pkt.stream_index = m_streamMapper[pkt.stream_index];

                AVStream *out_stream = output->streams[pkt.stream_index];

                /* copy packet */

                //    log_packet(*input, &pkt, "in",AV_LOG_FATAL);

                if(AV_NOPTS_VALUE != pkt.pts){
                    pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
                }
                if(pts.size() > 0 && pkt.pts <= pts[pkt.stream_index]){
                    pkt.pts = pts[pkt.stream_index]+1;
                }

                pts[pkt.stream_index] = pkt.pts;

                if(AV_NOPTS_VALUE != pkt.dts){
                    pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
                }
                if(dts.size() > 0 && pkt.dts <= dts[pkt.stream_index]){
                    pkt.dts = dts[pkt.stream_index]+1;
                }

                dts[pkt.stream_index] = pkt.dts;

                pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);
                pkt.pos = -1;

                log_packet(*input, &pkt, "in");

                _S(av_interleaved_write_frame(*output, &pkt));
            }

            av_packet_unref(&pkt);
        }
        return 0;
    }

    int Converter::init(std::shared_ptr<StreamBase> inputStream, std::shared_ptr<StreamBase> outputStream){

        state = INIT;

        _S( input.init(ConverterAppInst::instance().INPUT_FORMAT,inputStream ));
        _S( output.init(ConverterAppInst::instance().OUTPUT_FORMAT,
                        ConverterAppInst::instance().STREAM_BUFFER_SIZE,outputStream ));
        m_hash = av_md5_alloc();
        if(m_hash) {
            av_md5_init(m_hash);
        }
        state = CREATING;
        return 0;
    }

    int Converter::onData(){

        switch(state){
            case CREATING:
                if(checkForStreams()){
                    state = ERROR;
                }
                break;
            case PUSHING:
                if(pushData()) {
                    state = ERROR;
                }
                break;
            default:
                break;
        };

        return state == ERROR ? -1 : 0;

    }

    void Converter::close(){

        if(state == PUSHING){

            state = CLOSING;
            /*
             //HACK!!!
             if(m_creationTime == 0){
             m_creationTime = std::time(0) * 1000;
             av_log(nullptr,AV_LOG_WARNING,"Converter::close. assign gmt now since m_creationTime not set to valid value");
             MOVMuxContext *mov = reinterpret_cast<MOVMuxContext*>(output->priv_data);
             mov->time = m_creationTime / 1000 + 0x7C25B080; // 1970 based -> 1904 based
             }*/

            MediaFileInfo mfi;

            if(m_hash){
                uint8_t md5val[16];
                av_md5_final(m_hash, md5val);

                mfi.sig.resize(sizeof(md5val) * 2 + 1);
                const std::string map("0123456789ABCDEF");

                for( size_t i = 0; i < mfi.sig.length(); ){
                    uint8_t val = md5val[i/2];
                    mfi.sig[i++] = map[val>>4];
                    mfi.sig[i++] = map[val & 0xf];
                }
                mfi.sig[mfi.sig.length()-1] = 0;
            }
            for(size_t i = 0; i < input->nb_streams;i++)
            {
                AVStream *stream = this->input->streams[i];

                switch(stream->codec->codec_type){
                    case AVMEDIA_TYPE_VIDEO:
                    case AVMEDIA_TYPE_AUDIO:
                    {
                        double duration = stream->duration /(double)stream->time_base.den * TIMESTAMP_RESOLUTION * stream->time_base.num;
                        double startDTS = stream->start_time /(double)stream->time_base.den * TIMESTAMP_RESOLUTION * stream->time_base.num;
                        double wrapDTS = ::ceil((1ULL << stream->pts_wrap_bits) / (double)stream->time_base.den * stream->time_base.num * TIMESTAMP_RESOLUTION );
                        mfi.tracks.push_back({ this->m_creationTime + startDTS - m_minStartDTSMsec,
                            startDTS,
                            wrapDTS,
                            duration,
                            stream->codec->codec_type
                        });
                    }
                        break;
                    default:
                        break;
                };
            }
            output.Close();
            assert(mfi.tracks.size() > 0);
            mfi.startTimeUnixMs = this->m_creationTime;
            output.EmitInfo(mfi);
            input.Close();
            state = CLOSED;
        }
    }
};<commit_msg>dts timestamps reorder<commit_after>//
//  Converter.cpp
//  FormatConverter
//
//  Created by Igor Shevach on 2/29/16.
//  Copyright (c) 2016 Igor Shevach. All rights reserved.
//

#include "Converter.h"

extern "C"{
#include <libavformat/movenc.h>

    //invalid suffix on literal C++11 requires...
    // thus, some code is replicated
    //#include <libavutil/timestamp.h>
#define AV_TS_MAX_STRING_SIZE 32

#ifndef PRId64
#define PRId64 "ld"
#endif

    typedef char ts_buf[AV_TS_MAX_STRING_SIZE];
    /**
     * Fill the provided buffer with a string containing a timestamp
     * representation.
     *
     * @param buf a buffer with size in bytes of at least AV_TS_MAX_STRING_SIZE
     * @param ts the timestamp to represent
     * @return the buffer in input
     */
    static inline char *av_ts_make_string(char *buf, int64_t ts)
    {
        if (ts == AV_NOPTS_VALUE) snprintf(buf, AV_TS_MAX_STRING_SIZE, "NOPTS");
        else                      snprintf(buf, AV_TS_MAX_STRING_SIZE, "%" PRId64, ts);
        return buf;
    }

    /**
     * Fill the provided buffer with a string containing a timestamp time
     * representation.
     *
     * @param buf a buffer with size in bytes of at least AV_TS_MAX_STRING_SIZE
     * @param ts the timestamp to represent
     * @param tb the timebase of the timestamp
     * @return the buffer in input
     */
    static inline char *av_ts_make_time_string(char *buf, int64_t ts, AVRational *tb)
    {
        if (ts == AV_NOPTS_VALUE) snprintf(buf, AV_TS_MAX_STRING_SIZE, "NOPTS");
        else                      snprintf(buf, AV_TS_MAX_STRING_SIZE, "%.6g", av_q2d(*tb) * ts);
        return buf;
    }

    inline void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt, const char *tag,int avlog_level = AV_LOG_TRACE)
    {
        AVRational *time_base = &fmt_ctx->streams[pkt->stream_index]->time_base;
        ts_buf a,b,c,d,e,f;

        av_log(nullptr,avlog_level,"stm:%d sz:%d pts:%s pts_time:%s dts:%s dts_time:%s duration:%s duration_time:%s stream_index:%d\n",
               pkt->stream_index,
               pkt->size,
               av_ts_make_string(a,pkt->pts), av_ts_make_time_string(b,pkt->pts, time_base),
               av_ts_make_string(c,pkt->dts), av_ts_make_time_string(d,pkt->dts, time_base),
               av_ts_make_string(e,pkt->duration), av_ts_make_time_string(f,pkt->duration, time_base),
               pkt->stream_index);

    }
}

namespace converter{

    ConverterAppInst appInst;

    ConverterAppInst &ConverterAppInst::instance(){
        return appInst;
    }

    ConverterAppInst::ConverterAppInst()
    :STREAM_BUFFER_SIZE(1024*4),
    INPUT_FORMAT("mpegts"),
    OUTPUT_FORMAT("mp4")
    {}

    int ConverterAppInst::init(int logLevel){
        av_log_set_level(logLevel);
        av_register_all();
        return 0;
    }

    /*
     static void metadata_creation_time(AVDictionary **metadata, int64_t time)
     {
     char buffer[256];
     if (time) {
     struct tm *ptm, tmbuf;
     time_t timet;
     timet = time / 1000;
     ptm = gmtime_r(&timet, &tmbuf);
     if (!ptm) return;
     size_t n = strftime(buffer, sizeof(buffer) - 4, "%Y-%m-%d %H:%M:%S", ptm);
     if (n && sprintf(buffer+n,".%3lld",time % 1000))
     av_dict_set(metadata, "creation_time", buffer, 0);
     }
     }
     */

    Converter::Converter()
    :m_creationTime(0),
    m_hash(nullptr),
    m_minStartDTSMsec(0),
    state(CLOSED)
    {}

    Converter::~Converter(){
        close();
        if(m_hash){
            av_free(m_hash);
        }
    }

    int Converter::checkForStreams(){

        if(!input->nb_streams){
            _S(input.checkStreams());
            if(!input->nb_streams){
                return 0;
            }
        }

        _S(avformat_find_stream_info(*input,NULL));

        for( size_t i = 0 ; i < input->nb_streams; i++){
            AVStream *in_stream =input->streams[i];
            switch(in_stream->codec->codec_type){
                case AVMEDIA_TYPE_VIDEO:
                    if(in_stream->codec->width == 0 )
                        return 0;
                    break;
                case AVMEDIA_TYPE_AUDIO:
                    if(in_stream->codec->channels == 0 )
                        return 0;
                    break;
                default:
                    break;
            };
        }

        output->max_interleave_delta = 100;

        dts.resize(input->nb_streams);
        pts.resize(input->nb_streams);
        m_streamMapper.resize(input->nb_streams);

        m_minStartDTSMsec = std::numeric_limits<int64_t>::max();

        for( size_t i = 0 , output_stream = 0; i < input->nb_streams; i++){

            AVStream *in_stream =input->streams[i];

            int64_t start_time = in_stream->first_dts != AV_NOPTS_VALUE ? in_stream->first_dts : in_stream->start_time;
            m_minStartDTSMsec = std::min(m_minStartDTSMsec,av_rescale(start_time,1000 * in_stream->time_base.num,in_stream->time_base.den));

            if(in_stream->codec->codec_id == AV_CODEC_ID_TIMED_ID3)
                continue;

            AVStream *out_stream = avformat_new_stream(*output, in_stream->codec->codec);

            m_streamMapper[i] = output_stream++;

            _S(avcodec_copy_context(out_stream->codec, in_stream->codec));

            out_stream->time_base           = in_stream->time_base;
            out_stream->sample_aspect_ratio = in_stream->sample_aspect_ratio;

            out_stream->codec->codec_tag = 0;
            if (output->oformat->flags & AVFMT_GLOBALHEADER) {
                out_stream->codec->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
            }
            switch(out_stream->codec->codec_type){
                case AVMEDIA_TYPE_AUDIO:
                    if(out_stream->codec->codec_id == AV_CODEC_ID_AAC){
                        _S(ff_stream_add_bitstream_filter(out_stream, "aac_adtstoasc", NULL));
                    }
                    break;
                default:
                    break;
            }
        }

        AVDictionary *opts = nullptr;
        av_dict_set(&opts, "use_editlist", "0", 0);
        int success = avformat_write_header(*output, &opts);
        av_dict_free(&opts);

        _S(success);

        state = PUSHING;

        _S(pushData());

        return 0;
    }

    int Converter::pushData(){

        while(true){

            AVPacket pkt;
            if( av_read_frame(*input,&pkt) < 0 ){
                av_log(*input,AV_LOG_TRACE,"no more frames");
                break;
            }

            av_md5_update(m_hash, (const uint8_t *)&pkt.pts, sizeof(pkt.pts));

            AVStream *in_stream  = input->streams[pkt.stream_index];

            if(AV_NOPTS_VALUE != pkt.pts){
                pkt.pts -= av_rescale(m_minStartDTSMsec,in_stream->time_base.den,TIMESTAMP_RESOLUTION * in_stream->time_base.num);
            } else {
                av_log(*input,AV_LOG_WARNING,"Converter::pushData. stream %d. pkt with pts=AV_NOPTS_VALUE\n",m_streamMapper[pkt.stream_index]);
            }
            if(AV_NOPTS_VALUE != pkt.dts){
                pkt.dts -= av_rescale(m_minStartDTSMsec,in_stream->time_base.den,TIMESTAMP_RESOLUTION * in_stream->time_base.num);
            } else {
                av_log(*input,AV_LOG_WARNING,"Converter::pushData. stream %d. pkt with dts=AV_NOPTS_VALUE\n",m_streamMapper[pkt.stream_index]);
            }

            if(in_stream->codec->codec_id == AV_CODEC_ID_TIMED_ID3){
                if( m_creationTime ==0 ){
                    m_creationTime = extractUnixTimeMsecFromId3Tag(pkt.data,pkt.size);
                    if(m_creationTime > 0){
                        av_log(*input,AV_LOG_TRACE,"Converter::pushData. parsed id3 time %lld stream start time %lld pts %lld",
                               m_creationTime, in_stream->start_time,pkt.pts);

                        m_creationTime -= av_rescale(pkt.pts,TIMESTAMP_RESOLUTION * in_stream->time_base.num,
                                                     in_stream->time_base.den);

                        // hack for mp4
                        MOVMuxContext *mov = reinterpret_cast<MOVMuxContext*>(output->priv_data);
                        mov->time = m_creationTime / 1000 + 0x7C25B080; // 1970 based -> 1904 based
                    }
                }
            } else {

                pkt.stream_index = m_streamMapper[pkt.stream_index];

                AVStream *out_stream = output->streams[pkt.stream_index];

                /* copy packet */

                //log_packet(*input, &pkt, "in",AV_LOG_FATAL);

                if(AV_NOPTS_VALUE != pkt.pts){
                    pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
                } else {
                    pkt.pts = pts[pkt.stream_index]+1;
                }

                pts[pkt.stream_index] = pkt.pts;

                if(AV_NOPTS_VALUE != pkt.dts){
                    pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
                } else  {
                    pkt.dts = dts[pkt.stream_index]+1;
                }

                dts[pkt.stream_index] = pkt.dts;

                pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);
                pkt.pos = -1;

                log_packet(*input, &pkt, "in");

                _S(av_interleaved_write_frame(*output, &pkt));
            }

            av_packet_unref(&pkt);
        }
        return 0;
    }

    int Converter::init(std::shared_ptr<StreamBase> inputStream, std::shared_ptr<StreamBase> outputStream){

        state = INIT;

        _S( input.init(ConverterAppInst::instance().INPUT_FORMAT,inputStream ));
        _S( output.init(ConverterAppInst::instance().OUTPUT_FORMAT,
                        ConverterAppInst::instance().STREAM_BUFFER_SIZE,outputStream ));
        m_hash = av_md5_alloc();
        if(m_hash) {
            av_md5_init(m_hash);
        }
        state = CREATING;
        return 0;
    }

    int Converter::onData(){

        switch(state){
            case CREATING:
                if(checkForStreams()){
                    state = ERROR;
                }
                break;
            case PUSHING:
                if(pushData()) {
                    state = ERROR;
                }
                break;
            default:
                break;
        };

        return state == ERROR ? -1 : 0;

    }

    void Converter::close(){

        if(state == PUSHING){

            state = CLOSING;
            /*
             //HACK!!!
             if(m_creationTime == 0){
             m_creationTime = std::time(0) * 1000;
             av_log(nullptr,AV_LOG_WARNING,"Converter::close. assign gmt now since m_creationTime not set to valid value");
             MOVMuxContext *mov = reinterpret_cast<MOVMuxContext*>(output->priv_data);
             mov->time = m_creationTime / 1000 + 0x7C25B080; // 1970 based -> 1904 based
             }*/

            MediaFileInfo mfi;

            if(m_hash){
                uint8_t md5val[16];
                av_md5_final(m_hash, md5val);

                mfi.sig.resize(sizeof(md5val) * 2 + 1);
                const std::string map("0123456789ABCDEF");

                for( size_t i = 0; i < mfi.sig.length(); ){
                    uint8_t val = md5val[i/2];
                    mfi.sig[i++] = map[val>>4];
                    mfi.sig[i++] = map[val & 0xf];
                }
                mfi.sig[mfi.sig.length()-1] = 0;
            }
            for(size_t i = 0; i < input->nb_streams;i++)
            {
                AVStream *stream = this->input->streams[i];

                switch(stream->codec->codec_type){
                    case AVMEDIA_TYPE_VIDEO:
                    case AVMEDIA_TYPE_AUDIO:
                    {
                        double duration = stream->duration /(double)stream->time_base.den * TIMESTAMP_RESOLUTION * stream->time_base.num;
                        double startDTS = stream->start_time /(double)stream->time_base.den * TIMESTAMP_RESOLUTION * stream->time_base.num;
                        double wrapDTS = ::ceil((1ULL << stream->pts_wrap_bits) / (double)stream->time_base.den * stream->time_base.num * TIMESTAMP_RESOLUTION );
                        mfi.tracks.push_back({ this->m_creationTime + startDTS - m_minStartDTSMsec,
                            startDTS,
                            wrapDTS,
                            duration,
                            stream->codec->codec_type
                        });
                    }
                        break;
                    default:
                        break;
                };
            }
            output.Close();
            assert(mfi.tracks.size() > 0);
            mfi.startTimeUnixMs = this->m_creationTime;
            output.EmitInfo(mfi);
            input.Close();
            state = CLOSED;
        }
    }
};<|endoftext|>


<commit_before>// Copyright (C) 2008 Till Busch buti@bux.at
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program 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
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
//

#ifdef HAVE_CONFIG_H
#  include <simgear_config.h>
#endif

#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osgDB/Registry>

#include <simgear/constants.h>
#include <simgear/props/props.hxx>
#include <simgear/props/props_io.hxx>
#include <simgear/scene/model/ModelRegistry.hxx>

#include "SGPagedLOD.hxx"
#include "SGReaderWriterXML.hxx"
#include "SGReaderWriterXMLOptions.hxx"

//#include "model.hxx"
#include "modellib.hxx"

using namespace simgear;

osgDB::RegisterReaderWriterProxy<SGReaderWriterXML> g_readerWriter_XML_Proxy;
ModelRegistryCallbackProxy<LoadOnlyCallback> g_xmlCallbackProxy("xml");

////////////////////////////////////////////////////////////////////////
// Implementation of SGModelLib.
////////////////////////////////////////////////////////////////////////
void SGModelLib::init(const string &root_dir)
{
    osgDB::Registry::instance()->getDataFilePathList().push_front(root_dir);
}

SGModelLib::SGModelLib()
{
}

SGModelLib::~SGModelLib()
{
}

osg::Node*
SGModelLib::loadModel(const string &path,
                       SGPropertyNode *prop_root,
                       SGModelData *data)
{
    osg::ref_ptr<SGReaderWriterXMLOptions> opt = new SGReaderWriterXMLOptions(*(osgDB::Registry::instance()->getOptions()));
    opt->setPropRoot(prop_root);
    opt->setModelData(data);
    osg::Node *n = readNodeFile(path, opt.get());
    if(data)
        data->modelLoaded(path, data->getProperties(), n);
    return n;

}

osg::Node*
SGModelLib::loadModel(const string &path,
                                SGPropertyNode *prop_root,
                                panel_func pf)
{
    osg::ref_ptr<SGReaderWriterXMLOptions> opt = new SGReaderWriterXMLOptions(*(osgDB::Registry::instance()->getOptions()));
    opt->setPropRoot(prop_root);
    opt->setLoadPanel(pf);
    return readNodeFile(path, opt.get());
}

osg::Node*
SGModelLib::loadPagedModel(const string &path,
                           SGPropertyNode *prop_root,
                           SGModelData *data)
{
    SGPagedLOD *plod = new SGPagedLOD;
    plod->setFileName(0, path);
    plod->setRange(0, 0.0, 50.0*SG_NM_TO_METER);

    osg::ref_ptr<SGReaderWriterXMLOptions> opt = new SGReaderWriterXMLOptions(*(osgDB::Registry::instance()->getOptions()));
    opt->setPropRoot(prop_root);
    opt->setModelData(data);
    plod->setReaderWriterOptions(opt.get());
    return plod;
}

// end of modellib.cxx
<commit_msg>Put some annotations into the loaded models names.<commit_after>// Copyright (C) 2008 Till Busch buti@bux.at
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program 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
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
//

#ifdef HAVE_CONFIG_H
#  include <simgear_config.h>
#endif

#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osgDB/Registry>

#include <simgear/constants.h>
#include <simgear/props/props.hxx>
#include <simgear/props/props_io.hxx>
#include <simgear/scene/model/ModelRegistry.hxx>

#include "SGPagedLOD.hxx"
#include "SGReaderWriterXML.hxx"
#include "SGReaderWriterXMLOptions.hxx"

#include "modellib.hxx"

using namespace simgear;

osgDB::RegisterReaderWriterProxy<SGReaderWriterXML> g_readerWriter_XML_Proxy;
ModelRegistryCallbackProxy<LoadOnlyCallback> g_xmlCallbackProxy("xml");

////////////////////////////////////////////////////////////////////////
// Implementation of SGModelLib.
////////////////////////////////////////////////////////////////////////
void SGModelLib::init(const string &root_dir)
{
    osgDB::Registry::instance()->getDataFilePathList().push_front(root_dir);
}

SGModelLib::SGModelLib()
{
}

SGModelLib::~SGModelLib()
{
}

osg::Node*
SGModelLib::loadModel(const string &path,
                       SGPropertyNode *prop_root,
                       SGModelData *data)
{
    osg::ref_ptr<SGReaderWriterXMLOptions> opt = new SGReaderWriterXMLOptions(*(osgDB::Registry::instance()->getOptions()));
    opt->setPropRoot(prop_root);
    opt->setModelData(data);
    osg::Node *n = readNodeFile(path, opt.get());
    if(data)
        data->modelLoaded(path, data->getProperties(), n);
    if (n->getName().empty())
        n->setName("Direct loaded model \"" + path + "\"");
    return n;

}

osg::Node*
SGModelLib::loadModel(const string &path,
                                SGPropertyNode *prop_root,
                                panel_func pf)
{
    osg::ref_ptr<SGReaderWriterXMLOptions> opt = new SGReaderWriterXMLOptions(*(osgDB::Registry::instance()->getOptions()));
    opt->setPropRoot(prop_root);
    opt->setLoadPanel(pf);
    return readNodeFile(path, opt.get());
}

osg::Node*
SGModelLib::loadPagedModel(const string &path,
                           SGPropertyNode *prop_root,
                           SGModelData *data)
{
    SGPagedLOD *plod = new SGPagedLOD;
    plod->setName("Paged LOD for \"" + path + "\"");
    plod->setFileName(0, path);
    plod->setRange(0, 0.0, 50.0*SG_NM_TO_METER);

    osg::ref_ptr<SGReaderWriterXMLOptions> opt = new SGReaderWriterXMLOptions(*(osgDB::Registry::instance()->getOptions()));
    opt->setPropRoot(prop_root);
    opt->setModelData(data);
    plod->setReaderWriterOptions(opt.get());
    return plod;
}

// end of modellib.cxx
<|endoftext|>


<commit_before>// Copyright 2020 Google LLC
//
// 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
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// 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 <cstdlib>
#include <memory>
#include <string>

#include "llvm/Support/CommandLine.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/raw_ostream.h"
#include "mlir/IR/AsmState.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/InitAllDialects.h"
#include "mlir/InitAllPasses.h"
#include "mlir/Pass/PassManager.h"
#include "mlir/Pass/PassRegistry.h"
#include "mlir/Support/FileUtilities.h"
#include "mlir/Support/LogicalResult.h"
#include "mlir/Support/MlirOptMain.h"
#include "sair_dialect.h"
#include "sair_registration.h"

int main(int argc, char **argv) {
  llvm::cl::opt<std::string> input_filename(llvm::cl::Positional,
                                            llvm::cl::desc("<input file>"),
                                            llvm::cl::init("-"));
  llvm::cl::opt<std::string> output_filename(
      "o", llvm::cl::desc("Output filename"), llvm::cl::value_desc("filename"),
      llvm::cl::init("-"));

  llvm::cl::opt<bool> split_input_file(
      "split-input-file",
      llvm::cl::desc("Split the input file into pieces and process each chunk "
                     "independently"),
      llvm::cl::init(false));

  llvm::cl::opt<bool> verify_diagnostics(
      "verify-diagnostics",
      llvm::cl::desc("Check that emitted diagnostics match expected-* lines on "
                     "the corresponding line"),
      llvm::cl::init(false));

  llvm::cl::opt<bool> allowUnregisteredDialects(
      "allow-unregistered-dialect",
      llvm::cl::desc("Allow operation with no registered dialects"),
      llvm::cl::init(false));

  llvm::InitLLVM init(argc, argv);
  mlir::registerMLIRContextCLOptions();

  // Register dialects.
  mlir::DialectRegistry registry;
  mlir::registerAllDialects(registry);
  sair::RegisterSairDialect(registry);

  // Register any pass manager command line options.
  mlir::registerAllPasses();
  sair::RegisterSairPasses();
  mlir::registerPassManagerCLOptions();
  mlir::registerAsmPrinterCLOptions();
  mlir::PassPipelineCLParser passPipeline("", "MLIR passes to run");
  llvm::cl::ParseCommandLineOptions(argc, argv, "SAIR optimizer driver\n");

  std::string errorMessage;
  std::unique_ptr<llvm::MemoryBuffer> inputFile =
      mlir::openInputFile(input_filename, &errorMessage);
  if (!inputFile) {
    llvm::errs() << errorMessage << "\n";
    return EXIT_FAILURE;
  }

  std::unique_ptr<llvm::ToolOutputFile> outputFile =
      mlir::openOutputFile(output_filename, &errorMessage);
  if (!outputFile) {
    llvm::errs() << errorMessage << "\n";
    return EXIT_FAILURE;
  }

  return mlir::failed(
      mlir::MlirOptMain(outputFile->os(), std::move(inputFile), passPipeline,
                        registry, split_input_file, verify_diagnostics,
                        /*verifyPasses=*/true, allowUnregisteredDialects,
                        /*preloadDialectsInContext=*/false));
}
<commit_msg>Remove references to preloadDialects<commit_after>// Copyright 2020 Google LLC
//
// 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
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// 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 <cstdlib>
#include <memory>
#include <string>

#include "llvm/Support/CommandLine.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/raw_ostream.h"
#include "mlir/IR/AsmState.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/InitAllDialects.h"
#include "mlir/InitAllPasses.h"
#include "mlir/Pass/PassManager.h"
#include "mlir/Pass/PassRegistry.h"
#include "mlir/Support/FileUtilities.h"
#include "mlir/Support/LogicalResult.h"
#include "mlir/Support/MlirOptMain.h"
#include "sair_dialect.h"
#include "sair_registration.h"

int main(int argc, char **argv) {
  llvm::cl::opt<std::string> input_filename(llvm::cl::Positional,
                                            llvm::cl::desc("<input file>"),
                                            llvm::cl::init("-"));
  llvm::cl::opt<std::string> output_filename(
      "o", llvm::cl::desc("Output filename"), llvm::cl::value_desc("filename"),
      llvm::cl::init("-"));

  llvm::cl::opt<bool> split_input_file(
      "split-input-file",
      llvm::cl::desc("Split the input file into pieces and process each chunk "
                     "independently"),
      llvm::cl::init(false));

  llvm::cl::opt<bool> verify_diagnostics(
      "verify-diagnostics",
      llvm::cl::desc("Check that emitted diagnostics match expected-* lines on "
                     "the corresponding line"),
      llvm::cl::init(false));

  llvm::cl::opt<bool> allowUnregisteredDialects(
      "allow-unregistered-dialect",
      llvm::cl::desc("Allow operation with no registered dialects"),
      llvm::cl::init(false));

  llvm::InitLLVM init(argc, argv);
  mlir::registerMLIRContextCLOptions();

  // Register dialects.
  mlir::DialectRegistry registry;
  mlir::registerAllDialects(registry);
  sair::RegisterSairDialect(registry);

  // Register any pass manager command line options.
  mlir::registerAllPasses();
  sair::RegisterSairPasses();
  mlir::registerPassManagerCLOptions();
  mlir::registerAsmPrinterCLOptions();
  mlir::PassPipelineCLParser passPipeline("", "MLIR passes to run");
  llvm::cl::ParseCommandLineOptions(argc, argv, "SAIR optimizer driver\n");

  std::string errorMessage;
  std::unique_ptr<llvm::MemoryBuffer> inputFile =
      mlir::openInputFile(input_filename, &errorMessage);
  if (!inputFile) {
    llvm::errs() << errorMessage << "\n";
    return EXIT_FAILURE;
  }

  std::unique_ptr<llvm::ToolOutputFile> outputFile =
      mlir::openOutputFile(output_filename, &errorMessage);
  if (!outputFile) {
    llvm::errs() << errorMessage << "\n";
    return EXIT_FAILURE;
  }

  return mlir::failed(
      mlir::MlirOptMain(outputFile->os(), std::move(inputFile), passPipeline,
                        registry, split_input_file, verify_diagnostics,
                        /*verifyPasses=*/true, allowUnregisteredDialects));
}
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2016-present, Facebook, Inc.
 *
 * 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
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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 "caffe2/core/context.h"
#include "caffe2/core/operator.h"
#include "caffe2/mkl/mkl_utils.h"

#ifdef CAFFE2_HAS_MKL_DNN

namespace caffe2 {
namespace mkl {

template <typename T>
class MKLFullyConnectedOp final : public MKLOperator<T> {
 public:
  MKLFullyConnectedOp(const OperatorDef& operator_def, Workspace* ws)
      : MKLOperator<T>(operator_def, ws),
        axis_(OperatorBase::GetSingleArgument<int32_t>("axis", 1)) {}
  ~MKLFullyConnectedOp() {}

  bool RunOnDevice() override {
    auto& X = OperatorBase::Input<MKLMemory<float>>(INPUT);
    auto& filter = OperatorBase::Input<MKLMemory<float>>(FILTER);
    auto& bias = OperatorBase::Input<MKLMemory<float>>(BIAS);
    MKLMemory<float>* Y = OperatorBase::Output<MKLMemory<float>>(0);

    CAFFE_ENFORCE(filter.ndim() == 2, filter.ndim());
    CAFFE_ENFORCE(bias.ndim() == 1, bias.ndim());

    bool dims_changed;
    CHECK_INPUT_FILTER_DIMS(X, filter, dims_changed);
    if (dims_changed) {
      const int N = filter.dim32(0);
      CAFFE_ENFORCE(N == bias.dim32(0));

      auto Y_shape = X.dims();
      Y_shape[1] = N;
      Y_shape.resize(2);

      size_t inputSizes[4];
      if (X.ndim() == 2) {
        inputSizes[0] = X.dim32(1);
        inputSizes[1] = X.dim32(0);
      } else {
        inputSizes[0] = X.dim32(3);
        inputSizes[1] = X.dim32(2);
        inputSizes[2] = X.dim32(1);
        inputSizes[3] = X.dim32(0);
      }

      size_t outputSizes[2] = {Y_shape[1], Y_shape[0]};

      primitive_.Reset(
          dnnInnerProductCreateForwardBias<float>,
          nullptr,
          X.ndim(),
          inputSizes,
          outputSizes[0]);

      Y->Reset(Y_shape, primitive_, dnnResourceDst);
      buffer_.Reset(Y_shape, primitive_, dnnResourceDst, true);

      input_layout_.Reset(primitive_, dnnResourceSrc);
      filter_layout_.Reset(primitive_, dnnResourceFilter);
    }

    // Try to share from the output: this allows us to avoid unnecessary copy
    // operations, if the output is already allocated and is having the same
    // layout as the buffer has.
    buffer_.ShareFrom(*Y);

    std::shared_ptr<void> X_view =
        X.View(input_layout_, primitive_, dnnResourceSrc);
    std::shared_ptr<void> filter_view =
        filter.View(filter_layout_, primitive_, dnnResourceFilter);

    resources_[dnnResourceSrc] = X_view.get();
    resources_[dnnResourceFilter] = filter_view.get();

    resources_[dnnResourceBias] = bias.buffer();
    resources_[dnnResourceDst] = buffer_.buffer();

    MKLDNN_SAFE_CALL(mkl::dnnExecute<T>(primitive_, resources_));
    buffer_.CopyTo(Y, primitive_, dnnResourceDst);
    return true;
  }

 private:
  // Input: X, W, b
  // Output: Y
  size_t axis_{1};
  vector<TIndex> cached_input_dims_;
  vector<TIndex> cached_filter_dims_;
  PrimitiveWrapper<T> primitive_;
  LayoutWrapper<T> input_layout_;
  LayoutWrapper<T> filter_layout_;
  LayoutWrapper<T> bias_layout_;
  MKLMemory<T> buffer_;
  void* resources_[dnnResourceNumber] = {0};
  INPUT_TAGS(INPUT, FILTER, BIAS);
};

} // namespace mkl

REGISTER_MKL_OPERATOR(FC, mkl::MKLFullyConnectedOp<float>);

} // namespace caffe2

#endif // CAFFE2_HAS_MKL_DNN
<commit_msg>Fix FC op invariant<commit_after>/**
 * Copyright (c) 2016-present, Facebook, Inc.
 *
 * 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
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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 "caffe2/core/context.h"
#include "caffe2/core/operator.h"
#include "caffe2/mkl/mkl_utils.h"

#ifdef CAFFE2_HAS_MKL_DNN

namespace caffe2 {
namespace mkl {

template <typename T>
class MKLFullyConnectedOp final : public MKLOperator<T> {
 public:
  MKLFullyConnectedOp(const OperatorDef& operator_def, Workspace* ws)
      : MKLOperator<T>(operator_def, ws),
        axis_(OperatorBase::GetSingleArgument<int32_t>("axis", 1)) {}
  ~MKLFullyConnectedOp() {}

  bool RunOnDevice() override {
    auto& X = OperatorBase::Input<MKLMemory<float>>(INPUT);
    auto& filter = OperatorBase::Input<MKLMemory<float>>(FILTER);
    auto& bias = OperatorBase::Input<MKLMemory<float>>(BIAS);
    MKLMemory<float>* Y = OperatorBase::Output<MKLMemory<float>>(0);

    CAFFE_ENFORCE(filter.ndim() == 2, filter.ndim());
    CAFFE_ENFORCE(bias.ndim() == 1, bias.ndim());

    bool dims_changed;
    CHECK_INPUT_FILTER_DIMS(X, filter, dims_changed);
    if (dims_changed) {
      const int N = filter.dim32(0);
      CAFFE_ENFORCE(N == bias.dim32(0));

      auto Y_shape = X.dims();
      Y_shape[1] = N;
      Y_shape.resize(2);

      size_t inputSizes[4];
      if (X.ndim() == 2) {
        inputSizes[0] = X.dim32(1);
        inputSizes[1] = X.dim32(0);
      } else {
        CAFFE_ENFORCE(X.ndim(), 4);
        inputSizes[0] = X.dim32(3);
        inputSizes[1] = X.dim32(2);
        inputSizes[2] = X.dim32(1);
        inputSizes[3] = X.dim32(0);
      }

      size_t outputSizes[2] = {Y_shape[1], Y_shape[0]};

      primitive_.Reset(
          dnnInnerProductCreateForwardBias<float>,
          nullptr,
          X.ndim(),
          inputSizes,
          outputSizes[0]);

      Y->Reset(Y_shape, primitive_, dnnResourceDst);
      buffer_.Reset(Y_shape, primitive_, dnnResourceDst, true);

      input_layout_.Reset(primitive_, dnnResourceSrc);
      filter_layout_.Reset(primitive_, dnnResourceFilter);
    }

    // Try to share from the output: this allows us to avoid unnecessary copy
    // operations, if the output is already allocated and is having the same
    // layout as the buffer has.
    buffer_.ShareFrom(*Y);

    std::shared_ptr<void> X_view =
        X.View(input_layout_, primitive_, dnnResourceSrc);
    std::shared_ptr<void> filter_view =
        filter.View(filter_layout_, primitive_, dnnResourceFilter);

    resources_[dnnResourceSrc] = X_view.get();
    resources_[dnnResourceFilter] = filter_view.get();

    resources_[dnnResourceBias] = bias.buffer();
    resources_[dnnResourceDst] = buffer_.buffer();

    MKLDNN_SAFE_CALL(mkl::dnnExecute<T>(primitive_, resources_));
    buffer_.CopyTo(Y, primitive_, dnnResourceDst);
    return true;
  }

 private:
  // Input: X, W, b
  // Output: Y
  size_t axis_{1};
  vector<TIndex> cached_input_dims_;
  vector<TIndex> cached_filter_dims_;
  PrimitiveWrapper<T> primitive_;
  LayoutWrapper<T> input_layout_;
  LayoutWrapper<T> filter_layout_;
  LayoutWrapper<T> bias_layout_;
  MKLMemory<T> buffer_;
  void* resources_[dnnResourceNumber] = {0};
  INPUT_TAGS(INPUT, FILTER, BIAS);
};

} // namespace mkl

REGISTER_MKL_OPERATOR(FC, mkl::MKLFullyConnectedOp<float>);

} // namespace caffe2

#endif // CAFFE2_HAS_MKL_DNN
<|endoftext|>