<commit_before>#include "../SDP_Solver_Parameters.hxx"

#include <boost/program_options.hpp>
#include <boost/filesystem/fstream.hpp>

namespace po = boost::program_options;

SDP_Solver_Parameters::SDP_Solver_Parameters(int argc, char *argv[])
{
  int int_verbosity;
  std::string write_solution_string;
  using namespace std::string_literals;

  po::options_description required_options("Required options");
  required_options.add_options()(
    "sdpDir,s", po::value<boost::filesystem::path>(&sdp_directory)->required(),
    "Directory containing preprocessed SDP data files.");
  required_options.add_options()(
    "procsPerNode", po::value<size_t>(&procs_per_node)->required(),
    "The number of processes that can run on a node.  When running on "
    "more "
    "than one node, the load balancer needs to know how many processes "
    "are assigned to each node.  On a laptop or desktop, this would be "
    "the number of physical cores on your machine, not including "
    "hyperthreaded cores.  For current laptops (2018), this is probably "
    "2 or 4.\n\n"
    "If you are using the Slurm workload manager, this should be set to "
    "'$SLURM_NTASKS_PER_NODE'.");

  po::options_description basic_options("Basic options");
  basic_options.add_options()("help,h", "Show this helpful message.");
  basic_options.add_options()("version",
                              "Show version and configuration info.");
  basic_options.add_options()(
    "paramFile,p", po::value<boost::filesystem::path>(&param_file),
    "Any parameter can optionally be set via this file in key=value "
    "format. Command line arguments override values in the parameter "
    "file.");
  basic_options.add_options()(
    "outDir,o", po::value<boost::filesystem::path>(&out_directory),
    "The optimal solution is saved to this directory in Mathematica "
    "format. Defaults to sdpDir with '_out' appended.");
  basic_options.add_options()(
    "checkpointDir,c", po::value<boost::filesystem::path>(&checkpoint_out),
    "Checkpoints are saved to this directory every checkpointInterval. "
    "Defaults to sdpDir with '.ck' extension.");
  basic_options.add_options()(
    "initialCheckpointDir,i",
    po::value<boost::filesystem::path>(&checkpoint_in),
    "The initial checkpoint directory to load. Defaults to "
    "checkpointDir.");
  basic_options.add_options()(
    "checkpointInterval",
    po::value<int64_t>(&checkpoint_interval)->default_value(3600),
    "Save checkpoints to checkpointDir every checkpointInterval "
    "seconds.");
  basic_options.add_options()(
    "noFinalCheckpoint",
    po::bool_switch(&no_final_checkpoint)->default_value(false),
    "Don't save a final checkpoint after terminating (useful when "
    "debugging).");
  basic_options.add_options()(
    "writeSolution",
    po::value<std::string>(&write_solution_string)->default_value("x,y"s),
    "A comma separated list of vectors and matrices to write into the output "
    "directory.  The default only writes the vectors 'x' and 'y'.  If you add "
    "the 'X' and 'Y' matrices, then the output directory can be used as a "
    "final text "
    "checkpoint.  Runs started from text checkpoints will very close to, but "
    "not bitwise identical to, the original run.  To only output the result "
    "(because, for example, you only want to know if SDPB found a primal "
    "feasible point), set this to an empty string.");
  basic_options.add_options()(
    "procGranularity", po::value<size_t>(&proc_granularity)->default_value(1),
    "procGranularity must evenly divide procsPerNode.\n\n"
    "The minimum number of cores in a group, used during load balancing.  "
    "Setting it to anything larger than 1 will make the solution take "
    "longer.  "
    "This option is generally useful only when trying to fit a large problem "
    "in a small machine.");
  basic_options.add_options()("verbosity",
                              po::value<int>(&int_verbosity)->default_value(1),
                              "Verbosity.  0 -> no output, 1 -> regular "
                              "output, 2 -> debug output");

  // We set default parameters using El::BigFloat("1e-10",10)
  // rather than a straight double precision 1e-10 so that results
  // are more reproducible at high precision.  Using double
  // precision defaults results in differences of about 1e-15 in
  // primalObjective after one step.
  po::options_description solver_options("Solver parameters");
  solver_options.add_options()(
    "precision", po::value<size_t>(&precision)->default_value(400),
    "The precision, in the number of bits, for numbers in the "
    "computation. "
    " This should be less than or equal to the precision used when "
    "preprocessing the XML input files with 'pvm2sdp'.  GMP will round "
    "this up to a multiple of 32 or 64, depending on the system.");
  solver_options.add_options()(
    "findPrimalFeasible",
    po::bool_switch(&find_primal_feasible)->default_value(false),
    "Terminate once a primal feasible solution is found.");
  solver_options.add_options()(
    "findDualFeasible",
    po::bool_switch(&find_dual_feasible)->default_value(false),
    "Terminate once a dual feasible solution is found.");
  solver_options.add_options()(
    "detectPrimalFeasibleJump",
    po::bool_switch(&detect_primal_feasible_jump)->default_value(false),
    "Terminate if a primal-step of 1 is taken. This often indicates that "
    "a "
    "primal feasible solution would be found if the precision were high "
    "enough. Try increasing either primalErrorThreshold or precision "
    "and run from the latest checkpoint.");
  solver_options.add_options()(
    "detectDualFeasibleJump",
    po::bool_switch(&detect_dual_feasible_jump)->default_value(false),
    "Terminate if a dual-step of 1 is taken. This often indicates that a "
    "dual feasible solution would be found if the precision were high "
    "enough. Try increasing either dualErrorThreshold or precision "
    "and run from the latest checkpoint.");
  solver_options.add_options()(
    "maxIterations", po::value<int64_t>(&max_iterations)->default_value(500),
    "Maximum number of iterations to run the solver.");
  solver_options.add_options()(
    "maxRuntime", po::value<int64_t>(&max_runtime)->default_value(86400),
    "Maximum amount of time to run the solver in seconds.");
  solver_options.add_options()(
    "dualityGapThreshold",
    po::value<El::BigFloat>(&duality_gap_threshold)
      ->default_value(El::BigFloat("1e-30", 10)),
    "Threshold for duality gap (roughly the difference in primal and dual "
    "objective) at which the solution is considered "
    "optimal. Corresponds to SDPA's epsilonStar.");
  solver_options.add_options()(
    "primalErrorThreshold",
    po::value<El::BigFloat>(&primal_error_threshold)
      ->default_value(El::BigFloat("1e-30", 10)),
    "Threshold for feasibility of the primal problem. Corresponds to "
    "SDPA's epsilonBar.");
  solver_options.add_options()(
    "dualErrorThreshold",
    po::value<El::BigFloat>(&dual_error_threshold)
      ->default_value(El::BigFloat("1e-30", 10)),
    "Threshold for feasibility of the dual problem. Corresponds to SDPA's "
    "epsilonBar.");
  solver_options.add_options()(
    "initialMatrixScalePrimal",
    po::value<El::BigFloat>(&initial_matrix_scale_primal)
      ->default_value(El::BigFloat("1e20", 10)),
    "The primal matrix X begins at initialMatrixScalePrimal times the "
    "identity matrix. Corresponds to SDPA's lambdaStar.");
  solver_options.add_options()(
    "initialMatrixScaleDual",
    po::value<El::BigFloat>(&initial_matrix_scale_dual)
      ->default_value(El::BigFloat("1e20", 10)),
    "The dual matrix Y begins at initialMatrixScaleDual times the "
    "identity matrix. Corresponds to SDPA's lambdaStar.");
  solver_options.add_options()(
    "feasibleCenteringParameter",
    po::value<El::BigFloat>(&feasible_centering_parameter)
      ->default_value(El::BigFloat("0.1", 10)),
    "Shrink the complementarity X Y by this factor when the primal and "
    "dual "
    "problems are feasible. Corresponds to SDPA's betaStar.");
  solver_options.add_options()(
    "infeasibleCenteringParameter",
    po::value<El::BigFloat>(&infeasible_centering_parameter)
      ->default_value(El::BigFloat("0.3", 10)),
    "Shrink the complementarity X Y by this factor when either the primal "
    "or dual problems are infeasible. Corresponds to SDPA's betaBar.");
  solver_options.add_options()(
    "stepLengthReduction",
    po::value<El::BigFloat>(&step_length_reduction)
      ->default_value(El::BigFloat("0.7", 10)),
    "Shrink each newton step by this factor (smaller means slower, more "
    "stable convergence). Corresponds to SDPA's gammaStar.");
  solver_options.add_options()(
    "maxComplementarity",
    po::value<El::BigFloat>(&max_complementarity)
      ->default_value(El::BigFloat("1e100", 10)),
    "Terminate if the complementarity mu = Tr(X Y)/dim(X) "
    "exceeds this value.");

  po::options_description cmd_line_options;
  cmd_line_options.add(required_options).add(basic_options).add(solver_options);

  po::variables_map variables_map;
  try
    {
      po::store(po::parse_command_line(argc, argv, cmd_line_options),
                variables_map);

      if(variables_map.count("help") != 0)
        {
          if(El::mpi::Rank() == 0)
            {
              std::cout << cmd_line_options << '\n';
            }
        }
      else if(variables_map.count("version") != 0)
        {
          if(El::mpi::Rank() == 0)
            {
              std::cout << "SDPB " << SDPB_VERSION_STRING << "\n";
            }
          El::PrintVersion();
          El::PrintConfig();
          El::PrintCCompilerInfo();
          El::PrintCxxCompilerInfo();
        }
      else
        {
          if(variables_map.count("paramFile") != 0)
            {
              param_file
                = variables_map["paramFile"].as<boost::filesystem::path>();
              std::ifstream ifs(param_file.string().c_str());
              if(!ifs.good())
                {
                  throw std::runtime_error("Could not open '"
                                           + param_file.string() + "'");
                }

              po::store(po::parse_config_file(ifs, cmd_line_options),
                        variables_map);
            }

          po::notify(variables_map);

          if(!boost::filesystem::exists(sdp_directory))
            {
              throw std::runtime_error("sdp directory '"
                                       + sdp_directory.string()
                                       + "' does not exist");
            }
          if(!boost::filesystem::is_directory(sdp_directory))
            {
              throw std::runtime_error("sdp directory '"
                                       + sdp_directory.string()
                                       + "' is not a directory");
            }

          if(variables_map.count("outDir") == 0)
            {
              out_directory = sdp_directory;
              if(out_directory.filename() == ".")
                {
                  out_directory = out_directory.parent_path();
                }
              out_directory += "_out";
            }

          if(variables_map.count("checkpointDir") == 0)
            {
              checkpoint_out = sdp_directory;
              if(checkpoint_out.filename() == ".")
                {
                  checkpoint_out = checkpoint_out.parent_path();
                }
              checkpoint_out += ".ck";
            }

          if(variables_map.count("initialCheckpointDir") == 0)
            {
              checkpoint_in = checkpoint_out;
            }
          else
            {
              require_initial_checkpoint = true;
            }

          write_solution=Write_Solution(write_solution_string);

          if(El::mpi::Rank() == 0)
            {
              boost::filesystem::create_directories(out_directory);
              boost::filesystem::ofstream ofs(out_directory / "out.txt");
              if(!ofs.good())
                {
                  throw std::runtime_error("Cannot write to outDir: "
                                           + out_directory.string());
                }
            }

          if(int_verbosity != 0 && int_verbosity != 1 && int_verbosity != 2)
            {
              throw std::runtime_error(
                "Invalid number for Verbosity.  Only 0, 1 or 2 are allowed\n");
            }
          else
            {
              verbosity = static_cast<Verbosity>(int_verbosity);
            }
        }
    }
  catch(po::error &e)
    {
      El::ReportException(e);
      El::mpi::Abort(El::mpi::COMM_WORLD, 1);
    }
}
<commit_msg>Change default maxRuntime to effectively infinity<commit_after>#include "../SDP_Solver_Parameters.hxx"

#include <boost/program_options.hpp>
#include <boost/filesystem/fstream.hpp>

namespace po = boost::program_options;

SDP_Solver_Parameters::SDP_Solver_Parameters(int argc, char *argv[])
{
  int int_verbosity;
  std::string write_solution_string;
  using namespace std::string_literals;

  po::options_description required_options("Required options");
  required_options.add_options()(
    "sdpDir,s", po::value<boost::filesystem::path>(&sdp_directory)->required(),
    "Directory containing preprocessed SDP data files.");
  required_options.add_options()(
    "procsPerNode", po::value<size_t>(&procs_per_node)->required(),
    "The number of processes that can run on a node.  When running on "
    "more "
    "than one node, the load balancer needs to know how many processes "
    "are assigned to each node.  On a laptop or desktop, this would be "
    "the number of physical cores on your machine, not including "
    "hyperthreaded cores.  For current laptops (2018), this is probably "
    "2 or 4.\n\n"
    "If you are using the Slurm workload manager, this should be set to "
    "'$SLURM_NTASKS_PER_NODE'.");

  po::options_description basic_options("Basic options");
  basic_options.add_options()("help,h", "Show this helpful message.");
  basic_options.add_options()("version",
                              "Show version and configuration info.");
  basic_options.add_options()(
    "paramFile,p", po::value<boost::filesystem::path>(&param_file),
    "Any parameter can optionally be set via this file in key=value "
    "format. Command line arguments override values in the parameter "
    "file.");
  basic_options.add_options()(
    "outDir,o", po::value<boost::filesystem::path>(&out_directory),
    "The optimal solution is saved to this directory in Mathematica "
    "format. Defaults to sdpDir with '_out' appended.");
  basic_options.add_options()(
    "checkpointDir,c", po::value<boost::filesystem::path>(&checkpoint_out),
    "Checkpoints are saved to this directory every checkpointInterval. "
    "Defaults to sdpDir with '.ck' extension.");
  basic_options.add_options()(
    "initialCheckpointDir,i",
    po::value<boost::filesystem::path>(&checkpoint_in),
    "The initial checkpoint directory to load. Defaults to "
    "checkpointDir.");
  basic_options.add_options()(
    "checkpointInterval",
    po::value<int64_t>(&checkpoint_interval)->default_value(3600),
    "Save checkpoints to checkpointDir every checkpointInterval "
    "seconds.");
  basic_options.add_options()(
    "noFinalCheckpoint",
    po::bool_switch(&no_final_checkpoint)->default_value(false),
    "Don't save a final checkpoint after terminating (useful when "
    "debugging).");
  basic_options.add_options()(
    "writeSolution",
    po::value<std::string>(&write_solution_string)->default_value("x,y"s),
    "A comma separated list of vectors and matrices to write into the output "
    "directory.  The default only writes the vectors 'x' and 'y'.  If you add "
    "the 'X' and 'Y' matrices, then the output directory can be used as a "
    "final text "
    "checkpoint.  Runs started from text checkpoints will very close to, but "
    "not bitwise identical to, the original run.  To only output the result "
    "(because, for example, you only want to know if SDPB found a primal "
    "feasible point), set this to an empty string.");
  basic_options.add_options()(
    "procGranularity", po::value<size_t>(&proc_granularity)->default_value(1),
    "procGranularity must evenly divide procsPerNode.\n\n"
    "The minimum number of cores in a group, used during load balancing.  "
    "Setting it to anything larger than 1 will make the solution take "
    "longer.  "
    "This option is generally useful only when trying to fit a large problem "
    "in a small machine.");
  basic_options.add_options()("verbosity",
                              po::value<int>(&int_verbosity)->default_value(1),
                              "Verbosity.  0 -> no output, 1 -> regular "
                              "output, 2 -> debug output");

  // We set default parameters using El::BigFloat("1e-10",10)
  // rather than a straight double precision 1e-10 so that results
  // are more reproducible at high precision.  Using double
  // precision defaults results in differences of about 1e-15 in
  // primalObjective after one step.
  po::options_description solver_options("Solver parameters");
  solver_options.add_options()(
    "precision", po::value<size_t>(&precision)->default_value(400),
    "The precision, in the number of bits, for numbers in the "
    "computation. "
    " This should be less than or equal to the precision used when "
    "preprocessing the XML input files with 'pvm2sdp'.  GMP will round "
    "this up to a multiple of 32 or 64, depending on the system.");
  solver_options.add_options()(
    "findPrimalFeasible",
    po::bool_switch(&find_primal_feasible)->default_value(false),
    "Terminate once a primal feasible solution is found.");
  solver_options.add_options()(
    "findDualFeasible",
    po::bool_switch(&find_dual_feasible)->default_value(false),
    "Terminate once a dual feasible solution is found.");
  solver_options.add_options()(
    "detectPrimalFeasibleJump",
    po::bool_switch(&detect_primal_feasible_jump)->default_value(false),
    "Terminate if a primal-step of 1 is taken. This often indicates that "
    "a "
    "primal feasible solution would be found if the precision were high "
    "enough. Try increasing either primalErrorThreshold or precision "
    "and run from the latest checkpoint.");
  solver_options.add_options()(
    "detectDualFeasibleJump",
    po::bool_switch(&detect_dual_feasible_jump)->default_value(false),
    "Terminate if a dual-step of 1 is taken. This often indicates that a "
    "dual feasible solution would be found if the precision were high "
    "enough. Try increasing either dualErrorThreshold or precision "
    "and run from the latest checkpoint.");
  solver_options.add_options()(
    "maxIterations", po::value<int64_t>(&max_iterations)->default_value(500),
    "Maximum number of iterations to run the solver.");
  solver_options.add_options()(
    "maxRuntime",
    po::value<int64_t>(&max_runtime)
      ->default_value(std::numeric_limits<int64_t>::max()),
    "Maximum amount of time to run the solver in seconds.");
  solver_options.add_options()(
    "dualityGapThreshold",
    po::value<El::BigFloat>(&duality_gap_threshold)
      ->default_value(El::BigFloat("1e-30", 10)),
    "Threshold for duality gap (roughly the difference in primal and dual "
    "objective) at which the solution is considered "
    "optimal. Corresponds to SDPA's epsilonStar.");
  solver_options.add_options()(
    "primalErrorThreshold",
    po::value<El::BigFloat>(&primal_error_threshold)
      ->default_value(El::BigFloat("1e-30", 10)),
    "Threshold for feasibility of the primal problem. Corresponds to "
    "SDPA's epsilonBar.");
  solver_options.add_options()(
    "dualErrorThreshold",
    po::value<El::BigFloat>(&dual_error_threshold)
      ->default_value(El::BigFloat("1e-30", 10)),
    "Threshold for feasibility of the dual problem. Corresponds to SDPA's "
    "epsilonBar.");
  solver_options.add_options()(
    "initialMatrixScalePrimal",
    po::value<El::BigFloat>(&initial_matrix_scale_primal)
      ->default_value(El::BigFloat("1e20", 10)),
    "The primal matrix X begins at initialMatrixScalePrimal times the "
    "identity matrix. Corresponds to SDPA's lambdaStar.");
  solver_options.add_options()(
    "initialMatrixScaleDual",
    po::value<El::BigFloat>(&initial_matrix_scale_dual)
      ->default_value(El::BigFloat("1e20", 10)),
    "The dual matrix Y begins at initialMatrixScaleDual times the "
    "identity matrix. Corresponds to SDPA's lambdaStar.");
  solver_options.add_options()(
    "feasibleCenteringParameter",
    po::value<El::BigFloat>(&feasible_centering_parameter)
      ->default_value(El::BigFloat("0.1", 10)),
    "Shrink the complementarity X Y by this factor when the primal and "
    "dual "
    "problems are feasible. Corresponds to SDPA's betaStar.");
  solver_options.add_options()(
    "infeasibleCenteringParameter",
    po::value<El::BigFloat>(&infeasible_centering_parameter)
      ->default_value(El::BigFloat("0.3", 10)),
    "Shrink the complementarity X Y by this factor when either the primal "
    "or dual problems are infeasible. Corresponds to SDPA's betaBar.");
  solver_options.add_options()(
    "stepLengthReduction",
    po::value<El::BigFloat>(&step_length_reduction)
      ->default_value(El::BigFloat("0.7", 10)),
    "Shrink each newton step by this factor (smaller means slower, more "
    "stable convergence). Corresponds to SDPA's gammaStar.");
  solver_options.add_options()(
    "maxComplementarity",
    po::value<El::BigFloat>(&max_complementarity)
      ->default_value(El::BigFloat("1e100", 10)),
    "Terminate if the complementarity mu = Tr(X Y)/dim(X) "
    "exceeds this value.");

  po::options_description cmd_line_options;
  cmd_line_options.add(required_options).add(basic_options).add(solver_options);

  po::variables_map variables_map;
  try
    {
      po::store(po::parse_command_line(argc, argv, cmd_line_options),
                variables_map);

      if(variables_map.count("help") != 0)
        {
          if(El::mpi::Rank() == 0)
            {
              std::cout << cmd_line_options << '\n';
            }
        }
      else if(variables_map.count("version") != 0)
        {
          if(El::mpi::Rank() == 0)
            {
              std::cout << "SDPB " << SDPB_VERSION_STRING << "\n";
            }
          El::PrintVersion();
          El::PrintConfig();
          El::PrintCCompilerInfo();
          El::PrintCxxCompilerInfo();
        }
      else
        {
          if(variables_map.count("paramFile") != 0)
            {
              param_file
                = variables_map["paramFile"].as<boost::filesystem::path>();
              std::ifstream ifs(param_file.string().c_str());
              if(!ifs.good())
                {
                  throw std::runtime_error("Could not open '"
                                           + param_file.string() + "'");
                }

              po::store(po::parse_config_file(ifs, cmd_line_options),
                        variables_map);
            }

          po::notify(variables_map);

          if(!boost::filesystem::exists(sdp_directory))
            {
              throw std::runtime_error("sdp directory '"
                                       + sdp_directory.string()
                                       + "' does not exist");
            }
          if(!boost::filesystem::is_directory(sdp_directory))
            {
              throw std::runtime_error("sdp directory '"
                                       + sdp_directory.string()
                                       + "' is not a directory");
            }

          if(variables_map.count("outDir") == 0)
            {
              out_directory = sdp_directory;
              if(out_directory.filename() == ".")
                {
                  out_directory = out_directory.parent_path();
                }
              out_directory += "_out";
            }

          if(variables_map.count("checkpointDir") == 0)
            {
              checkpoint_out = sdp_directory;
              if(checkpoint_out.filename() == ".")
                {
                  checkpoint_out = checkpoint_out.parent_path();
                }
              checkpoint_out += ".ck";
            }

          if(variables_map.count("initialCheckpointDir") == 0)
            {
              checkpoint_in = checkpoint_out;
            }
          else
            {
              require_initial_checkpoint = true;
            }

          write_solution = Write_Solution(write_solution_string);

          if(El::mpi::Rank() == 0)
            {
              boost::filesystem::create_directories(out_directory);
              boost::filesystem::ofstream ofs(out_directory / "out.txt");
              if(!ofs.good())
                {
                  throw std::runtime_error("Cannot write to outDir: "
                                           + out_directory.string());
                }
            }

          if(int_verbosity != 0 && int_verbosity != 1 && int_verbosity != 2)
            {
              throw std::runtime_error(
                "Invalid number for Verbosity.  Only 0, 1 or 2 are allowed\n");
            }
          else
            {
              verbosity = static_cast<Verbosity>(int_verbosity);
            }
        }
    }
  catch(po::error &e)
    {
      El::ReportException(e);
      El::mpi::Abort(El::mpi::COMM_WORLD, 1);
    }
}
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <cstring>
#include <cmath>
#include <ctime>
#include <fstream>
#include <sstream>
#include <exception>
#include <cstring>
#include <boost/tokenizer.hpp>
#include <boost/circular_buffer.hpp>
#include <boost/filesystem.hpp>
#include <map>
#include <set>
#include <unordered_map>
#include <cstdarg>
#include "options.hpp"
#include "basic_utils/stream_reader.hpp"

typedef int64_t Index;

#include "basic_utils/utils.hpp"
#include "vocabulary.hpp"
#include "json.hpp"

using json = nlohmann::json;
typedef std::map<Index,Index> Accumulator;
std::vector<Accumulator> counters;
json metadata;

Vocabulary vocab;

#include "basic_utils/file_io.hpp"

struct window_params
{
    uint64_t size_window;
    bool symmetric;
};

std::string get_str_time()
{
    std::time_t result = std::time(nullptr);
    auto res = std::asctime(std::localtime(&result));
    return std::string(res);
}

int main(int argc, char * argv[])
{
    auto time_start = std::time(nullptr);
    Options options = ProcessOptions(argc,argv);
    auto str_path_in = options.path_in.string();
    auto path_out=options.path_out;
    if (boost::filesystem::create_directory(path_out))
    {
        std::cerr << "creating target directory\n";
    }
    metadata["timestamp"] = get_str_time();
    metadata["path_source"] = str_path_in;

    std::cerr<<"assigning ids\n";
    vocab.read_from_dir(str_path_in);

    metadata["size_corpus"] = vocab.cnt_words_processed;
    metadata["cnt_words_untrimmed"] = vocab.cnt_words;

    vocab.reduce(options.min_frequency);
    metadata["min_frequency"] = options.min_frequency;
    metadata["cnt_words"] = vocab.cnt_words;

    std::cerr<<"creating list of frequencies\n";

    vocab.freq_per_id.resize(vocab.cnt_words);
    vocab.lst_id2word.resize(vocab.cnt_words);
    std::fill (vocab.freq_per_id.begin(),vocab.freq_per_id.end(),0);
    std::cerr<<"populating frequencies\n";
    vocab.populate_frequency();
    vocab.reassign_ids(vocab.freq_per_id);
    vocab.populate_frequency();
    vocab.populate_ids();
    auto time_end = std::time(nullptr);
    metadata["execution_time"] = time_end - time_start;
    std::cerr<<"dumping ids and frequencies\n";

    vocab.dump_ids((path_out / boost::filesystem::path("ids")).string());
    vocab.dump_frequency((path_out / boost::filesystem::path("frequencies")).string());
    write_vector_to_file((path_out / boost::filesystem::path("freq_per_id")).string(),vocab.freq_per_id);
    write_value_to_file((path_out / boost::filesystem::path("metadata.json")).string(), metadata.dump(4));

    return 0;
}<commit_msg>style<commit_after>#include <iostream>
#include <string>
#include <cstring>
#include <cmath>
#include <ctime>
#include <fstream>
#include <sstream>
#include <exception>
#include <cstring>
#include <boost/tokenizer.hpp>
#include <boost/circular_buffer.hpp>
#include <boost/filesystem.hpp>
#include <map>
#include <set>
#include <unordered_map>
#include <cstdarg>
#include "options.hpp"
#include "basic_utils/stream_reader.hpp"

typedef int64_t Index;

#include "basic_utils/utils.hpp"
#include "vocabulary.hpp"
#include "json.hpp"

using json = nlohmann::json;
typedef std::map<Index, Index> Accumulator;
std::vector<Accumulator> counters;
json metadata;

Vocabulary vocab;

#include "basic_utils/file_io.hpp"

struct window_params
{
    uint64_t size_window;
    bool symmetric;
};

std::string get_str_time()
{
    std::time_t result = std::time(nullptr);
    auto res = std::asctime(std::localtime(&result));
    return std::string(res);
}

int main(int argc, char * argv[])
{
    auto time_start = std::time(nullptr);
    Options options = ProcessOptions(argc, argv);
    auto str_path_in = options.path_in.string();
    auto path_out = options.path_out;
    if (boost::filesystem::create_directory(path_out))
    {
        std::cerr << "creating target directory\n";
    }
    metadata["timestamp"] = get_str_time();
    metadata["path_source"] = str_path_in;

    std::cerr << "assigning ids\n";
    vocab.read_from_dir(str_path_in);

    metadata["size_corpus"] = vocab.cnt_words_processed;
    metadata["cnt_words_untrimmed"] = vocab.cnt_words;

    vocab.reduce(options.min_frequency);
    metadata["min_frequency"] = options.min_frequency;
    metadata["cnt_words"] = vocab.cnt_words;

    std::cerr << "creating list of frequencies\n";

    vocab.freq_per_id.resize(vocab.cnt_words);
    vocab.lst_id2word.resize(vocab.cnt_words);
    std::fill (vocab.freq_per_id.begin(), vocab.freq_per_id.end(), 0);
    std::cerr << "populating frequencies\n";
    vocab.populate_frequency();
    vocab.reassign_ids(vocab.freq_per_id);
    vocab.populate_frequency();
    vocab.populate_ids();
    auto time_end = std::time(nullptr);
    metadata["execution_time"] = time_end - time_start;
    std::cerr << "dumping ids and frequencies\n";

    vocab.dump_ids((path_out / boost::filesystem::path("ids")).string());
    vocab.dump_frequency((path_out / boost::filesystem::path("frequencies")).string());
    write_vector_to_file((path_out / boost::filesystem::path("freq_per_id")).string(), vocab.freq_per_id);
    write_value_to_file((path_out / boost::filesystem::path("metadata.json")).string(), metadata.dump(4));

    return 0;
}<|endoftext|>


<commit_before>/**
 * \class DirectionlessOdometer
 * A class to represent the common - directionless - Odometers (speed encoders)
 * that can be used to primarily measure the travelled distance of the car
 * as well as its speed.
 */
#pragma once

#include <stdint.h>

#include "../../../runtime/Runtime.hpp"
#include "../Odometer.hpp"

#ifdef SMARTCAR_BUILD_FOR_ARDUINO
#include "../../../runtime/arduino_runtime/ArduinoRuntime.hpp"
extern ArduinoRuntime arduinoRuntime;
#endif

class DirectionlessOdometer : public Odometer
{
public:
#ifdef SMARTCAR_BUILD_FOR_ARDUINO
    /**
     * Constructs an odometer that can measure distance, speed but not direction
     * @param pulsesPerMeter The amount of odometer pulses that constitute a meter
     *
     * **Example:**
     * \code
     * unsigned short ODOMETER_PIN = 32;
     * unsigned long PULSES_PER_METER = 110;
     *
     * DirectionlessOdometer odometer(ODOMETER_PIN,
     *                                []() { odometer.update(); },
     *                                PULSES_PER_METER);
     * \endcode
     */
    DirectionlessOdometer(uint8_t pin,
                          InterruptCallback callback,
                          unsigned long pulsesPerMeter,
                          Runtime& runtime = arduinoRuntime);
#else
    DirectionlessOdometer(uint8_t pin,
                          InterruptCallback callback,
                          unsigned long pulsesPerMeter,
                          Runtime& runtime);
#endif

    virtual ~DirectionlessOdometer() = default;

    /* Check `Odometer` interface for documentation */
    long getDistance() override;

    /* Check `Odometer` interface for documentation */
    float getSpeed() override;

    /* Check `Odometer` interface for documentation */
    bool isAttached() const override;

    /* Check `Odometer` interface for documentation */
    bool providesDirection() const override;

    /**
     * Resets the total travelled distance and speed to `0`
     */
    virtual void reset();

    /**
     * Conducts the distance and speed measurements.
     * Updates the current dt with the time difference between the last two pulses
     * and increases the pulse counter.
     * **Do not** call it directly in your sketch!
     * Instead, pass it in a lambda to the constructor.
     */
    virtual void update();

    volatile unsigned long mPulsesCounter{ 0 };

protected:
    const float mPulsesPerMeterRatio;

private:
    const unsigned long mMillimetersPerPulse;
    Runtime& mRuntime;
    const bool kSensorAttached;
    // volatile unsigned long mPulsesCounter{ 0 };
    volatile unsigned long mPreviousPulse{ 0 };
    volatile unsigned long mDt{ 0 };
};

/**
 * \example findPulsesPerMeter.ino
 * An example on how to determine how many pulses are emitted from your Odometer
 * for every meter travelled. The output should be supplied to the constructor.
 *
 * \example singleOdometer.ino
 * An example on how to get the travelled distance from a single DirectionlessOdometer.
 *
 * \example twoOdometers.ino
 * An example on how to get the travelled distance from two DirectionlessOdometer.
 */
<commit_msg>Revert pulses counter to being a private variable<commit_after>/**
 * \class DirectionlessOdometer
 * A class to represent the common - directionless - Odometers (speed encoders)
 * that can be used to primarily measure the travelled distance of the car
 * as well as its speed.
 */
#pragma once

#include <stdint.h>

#include "../../../runtime/Runtime.hpp"
#include "../Odometer.hpp"

#ifdef SMARTCAR_BUILD_FOR_ARDUINO
#include "../../../runtime/arduino_runtime/ArduinoRuntime.hpp"
extern ArduinoRuntime arduinoRuntime;
#endif

class DirectionlessOdometer : public Odometer
{
public:
#ifdef SMARTCAR_BUILD_FOR_ARDUINO
    /**
     * Constructs an odometer that can measure distance, speed but not direction
     * @param pulsesPerMeter The amount of odometer pulses that constitute a meter
     *
     * **Example:**
     * \code
     * unsigned short ODOMETER_PIN = 32;
     * unsigned long PULSES_PER_METER = 110;
     *
     * DirectionlessOdometer odometer(ODOMETER_PIN,
     *                                []() { odometer.update(); },
     *                                PULSES_PER_METER);
     * \endcode
     */
    DirectionlessOdometer(uint8_t pin,
                          InterruptCallback callback,
                          unsigned long pulsesPerMeter,
                          Runtime& runtime = arduinoRuntime);
#else
    DirectionlessOdometer(uint8_t pin,
                          InterruptCallback callback,
                          unsigned long pulsesPerMeter,
                          Runtime& runtime);
#endif

    virtual ~DirectionlessOdometer() = default;

    /* Check `Odometer` interface for documentation */
    long getDistance() override;

    /* Check `Odometer` interface for documentation */
    float getSpeed() override;

    /* Check `Odometer` interface for documentation */
    bool isAttached() const override;

    /* Check `Odometer` interface for documentation */
    bool providesDirection() const override;

    /**
     * Resets the total travelled distance and speed to `0`
     */
    virtual void reset();

    /**
     * Conducts the distance and speed measurements.
     * Updates the current dt with the time difference between the last two pulses
     * and increases the pulse counter.
     * **Do not** call it directly in your sketch!
     * Instead, pass it in a lambda to the constructor.
     */
    virtual void update();

protected:
    const float mPulsesPerMeterRatio;

private:
    const unsigned long mMillimetersPerPulse;
    Runtime& mRuntime;
    const bool kSensorAttached;
    volatile unsigned long mPulsesCounter{ 0 };
    volatile unsigned long mPreviousPulse{ 0 };
    volatile unsigned long mDt{ 0 };
};

/**
 * \example findPulsesPerMeter.ino
 * An example on how to determine how many pulses are emitted from your Odometer
 * for every meter travelled. The output should be supplied to the constructor.
 *
 * \example singleOdometer.ino
 * An example on how to get the travelled distance from a single DirectionlessOdometer.
 *
 * \example twoOdometers.ino
 * An example on how to get the travelled distance from two DirectionlessOdometer.
 */
<|endoftext|>


<commit_before>//===-- LLVMTargetMachine.cpp - Implement the LLVMTargetMachine class -----===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by Chris Lattner and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the LLVMTargetMachine class.
//
//===----------------------------------------------------------------------===//

#include "llvm/Target/TargetMachine.h"
#include "llvm/PassManager.h"
#include "llvm/Pass.h"
#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/CommandLine.h"
using namespace llvm;

static cl::opt<bool> PrintLSR("print-lsr-output", cl::Hidden,
    cl::desc("Print LLVM IR produced by the loop-reduce pass"));
static cl::opt<bool> PrintISelInput("print-isel-input", cl::Hidden,
    cl::desc("Print LLVM IR input to isel pass"));

FileModel::Model
LLVMTargetMachine::addPassesToEmitFile(FunctionPassManager &PM,
                                       std::ostream &Out,
                                       CodeGenFileType FileType,
                                       bool Fast) {
  // Standard LLVM-Level Passes.

  // Run loop strength reduction before anything else.
  if (!Fast) {
    PM.add(createLoopStrengthReducePass(getTargetLowering()));
    if (PrintLSR)
      PM.add(new PrintFunctionPass("\n\n*** Code after LSR *** \n", &cerr));
  }

  // FIXME: Implement efficient support for garbage collection intrinsics.
  PM.add(createLowerGCPass());

  // FIXME: Implement the invoke/unwind instructions!
  if (!ExceptionHandling)
    PM.add(createLowerInvokePass(getTargetLowering()));

  // Make sure that no unreachable blocks are instruction selected.
  PM.add(createUnreachableBlockEliminationPass());

  if (!Fast)
    PM.add(createCodeGenPreparePass(getTargetLowering()));

  if (PrintISelInput)
    PM.add(new PrintFunctionPass("\n\n*** Final LLVM Code input to ISel *** \n",
                                 &cerr));

  // Ask the target for an isel.
  if (addInstSelector(PM, Fast))
    return FileModel::Error;

  // Print the instruction selected machine code...
  if (PrintMachineCode)
    PM.add(createMachineFunctionPrinterPass(cerr));

  // Perform register allocation to convert to a concrete x86 representation
  PM.add(createRegisterAllocator());

  if (PrintMachineCode)
    PM.add(createMachineFunctionPrinterPass(cerr));

  // Run post-ra passes.
  if (addPostRegAlloc(PM, Fast) && PrintMachineCode)
    PM.add(createMachineFunctionPrinterPass(cerr));

  // Insert prolog/epilog code.  Eliminate abstract frame index references...
  PM.add(createPrologEpilogCodeInserter());

  // Branch folding must be run after regalloc and prolog/epilog insertion.
  if (!Fast)
    PM.add(createBranchFoldingPass(getEnableTailMergeDefault()));

  // Fold redundant debug labels.
  PM.add(createDebugLabelFoldingPass());

  if (PrintMachineCode)  // Print the register-allocated code
    PM.add(createMachineFunctionPrinterPass(cerr));

  if (addPreEmitPass(PM, Fast) && PrintMachineCode)
    PM.add(createMachineFunctionPrinterPass(cerr));

  switch (FileType) {
  default:
    break;
  case TargetMachine::AssemblyFile:
    if (addAssemblyEmitter(PM, Fast, Out))
      return FileModel::Error;
    return FileModel::AsmFile;
  case TargetMachine::ObjectFile:
    if (getMachOWriterInfo())
      return FileModel::MachOFile;
    else if (getELFWriterInfo())
      return FileModel::ElfFile;
  }

  return FileModel::Error;
}

/// addPassesToEmitFileFinish - If the passes to emit the specified file had to
/// be split up (e.g., to add an object writer pass), this method can be used to
/// finish up adding passes to emit the file, if necessary.
bool LLVMTargetMachine::addPassesToEmitFileFinish(FunctionPassManager &PM,
                                                  MachineCodeEmitter *MCE,
                                                  bool Fast) {
  if (MCE)
    addSimpleCodeEmitter(PM, Fast, *MCE);

  // Delete machine code for this function
  PM.add(createMachineCodeDeleter());

  return false; // success!
}

/// addPassesToEmitMachineCode - Add passes to the specified pass manager to
/// get machine code emitted.  This uses a MachineCodeEmitter object to handle
/// actually outputting the machine code and resolving things like the address
/// of functions.  This method should returns true if machine code emission is
/// not supported.
///
bool LLVMTargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM,
                                                   MachineCodeEmitter &MCE,
                                                   bool Fast) {
  // Standard LLVM-Level Passes.

  // Run loop strength reduction before anything else.
  if (!Fast) {
    PM.add(createLoopStrengthReducePass(getTargetLowering()));
    if (PrintLSR)
      PM.add(new PrintFunctionPass("\n\n*** Code after LSR *** \n", &cerr));
  }

  // FIXME: Implement efficient support for garbage collection intrinsics.
  PM.add(createLowerGCPass());

  // FIXME: Implement the invoke/unwind instructions!
  PM.add(createLowerInvokePass(getTargetLowering()));

  // Make sure that no unreachable blocks are instruction selected.
  PM.add(createUnreachableBlockEliminationPass());

  if (!Fast)
    PM.add(createCodeGenPreparePass(getTargetLowering()));

  if (PrintISelInput)
    PM.add(new PrintFunctionPass("\n\n*** Final LLVM Code input to ISel *** \n",
                                 &cerr));

  // Ask the target for an isel.
  if (addInstSelector(PM, Fast))
    return true;

  // Print the instruction selected machine code...
  if (PrintMachineCode)
    PM.add(createMachineFunctionPrinterPass(cerr));

  // Perform register allocation to convert to a concrete x86 representation
  PM.add(createRegisterAllocator());

  if (PrintMachineCode)
    PM.add(createMachineFunctionPrinterPass(cerr));

  // Run post-ra passes.
  if (addPostRegAlloc(PM, Fast) && PrintMachineCode)
    PM.add(createMachineFunctionPrinterPass(cerr));

  // Insert prolog/epilog code.  Eliminate abstract frame index references...
  PM.add(createPrologEpilogCodeInserter());

  if (PrintMachineCode)  // Print the register-allocated code
    PM.add(createMachineFunctionPrinterPass(cerr));

  // Branch folding must be run after regalloc and prolog/epilog insertion.
  if (!Fast)
    PM.add(createBranchFoldingPass(getEnableTailMergeDefault()));

  if (addPreEmitPass(PM, Fast) && PrintMachineCode)
    PM.add(createMachineFunctionPrinterPass(cerr));

  addCodeEmitter(PM, Fast, MCE);

  // Delete machine code for this function
  PM.add(createMachineCodeDeleter());

  return false; // success!
}
<commit_msg>Exception handling has been implemented.<commit_after>//===-- LLVMTargetMachine.cpp - Implement the LLVMTargetMachine class -----===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by Chris Lattner and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the LLVMTargetMachine class.
//
//===----------------------------------------------------------------------===//

#include "llvm/Target/TargetMachine.h"
#include "llvm/PassManager.h"
#include "llvm/Pass.h"
#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/CommandLine.h"
using namespace llvm;

static cl::opt<bool> PrintLSR("print-lsr-output", cl::Hidden,
    cl::desc("Print LLVM IR produced by the loop-reduce pass"));
static cl::opt<bool> PrintISelInput("print-isel-input", cl::Hidden,
    cl::desc("Print LLVM IR input to isel pass"));

FileModel::Model
LLVMTargetMachine::addPassesToEmitFile(FunctionPassManager &PM,
                                       std::ostream &Out,
                                       CodeGenFileType FileType,
                                       bool Fast) {
  // Standard LLVM-Level Passes.

  // Run loop strength reduction before anything else.
  if (!Fast) {
    PM.add(createLoopStrengthReducePass(getTargetLowering()));
    if (PrintLSR)
      PM.add(new PrintFunctionPass("\n\n*** Code after LSR *** \n", &cerr));
  }

  // FIXME: Implement efficient support for garbage collection intrinsics.
  PM.add(createLowerGCPass());

  if (!ExceptionHandling)
    PM.add(createLowerInvokePass(getTargetLowering()));

  // Make sure that no unreachable blocks are instruction selected.
  PM.add(createUnreachableBlockEliminationPass());

  if (!Fast)
    PM.add(createCodeGenPreparePass(getTargetLowering()));

  if (PrintISelInput)
    PM.add(new PrintFunctionPass("\n\n*** Final LLVM Code input to ISel *** \n",
                                 &cerr));

  // Ask the target for an isel.
  if (addInstSelector(PM, Fast))
    return FileModel::Error;

  // Print the instruction selected machine code...
  if (PrintMachineCode)
    PM.add(createMachineFunctionPrinterPass(cerr));

  // Perform register allocation to convert to a concrete x86 representation
  PM.add(createRegisterAllocator());

  if (PrintMachineCode)
    PM.add(createMachineFunctionPrinterPass(cerr));

  // Run post-ra passes.
  if (addPostRegAlloc(PM, Fast) && PrintMachineCode)
    PM.add(createMachineFunctionPrinterPass(cerr));

  // Insert prolog/epilog code.  Eliminate abstract frame index references...
  PM.add(createPrologEpilogCodeInserter());

  // Branch folding must be run after regalloc and prolog/epilog insertion.
  if (!Fast)
    PM.add(createBranchFoldingPass(getEnableTailMergeDefault()));

  // Fold redundant debug labels.
  PM.add(createDebugLabelFoldingPass());

  if (PrintMachineCode)  // Print the register-allocated code
    PM.add(createMachineFunctionPrinterPass(cerr));

  if (addPreEmitPass(PM, Fast) && PrintMachineCode)
    PM.add(createMachineFunctionPrinterPass(cerr));

  switch (FileType) {
  default:
    break;
  case TargetMachine::AssemblyFile:
    if (addAssemblyEmitter(PM, Fast, Out))
      return FileModel::Error;
    return FileModel::AsmFile;
  case TargetMachine::ObjectFile:
    if (getMachOWriterInfo())
      return FileModel::MachOFile;
    else if (getELFWriterInfo())
      return FileModel::ElfFile;
  }

  return FileModel::Error;
}

/// addPassesToEmitFileFinish - If the passes to emit the specified file had to
/// be split up (e.g., to add an object writer pass), this method can be used to
/// finish up adding passes to emit the file, if necessary.
bool LLVMTargetMachine::addPassesToEmitFileFinish(FunctionPassManager &PM,
                                                  MachineCodeEmitter *MCE,
                                                  bool Fast) {
  if (MCE)
    addSimpleCodeEmitter(PM, Fast, *MCE);

  // Delete machine code for this function
  PM.add(createMachineCodeDeleter());

  return false; // success!
}

/// addPassesToEmitMachineCode - Add passes to the specified pass manager to
/// get machine code emitted.  This uses a MachineCodeEmitter object to handle
/// actually outputting the machine code and resolving things like the address
/// of functions.  This method should returns true if machine code emission is
/// not supported.
///
bool LLVMTargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM,
                                                   MachineCodeEmitter &MCE,
                                                   bool Fast) {
  // Standard LLVM-Level Passes.

  // Run loop strength reduction before anything else.
  if (!Fast) {
    PM.add(createLoopStrengthReducePass(getTargetLowering()));
    if (PrintLSR)
      PM.add(new PrintFunctionPass("\n\n*** Code after LSR *** \n", &cerr));
  }

  // FIXME: Implement efficient support for garbage collection intrinsics.
  PM.add(createLowerGCPass());

  // FIXME: Implement the invoke/unwind instructions!
  PM.add(createLowerInvokePass(getTargetLowering()));

  // Make sure that no unreachable blocks are instruction selected.
  PM.add(createUnreachableBlockEliminationPass());

  if (!Fast)
    PM.add(createCodeGenPreparePass(getTargetLowering()));

  if (PrintISelInput)
    PM.add(new PrintFunctionPass("\n\n*** Final LLVM Code input to ISel *** \n",
                                 &cerr));

  // Ask the target for an isel.
  if (addInstSelector(PM, Fast))
    return true;

  // Print the instruction selected machine code...
  if (PrintMachineCode)
    PM.add(createMachineFunctionPrinterPass(cerr));

  // Perform register allocation to convert to a concrete x86 representation
  PM.add(createRegisterAllocator());

  if (PrintMachineCode)
    PM.add(createMachineFunctionPrinterPass(cerr));

  // Run post-ra passes.
  if (addPostRegAlloc(PM, Fast) && PrintMachineCode)
    PM.add(createMachineFunctionPrinterPass(cerr));

  // Insert prolog/epilog code.  Eliminate abstract frame index references...
  PM.add(createPrologEpilogCodeInserter());

  if (PrintMachineCode)  // Print the register-allocated code
    PM.add(createMachineFunctionPrinterPass(cerr));

  // Branch folding must be run after regalloc and prolog/epilog insertion.
  if (!Fast)
    PM.add(createBranchFoldingPass(getEnableTailMergeDefault()));

  if (addPreEmitPass(PM, Fast) && PrintMachineCode)
    PM.add(createMachineFunctionPrinterPass(cerr));

  addCodeEmitter(PM, Fast, MCE);

  // Delete machine code for this function
  PM.add(createMachineCodeDeleter());

  return false; // success!
}
<|endoftext|>


<commit_before>/* bzflag
* Copyright (c) 1993 - 2005 Tim Riker
*
* This package is free software;  you can redistribute it and/or
* modify it under the terms of the license found in the file
* named COPYING that should have accompanied this file.
*
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/

#ifdef _MSC_VER
#pragma warning( 4: 4786)
#define _WINSOCK2API_
#endif

// bzflag common header
#include "common.h"

// class interface header
#include "URLManager.h"

// system headers
#include <winsock2.h>
#ifdef HAVE_CURL
#include <curl/curl.h>
#endif
#include <iostream>

// common implementation headers
#include "bzfio.h"
#include "StateDatabase.h"

template <>
URLManager* Singleton<URLManager>::_instance = (URLManager*)0;

#ifdef HAVE_CURL
static size_t writeFunction(void *ptr, size_t size, size_t nmemb, void *stream);
#endif // HAVE_CURL

bool URLManager::getURL(const std::string URL, std::string &data)
{
  clearInternal();

  if (!beginGet(URL))
    return false;

  char* newData = (char*)malloc(theLen + 1);
  memcpy(newData, theData, theLen);
  newData[theLen] = 0;

  data = newData;
  free(newData);

  return true;
}

bool URLManager::getURL(const std::string URL, void **data, unsigned int& size)
{
  clearInternal();

  if (!beginGet(URL))
    return false;

  *data = malloc(theLen);
  memcpy(*data, theData, theLen);
  size = theLen;
  return true;
}

void URLManager::freeURLData(void *data)
{
  free(data);
}

URLManager::URLManager()
{
  easyHandle = NULL;
  theData = NULL;
  theLen = 0;

#ifdef HAVE_CURL
  CURLcode curlResult;

#if LIBCURL_VERSION_NUM >= 0x070a00
  if ((curlResult = curl_global_init(CURL_GLOBAL_NOTHING)))
    DEBUG1("Unexpected error from libcurl; Error: %d\n", curlResult);
#endif

  easyHandle = curl_easy_init();
  if (!easyHandle) {
    DEBUG1("Something wrong with CURL\n");
    return;
  }

  CURLcode result = curl_easy_setopt((CURL*)easyHandle, CURLOPT_WRITEFUNCTION, writeFunction);
  if (result)
    DEBUG1("Something wrong with CURL; Error: %d\n", result);

  result = curl_easy_setopt((CURL*)easyHandle, CURLOPT_FILE, this);
  if (result)
    DEBUG1("Something wrong with CURL; Error: %d\n", result);
#endif
}

URLManager::~URLManager()
{
  clearInternal();

#ifdef HAVE_CURL
  if (easyHandle)
    curl_easy_cleanup((CURL*)easyHandle);

#if LIBCURL_VERSION_NUM >= 0x070a00
  curl_global_cleanup();
#endif

#endif
}

void URLManager::collectData(char* ptr, int len)
{
  unsigned char	*newData = (unsigned char*)malloc(theLen + len);
  if (theData)
    memcpy(newData, theData, theLen);

  memcpy(&(newData[theLen]), ptr, len);
  theLen += len;

  free(theData);
  theData = newData;
}

void URLManager::clearInternal()
{
  if (theData)
    free (theData);

  theData = NULL;
  theLen = 0;
}

#ifdef HAVE_CURL
bool URLManager::beginGet(const std::string URL)
#else
bool URLManager::beginGet(const std::string)
#endif
{
#ifdef HAVE_CURL
  CURLcode result = CURLE_OK;
  if (!easyHandle) {
    return false;
  }

  float timeout = 15;
  if (BZDB.isSet("httpTimeout"))
    timeout = BZDB.eval("httpTimeout");

#if LIBCURL_VERSION_NUM >= 0x070a00
  result = curl_easy_setopt((CURL*)easyHandle, CURLOPT_NOSIGNAL, true);
  if (result) {
    DEBUG1("Something wrong with CURL; Error: %d\n", result);
  }
#endif

  result = curl_easy_setopt((CURL*)easyHandle, CURLOPT_TIMEOUT, timeout);
  if (result) {
    DEBUG1("Something wrong with CURL; Error: %d\n", result);
  }

  result = curl_easy_setopt((CURL*)easyHandle, CURLOPT_URL, URL.c_str());
  if (result) {
    DEBUG1("Something wrong with CURL; Error: %d\n", result);
  }

  // FIXME: This could block for a _long_ time.
  result = curl_easy_perform((CURL*)easyHandle);
  if (result == (CURLcode)CURLOPT_ERRORBUFFER) {
    DEBUG1("Error: server reported: %d\n", result);
    return false;
  } else if (result) {
    DEBUG1("Something wrong with CURL; Error: %d\n", result);
    return false;
  }

  result = curl_easy_setopt((CURL*)easyHandle, CURLOPT_URL, NULL);
  if (result) {
    DEBUG1("Something wrong with CURL; Error: %d\n", result);
    return false;
  }

  if (!theData)
    return false;

  return true;
#else
  return false;
#endif // HAVE_CURL
}

#ifdef HAVE_CURL
static size_t writeFunction(void *ptr, size_t size, size_t nmemb, void *stream)
{
  int len = size * nmemb;
  ((URLManager*)stream)->collectData((char*)ptr, len);
  return len;
}
#endif // HAVE_CURL

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>yeah, and only include winsock on windows<commit_after>/* bzflag
* Copyright (c) 1993 - 2005 Tim Riker
*
* This package is free software;  you can redistribute it and/or
* modify it under the terms of the license found in the file
* named COPYING that should have accompanied this file.
*
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/

#ifdef _MSC_VER
#pragma warning( 4: 4786)
#define _WINSOCK2API_
#endif

// bzflag common header
#include "common.h"

// class interface header
#include "URLManager.h"

// system headers
#ifdef _WIN32
#include <winsock2.h>
#endif
#ifdef HAVE_CURL
#include <curl/curl.h>
#endif
#include <iostream>

// common implementation headers
#include "bzfio.h"
#include "StateDatabase.h"

template <>
URLManager* Singleton<URLManager>::_instance = (URLManager*)0;

#ifdef HAVE_CURL
static size_t writeFunction(void *ptr, size_t size, size_t nmemb, void *stream);
#endif // HAVE_CURL

bool URLManager::getURL(const std::string URL, std::string &data)
{
  clearInternal();

  if (!beginGet(URL))
    return false;

  char* newData = (char*)malloc(theLen + 1);
  memcpy(newData, theData, theLen);
  newData[theLen] = 0;

  data = newData;
  free(newData);

  return true;
}

bool URLManager::getURL(const std::string URL, void **data, unsigned int& size)
{
  clearInternal();

  if (!beginGet(URL))
    return false;

  *data = malloc(theLen);
  memcpy(*data, theData, theLen);
  size = theLen;
  return true;
}

void URLManager::freeURLData(void *data)
{
  free(data);
}

URLManager::URLManager()
{
  easyHandle = NULL;
  theData = NULL;
  theLen = 0;

#ifdef HAVE_CURL
  CURLcode curlResult;

#if LIBCURL_VERSION_NUM >= 0x070a00
  if ((curlResult = curl_global_init(CURL_GLOBAL_NOTHING)))
    DEBUG1("Unexpected error from libcurl; Error: %d\n", curlResult);
#endif

  easyHandle = curl_easy_init();
  if (!easyHandle) {
    DEBUG1("Something wrong with CURL\n");
    return;
  }

  CURLcode result = curl_easy_setopt((CURL*)easyHandle, CURLOPT_WRITEFUNCTION, writeFunction);
  if (result)
    DEBUG1("Something wrong with CURL; Error: %d\n", result);

  result = curl_easy_setopt((CURL*)easyHandle, CURLOPT_FILE, this);
  if (result)
    DEBUG1("Something wrong with CURL; Error: %d\n", result);
#endif
}

URLManager::~URLManager()
{
  clearInternal();

#ifdef HAVE_CURL
  if (easyHandle)
    curl_easy_cleanup((CURL*)easyHandle);

#if LIBCURL_VERSION_NUM >= 0x070a00
  curl_global_cleanup();
#endif

#endif
}

void URLManager::collectData(char* ptr, int len)
{
  unsigned char	*newData = (unsigned char*)malloc(theLen + len);
  if (theData)
    memcpy(newData, theData, theLen);

  memcpy(&(newData[theLen]), ptr, len);
  theLen += len;

  free(theData);
  theData = newData;
}

void URLManager::clearInternal()
{
  if (theData)
    free (theData);

  theData = NULL;
  theLen = 0;
}

#ifdef HAVE_CURL
bool URLManager::beginGet(const std::string URL)
#else
bool URLManager::beginGet(const std::string)
#endif
{
#ifdef HAVE_CURL
  CURLcode result = CURLE_OK;
  if (!easyHandle) {
    return false;
  }

  float timeout = 15;
  if (BZDB.isSet("httpTimeout"))
    timeout = BZDB.eval("httpTimeout");

#if LIBCURL_VERSION_NUM >= 0x070a00
  result = curl_easy_setopt((CURL*)easyHandle, CURLOPT_NOSIGNAL, true);
  if (result) {
    DEBUG1("Something wrong with CURL; Error: %d\n", result);
  }
#endif

  result = curl_easy_setopt((CURL*)easyHandle, CURLOPT_TIMEOUT, timeout);
  if (result) {
    DEBUG1("Something wrong with CURL; Error: %d\n", result);
  }

  result = curl_easy_setopt((CURL*)easyHandle, CURLOPT_URL, URL.c_str());
  if (result) {
    DEBUG1("Something wrong with CURL; Error: %d\n", result);
  }

  // FIXME: This could block for a _long_ time.
  result = curl_easy_perform((CURL*)easyHandle);
  if (result == (CURLcode)CURLOPT_ERRORBUFFER) {
    DEBUG1("Error: server reported: %d\n", result);
    return false;
  } else if (result) {
    DEBUG1("Something wrong with CURL; Error: %d\n", result);
    return false;
  }

  result = curl_easy_setopt((CURL*)easyHandle, CURLOPT_URL, NULL);
  if (result) {
    DEBUG1("Something wrong with CURL; Error: %d\n", result);
    return false;
  }

  if (!theData)
    return false;

  return true;
#else
  return false;
#endif // HAVE_CURL
}

#ifdef HAVE_CURL
static size_t writeFunction(void *ptr, size_t size, size_t nmemb, void *stream)
{
  int len = size * nmemb;
  ((URLManager*)stream)->collectData((char*)ptr, len);
  return len;
}
#endif // HAVE_CURL

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>


<commit_before>#include <deal.II/fe/fe_values.h>

#include <boost/algorithm/string.hpp>
#include <deal.II/dofs/dof_tools.h>
#include <deal.II/grid/cell_id.h>

#include <deal.II/lac/petsc_solver.h>
#include <deal.II/lac/solver_bicgstab.h>

#include <algorithm>

#include "transport_base.h"
#include "../aqdata/aq_base.h"
#include "../aqdata/aq_lsgc.h"

using namespace dealii;

template <int dim>
BartDriver<dim>::BartDriver (ParameterHandler &prm)
:
mpi_communicator (MPI_COMM_WORLD),
triangulation (mpi_communicator,
               typename Triangulation<dim>::MeshSmoothing
               (Triangulation<dim>::smoothing_on_refinement |
                Triangulation<dim>::smoothing_on_coarsening)),
dof_handler (triangulation),
prm(prm),
transport_model_name(prm.get("transport model")),
aq_name(prm.get("angular quadrature name")),
discretization(prm.get("spatial discretization")),
n_group(prm.get_integer("number of groups")),
n_azi(prm.get_integer("angular quadrature order")),
is_eigen_problem(prm.get_bool("do eigenvalue calculations")),
do_nda(prm.get_bool("do NDA")),
do_print_sn_quad(prm.get_bool("do print angular quadrature info")),
have_reflective_bc(prm.get_bool("have reflective BC")),
p_order(prm.get_integer("finite element polynomial degree")),
global_refinements(prm.get_integer("uniform refinements")),
namebase(prm.get("output file name base")),
ho_linear_solver_name(prm.get("HO linear solver name")),
ho_preconditioner_name(prm.get("HO preconditioner name")),
pcout(std::cout,
      (Utilities::MPI::this_mpi_process(mpi_communicator)
       == 0))
{
  aqd_ptr = build_aq_model (prm)
  aqd_ptr->make_aq (prm);
  n_total_ho_vars = aqd_ptr->get_n_total_ho_vars ();
  n_azi = aqd_ptr->get_sn_order ();
  n_dir = aqd_ptr->get_n_dir ();
  msh_ptr = std_cxx11::shared_ptr<MeshGenerator<dim> >
  (new MeshGenerator<dim>(prm));
  this->process_input ();
}

template <int dim>
BartDriver<dim>::~BartDriver ()
{
  dof_handler.clear();
}

template <int dim>
void BartDriver<dim>::report_system ()
{
  pcout << "SN quadrature order: " << n_azi << std::endl
  << "Number of angles: " << n_dir << std::endl
  << "Number of groups: " << n_group << std::endl;

  radio ("Transport model", transport_model_name);
  radio ("Spatial discretization", discretization);
  radio ("HO linear solver", ho_linear_solver_name);
  if (ho_linear_solver_name!="direct")
    radio ("HO preconditioner", ho_preconditioner_name);
  radio ("do NDA?", do_nda);

  radio ("Number of cells", triangulation.n_global_active_cells());
  radio ("High-order total DoF counts", n_total_ho_vars*dof_handler.n_dofs());

  if (is_eigen_problem)
    radio ("Problem type: k-eigenvalue problem");
  if (do_nda)
    radio ("NDA total DoF counts", n_group*dof_handler.n_dofs());
  radio ("print sn quad?", do_print_sn_quad);
  if (do_print_sn_quad &&
      Utilities::MPI::this_mpi_process(mpi_communicator)==0)
    aqd_ptr->print_angular_quad ();
  radio ("is eigenvalue problem?", is_eigen_problem);
}

template <int dim>
void BartDriver<dim>::setup_system ()
{
  radio ("setup system");
  initialize_dealii_objects ();
  initialize_system_matrices_vectors ();
}

template <int dim>
void BartDriver<dim>::initialize_system_matrices_vectors ()
{
  DynamicSparsityPattern dsp (relevant_dofs);

  if (discretization=="dfem")
  {
    /*
     Table<2,DoFTools::Coupling> cell_coupling (1,1);
     Table<2,DoFTools::Coupling> face_coupling (1,1);

     cell_coupling[0][0] = DoFTools::nonzero;
     face_coupling[0][0] = DoFTools::nonzero;

     DoFTools::make_flux_sparsity_pattern (dof_handler,
     dsp,
     cell_coupling,
     face_coupling);
     */

    DoFTools::make_flux_sparsity_pattern (dof_handler,
                                          dsp,
                                          constraints,
                                          false);
  }
  else
    DoFTools::make_sparsity_pattern (dof_handler,
                                     dsp,
                                     constraints,
                                     false);

  // be careful with the following
  SparsityTools::distribute_sparsity_pattern (dsp,
                                              dof_handler.n_locally_owned_dofs_per_processor (),
                                              mpi_communicator,
                                              relevant_dofs);

  for (unsigned int g=0; g<n_group; ++g)
  {
    if (do_nda)
    {
      vec_lo_sys.push_back (new LA::MPI::SparseMatrix);
      vec_lo_rhs.push_back (new LA::MPI::Vector);
      vec_lo_sflx.push_back (new LA::MPI::Vector);
      vec_lo_sflx_old.push_back (new LA::MPI::Vector);
      vec_lo_fixed_rhs.push_back (new LA::MPI::Vector);
    }

    vec_ho_sflx.push_back (new LA::MPI::Vector);
    vec_ho_sflx_prev_gen.push_back (new LA::MPI::Vector);
    vec_ho_sflx_old.push_back (new LA::MPI::Vector);

    for (unsigned int i_dir=0; i_dir<n_dir; ++i_dir)
    {
      vec_ho_sys.push_back (new LA::MPI::SparseMatrix);
      vec_aflx.push_back (new LA::MPI::Vector);
      vec_ho_rhs.push_back (new LA::MPI::Vector);
      vec_ho_fixed_rhs.push_back (new LA::MPI::Vector);
    }
  }

  for (unsigned int g=0; g<n_group; ++g)
  {
    if (do_nda)
    {
      vec_lo_sys[g]->reinit (local_dofs,
                             local_dofs,
                             dsp,
                             mpi_communicator);
      vec_lo_rhs[g]->reinit (local_dofs,
                             mpi_communicator);
      vec_lo_fixed_rhs[g]->reinit (local_dofs,
                                   mpi_communicator);
      vec_lo_sflx[g]->reinit (local_dofs,
                              mpi_communicator);
      vec_lo_sflx_old[g]->reinit (local_dofs,
                                  mpi_communicator);
    }

    vec_ho_sflx[g]->reinit (local_dofs,
                            mpi_communicator);
    vec_ho_sflx_old[g]->reinit (local_dofs,
                                mpi_communicator);

    for (unsigned int i_dir=0; i_dir<n_dir; ++i_dir)
    {
      vec_ho_sys[get_component_index(i_dir, g)]->reinit(local_dofs,
                                                        local_dofs,
                                                        dsp,
                                                        mpi_communicator);
      vec_aflx[get_component_index(i_dir, g)]->reinit(local_dofs,
                                                      mpi_communicator);
      vec_ho_rhs[get_component_index(i_dir, g)]->reinit (local_dofs,
                                                         mpi_communicator);
      vec_ho_fixed_rhs[get_component_index(i_dir, g)]->reinit (local_dofs,
                                                               mpi_communicator);
    }
  }
}

template <int dim>
void BartDriver<dim>::initialize_dealii_objects ()
{
  if (discretization=="dfem")
    fe = (new FE_DGQ<dim> (p_order));
  else
    fe = (new FE_Q<dim> (p_order));

  dof_handler.distribute_dofs (*fe);

  local_dofs = dof_handler.locally_owned_dofs ();
  DoFTools::extract_locally_relevant_dofs (dof_handler,
                                           relevant_dofs);

  constraints.clear ();
  constraints.reinit (relevant_dofs);
  DoFTools::make_hanging_node_constraints (dof_handler,
                                           constraints);
  constraints.close ();
}

template <int dim>
void BartDriver<dim>::output_results () const
{
  std::string sec_name = "Graphical output";
  DataOut<dim> data_out;
  data_out.attach_dof_handler (dof_handler);

  for (unsigned int g=0; g<n_group; ++g)
  {
    std::ostringstream os;
    os << "ho_phi_g_" << g;
    data_out.add_data_vector (sflx_proc[g], os.str ());
  }

  Vector<float> subdomain (triangulation.n_active_cells ());
  for (unsigned int i=0; i<subdomain.size(); ++i)
    subdomain(i) = triangulation.locally_owned_subdomain ();
  data_out.add_data_vector (subdomain, "subdomain");

  data_out.build_patches ();

  const std::string filename =
  (namebase + "-" + discretization + "-" + Utilities::int_to_string
   (triangulation.locally_owned_subdomain (), 4));
  std::ofstream output ((filename + ".vtu").c_str ());
  data_out.write_vtu (output);

  if (Utilities::MPI::this_mpi_process(mpi_communicator) == 0)
  {
    std::vector<std::string> filenames;
    for (unsigned int i=0;
         i<Utilities::MPI::n_mpi_processes(mpi_communicator);
         ++i)
      filenames.push_back (namebase + "-" + discretization + "-" +
                           Utilities::int_to_string (i, 4) + ".vtu");
    std::ostringstream os;
    os << namebase << "-" << discretization << "-" << global_refinements << ".pvtu";
    std::ofstream master_output ((os.str()).c_str ());
    data_out.write_pvtu_record (master_output, filenames);
  }
}

template <int dim>
void BartDriver<dim>::run ()
{
  radio ("making grid");
  msh_ptr->make_grid (triangulation);
  msh_ptr->get_relevant_cell_iterators (dof_handler,
                                        local_cells,
                                        ref_bd_cells,
                                        is_cell_at_bd,
                                        is_cell_at_ref_bd);
  setup_system ();
  report_system ();
  assemble_ho_system ();
  do_iterations ();
  output_results();
}

// wrapper functions used to retrieve info from various Hash tables
template <int dim>
unsigned int BartDriver<dim>::get_component_index
(unsigned int incident_angle_index, unsigned int g)
{
  // retrieve component indecis given direction and group
  // must be used after initializing the index map
  return component_index[std::make_pair (incident_angle_index, g)];
}

template <int dim>
unsigned int BartDriver<dim>::get_component_direction (unsigned int comp_ind)
{
  return inverse_component_index[comp_ind].first;
}

template <int dim>
unsigned int BartDriver<dim>::get_component_group (unsigned int comp_ind)
{
  return inverse_component_index[comp_ind].second;
}

template <int dim>
unsigned int BartDriver<dim>::get_reflective_direction_index
(unsigned int boundary_id, unsigned int incident_angle_index)
{
  AssertThrow (is_reflective_bc[boundary_id],
               ExcMessage ("must be reflective boundary to retrieve the reflective boundary"));
  return reflective_direction_index[std::make_pair (boundary_id,
                                                    incident_angle_index)];
}

//functions used to cout information for diagonose or just simply cout
template <int dim>
void BartDriver<dim>::radio (std::string str)
{
  pcout << str << std::endl;
}

template <int dim>
void BartDriver<dim>::radio (std::string str1, std::string str2)
{
  pcout << str1 << ": " << str2 << std::endl;
}

template <int dim>
void BartDriver<dim>::radio (std::string str,
                                double num)
{
  pcout << str << ": " << num << std::endl;
}

template <int dim>
void BartDriver<dim>::radio (std::string str1, unsigned int num1,
                                std::string str2, unsigned int num2,
                                std::string str3, unsigned int num3)
{
  pcout << str1 << ": " << num1 << ", ";
  pcout << str2 << ": " << num2 << ", ";
  pcout << str3 << ": " << num3 << std::endl;;
}

template <int dim>
void BartDriver<dim>::radio (std::string str,
                                unsigned int num)
{
  pcout << str << ": " << num << std::endl;
}

template <int dim>
void BartDriver<dim>::radio (std::string str, bool boolean)
{
  pcout << str << ": " << (boolean?"true":"false") << std::endl;
}

template <int dim>
void BartDriver<dim>::radio ()
{
  pcout << "-------------------------------------" << std::endl << std::endl;
}

// explicit instantiation to avoid linking error
template class BartDriver<2>;
template class BartDriver<3>;
<commit_msg>BartDriver cleaning #10<commit_after>#include <deal.II/fe/fe_values.h>

#include <boost/algorithm/string.hpp>
#include <deal.II/dofs/dof_tools.h>
#include <deal.II/grid/cell_id.h>

#include <deal.II/lac/petsc_solver.h>
#include <deal.II/lac/solver_bicgstab.h>

#include <algorithm>

#include "transport_base.h"
#include "../aqdata/aq_base.h"
#include "../aqdata/aq_lsgc.h"

using namespace dealii;

template <int dim>
BartDriver<dim>::BartDriver (ParameterHandler &prm)
:
triangulation (MPI_COMM_WORLD,
               typename Triangulation<dim>::MeshSmoothing
               (Triangulation<dim>::smoothing_on_refinement |
                Triangulation<dim>::smoothing_on_coarsening)),
dof_handler (triangulation),
prm(prm),
transport_model_name(prm.get("transport model")),
aq_name(prm.get("angular quadrature name")),
discretization(prm.get("spatial discretization")),
n_group(prm.get_integer("number of groups")),
n_azi(prm.get_integer("angular quadrature order")),
is_eigen_problem(prm.get_bool("do eigenvalue calculations")),
do_nda(prm.get_bool("do NDA")),
do_print_sn_quad(prm.get_bool("do print angular quadrature info")),
have_reflective_bc(prm.get_bool("have reflective BC")),
p_order(prm.get_integer("finite element polynomial degree")),
global_refinements(prm.get_integer("uniform refinements")),
namebase(prm.get("output file name base")),
ho_linear_solver_name(prm.get("HO linear solver name")),
ho_preconditioner_name(prm.get("HO preconditioner name")),
pcout(std::cout,
      Utilities::MPI::this_mpi_process(MPI_COMM_WORLD)==0)
{
  aqd_ptr = build_aq_model (prm)
  aqd_ptr->make_aq (prm);
  n_total_ho_vars = aqd_ptr->get_n_total_ho_vars ();
  n_azi = aqd_ptr->get_sn_order ();
  n_dir = aqd_ptr->get_n_dir ();
  msh_ptr = std_cxx11::shared_ptr<MeshGenerator<dim> >
  (new MeshGenerator<dim>(prm));
  this->process_input ();
}

template <int dim>
BartDriver<dim>::~BartDriver ()
{
  dof_handler.clear();
}

template <int dim>
void BartDriver<dim>::report_system ()
{
  pcout << "SN quadrature order: " << n_azi << std::endl
  << "Number of angles: " << n_dir << std::endl
  << "Number of groups: " << n_group << std::endl;

  radio ("Transport model", transport_model_name);
  radio ("Spatial discretization", discretization);
  radio ("HO linear solver", ho_linear_solver_name);
  if (ho_linear_solver_name!="direct")
    radio ("HO preconditioner", ho_preconditioner_name);
  radio ("do NDA?", do_nda);

  radio ("Number of cells", triangulation.n_global_active_cells());
  radio ("High-order total DoF counts", n_total_ho_vars*dof_handler.n_dofs());

  if (is_eigen_problem)
    radio ("Problem type: k-eigenvalue problem");
  if (do_nda)
    radio ("NDA total DoF counts", n_group*dof_handler.n_dofs());
  radio ("print sn quad?", do_print_sn_quad);
  radio ("is eigenvalue problem?", is_eigen_problem);
}

template <int dim>
void BartDriver<dim>::setup_system ()
{
  radio ("setup system");
  initialize_dealii_objects ();
  initialize_system_matrices_vectors ();
}

template <int dim>
void BartDriver<dim>::initialize_system_matrices_vectors ()
{
  DynamicSparsityPattern dsp (relevant_dofs);

  if (discretization=="dfem")
  {
    /*
     Table<2,DoFTools::Coupling> cell_coupling (1,1);
     Table<2,DoFTools::Coupling> face_coupling (1,1);

     cell_coupling[0][0] = DoFTools::nonzero;
     face_coupling[0][0] = DoFTools::nonzero;

     DoFTools::make_flux_sparsity_pattern (dof_handler,
     dsp,
     cell_coupling,
     face_coupling);
     */

    DoFTools::make_flux_sparsity_pattern (dof_handler,
                                          dsp,
                                          constraints,
                                          false);
  }
  else
    DoFTools::make_sparsity_pattern (dof_handler,
                                     dsp,
                                     constraints,
                                     false);

  // be careful with the following
  SparsityTools::distribute_sparsity_pattern (dsp,
                                              dof_handler.n_locally_owned_dofs_per_processor (),
                                              MPI_COMM_WORLD,
                                              relevant_dofs);

  for (unsigned int g=0; g<n_group; ++g)
  {
    if (do_nda)
    {
      vec_lo_sys.push_back (new LA::MPI::SparseMatrix);
      vec_lo_rhs.push_back (new LA::MPI::Vector);
      vec_lo_sflx.push_back (new LA::MPI::Vector);
      vec_lo_sflx_old.push_back (new LA::MPI::Vector);
      vec_lo_fixed_rhs.push_back (new LA::MPI::Vector);
    }

    vec_ho_sflx.push_back (new LA::MPI::Vector);
    vec_ho_sflx_prev_gen.push_back (new LA::MPI::Vector);
    vec_ho_sflx_old.push_back (new LA::MPI::Vector);

    for (unsigned int i_dir=0; i_dir<n_dir; ++i_dir)
    {
      vec_ho_sys.push_back (new LA::MPI::SparseMatrix);
      vec_aflx.push_back (new LA::MPI::Vector);
      vec_ho_rhs.push_back (new LA::MPI::Vector);
      vec_ho_fixed_rhs.push_back (new LA::MPI::Vector);
    }
  }

  for (unsigned int g=0; g<n_group; ++g)
  {
    if (do_nda)
    {
      vec_lo_sys[g]->reinit (local_dofs,
                             local_dofs,
                             dsp,
                             MPI_COMM_WORLD);
      vec_lo_rhs[g]->reinit (local_dofs, MPI_COMM_WORLD);
      vec_lo_fixed_rhs[g]->reinit (local_dofs, MPI_COMM_WORLD);
      vec_lo_sflx[g]->reinit (local_dofs, MPI_COMM_WORLD);
      vec_lo_sflx_old[g]->reinit (local_dofs, MPI_COMM_WORLD);
    }

    vec_ho_sflx[g]->reinit (local_dofs, MPI_COMM_WORLD);
    vec_ho_sflx_old[g]->reinit (local_dofs, MPI_COMM_WORLD);
  }

  for (unsigned int k=0; k<n_total_ho_vars; ++k)
  {
    vec_ho_sys[k]->reinit(local_dofs,
                          local_dofs,
                          dsp,
                          MPI_COMM_WORLD);
    vec_aflx[k]->reinit(local_dofs, MPI_COMM_WORLD);
    vec_ho_rhs[k]->reinit (local_dofs, MPI_COMM_WORLD);
    vec_ho_fixed_rhs[k]->reinit (local_dofs, MPI_COMM_WORLD);
  }
}

template <int dim>
void BartDriver<dim>::initialize_dealii_objects ()
{
  if (discretization=="dfem")
    fe = (new FE_DGQ<dim> (p_order));
  else
    fe = (new FE_Q<dim> (p_order));

  dof_handler.distribute_dofs (*fe);

  local_dofs = dof_handler.locally_owned_dofs ();
  DoFTools::extract_locally_relevant_dofs (dof_handler,
                                           relevant_dofs);

  constraints.clear ();
  constraints.reinit (relevant_dofs);
  DoFTools::make_hanging_node_constraints (dof_handler,
                                           constraints);
  constraints.close ();
}

template <int dim>
void BartDriver<dim>::output_results () const
{
  std::string sec_name = "Graphical output";
  DataOut<dim> data_out;
  data_out.attach_dof_handler (dof_handler);

  for (unsigned int g=0; g<n_group; ++g)
  {
    std::ostringstream os;
    os << "ho_phi_g_" << g;
    data_out.add_data_vector (sflx_proc[g], os.str ());
  }

  Vector<float> subdomain (triangulation.n_active_cells ());
  for (unsigned int i=0; i<subdomain.size(); ++i)
    subdomain(i) = triangulation.locally_owned_subdomain ();
  data_out.add_data_vector (subdomain, "subdomain");

  data_out.build_patches ();

  const std::string filename =
  (namebase + "-" + discretization + "-" + Utilities::int_to_string
   (triangulation.locally_owned_subdomain (), 4));
  std::ofstream output ((filename + ".vtu").c_str ());
  data_out.write_vtu (output);

  if (Utilities::MPI::this_mpi_process(MPI_COMM_WORLD) == 0)
  {
    std::vector<std::string> filenames;
    for (unsigned int i=0;
         i<Utilities::MPI::n_mpi_processes(MPI_COMM_WORLD);
         ++i)
      filenames.push_back (namebase + "-" + discretization + "-" +
                           Utilities::int_to_string (i, 4) + ".vtu");
    std::ostringstream os;
    os << namebase << "-" << discretization << "-" << global_refinements << ".pvtu";
    std::ofstream master_output ((os.str()).c_str ());
    data_out.write_pvtu_record (master_output, filenames);
  }
}

template <int dim>
void BartDriver<dim>::run ()
{
  radio ("making grid");
  msh_ptr->make_grid (triangulation);
  msh_ptr->get_relevant_cell_iterators (dof_handler,
                                        local_cells,
                                        ref_bd_cells,
                                        is_cell_at_bd,
                                        is_cell_at_ref_bd);
  setup_system ();
  report_system ();
  assemble_ho_system ();
  do_iterations ();
  output_results();
}

// explicit instantiation to avoid linking error
template class BartDriver<2>;
template class BartDriver<3>;
<|endoftext|>


<commit_before>//===-- LoopUnroll.cpp - Loop unroller pass -------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This pass implements a simple loop unroller.  It works best when loops have
// been canonicalized by the -indvars pass, allowing it to determine the trip
// counts of loops easily.
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "loop-unroll"
#include "llvm/IntrinsicInst.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/InlineCost.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/UnrollLoop.h"
#include <climits>

using namespace llvm;

static cl::opt<unsigned>
UnrollThreshold("unroll-threshold", cl::init(200), cl::Hidden,
  cl::desc("The cut-off point for automatic loop unrolling"));

static cl::opt<unsigned>
UnrollCount("unroll-count", cl::init(0), cl::Hidden,
  cl::desc("Use this unroll count for all loops, for testing purposes"));

static cl::opt<bool>
UnrollAllowPartial("unroll-allow-partial", cl::init(false), cl::Hidden,
  cl::desc("Allows loops to be partially unrolled until "
           "-unroll-threshold loop size is reached."));

namespace {
  class LoopUnroll : public LoopPass {
  public:
    static char ID; // Pass ID, replacement for typeid
    LoopUnroll() : LoopPass(ID) {}

    /// A magic value for use with the Threshold parameter to indicate
    /// that the loop unroll should be performed regardless of how much
    /// code expansion would result.
    static const unsigned NoThreshold = UINT_MAX;

    bool runOnLoop(Loop *L, LPPassManager &LPM);

    /// This transformation requires natural loop information & requires that
    /// loop preheaders be inserted into the CFG...
    ///
    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.addRequired<LoopInfo>();
      AU.addPreserved<LoopInfo>();
      AU.addRequiredID(LoopSimplifyID);
      AU.addPreservedID(LoopSimplifyID);
      AU.addRequiredID(LCSSAID);
      AU.addPreservedID(LCSSAID);
      AU.addPreserved<ScalarEvolution>();
      // FIXME: Loop unroll requires LCSSA. And LCSSA requires dom info.
      // If loop unroll does not preserve dom info then LCSSA pass on next
      // loop will receive invalid dom info.
      // For now, recreate dom info, if loop is unrolled.
      AU.addPreserved<DominatorTree>();
    }
  };
}

char LoopUnroll::ID = 0;
INITIALIZE_PASS(LoopUnroll, "loop-unroll", "Unroll loops", false, false);

Pass *llvm::createLoopUnrollPass() { return new LoopUnroll(); }

/// ApproximateLoopSize - Approximate the size of the loop.
static unsigned ApproximateLoopSize(const Loop *L, unsigned &NumCalls) {
  CodeMetrics Metrics;
  for (Loop::block_iterator I = L->block_begin(), E = L->block_end();
       I != E; ++I)
    Metrics.analyzeBasicBlock(*I);
  NumCalls = Metrics.NumCalls;
  return Metrics.NumInsts;
}

bool LoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) {
  LoopInfo *LI = &getAnalysis<LoopInfo>();

  BasicBlock *Header = L->getHeader();
  DEBUG(dbgs() << "Loop Unroll: F[" << Header->getParent()->getName()
        << "] Loop %" << Header->getName() << "\n");
  (void)Header;

  // Find trip count
  unsigned TripCount = L->getSmallConstantTripCount();
  unsigned Count = UnrollCount;

  // Automatically select an unroll count.
  if (Count == 0) {
    // Conservative heuristic: if we know the trip count, see if we can
    // completely unroll (subject to the threshold, checked below); otherwise
    // try to find greatest modulo of the trip count which is still under
    // threshold value.
    if (TripCount == 0)
      return false;
    Count = TripCount;
  }

  // Enforce the threshold.
  if (UnrollThreshold != NoThreshold) {
    unsigned NumCalls;
    unsigned LoopSize = ApproximateLoopSize(L, NumCalls);
    DEBUG(dbgs() << "  Loop Size = " << LoopSize << "\n");
    if (NumCalls != 0) {
      DEBUG(dbgs() << "  Not unrolling loop with function calls.\n");
      return false;
    }
    uint64_t Size = (uint64_t)LoopSize*Count;
    if (TripCount != 1 && Size > UnrollThreshold) {
      DEBUG(dbgs() << "  Too large to fully unroll with count: " << Count
            << " because size: " << Size << ">" << UnrollThreshold << "\n");
      if (!UnrollAllowPartial) {
        DEBUG(dbgs() << "  will not try to unroll partially because "
              << "-unroll-allow-partial not given\n");
        return false;
      }
      // Reduce unroll count to be modulo of TripCount for partial unrolling
      Count = UnrollThreshold / LoopSize;
      while (Count != 0 && TripCount%Count != 0) {
        Count--;
      }
      if (Count < 2) {
        DEBUG(dbgs() << "  could not unroll partially\n");
        return false;
      }
      DEBUG(dbgs() << "  partially unrolling with count: " << Count << "\n");
    }
  }

  // Unroll the loop.
  Function *F = L->getHeader()->getParent();
  if (!UnrollLoop(L, Count, LI, &LPM))
    return false;

  // FIXME: Reconstruct dom info, because it is not preserved properly.
  if (DominatorTree *DT = getAnalysisIfAvailable<DominatorTree>())
    DT->runOnFunction(*F);
  return true;
}
<commit_msg>Add a separate unrolling threshold when the current function is being optimized for size. The threshold value of 50 is arbitrary, and I chose it simply by analogy to the inlining thresholds, where the baseline unrolling threshold is slightly smaller than the baseline inlining threshold.  This could undoubtedly use some tuning.<commit_after>//===-- LoopUnroll.cpp - Loop unroller pass -------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This pass implements a simple loop unroller.  It works best when loops have
// been canonicalized by the -indvars pass, allowing it to determine the trip
// counts of loops easily.
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "loop-unroll"
#include "llvm/IntrinsicInst.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/InlineCost.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/UnrollLoop.h"
#include <climits>

using namespace llvm;

static cl::opt<unsigned>
UnrollThreshold("unroll-threshold", cl::init(200), cl::Hidden,
  cl::desc("The cut-off point for automatic loop unrolling"));

static cl::opt<unsigned>
UnrollCount("unroll-count", cl::init(0), cl::Hidden,
  cl::desc("Use this unroll count for all loops, for testing purposes"));

static cl::opt<bool>
UnrollAllowPartial("unroll-allow-partial", cl::init(false), cl::Hidden,
  cl::desc("Allows loops to be partially unrolled until "
           "-unroll-threshold loop size is reached."));

namespace {
  class LoopUnroll : public LoopPass {
  public:
    static char ID; // Pass ID, replacement for typeid
    LoopUnroll() : LoopPass(ID) {}

    /// A magic value for use with the Threshold parameter to indicate
    /// that the loop unroll should be performed regardless of how much
    /// code expansion would result.
    static const unsigned NoThreshold = UINT_MAX;

    // Threshold to use when optsize is specified (and there is no
    // explicit -unroll-threshold).
    static const unsigned OptSizeUnrollThreshold = 50;

    unsigned CurrentThreshold;

    bool runOnLoop(Loop *L, LPPassManager &LPM);

    /// This transformation requires natural loop information & requires that
    /// loop preheaders be inserted into the CFG...
    ///
    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.addRequired<LoopInfo>();
      AU.addPreserved<LoopInfo>();
      AU.addRequiredID(LoopSimplifyID);
      AU.addPreservedID(LoopSimplifyID);
      AU.addRequiredID(LCSSAID);
      AU.addPreservedID(LCSSAID);
      AU.addPreserved<ScalarEvolution>();
      // FIXME: Loop unroll requires LCSSA. And LCSSA requires dom info.
      // If loop unroll does not preserve dom info then LCSSA pass on next
      // loop will receive invalid dom info.
      // For now, recreate dom info, if loop is unrolled.
      AU.addPreserved<DominatorTree>();
    }
  };
}

char LoopUnroll::ID = 0;
INITIALIZE_PASS(LoopUnroll, "loop-unroll", "Unroll loops", false, false);

Pass *llvm::createLoopUnrollPass() { return new LoopUnroll(); }

/// ApproximateLoopSize - Approximate the size of the loop.
static unsigned ApproximateLoopSize(const Loop *L, unsigned &NumCalls) {
  CodeMetrics Metrics;
  for (Loop::block_iterator I = L->block_begin(), E = L->block_end();
       I != E; ++I)
    Metrics.analyzeBasicBlock(*I);
  NumCalls = Metrics.NumCalls;
  return Metrics.NumInsts;
}

bool LoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) {

  LoopInfo *LI = &getAnalysis<LoopInfo>();

  BasicBlock *Header = L->getHeader();
  DEBUG(dbgs() << "Loop Unroll: F[" << Header->getParent()->getName()
        << "] Loop %" << Header->getName() << "\n");
  (void)Header;

  // Determine the current unrolling threshold.  While this is normally set
  // from UnrollThreshold, it is overridden to a smaller value if the current
  // function is marked as optimize-for-size, and the unroll threshold was
  // not user specified.
  CurrentThreshold = UnrollThreshold;
  if (Header->getParent()->hasFnAttr(Attribute::OptimizeForSize) &&
      UnrollThreshold.getNumOccurrences() == 0)
    CurrentThreshold = OptSizeUnrollThreshold;

  // Find trip count
  unsigned TripCount = L->getSmallConstantTripCount();
  unsigned Count = UnrollCount;

  // Automatically select an unroll count.
  if (Count == 0) {
    // Conservative heuristic: if we know the trip count, see if we can
    // completely unroll (subject to the threshold, checked below); otherwise
    // try to find greatest modulo of the trip count which is still under
    // threshold value.
    if (TripCount == 0)
      return false;
    Count = TripCount;
  }

  // Enforce the threshold.
  if (CurrentThreshold != NoThreshold) {
    unsigned NumCalls;
    unsigned LoopSize = ApproximateLoopSize(L, NumCalls);
    DEBUG(dbgs() << "  Loop Size = " << LoopSize << "\n");
    if (NumCalls != 0) {
      DEBUG(dbgs() << "  Not unrolling loop with function calls.\n");
      return false;
    }
    uint64_t Size = (uint64_t)LoopSize*Count;
    if (TripCount != 1 && Size > CurrentThreshold) {
      DEBUG(dbgs() << "  Too large to fully unroll with count: " << Count
            << " because size: " << Size << ">" << CurrentThreshold << "\n");
      if (!UnrollAllowPartial) {
        DEBUG(dbgs() << "  will not try to unroll partially because "
              << "-unroll-allow-partial not given\n");
        return false;
      }
      // Reduce unroll count to be modulo of TripCount for partial unrolling
      Count = CurrentThreshold / LoopSize;
      while (Count != 0 && TripCount%Count != 0) {
        Count--;
      }
      if (Count < 2) {
        DEBUG(dbgs() << "  could not unroll partially\n");
        return false;
      }
      DEBUG(dbgs() << "  partially unrolling with count: " << Count << "\n");
    }
  }

  // Unroll the loop.
  Function *F = L->getHeader()->getParent();
  if (!UnrollLoop(L, Count, LI, &LPM))
    return false;

  // FIXME: Reconstruct dom info, because it is not preserved properly.
  if (DominatorTree *DT = getAnalysisIfAvailable<DominatorTree>())
    DT->runOnFunction(*F);
  return true;
}
<|endoftext|>