<commit_before>/** \file    translate_chainer.cc
 *  \brief   Simple tool for generating a sequence of Web pages for translations.
 *  \author  Dr. Johannes Ruscheinski
 */

/*
    Copyright (C) 2016, Library of the University of Tübingen

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as
    published by the Free Software Foundation, either version 3 of the
    License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <iostream>
#include <fstream>
#include <cerrno>
#include <cstdio>
#include <cstring>
#include "Compiler.h"
#include "ExecUtil.h"
#include "MiscUtil.h"
#include "StringUtil.h"
#include "UrlUtil.h"
#include "WebUtil.h"
#include "util.h"

void DumpCgiArgs(const std::multimap<std::string, std::string> &cgi_args) {
    for (const auto &key_and_values : cgi_args)
        std::cout << key_and_values.first << " = " << key_and_values.second << '\n';
}

void ParseEscapedCommaSeparatedList(const std::string &escaped_text, std::vector<std::string> * const list) {
    list->clear();

    std::string unescaped_text;
    bool last_char_was_backslash(false);

    for (const auto ch : escaped_text) {
        if (last_char_was_backslash) {
            last_char_was_backslash = false;
            unescaped_text += ch;
        } else if (ch == '\\')
            last_char_was_backslash = true;
        else if (ch == ',') {
            list->emplace_back(unescaped_text);
            unescaped_text.clear();
        } else
            unescaped_text += ch;
    }

    if (unlikely(last_char_was_backslash))
        Error("weird escaped string ends in backslash \"" + escaped_text + "\"!");

    list->emplace_back(StringUtil::RightTrim(&unescaped_text, '\n'));
}

struct Translation {
    std::string index_, remaining_count_, language_code_, text_, category_, gnd_code_;
};

const std::string NO_GND_CODE("-1");

void ParseGetMissingLine(const std::string &line, Translation * const translation) {
    std::vector<std::string> parts;
    ParseEscapedCommaSeparatedList(line, &parts);
    if (unlikely(parts.size() != 5 and parts.size() != 6))
        Error("expected 5 or 6 parts, found \"" + line + "\"!");

    translation->index_           = parts[0];
    translation->remaining_count_ = parts[1];
    translation->language_code_   = parts[2];
    translation->text_            = parts[3];
    translation->category_        = parts[4];
    translation->gnd_code_        = (parts.size() == 5) ? NO_GND_CODE : parts[5];
}

void ParseTranslationsDbToolOutput(const std::string &output, std::vector<Translation> * const translations) {
    std::vector<std::string> lines;
    StringUtil::Split(output, '\n', &lines);

    for (const auto &line : lines) {
        Translation new_translation;
        ParseGetMissingLine(line, &new_translation);
        translations->emplace_back(new_translation);
    }
}

std::string GetCGIParameterOrDie(const std::multimap<std::string, std::string> &cgi_args,
                                 const std::string &parameter_name)
{
    const auto key_and_value(cgi_args.find(parameter_name));
    if (key_and_value == cgi_args.cend())
        Error("expected a(n) \"" + parameter_name + "\" parameter!");

    return key_and_value->second;
}

std::string GetCGIParameterOrEmptyString(const std::multimap<std::string, std::string> &cgi_args,
                                         const std::string &parameter_name)
{
    const auto key_and_value(cgi_args.find(parameter_name));
    if (key_and_value == cgi_args.cend())
        return "";

    return key_and_value->second;
}

void ParseTranslationsDbToolOutputAndGenerateNewDisplay(const std::string &output, const std::string &language_code,
                                                        const std::string &ixtheo_base_url)
{
    std::vector<Translation> translations;
    ParseTranslationsDbToolOutput(output, &translations);
    if (translations.empty()) {
        std::ifstream done_html("/var/lib/tuelib/translate_chainer/done_translating.html", std::ios::binary);
        std::cout << done_html.rdbuf();
    } else {
        std::map<std::string, std::vector<std::string>> names_to_values_map;
        names_to_values_map.emplace(std::make_pair(std::string("index"),
                                                   std::vector<std::string>{ translations.front().index_ }));
        names_to_values_map.emplace(std::make_pair(std::string("remaining_count"),
                                                   std::vector<std::string>{ translations.front().remaining_count_ }));
        names_to_values_map.emplace(std::make_pair(std::string("target_language_code"),
                                                   std::vector<std::string>{ language_code }));
        names_to_values_map.emplace(std::make_pair(std::string("ixtheo_base_url"),
                                                   std::vector<std::string>{ UrlUtil::UrlDecode(ixtheo_base_url) }));
        names_to_values_map.emplace(std::make_pair(std::string("category"),
                                                   std::vector<std::string>{ translations.front().category_ }));
        if (translations.front().gnd_code_ != NO_GND_CODE)
            names_to_values_map.emplace(std::make_pair(std::string("gnd_code"),
                                                       std::vector<std::string>{ translations.front().gnd_code_ }));

        std::vector<std::string> language_codes, example_texts, url_escaped_example_texts;
        for (const auto &translation : translations) {
            language_codes.emplace_back(translation.language_code_);
            example_texts.emplace_back(translation.text_);
            url_escaped_example_texts.emplace_back(UrlUtil::UrlEncode(translation.text_));
        }
        names_to_values_map.emplace(std::make_pair(std::string("language_code"), language_codes));
        names_to_values_map.emplace(std::make_pair(std::string("example_text"), example_texts));
        names_to_values_map.emplace(std::make_pair(std::string("url_escaped_example_text"),
                                                   url_escaped_example_texts));

        std::ifstream translate_html("/var/lib/tuelib/translate_chainer/translate.html", std::ios::binary);
        MiscUtil::ExpandTemplate(translate_html, std::cout, names_to_values_map);
    }
}

void GetMissing(const std::multimap<std::string, std::string> &cgi_args) {
    const std::string language_code(GetCGIParameterOrDie(cgi_args, "language_code"));
    const std::string ixtheo_base_url(GetCGIParameterOrDie(cgi_args, "ixtheo_base_url"));

    const std::string GET_MISSING_COMMAND("/usr/local/bin/translation_db_tool get_missing " + language_code);
    std::string output;
    if (not ExecUtil::ExecSubcommandAndCaptureStdout(GET_MISSING_COMMAND, &output))
        Error("failed to execute \"" + GET_MISSING_COMMAND + "\" or it returned a non-zero exit code!");

    ParseTranslationsDbToolOutputAndGenerateNewDisplay(output, language_code, ixtheo_base_url);
}

void Insert(const std::multimap<std::string, std::string> &cgi_args) {
    const std::string language_code(GetCGIParameterOrDie(cgi_args, "language_code"));
    const std::string translation(GetCGIParameterOrDie(cgi_args, "translation"));
    const std::string index(GetCGIParameterOrDie(cgi_args, "index"));
    const std::string gnd_code(GetCGIParameterOrEmptyString(cgi_args, "gnd_code"));

    if (translation.empty())
        return;

    std::string insert_command("/usr/local/bin/translation_db_tool insert '" + index);
    if (not gnd_code.empty())
        insert_command += "' '" + gnd_code;
    insert_command += "' " + language_code + " '" + translation + "'";

    std::string output;
    if (not ExecUtil::ExecSubcommandAndCaptureStdout(insert_command, &output))
        Error("failed to execute \"" + insert_command + "\" or it returned a non-zero exit code!");
}

int main(int argc, char *argv[]) {
    ::progname = argv[0];

    try {
        std::multimap<std::string, std::string> cgi_args;
        WebUtil::GetAllCgiArgs(&cgi_args, argc, argv);

        if (cgi_args.size() == 1) {
            std::cout << "Content-Type: text/html; charset=utf-8\r\n\r\n";
            GetMissing(cgi_args);
        } else if (cgi_args.size() == 5) {
            const std::string language_code(GetCGIParameterOrDie(cgi_args, "language_code"));
            const std::string ixtheo_base_url(GetCGIParameterOrDie(cgi_args, "ixtheo_base_url"));
            std::cout << "Status: 302 Found\r\n";
            std::cout << "Location: /cgi-bin/translate_chainer?language_code=" << language_code
                      << "&ixtheo_base_url=" << ixtheo_base_url << "\r\n\r\n";
            Insert(cgi_args);
        } else
            Error("we should be called w/ either 1 or 5 CGI arguments!");
    } catch (const std::exception &x) {
        Error("caught exception: " + std::string(x.what()));
    }
}
<commit_msg>Work in progress.<commit_after>/** \file    translate_chainer.cc
 *  \brief   Simple tool for generating a sequence of Web pages for translations.
 *  \author  Dr. Johannes Ruscheinski
 */

/*
    Copyright (C) 2016, Library of the University of Tübingen

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as
    published by the Free Software Foundation, either version 3 of the
    License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <iostream>
#include <fstream>
#include <cerrno>
#include <cstdio>
#include <cstring>
#include "Compiler.h"
#include "ExecUtil.h"
#include "MiscUtil.h"
#include "StringUtil.h"
#include "UrlUtil.h"
#include "WebUtil.h"
#include "util.h"

void DumpCgiArgs(const std::multimap<std::string, std::string> &cgi_args) {
    for (const auto &key_and_values : cgi_args)
        std::cout << key_and_values.first << " = " << key_and_values.second << '\n';
}

void ParseEscapedCommaSeparatedList(const std::string &escaped_text, std::vector<std::string> * const list) {
    list->clear();

    std::string unescaped_text;
    bool last_char_was_backslash(false);

    for (const auto ch : escaped_text) {
        if (last_char_was_backslash) {
            last_char_was_backslash = false;
            unescaped_text += ch;
        } else if (ch == '\\')
            last_char_was_backslash = true;
        else if (ch == ',') {
            list->emplace_back(unescaped_text);
            unescaped_text.clear();
        } else
            unescaped_text += ch;
    }

    if (unlikely(last_char_was_backslash))
        Error("weird escaped string ends in backslash \"" + escaped_text + "\"!");

    list->emplace_back(StringUtil::RightTrim(&unescaped_text, '\n'));
}

struct Translation {
    std::string index_, remaining_count_, language_code_, text_, category_, gnd_code_;
};

const std::string NO_GND_CODE("-1");

void ParseGetMissingLine(const std::string &line, Translation * const translation) {
    std::vector<std::string> parts;
    ParseEscapedCommaSeparatedList(line, &parts);
    if (unlikely(parts.size() != 5 and parts.size() != 6))
        Error("expected 5 or 6 parts, found \"" + line + "\"!");

    translation->index_           = parts[0];
    translation->remaining_count_ = parts[1];
    translation->language_code_   = parts[2];
    translation->text_            = parts[3];
    translation->category_        = parts[4];
    translation->gnd_code_        = (parts.size() == 5) ? NO_GND_CODE : parts[5];
}

void ParseTranslationsDbToolOutput(const std::string &output, std::vector<Translation> * const translations) {
    std::vector<std::string> lines;
    StringUtil::Split(output, '\n', &lines);

    for (const auto &line : lines) {
        Translation new_translation;
        ParseGetMissingLine(line, &new_translation);
        translations->emplace_back(new_translation);
    }
}

std::string GetCGIParameterOrDie(const std::multimap<std::string, std::string> &cgi_args,
                                 const std::string &parameter_name)
{
    const auto key_and_value(cgi_args.find(parameter_name));
    if (key_and_value == cgi_args.cend())
        Error("expected a(n) \"" + parameter_name + "\" parameter!");

    return key_and_value->second;
}

std::string GetCGIParameterOrEmptyString(const std::multimap<std::string, std::string> &cgi_args,
                                         const std::string &parameter_name)
{
    const auto key_and_value(cgi_args.find(parameter_name));
    if (key_and_value == cgi_args.cend())
        return "";

    return key_and_value->second;
}

void ParseTranslationsDbToolOutputAndGenerateNewDisplay(const std::string &output, const std::string &language_code,
                                                        const std::string &ixtheo_base_url)
{
    std::vector<Translation> translations;
    ParseTranslationsDbToolOutput(output, &translations);
    if (translations.empty()) {
        std::ifstream done_html("/var/lib/tuelib/translate_chainer/done_translating.html", std::ios::binary);
        std::cout << done_html.rdbuf();
    } else {
        std::map<std::string, std::vector<std::string>> names_to_values_map;
        names_to_values_map.emplace(std::make_pair(std::string("index"),
                                                   std::vector<std::string>{ translations.front().index_ }));
        names_to_values_map.emplace(std::make_pair(std::string("remaining_count"),
                                                   std::vector<std::string>{ translations.front().remaining_count_ }));
        names_to_values_map.emplace(std::make_pair(std::string("target_language_code"),
                                                   std::vector<std::string>{ language_code }));
        names_to_values_map.emplace(std::make_pair(std::string("ixtheo_base_url"),
                                                   std::vector<std::string>{ UrlUtil::UrlDecode(ixtheo_base_url) }));
        names_to_values_map.emplace(std::make_pair(std::string("category"),
                                                   std::vector<std::string>{ translations.front().category_ }));
        if (translations.front().gnd_code_ != NO_GND_CODE)
            names_to_values_map.emplace(std::make_pair(std::string("gnd_code"),
                                                       std::vector<std::string>{ translations.front().gnd_code_ }));

        std::vector<std::string> language_codes, example_texts, url_escaped_example_texts;
        for (const auto &translation : translations) {
            language_codes.emplace_back(translation.language_code_);
            example_texts.emplace_back(translation.text_);
            url_escaped_example_texts.emplace_back(UrlUtil::UrlEncode(translation.text_));
        }
        names_to_values_map.emplace(std::make_pair(std::string("language_code"), language_codes));
        names_to_values_map.emplace(std::make_pair(std::string("example_text"), example_texts));
        names_to_values_map.emplace(std::make_pair(std::string("url_escaped_example_text"),
                                                   url_escaped_example_texts));

        std::ifstream translate_html("/var/lib/tuelib/translate_chainer/translate.html", std::ios::binary);
        MiscUtil::ExpandTemplate(translate_html, std::cout, names_to_values_map);
    }
}

void GetMissing(const std::multimap<std::string, std::string> &cgi_args) {
    const std::string language_code(GetCGIParameterOrDie(cgi_args, "language_code"));
    const std::string ixtheo_base_url(GetCGIParameterOrDie(cgi_args, "ixtheo_base_url"));

    const std::string GET_MISSING_COMMAND("/usr/local/bin/translation_db_tool get_missing " + language_code);
    std::string output;
    if (not ExecUtil::ExecSubcommandAndCaptureStdout(GET_MISSING_COMMAND, &output))
        Error("failed to execute \"" + GET_MISSING_COMMAND + "\" or it returned a non-zero exit code!");

    ParseTranslationsDbToolOutputAndGenerateNewDisplay(output, language_code, ixtheo_base_url);
}

void Insert(const std::multimap<std::string, std::string> &cgi_args) {
    const std::string language_code(GetCGIParameterOrDie(cgi_args, "language_code"));
    const std::string translation(GetCGIParameterOrDie(cgi_args, "translation"));
    const std::string index(GetCGIParameterOrDie(cgi_args, "index"));
    const std::string gnd_code(GetCGIParameterOrEmptyString(cgi_args, "gnd_code"));

    if (translation.empty())
        return;

    std::string insert_command("/usr/local/bin/translation_db_tool insert '" + index);
    if (not gnd_code.empty())
        insert_command += "' '" + gnd_code;
    insert_command += "' " + language_code + " '" + translation + "'";

    std::string output;
    if (not ExecUtil::ExecSubcommandAndCaptureStdout(insert_command, &output))
        Error("failed to execute \"" + insert_command + "\" or it returned a non-zero exit code!");
}

int main(int argc, char *argv[]) {
    ::progname = argv[0];

    try {
        std::multimap<std::string, std::string> cgi_args;
        WebUtil::GetAllCgiArgs(&cgi_args, argc, argv);

        if (cgi_args.size() == 2) {
            std::cout << "Content-Type: text/html; charset=utf-8\r\n\r\n";
            GetMissing(cgi_args);
        } else if (cgi_args.size() == 5) {
            const std::string language_code(GetCGIParameterOrDie(cgi_args, "language_code"));
            const std::string ixtheo_base_url(GetCGIParameterOrDie(cgi_args, "ixtheo_base_url"));
            std::cout << "Status: 302 Found\r\n";
            std::cout << "Location: /cgi-bin/translate_chainer?language_code=" << language_code
                      << "&ixtheo_base_url=" << ixtheo_base_url << "\r\n\r\n";
            Insert(cgi_args);
        } else
            Error("we should be called w/ either 1 or 5 CGI arguments!");
    } catch (const std::exception &x) {
        Error("caught exception: " + std::string(x.what()));
    }
}
<|endoftext|>


<commit_before>#include "Distributions.hh"
#include "conf.hh"
#include "LinearAlgebra.hh"

conf::Config config;

int
main(int argc, char *argv[])
{
  try {
    config("usage: gconvert [OPTION...]\n")
      ('h', "help", "", "", "display help")
      ('g', "gk=FILE", "arg must", "", "previous distributions (.gk)")
      ('o', "out=FILE", "arg must", "", "converted file (.gk)")
      ('d', "to-diagonal", "", "", "convert Gaussians to diagonal")
      ('f', "to-full", "", "", "convert Gaussians to full covariances")
      ('\0', "minvar=FLOAT", "arg", "0", "minimum diagonal variance")
      ;
    config.default_parse(argc, argv);

    if (config["to-diagonal"].specified && config["to-full"].specified)
      throw std::string("Don't define both -d and -f!");

    if (!config["to-diagonal"].specified && !config["to-full"].specified)
      throw std::string("Define either -d and -f!");

    PDFPool pool;
    PDFPool new_pool;
    pool.read_gk(config["gk"].get_str());
    new_pool.set_dim(pool.dim());

    Matrix covariance;
    Vector mean;
    for (int i=0; i<pool.size(); i++) {

      // Fetch source Gaussian
      Gaussian *gaussian = dynamic_cast< Gaussian* > (pool.get_pdf(i));
      if (gaussian == NULL)
        continue;

      // Create target Gaussian
      Gaussian *new_gaussian = NULL;
      if (config["to-diagonal"].specified)
        new_gaussian = new DiagonalGaussian(gaussian->dim());
      if (config["to-full"].specified)
        new_gaussian = new FullCovarianceGaussian(gaussian->dim());

      // Convert
      gaussian->get_covariance(covariance);
      gaussian->get_mean(mean);

      if (config["minvar"].specified)
      {
        double minvar = config["minvar"].get_float();
        for (int j = 0; j < gaussian->dim(); j++)
          if (covariance(j,j) < minvar)
            covariance(j,j) = minvar;
      }

      new_gaussian->set_covariance(covariance);
      new_gaussian->set_mean(mean);

      new_pool.set_pdf(i, new_gaussian);
    }

    new_pool.write_gk(config["out"].get_str());
  }
  catch (std::exception &e) {
    fprintf(stderr, "exception: %s\n", e.what());
    abort();
  }
}
<commit_msg>options to convert to subspace gaussians<commit_after>#include "Distributions.hh"
#include "conf.hh"
#include "LinearAlgebra.hh"

conf::Config config;
PrecisionSubspace *ps;
ExponentialSubspace *es;

int
main(int argc, char *argv[])
{
  try {
    config("usage: gconvert [OPTION...]\n")
      ('h', "help", "", "", "display help")
      ('g', "gk=FILE", "arg must", "", "previous distributions (.gk)")
      ('o', "out=FILE", "arg must", "", "converted file (.gk)")
      ('d', "to-diagonal", "", "", "convert Gaussians to diagonal")
      ('f', "to-full", "", "", "convert Gaussians to full covariances")
      ('p', "to-pcgmm", "", "", "convert Gaussians to have a subspace constraint on precisions")
      ('s', "to-scgmm", "", "", "convert Gaussians to have an exponential subspace constraint")
      ('i', "info=INT", "arg", "0", "info level")
      ('\0', "ssdim=INT", "arg", "0", "subspace dimensionality")
      ('\0', "minvar=FLOAT", "arg", "0", "minimum diagonal variance")
      ;
    config.default_parse(argc, argv);

    int count=0;

    if (config["to-diagonal"].specified)
      count++;
    if (config["to-full"].specified)
      count++;
    if (config["to-pcgmm"].specified)
      count++;
    if (config["to-scgmm"].specified)
      count++;
    if (count==0)
      throw std::string("Define a target Gaussian type!");
    if (count>1)
      throw std::string("Define only one target Gaussian type!");

    PDFPool pool;
    PDFPool new_pool;
    pool.read_gk(config["gk"].get_str());
    new_pool.set_dim(pool.dim());

    // Initialize precision subspace if needed
    if (config["to-pcgmm"].specified) {
      if (config["ssdim"].get_int() <= 0)
        throw std::string("The subspace dimensionality must be above zero!");
      ps = new PrecisionSubspace(config["ssdim"].get_int(), pool.dim());

      if (config["info"].get_int() > 0)
        std::cout << "Initializing the precision subspace\n";

      std::vector<double> weights;
      std::vector<LaGenMatDouble> covs;
      weights.resize(pool.size());
      covs.resize(pool.size());

      for (int i=0; i<pool.size(); i++) {
        // Fetch source Gaussian
        Gaussian *gaussian = dynamic_cast< Gaussian* > (pool.get_pdf(i));
        if (gaussian == NULL)
          continue;
        gaussian->get_covariance(covs[i]);
        weights[i] = 1;
      }

      ps->initialize_basis_pca(weights, covs, config["ssdim"].get_int());
    }

    // Initialize exponential subspace if needed
    if (config["to-scgmm"].specified) {
      if (config["ssdim"].get_int() <= 0)
        throw std::string("The subspace dimensionality must be above zero!");
      es = new ExponentialSubspace(config["ssdim"].get_int(), pool.dim());

      if (config["info"].get_int() > 0)
        std::cout << "Initializing the exponential subspace\n";

      std::vector<double> weights;
      std::vector<LaVectorDouble> means;
      std::vector<LaGenMatDouble> covs;
      weights.resize(pool.size());
      covs.resize(pool.size());
      means.resize(pool.size());

      for (int i=0; i<pool.size(); i++) {
        // Fetch source Gaussian
        Gaussian *gaussian = dynamic_cast< Gaussian* > (pool.get_pdf(i));
        if (gaussian == NULL)
          continue;
        gaussian->get_covariance(covs[i]);
        gaussian->get_mean(means[i]);
        weights[i] = 1;
      }

      es->initialize_basis_pca(weights, covs, means, config["ssdim"].get_int());
    }

    Matrix covariance;
    Vector mean;
    for (int i=0; i<pool.size(); i++) {

      if (config["info"].get_int() > 0)
        std::cout << "Converting Gaussian: " << i << "/" << pool.size() << std::endl;

      // Fetch source Gaussian
      Gaussian *gaussian = dynamic_cast< Gaussian* > (pool.get_pdf(i));
      if (gaussian == NULL)
        continue;

      // Create target Gaussian
      Gaussian *new_gaussian = NULL;
      if (config["to-diagonal"].specified)
        new_gaussian = new DiagonalGaussian(gaussian->dim());
      if (config["to-full"].specified)
        new_gaussian = new FullCovarianceGaussian(gaussian->dim());
      if (config["to-pcgmm"].specified)
        new_gaussian = new PrecisionConstrainedGaussian(ps);
      if (config["to-scgmm"].specified)
        new_gaussian = new SubspaceConstrainedGaussian(es);

      // Convert
      gaussian->get_covariance(covariance);
      gaussian->get_mean(mean);

      if (config["minvar"].specified)
      {
        double minvar = config["minvar"].get_float();
        for (int j = 0; j < gaussian->dim(); j++)
          if (covariance(j,j) < minvar)
            covariance(j,j) = minvar;
      }

      new_gaussian->set_parameters(mean, covariance);

      new_pool.set_pdf(i, new_gaussian);
    }

    new_pool.write_gk(config["out"].get_str());
  }
  catch (std::exception &e) {
    fprintf(stderr, "exception: %s\n", e.what());
    abort();
  }
}
<|endoftext|>


<commit_before>/*ckwg +5
 * Copyright 2011 by Kitware, Inc. All Rights Reserved. Please refer to
 * KITWARE_LICENSE.TXT for licensing information, or contact General Counsel,
 * Kitware, Inc., 28 Corporate Drive, Clifton Park, NY 12065.
 */

#include <vistk/pipeline/pipeline.h>
#include <vistk/pipeline/pipeline_exception.h>

#include <boost/python/class.hpp>
#include <boost/python/module.hpp>

/**
 * \file pipeline.cxx
 *
 * \brief Python bindings for \link vistk::pipeline\endlink.
 */

using namespace boost::python;

BOOST_PYTHON_MODULE(pipeline)
{
  class_<vistk::pipeline, vistk::pipeline_t, boost::noncopyable>("Pipeline"
    , "A data structure for a collection of connected processes."
    , no_init)
    .def(init<vistk::config_t>())
    .def("add_process", &vistk::pipeline::add_process
      , (arg("process"))
      , "Add a process to the pipeline.")
    .def("add_group", &vistk::pipeline::add_group
      , (arg("group"))
      , "Create a group within the pipeline.")
    .def("remove_process", &vistk::pipeline::remove_process
      , (arg("name"))
      , "Remove a process from the pipeline.")
    .def("remove_group", &vistk::pipeline::remove_group
      , (arg("group"))
      , "Remove a group from the pipeline.")
    .def("connect", &vistk::pipeline::connect
      , (arg("upstream"), arg("upstream_port"), arg("downstream"), arg("downstream_port"))
      , "Connect two ports within the pipeline together.")
    .def("disconnect", &vistk::pipeline::disconnect
      , (arg("upstream"), arg("upstream_port"), arg("downstream"), arg("downstream_port"))
      , "Disconnect two ports from each other in the pipeline.")
    .def("map_input_port", &vistk::pipeline::map_input_port
      , (arg("group"), arg("group_port"), arg("process"), arg("process_port"), arg("flags"))
      , "Maps a group input port to an input port on a process.")
    .def("map_output_port", &vistk::pipeline::map_output_port
      , (arg("group"), arg("group_port"), arg("process"), arg("process_port"), arg("flags"))
      , "Maps a group output port to an output port on a process.")
    .def("unmap_input_port", &vistk::pipeline::unmap_input_port
      , (arg("group"), arg("group_port"), arg("name"), arg("process_port"))
      , "Unmaps a group input port from an input port on a process.")
    .def("unmap_output_port", &vistk::pipeline::unmap_output_port
      , (arg("group"), arg("group_port"), arg("name"), arg("process_port"))
      , "Unmaps a group output port from an output port on a process.")
    .def("setup_pipeline", &vistk::pipeline::setup_pipeline
      , "Prepares the pipeline for execution.")
    .def("is_setup", &vistk::pipeline::is_setup
      , "Returns True if the pipeline has been setup, False otherwise.")
    .def("setup_successful", &vistk::pipeline::setup_successful
      , "Returns True if the pipeline has been successfully setup, False otherwise.")
    .def("reset", &vistk::pipeline::reset
      , "Resets connections within the pipeline.")
    .def("start", &vistk::pipeline::start
      , "Notify the pipeline that its execution has started.")
    .def("stop", &vistk::pipeline::stop
      , "Notify the pipeline that its execution has ended.")
    .def("process_names", &vistk::pipeline::process_names
      , "Returns a list of all process names in the pipeline.")
    .def("process_by_name", &vistk::pipeline::process_by_name
      , (arg("name"))
      , "Get a process by name.")
    .def("connections_from_addr", &vistk::pipeline::connections_from_addr
      , (arg("name"), arg("port"))
      , "Return the addresses of ports that are connected downstream of a port.")
    .def("connection_to_addr", &vistk::pipeline::connection_to_addr
      , (arg("name"), arg("port"))
      , "Return the address for the port that is connected upstream of a port.")
    .def("upstream_for_process", &vistk::pipeline::upstream_for_process
      , (arg("name"))
      , "Return all processes upstream of the given process.")
    .def("upstream_for_port", &vistk::pipeline::upstream_for_port
      , (arg("name"), arg("port"))
      , "Return the process upstream of the given port.")
    .def("downstream_for_process", &vistk::pipeline::downstream_for_process
      , (arg("name"))
      , "Return all processes downstream of the given process.")
    .def("downstream_for_port", &vistk::pipeline::downstream_for_port
      , (arg("name"), arg("port"))
      , "Return the processes downstream of the given port.")
    .def("sender_for_port", &vistk::pipeline::sender_for_port
      , (arg("name"), arg("port"))
      , "Return the port that is sending to the given port.")
    .def("receivers_for_port", &vistk::pipeline::receivers_for_port
      , (arg("name"), arg("port"))
      , "Return the port that is receiving from the given port.")
    .def("edge_for_connection", &vistk::pipeline::edge_for_connection
      , (arg("upstream_name"), arg("upstream_port"), arg("downstream_name"), arg("downstream_port"))
      , "Returns the edge for the connection.")
    .def("input_edges_for_process", &vistk::pipeline::input_edges_for_process
      , (arg("name"))
      , "Return the edges that are sending to the given process.")
    .def("input_edge_for_port", &vistk::pipeline::input_edge_for_port
      , (arg("name"), arg("port"))
      , "Return the edge that is sending to the given port.")
    .def("output_edges_for_process", &vistk::pipeline::output_edges_for_process
      , (arg("name"))
      , "Return the edges that are receiving data from the given process.")
    .def("output_edges_for_port", &vistk::pipeline::output_edges_for_port
      , (arg("name"), arg("port"))
      , "Return the edges that are receiving data from the given port.")
    .def("groups", &vistk::pipeline::groups
      , "Returns a list of all groups in the pipeline.")
    .def("input_ports_for_group", &vistk::pipeline::input_ports_for_group
      , (arg("name"))
      , "Return the input ports on a group.")
    .def("output_ports_for_group", &vistk::pipeline::output_ports_for_group
      , (arg("name"))
      , "Return the output ports on a group.")
    .def("mapped_group_input_port_flags", &vistk::pipeline::mapped_group_input_port_flags
      , (arg("name"), arg("port"))
      , "Return the flags on a group\'s input port.")
    .def("mapped_group_output_port_flags", &vistk::pipeline::mapped_group_output_port_flags
      , (arg("name"), arg("port"))
      , "Return the flags on a group\'s output port.")
    .def("mapped_group_input_ports", &vistk::pipeline::mapped_group_input_ports
      , (arg("name"), arg("port"))
      , "Return the ports that are mapped to the group's input port.")
    .def("mapped_group_output_port", &vistk::pipeline::mapped_group_output_port
      , (arg("name"), arg("port"))
      , "Return the ports that are mapped to the group's output port.")
  ;
}
<commit_msg>Fix some docstring typos in pipeline bindings<commit_after>/*ckwg +5
 * Copyright 2011 by Kitware, Inc. All Rights Reserved. Please refer to
 * KITWARE_LICENSE.TXT for licensing information, or contact General Counsel,
 * Kitware, Inc., 28 Corporate Drive, Clifton Park, NY 12065.
 */

#include <vistk/pipeline/pipeline.h>
#include <vistk/pipeline/pipeline_exception.h>

#include <boost/python/class.hpp>
#include <boost/python/module.hpp>

/**
 * \file pipeline.cxx
 *
 * \brief Python bindings for \link vistk::pipeline\endlink.
 */

using namespace boost::python;

BOOST_PYTHON_MODULE(pipeline)
{
  class_<vistk::pipeline, vistk::pipeline_t, boost::noncopyable>("Pipeline"
    , "A data structure for a collection of connected processes."
    , no_init)
    .def(init<vistk::config_t>())
    .def("add_process", &vistk::pipeline::add_process
      , (arg("process"))
      , "Add a process to the pipeline.")
    .def("add_group", &vistk::pipeline::add_group
      , (arg("group"))
      , "Create a group within the pipeline.")
    .def("remove_process", &vistk::pipeline::remove_process
      , (arg("name"))
      , "Remove a process from the pipeline.")
    .def("remove_group", &vistk::pipeline::remove_group
      , (arg("group"))
      , "Remove a group from the pipeline.")
    .def("connect", &vistk::pipeline::connect
      , (arg("upstream"), arg("upstream_port"), arg("downstream"), arg("downstream_port"))
      , "Connect two ports within the pipeline together.")
    .def("disconnect", &vistk::pipeline::disconnect
      , (arg("upstream"), arg("upstream_port"), arg("downstream"), arg("downstream_port"))
      , "Disconnect two ports from each other in the pipeline.")
    .def("map_input_port", &vistk::pipeline::map_input_port
      , (arg("group"), arg("group_port"), arg("name"), arg("process_port"), arg("flags"))
      , "Maps a group input port to an input port on a process.")
    .def("map_output_port", &vistk::pipeline::map_output_port
      , (arg("group"), arg("group_port"), arg("name"), arg("process_port"), arg("flags"))
      , "Maps a group output port to an output port on a process.")
    .def("unmap_input_port", &vistk::pipeline::unmap_input_port
      , (arg("group"), arg("group_port"), arg("name"), arg("process_port"))
      , "Unmaps a group input port from an input port on a process.")
    .def("unmap_output_port", &vistk::pipeline::unmap_output_port
      , (arg("group"), arg("group_port"), arg("name"), arg("process_port"))
      , "Unmaps a group output port from an output port on a process.")
    .def("setup_pipeline", &vistk::pipeline::setup_pipeline
      , "Prepares the pipeline for execution.")
    .def("is_setup", &vistk::pipeline::is_setup
      , "Returns True if the pipeline has been setup, False otherwise.")
    .def("setup_successful", &vistk::pipeline::setup_successful
      , "Returns True if the pipeline has been successfully setup, False otherwise.")
    .def("reset", &vistk::pipeline::reset
      , "Resets connections within the pipeline.")
    .def("start", &vistk::pipeline::start
      , "Notify the pipeline that its execution has started.")
    .def("stop", &vistk::pipeline::stop
      , "Notify the pipeline that its execution has ended.")
    .def("process_names", &vistk::pipeline::process_names
      , "Returns a list of all process names in the pipeline.")
    .def("process_by_name", &vistk::pipeline::process_by_name
      , (arg("name"))
      , "Get a process by name.")
    .def("connections_from_addr", &vistk::pipeline::connections_from_addr
      , (arg("name"), arg("port"))
      , "Return the addresses of ports that are connected downstream of a port.")
    .def("connection_to_addr", &vistk::pipeline::connection_to_addr
      , (arg("name"), arg("port"))
      , "Return the address for the port that is connected upstream of a port.")
    .def("upstream_for_process", &vistk::pipeline::upstream_for_process
      , (arg("name"))
      , "Return all processes upstream of the given process.")
    .def("upstream_for_port", &vistk::pipeline::upstream_for_port
      , (arg("name"), arg("port"))
      , "Return the process upstream of the given port.")
    .def("downstream_for_process", &vistk::pipeline::downstream_for_process
      , (arg("name"))
      , "Return all processes downstream of the given process.")
    .def("downstream_for_port", &vistk::pipeline::downstream_for_port
      , (arg("name"), arg("port"))
      , "Return the processes downstream of the given port.")
    .def("sender_for_port", &vistk::pipeline::sender_for_port
      , (arg("name"), arg("port"))
      , "Return the port that is sending to the given port.")
    .def("receivers_for_port", &vistk::pipeline::receivers_for_port
      , (arg("name"), arg("port"))
      , "Return the ports that are receiving from the given port.")
    .def("edge_for_connection", &vistk::pipeline::edge_for_connection
      , (arg("upstream_name"), arg("upstream_port"), arg("downstream_name"), arg("downstream_port"))
      , "Returns the edge for the connection.")
    .def("input_edges_for_process", &vistk::pipeline::input_edges_for_process
      , (arg("name"))
      , "Return the edges that are sending to the given process.")
    .def("input_edge_for_port", &vistk::pipeline::input_edge_for_port
      , (arg("name"), arg("port"))
      , "Return the edge that is sending to the given port.")
    .def("output_edges_for_process", &vistk::pipeline::output_edges_for_process
      , (arg("name"))
      , "Return the edges that are receiving data from the given process.")
    .def("output_edges_for_port", &vistk::pipeline::output_edges_for_port
      , (arg("name"), arg("port"))
      , "Return the edges that are receiving data from the given port.")
    .def("groups", &vistk::pipeline::groups
      , "Returns a list of all groups in the pipeline.")
    .def("input_ports_for_group", &vistk::pipeline::input_ports_for_group
      , (arg("name"))
      , "Return the input ports on a group.")
    .def("output_ports_for_group", &vistk::pipeline::output_ports_for_group
      , (arg("name"))
      , "Return the output ports on a group.")
    .def("mapped_group_input_port_flags", &vistk::pipeline::mapped_group_input_port_flags
      , (arg("name"), arg("port"))
      , "Return the flags on a group\'s input port.")
    .def("mapped_group_output_port_flags", &vistk::pipeline::mapped_group_output_port_flags
      , (arg("name"), arg("port"))
      , "Return the flags on a group\'s output port.")
    .def("mapped_group_input_ports", &vistk::pipeline::mapped_group_input_ports
      , (arg("name"), arg("port"))
      , "Return the ports that are mapped to the group's input port.")
    .def("mapped_group_output_port", &vistk::pipeline::mapped_group_output_port
      , (arg("name"), arg("port"))
      , "Return the ports that are mapped to the group's output port.")
  ;
}
<|endoftext|>


<commit_before>#include "nany/nany.h"
#include <yuni/io/file.h>
#include <yuni/core/math.h>
#include <yuni/core/process/program.h>
#include "libnany-config.h"
#include "common-debuginfo.hxx"
#include <string.h>
#include <iostream>

using namespace Yuni;

namespace // anonymous
{

	template<class T>
	static inline void buildBugReport(T& string)
	{
		string << "> nanyc {c++/bootstrap} v" << libnany_version();
		if (debugmode)
			string << " {debug}";
		string << '\n';

		string << "> compiled with ";
		nany_details_export_compiler_version(string);
		string << '\n';

		bool custombuild = Nany::Config::maxSymbolNameLength != 64
			or Nany::Config::maxNamespaceDepth != 32
			or Nany::Config::maxFuncDeclParameterCount != 7
			or Nany::Config::maxPushedParameters != 32;
		if (custombuild)
		{
			string << "> !! nany.build.config: "
				<< "pp:" << Nany::Config::maxPushedParameters
				<< ", p:" << Nany::Config::maxFuncDeclParameterCount
				<< ", nd:" << Nany::Config::maxNamespaceDepth
				<< ", sl:" << Nany::Config::maxSymbolNameLength
				<< '\n';
		}

		string << "> os: ";
		#ifdef YUNI_OS_LINUX
		{
			String distribName;
			if (IO::errNone == IO::File::LoadFromFile(distribName, "/etc/issue.net"))
			{
				distribName.replace("\n", " ");
				distribName.trim();
				if (not distribName.empty())
					string << distribName << ", ";
			}
			string << Process::System("uname -m -s -p -r") << ", ";
		}
		#endif
		nany_details_export_system(string);
		string << '\n';

		string << "> cpu: " << System::CPU::Count() << " cpu(s)/core(s)\n";
		#ifdef YUNI_OS_LINUX
		{
			auto cpus = Process::System("sh -c \"grep 'model name' /proc/cpuinfo | cut -d':' -f 2 |  sort -u\"");
			cpus.words("\n", [&](AnyString line) -> bool {
				line.trim();
				if (not line.empty())
					string << "> cpu: " << line << '\n';
				return true;
			});
		}
		#endif

		string << "> ";
		nany_details_export_memory_usage(string);
		string << '\n';
	}

} // anonymous namespace

extern "C" void libnany_print_info_for_bugreport()
{
	buildBugReport(std::cout);
}

extern "C" char* libnany_get_info_for_bugreport(uint32_t* length)
{
	String string;
	string.reserve(512);
	buildBugReport(string);

	char* result = (char*)::malloc(sizeof(char) * (string.sizeInBytes() + 1));
	if (!result)
	{
		if (length)
			*length = 0u;
		return nullptr;
	}
	memcpy(result, string.data(), string.sizeInBytes());
	result[string.sizeInBytes()] = '\0';
	if (length)
		*length = string.size();
	return result;
}
<commit_msg>bugreport: simplified output, unified cpu descriptions<commit_after>#include "nany/nany.h"
#include <yuni/io/file.h>
#include <yuni/core/math.h>
#include <yuni/core/process/program.h>
#include "libnany-config.h"
#include "common-debuginfo.hxx"
#include <string.h>
#include <iostream>

using namespace Yuni;

namespace // anonymous
{

	template<class T>
	static inline void buildBugReport(T& string)
	{
		string << "> nanyc {c++/bootstrap} v" << libnany_version();
		if (debugmode)
			string << " {debug}";
		string << '\n';

		string << "> compiled with ";
		nany_details_export_compiler_version(string);
		string << '\n';

		string << "> config: "
			<< "params:" << Nany::Config::maxFuncDeclParameterCount
			<< ", pushedparams:" << Nany::Config::maxPushedParameters
			<< ", nmspc depth:" << Nany::Config::maxNamespaceDepth
			<< ", symbol:" << Nany::Config::maxSymbolNameLength
			<< ", nsl:" << Nany::Config::importNSL
			<< '\n';

		string << "> os: ";
		if (System::linux)
		{
			String distribName;
			if (IO::errNone == IO::File::LoadFromFile(distribName, "/etc/issue.net"))
			{
				distribName.replace("\n", " ");
				distribName.trim();
				if (not distribName.empty())
					string << distribName << ", ";
			}
			string << Process::System("uname -m -s -p -r") << ", ";
		}
		nany_details_export_system(string);
		string << '\n';

		ShortString64 cpustr;
		cpustr << System::CPU::Count() << " cpu(s)/core(s)";

		bool cpuAdded = false;
		if (System::linux)
		{
			auto cpus = Process::System("sh -c \"grep 'model name' /proc/cpuinfo | cut -d':' -f 2 |  sort -u\"");
			cpus.words("\n", [&](AnyString line) -> bool
			{
				line.trim();
				if (not line.empty())
				{
					string << "> cpu: " << line;
					if (not cpuAdded)
					{
						string << " (" << cpustr << ')';
						cpuAdded = true;
					}
					string << '\n';
				}
				return true;
			});
		}

		if (not cpuAdded)
			string << "> cpu: " << cpustr << '\n';

		string << "> ";
		nany_details_export_memory_usage(string);
		string << '\n';
	}

} // anonymous namespace

extern "C" void libnany_print_info_for_bugreport()
{
	buildBugReport(std::cout);
}

extern "C" char* libnany_get_info_for_bugreport(uint32_t* length)
{
	String string;
	string.reserve(512);
	buildBugReport(string);

	char* result = (char*)::malloc(sizeof(char) * (string.sizeInBytes() + 1));
	if (!result)
	{
		if (length)
			*length = 0u;
		return nullptr;
	}
	memcpy(result, string.data(), string.sizeInBytes());
	result[string.sizeInBytes()] = '\0';
	if (length)
		*length = string.size();
	return result;
}
<|endoftext|>


<commit_before>#include "chrono_parallel/solver/ChSolverBB.h"
#include <blaze/math/CompressedVector.h>
using namespace chrono;

ChSolverBB::ChSolverBB() : ChSolverParallel() {}

void ChSolverBB::UpdateR() {
    const SubMatrixType& D_n_T = _DNT_;
    const DynamicVector<real>& M_invk = data_manager->host_data.M_invk;
    const DynamicVector<real>& b = data_manager->host_data.b;
    DynamicVector<real>& R = data_manager->host_data.R;
    DynamicVector<real>& s = data_manager->host_data.s;

    uint num_contacts = data_manager->num_rigid_contacts;

    s.resize(data_manager->num_rigid_contacts);
    reset(s);

    rigid_rigid->Build_s();

    ConstSubVectorType b_n = blaze::subvector(b, 0, num_contacts);
    SubVectorType R_n = blaze::subvector(R, 0, num_contacts);
    SubVectorType s_n = blaze::subvector(s, 0, num_contacts);

    R_n = -b_n - D_n_T * M_invk + s_n;
}

uint ChSolverBB::SolveBB(const uint max_iter,
                         const uint size,
                         const DynamicVector<real>& r,
                         DynamicVector<real>& gamma) {
    real& lastgoodres = data_manager->measures.solver.residual;
    real& objective_value = data_manager->measures.solver.objective_value;

    // ChTimer<> t1, t2, t3, t4;
    // t1.start();

    temp.resize(size);
    ml.resize(size);
    mg.resize(size);
    mg_p.resize(size);
    ml_candidate.resize(size);
    ms.resize(size);
    my.resize(size);
    mdir.resize(size);
    ml_p.resize(size);

    temp = 0;
    ml = 0;
    mg = 0;
    mg_p = 0;
    ml_candidate = 0;
    ms = 0;
    my = 0;
    mdir = 0;
    ml_p = 0;

    // Tuning of the spectral gradient search
    real a_min = 1e-13;
    real a_max = 1e13;
    real sigma_min = 0.1;
    real sigma_max = 0.9;

    real alpha = 0.0001;
    if (data_manager->settings.solver.cache_step_length == true) {
        if (data_manager->settings.solver.solver_mode == NORMAL) {
            alpha = data_manager->measures.solver.normal_apgd_step_length;
        } else if (data_manager->settings.solver.solver_mode == SLIDING) {
            alpha = data_manager->measures.solver.sliding_apgd_step_length;
        } else if (data_manager->settings.solver.solver_mode == SPINNING) {
            alpha = data_manager->measures.solver.spinning_apgd_step_length;
        } else if (data_manager->settings.solver.solver_mode == BILATERAL) {
            alpha = data_manager->measures.solver.bilateral_apgd_step_length;
        } else if (data_manager->settings.solver.use_power_iteration) {
            data_manager->measures.solver.lambda_max =
                LargestEigenValue(temp, data_manager->measures.solver.lambda_max);
            alpha = 1.95 / data_manager->measures.solver.lambda_max;
        }
    } else {
        alpha = 0.0001;
    }
    real gmma = 1e-4;
    real gdiff = 1.0 / pow(size, 2.0);
    bool do_preconditioning = false;
    real neg_BB1_fallback = 0.11;
    real neg_BB2_fallback = 0.12;
    ml = gamma;
    lastgoodres = 10e30;
    real lastgoodfval = 10e30;
    ml_candidate = ml;
    ShurProduct(ml, temp);
    mg = temp - r;
    mg_p = mg;

    real mf_p = 0;
    real mf = 1e29;
    int n_armijo = 10;
    int max_armijo_backtrace = 3;
    std::vector<real> f_hist;
    // t1.stop();

    for (current_iteration = 0; current_iteration < max_iter; current_iteration++) {
        // t2.start();
        temp = (ml - alpha * mg);
        Project(temp.data());
        mdir = temp - ml;

        real dTg = (mdir, mg);
        real lambda = 1.0;
        int n_backtracks = 0;
        bool armijo_repeat = true;
        // t2.stop();
        // t3.start();
        while (armijo_repeat) {
            ml_p = ml + lambda * mdir;

            ShurProduct(ml_p, temp);
            mg_p = temp - r;
            mf_p = (ml_p, 0.5 * temp - r);

            f_hist.push_back(mf_p);

            real max_compare = 10e29;
            for (int h = 1; h <= Min(current_iteration, n_armijo); h++) {
                real compare = f_hist[current_iteration - h] + gmma * lambda * dTg;
                if (compare > max_compare)
                    max_compare = compare;
            }
            if (mf_p > max_compare) {
                armijo_repeat = true;
                if (current_iteration > 0)
                    mf = f_hist[current_iteration - 1];
                real lambdanew = -lambda * lambda * dTg / (2 * (mf_p - mf - lambda * dTg));
                lambda = Max(sigma_min * lambda, Min(sigma_max * lambda, lambdanew));
                printf("Repeat Armijo, new lambda = %f \n", lambda);
            } else {
                armijo_repeat = false;
            }
            n_backtracks = n_backtracks + 1;
            if (n_backtracks > max_armijo_backtrace)
                armijo_repeat = false;
        }
        // t3.stop();
        // t4.start();
        ms = ml_p - ml;
        my = mg_p - mg;
        ml = ml_p;
        mg = mg_p;

        if (current_iteration % 2 == 0) {
            real sDs = (ms, ms);
            real sy = (ms, my);
            if (sy <= 0) {
                alpha = neg_BB1_fallback;
            } else {
                alpha = Min(a_max, Max(a_min, sDs / sy));
            }
        } else {
            real sy = (ms, my);
            real yDy = (my, my);
            if (sy <= 0) {
                alpha = neg_BB2_fallback;
            } else {
                alpha = Min(a_max, Max(a_min, sy / yDy));
            }
        }
        temp = ml - gdiff * mg;
        Project(temp.data());
        temp = (ml - temp) / (-gdiff);

        real g_proj_norm = Sqrt((temp, temp));
        if (g_proj_norm < lastgoodres) {
            lastgoodres = g_proj_norm;
            objective_value = mf_p;
            ml_candidate = ml;
        }

        AtIterationEnd(lastgoodres, objective_value);
        if (lastgoodres < data_manager->settings.solver.tol_speed) {
            break;
        }

        // t4.stop();
    }
    // printf("TIME: [%f %f %f %f]\n", t1(), t2(), t3(), t4());
    if (data_manager->settings.solver.solver_mode == NORMAL) {
        data_manager->measures.solver.normal_apgd_step_length = alpha;
    } else if (data_manager->settings.solver.solver_mode == SLIDING) {
        data_manager->measures.solver.sliding_apgd_step_length = alpha;
    } else if (data_manager->settings.solver.solver_mode == SPINNING) {
        data_manager->measures.solver.spinning_apgd_step_length = alpha;
    } else if (data_manager->settings.solver.solver_mode == BILATERAL) {
        data_manager->measures.solver.bilateral_apgd_step_length = alpha;
    }
    gamma = ml_candidate;
    data_manager->system_timer.stop("ChSolverParallel_Solve");
    return current_iteration;
}
<commit_msg>BB solver was not using power iterations correctly<commit_after>#include "chrono_parallel/solver/ChSolverBB.h"
#include <blaze/math/CompressedVector.h>
using namespace chrono;

ChSolverBB::ChSolverBB() : ChSolverParallel() {}

void ChSolverBB::UpdateR() {
    const SubMatrixType& D_n_T = _DNT_;
    const DynamicVector<real>& M_invk = data_manager->host_data.M_invk;
    const DynamicVector<real>& b = data_manager->host_data.b;
    DynamicVector<real>& R = data_manager->host_data.R;
    DynamicVector<real>& s = data_manager->host_data.s;

    uint num_contacts = data_manager->num_rigid_contacts;

    s.resize(data_manager->num_rigid_contacts);
    reset(s);

    rigid_rigid->Build_s();

    ConstSubVectorType b_n = blaze::subvector(b, 0, num_contacts);
    SubVectorType R_n = blaze::subvector(R, 0, num_contacts);
    SubVectorType s_n = blaze::subvector(s, 0, num_contacts);

    R_n = -b_n - D_n_T * M_invk + s_n;
}

uint ChSolverBB::SolveBB(const uint max_iter,
                         const uint size,
                         const DynamicVector<real>& r,
                         DynamicVector<real>& gamma) {
    real& lastgoodres = data_manager->measures.solver.residual;
    real& objective_value = data_manager->measures.solver.objective_value;

    // ChTimer<> t1, t2, t3, t4;
    // t1.start();

    temp.resize(size);
    ml.resize(size);
    mg.resize(size);
    mg_p.resize(size);
    ml_candidate.resize(size);
    ms.resize(size);
    my.resize(size);
    mdir.resize(size);
    ml_p.resize(size);

    temp = 0;
    ml = 0;
    mg = 0;
    mg_p = 0;
    ml_candidate = 0;
    ms = 0;
    my = 0;
    mdir = 0;
    ml_p = 0;

    // Tuning of the spectral gradient search
    real a_min = 1e-13;
    real a_max = 1e13;
    real sigma_min = 0.1;
    real sigma_max = 0.9;

    real alpha = 0.0001;
    if (data_manager->settings.solver.cache_step_length == true) {
        if (data_manager->settings.solver.solver_mode == NORMAL) {
            alpha = data_manager->measures.solver.normal_apgd_step_length;
        } else if (data_manager->settings.solver.solver_mode == SLIDING) {
            alpha = data_manager->measures.solver.sliding_apgd_step_length;
        } else if (data_manager->settings.solver.solver_mode == SPINNING) {
            alpha = data_manager->measures.solver.spinning_apgd_step_length;
        } else if (data_manager->settings.solver.solver_mode == BILATERAL) {
            alpha = data_manager->measures.solver.bilateral_apgd_step_length;
        } else {
            alpha = 0.0001;
        }
    } else if (data_manager->settings.solver.use_power_iteration) {
        data_manager->measures.solver.lambda_max = LargestEigenValue(temp, data_manager->measures.solver.lambda_max);
        alpha = 1.95 / data_manager->measures.solver.lambda_max;
    }
    real gmma = 1e-4;
    real gdiff = 1.0 / pow(size, 2.0);
    bool do_preconditioning = false;
    real neg_BB1_fallback = 0.11;
    real neg_BB2_fallback = 0.12;
    ml = gamma;
    lastgoodres = 10e30;
    real lastgoodfval = 10e30;
    ml_candidate = ml;
    ShurProduct(ml, temp);
    mg = temp - r;
    mg_p = mg;

    real mf_p = 0;
    real mf = 1e29;
    int n_armijo = 10;
    int max_armijo_backtrace = 3;
    std::vector<real> f_hist;
    // t1.stop();

    for (current_iteration = 0; current_iteration < max_iter; current_iteration++) {
        // t2.start();
        temp = (ml - alpha * mg);
        Project(temp.data());
        mdir = temp - ml;

        real dTg = (mdir, mg);
        real lambda = 1.0;
        int n_backtracks = 0;
        bool armijo_repeat = true;
        // t2.stop();
        // t3.start();
        while (armijo_repeat) {
            ml_p = ml + lambda * mdir;

            ShurProduct(ml_p, temp);
            mg_p = temp - r;
            mf_p = (ml_p, 0.5 * temp - r);

            f_hist.push_back(mf_p);

            real max_compare = 10e29;
            for (int h = 1; h <= Min(current_iteration, n_armijo); h++) {
                real compare = f_hist[current_iteration - h] + gmma * lambda * dTg;
                if (compare > max_compare)
                    max_compare = compare;
            }
            if (mf_p > max_compare) {
                armijo_repeat = true;
                if (current_iteration > 0)
                    mf = f_hist[current_iteration - 1];
                real lambdanew = -lambda * lambda * dTg / (2 * (mf_p - mf - lambda * dTg));
                lambda = Max(sigma_min * lambda, Min(sigma_max * lambda, lambdanew));
                printf("Repeat Armijo, new lambda = %f \n", lambda);
            } else {
                armijo_repeat = false;
            }
            n_backtracks = n_backtracks + 1;
            if (n_backtracks > max_armijo_backtrace)
                armijo_repeat = false;
        }
        // t3.stop();
        // t4.start();
        ms = ml_p - ml;
        my = mg_p - mg;
        ml = ml_p;
        mg = mg_p;

        if (current_iteration % 2 == 0) {
            real sDs = (ms, ms);
            real sy = (ms, my);
            if (sy <= 0) {
                alpha = neg_BB1_fallback;
            } else {
                alpha = Min(a_max, Max(a_min, sDs / sy));
            }
        } else {
            real sy = (ms, my);
            real yDy = (my, my);
            if (sy <= 0) {
                alpha = neg_BB2_fallback;
            } else {
                alpha = Min(a_max, Max(a_min, sy / yDy));
            }
        }
        temp = ml - gdiff * mg;
        Project(temp.data());
        temp = (ml - temp) / (-gdiff);

        real g_proj_norm = Sqrt((temp, temp));
        if (g_proj_norm < lastgoodres) {
            lastgoodres = g_proj_norm;
            objective_value = mf_p;
            ml_candidate = ml;
        }

        AtIterationEnd(lastgoodres, objective_value);
        if (lastgoodres < data_manager->settings.solver.tol_speed) {
            break;
        }

        // t4.stop();
    }
    // printf("TIME: [%f %f %f %f]\n", t1(), t2(), t3(), t4());
    if (data_manager->settings.solver.solver_mode == NORMAL) {
        data_manager->measures.solver.normal_apgd_step_length = alpha;
    } else if (data_manager->settings.solver.solver_mode == SLIDING) {
        data_manager->measures.solver.sliding_apgd_step_length = alpha;
    } else if (data_manager->settings.solver.solver_mode == SPINNING) {
        data_manager->measures.solver.spinning_apgd_step_length = alpha;
    } else if (data_manager->settings.solver.solver_mode == BILATERAL) {
        data_manager->measures.solver.bilateral_apgd_step_length = alpha;
    }
    gamma = ml_candidate;
    data_manager->system_timer.stop("ChSolverParallel_Solve");
    return current_iteration;
}
<|endoftext|>


<commit_before>/*
	This file is part of the E_Util library.
	Copyright (C) 2009-2012 Benjamin Eikel <benjamin@eikel.org>
	Copyright (C) 2009-2012 Claudius Jähn <claudius@uni-paderborn.de>
	Copyright (C) 2009-2012 Ralf Petring <ralf@petring.net>

	This library is subject to the terms of the Mozilla Public License, v. 2.0.
	You should have received a copy of the MPL along with this library; see the
	file LICENSE. If not, you can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include "E_NetworkTCP.h"

#include <EScript/EScript.h>

using namespace EScript;
using namespace Util::Network;

namespace E_Util {
namespace Network {

//! (static)
EScript::Type * E_TCPConnection::getTypeObject() {
	// E_TCPConnection ---|> Object
	static EScript::ERef<EScript::Type> typeObject = new EScript::Type(EScript::Object::getTypeObject());
	return typeObject.get();
}

//! [E_TCPConnection] initMembers
void E_TCPConnection::init(EScript::Namespace & lib) {
	EScript::Type * typeObject = getTypeObject();
	declareConstant(&lib,getClassName(),typeObject);

	//! [ESF] (static) TCPConnection|false TCPConnection.connect(host,port)
	ES_FUNCTION(typeObject,"connect",2,2,{
		Util::Reference<TCPConnection> s=TCPConnection::connect(IPv4Address::resolveHost(parameter[0].toString(), parameter[1].toInt()));
		if (s.isNull()) {
			return Bool::create(false);
		} else {
			return new E_TCPConnection(s);
		}
	})
	// ----

	//! [ESMF] thisObj TCPConnection.close()
	ES_MFUN(typeObject,E_TCPConnection,"close",0,0,((**thisObj)->close(),thisEObj))

	//! [ESMF] thisObj TCPConnection.isOpen()
	ES_MFUN(typeObject,E_TCPConnection,"isOpen",0,0,(**thisObj)->isOpen())

	//! [ESMF] String|false TCPConnection.receiveString([delimiter='\0'])
	ES_MFUNCTION(typeObject,E_TCPConnection,"receiveString",0,1,{
		std::string s=(**thisObj)->receiveString(parameter[0].toString("\0").c_str()[0]);
		if (s.empty()) {
			return EScript::create(false);
		} else {
			return EScript::create(s);
		}
	})

	//! [ESMF] thisObj TCPConnection.sendString(String,[delimiter='\0'])
	ES_MFUN(typeObject,E_TCPConnection,"sendString",1,2,
				((**thisObj)->sendString(parameter[0].toString()+parameter[1].toString("\0").c_str()[0]),thisEObj))
}

//---

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

//! (static)
EScript::Type * E_TCPServer::getTypeObject() {
	// E_TCPServer ---|> Object
	static EScript::ERef<EScript::Type> typeObject = new EScript::Type(EScript::Object::getTypeObject());
	return typeObject.get();
}

//! [E_TCPServer] initMembers
void E_TCPServer::init(EScript::Namespace & lib) {

	EScript::Type * typeObject = getTypeObject();
	declareConstant(&lib,getClassName(),typeObject);

	//! [ESF] (static) TCPServer|false TCPServer.create(port)
	ES_FUNCTION(typeObject,"create",1,1,{
		TCPServer * s=TCPServer::create(parameter[0].toInt());
		if (s == nullptr) {
			return Bool::create(false);
		} else {
			return new E_TCPServer(s);
		}
	})

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

	//! [ESMF] thisObj TCPServer.close()
	ES_MFUN(typeObject,E_TCPServer,"close",0,0,((**thisObj)->close(),thisEObj))

	//! [ESMF] bool TCPServer.isOpen()
	ES_MFUN(typeObject,const E_TCPServer,"isOpen",0,0,Bool::create((**thisObj)->isOpen()))

	//! [ESMF] TCPConnection|false TCPServer.getIncomingConnection()
	ES_MFUNCTION(typeObject,E_TCPServer,"getIncomingConnection",0,0,{
		Util::Reference<TCPConnection> c=(**thisObj)->getIncomingConnection();
		if (c == nullptr) {
			return EScript::create(false);
		} else {
			return new E_TCPConnection(c);
		}
	})

}

}
}
<commit_msg>ignore delimiter when exlicitly passing empty string as delimiter in TCPConnection.sendString<commit_after>/*
	This file is part of the E_Util library.
	Copyright (C) 2009-2012 Benjamin Eikel <benjamin@eikel.org>
	Copyright (C) 2009-2012 Claudius Jähn <claudius@uni-paderborn.de>
	Copyright (C) 2009-2012 Ralf Petring <ralf@petring.net>

	This library is subject to the terms of the Mozilla Public License, v. 2.0.
	You should have received a copy of the MPL along with this library; see the
	file LICENSE. If not, you can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include "E_NetworkTCP.h"

#include <EScript/EScript.h>

using namespace EScript;
using namespace Util::Network;

namespace E_Util {
namespace Network {

//! (static)
EScript::Type * E_TCPConnection::getTypeObject() {
	// E_TCPConnection ---|> Object
	static EScript::ERef<EScript::Type> typeObject = new EScript::Type(EScript::Object::getTypeObject());
	return typeObject.get();
}

//! [E_TCPConnection] initMembers
void E_TCPConnection::init(EScript::Namespace & lib) {
	EScript::Type * typeObject = getTypeObject();
	declareConstant(&lib,getClassName(),typeObject);

	//! [ESF] (static) TCPConnection|false TCPConnection.connect(host,port)
	ES_FUNCTION(typeObject,"connect",2,2,{
		Util::Reference<TCPConnection> s=TCPConnection::connect(IPv4Address::resolveHost(parameter[0].toString(), parameter[1].toInt()));
		if (s.isNull()) {
			return Bool::create(false);
		} else {
			return new E_TCPConnection(s);
		}
	})
	// ----

	//! [ESMF] thisObj TCPConnection.close()
	ES_MFUN(typeObject,E_TCPConnection,"close",0,0,((**thisObj)->close(),thisEObj))

	//! [ESMF] thisObj TCPConnection.isOpen()
	ES_MFUN(typeObject,E_TCPConnection,"isOpen",0,0,(**thisObj)->isOpen())

	//! [ESMF] String|false TCPConnection.receiveString([delimiter='\0'|length])
	ES_MFUNCTION(typeObject,E_TCPConnection,"receiveString",0,1,{
		EScript::Number* len = parameter[0].toType<EScript::Number>();
		std::string s;
		if(len) {
			const std::vector<uint8_t> d = (**thisObj)->receiveData(len->toUInt());
			if(!d.empty())
				s.assign(d.begin(), d.end());
		} else {
			s=(**thisObj)->receiveString(parameter[0].toString("\0").c_str()[0]);
		}
		if (s.empty()) {
			return EScript::create(false);
		} else {
			return EScript::create(s);
		}
	})

	//! [ESMF] thisObj TCPConnection.sendString(String,[delimiter='\0'])
	ES_MFUN(typeObject,E_TCPConnection,"sendString",1,2,
				((**thisObj)->sendString((parameter[1].isNotNull() && parameter[1].toString().empty()) ? parameter[0].toString() : parameter[0].toString()+parameter[1].toString("\0").c_str()[0]),thisEObj))
}

//---

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

//! (static)
EScript::Type * E_TCPServer::getTypeObject() {
	// E_TCPServer ---|> Object
	static EScript::ERef<EScript::Type> typeObject = new EScript::Type(EScript::Object::getTypeObject());
	return typeObject.get();
}

//! [E_TCPServer] initMembers
void E_TCPServer::init(EScript::Namespace & lib) {

	EScript::Type * typeObject = getTypeObject();
	declareConstant(&lib,getClassName(),typeObject);

	//! [ESF] (static) TCPServer|false TCPServer.create(port)
	ES_FUNCTION(typeObject,"create",1,1,{
		TCPServer * s=TCPServer::create(parameter[0].toInt());
		if (s == nullptr) {
			return Bool::create(false);
		} else {
			return new E_TCPServer(s);
		}
	})

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

	//! [ESMF] thisObj TCPServer.close()
	ES_MFUN(typeObject,E_TCPServer,"close",0,0,((**thisObj)->close(),thisEObj))

	//! [ESMF] bool TCPServer.isOpen()
	ES_MFUN(typeObject,const E_TCPServer,"isOpen",0,0,Bool::create((**thisObj)->isOpen()))

	//! [ESMF] TCPConnection|false TCPServer.getIncomingConnection()
	ES_MFUNCTION(typeObject,E_TCPServer,"getIncomingConnection",0,0,{
		Util::Reference<TCPConnection> c=(**thisObj)->getIncomingConnection();
		if (c == nullptr) {
			return EScript::create(false);
		} else {
			return new E_TCPConnection(c);
		}
	})

}

}
}
<|endoftext|>


<commit_before>#ifndef BEAM_MESSAGE_CAPNPROTO_HPP
#define BEAM_MESSAGE_CAPNPROTO_HPP

#include <utility>
#include <beam/message/buffer.hpp>
#include <beam/message/buffer_pool.hpp>
#include <capnp/common.h>
#include <capnp/message.h>
#include <capnp/serialize.h>
#include <kj/array.h>
#include <kj/io.h>
#include <turbo/toolset/attribute.hpp>

namespace beam {
namespace message {
namespace capnproto {

template <class message_t>
class TURBO_SYMBOL_DECL key;

template <class message_t>
class TURBO_SYMBOL_DECL payload
{
public:
    typedef message_t message_type;
    inline payload() : buffer_() { };
    inline payload(payload&& other) : buffer_(std::move(other.buffer_)) { };
    inline explicit payload(unique_pool_ptr&& buffer) : buffer_(std::move(buffer)) { }
    inline payload& operator=(payload&& other)
    {
	buffer_ = std::move(other.buffer_);
	return *this;
    }
    inline explicit operator unique_pool_ptr()
    {
	return std::move(unique_pool_ptr(std::move(buffer_)));
    }
private:
    payload(const payload&) = delete;
    payload& operator=(const payload&) = delete;
    unique_pool_ptr buffer_;
};

template <class message_t>
class TURBO_SYMBOL_DECL statement
{
public:
    typedef message_t message_type;
    explicit statement(payload<message_t>&& source);
    inline typename message_type::Reader read()
    {
	return reader_.template getRoot<message_type>();
    }
private:
    statement() = delete;
    statement(const statement&) = delete;
    statement& operator=(const statement&) = delete;
    unique_pool_ptr buffer_;
    capnp::FlatArrayMessageReader reader_;
};

template <class message_t>
class TURBO_SYMBOL_DECL form
{
public:
    typedef message_t message_type;
    explicit form(unique_pool_ptr&& buffer);
    form(const statement<message_t>& source, unique_pool_ptr&& buffer);
    inline typename message_type::Reader read()
    {
	return builder_.getRoot<message_type>().asReader();
    }
    inline typename message_type::Builder build()
    {
	return builder_.initRoot<message_type>();
    }
    ///
    /// Despite its claim to not require serialisation Capn Proto does need to
    /// serialise variable length segment information in front of the message.
    /// The segments required will depend on the message body content.
    /// This means the storage buffer passed to the constructor can't be used for
    /// serialisation and a new buffer needs to be allocated to store
    /// the segment info + body message.
    ///
    buffer serialise();
    buffer serialise(const key<message_t>&);
private:
    form() = delete;
    form(const form&) = delete;
    form& operator=(const form&) = delete;
    unique_pool_ptr buffer_;
    capnp::MallocMessageBuilder builder_;
};

template <class message_t>
TURBO_SYMBOL_DECL payload<message_t> serialise(buffer_pool& pool, form<message_t>& message);

template <class message_t>
TURBO_SYMBOL_DECL void write(int fd, payload<message_t>&& payload);

template <class message_t>
TURBO_SYMBOL_DECL payload<message_t> read(int fd, std::size_t expected_word_length, buffer_pool& pool);

} // namespace capnproto
} // namespace message
} // namespace beam

#endif
<commit_msg>adding a new move constructor to payload that allows a consuming conversion from a statement to payload<commit_after>#ifndef BEAM_MESSAGE_CAPNPROTO_HPP
#define BEAM_MESSAGE_CAPNPROTO_HPP

#include <utility>
#include <beam/message/buffer.hpp>
#include <beam/message/buffer_pool.hpp>
#include <capnp/common.h>
#include <capnp/message.h>
#include <capnp/serialize.h>
#include <kj/array.h>
#include <kj/io.h>
#include <turbo/toolset/attribute.hpp>

namespace beam {
namespace message {
namespace capnproto {

template <class message_t>
class TURBO_SYMBOL_DECL key;

template <class message_t>
class TURBO_SYMBOL_DECL statement;

template <class message_t>
class TURBO_SYMBOL_DECL payload
{
public:
    typedef message_t message_type;
    inline payload() : buffer_() { };
    inline payload(payload&& other) : buffer_(std::move(other.buffer_)) { };
    inline payload(statement<message_type>&& other) : buffer_(std::move(static_cast<unique_pool_ptr>(other))) { };
    inline explicit payload(unique_pool_ptr&& buffer) : buffer_(std::move(buffer)) { }
    inline payload& operator=(payload&& other)
    {
	buffer_ = std::move(other.buffer_);
	return *this;
    }
    inline explicit operator unique_pool_ptr()
    {
	return std::move(unique_pool_ptr(std::move(buffer_)));
    }
private:
    payload(const payload&) = delete;
    payload& operator=(const payload&) = delete;
    unique_pool_ptr buffer_;
};

template <class message_t>
class TURBO_SYMBOL_DECL statement
{
public:
    typedef message_t message_type;
    explicit statement(payload<message_t>&& source);
    inline explicit operator unique_pool_ptr()
    {
	return std::move(unique_pool_ptr(std::move(buffer_)));
    }
    inline typename message_type::Reader read()
    {
	return reader_.template getRoot<message_type>();
    }
private:
    statement() = delete;
    statement(const statement&) = delete;
    statement& operator=(const statement&) = delete;
    unique_pool_ptr buffer_;
    capnp::FlatArrayMessageReader reader_;
};

template <class message_t>
class TURBO_SYMBOL_DECL form
{
public:
    typedef message_t message_type;
    explicit form(unique_pool_ptr&& buffer);
    form(const statement<message_t>& source, unique_pool_ptr&& buffer);
    inline typename message_type::Reader read()
    {
	return builder_.getRoot<message_type>().asReader();
    }
    inline typename message_type::Builder build()
    {
	return builder_.initRoot<message_type>();
    }
    ///
    /// Despite its claim to not require serialisation Capn Proto does need to
    /// serialise variable length segment information in front of the message.
    /// The segments required will depend on the message body content.
    /// This means the storage buffer passed to the constructor can't be used for
    /// serialisation and a new buffer needs to be allocated to store
    /// the segment info + body message.
    ///
    buffer serialise();
    buffer serialise(const key<message_t>&);
private:
    form() = delete;
    form(const form&) = delete;
    form& operator=(const form&) = delete;
    unique_pool_ptr buffer_;
    capnp::MallocMessageBuilder builder_;
};

template <class message_t>
TURBO_SYMBOL_DECL payload<message_t> serialise(buffer_pool& pool, form<message_t>& message);

template <class message_t>
TURBO_SYMBOL_DECL void write(int fd, payload<message_t>&& payload);

template <class message_t>
TURBO_SYMBOL_DECL payload<message_t> read(int fd, std::size_t expected_word_length, buffer_pool& pool);

} // namespace capnproto
} // namespace message
} // namespace beam

#endif
<|endoftext|>


<commit_before>#include "test/integration/http_timeout_integration_test.h"

#include "gtest/gtest.h"

namespace Envoy {

INSTANTIATE_TEST_SUITE_P(IpVersions, HttpTimeoutIntegrationTest,
                         testing::ValuesIn(TestEnvironment::getIpVersionsForTest()),
                         TestUtility::ipTestParamsToString);

// Sends a request with a global timeout specified, sleeps for longer than the
// timeout, and ensures that a timeout is received.
TEST_P(HttpTimeoutIntegrationTest, GlobalTimeout) {
  initialize();

  codec_client_ = makeHttpConnection(makeClientConnection(lookupPort("http")));
  auto encoder_decoder = codec_client_->startRequest(
      Http::TestHeaderMapImpl{{":method", "POST"},
                              {":path", "/test/long/url"},
                              {":scheme", "http"},
                              {":authority", "host"},
                              {"x-forwarded-for", "10.0.0.1"},
                              {"x-envoy-upstream-rq-timeout-ms", "500"}});
  auto response = std::move(encoder_decoder.second);
  request_encoder_ = &encoder_decoder.first;

  ASSERT_TRUE(fake_upstreams_[0]->waitForHttpConnection(*dispatcher_, fake_upstream_connection_));
  ASSERT_TRUE(fake_upstream_connection_->waitForNewStream(*dispatcher_, upstream_request_));
  ASSERT_TRUE(upstream_request_->waitForHeadersComplete());
  codec_client_->sendData(*request_encoder_, 0, true);

  ASSERT_TRUE(upstream_request_->waitForEndStream(*dispatcher_));

  // Trigger global timeout.
  timeSystem().sleep(std::chrono::milliseconds(501));

  // Ensure we got a timeout downstream and canceled the upstream request.
  response->waitForHeaders();
  ASSERT_TRUE(upstream_request_->waitForReset(std::chrono::milliseconds(0)));

  codec_client_->close();

  EXPECT_TRUE(upstream_request_->complete());
  EXPECT_EQ(0U, upstream_request_->bodyLength());

  EXPECT_TRUE(response->complete());
  EXPECT_EQ("504", response->headers().Status()->value().getStringView());
}

// Sends a request with a global timeout and per try timeout specified, sleeps
// for longer than the per try but slightly less than the global timeout.
// Ensures that two requests are attempted and a timeout is returned
// downstream.
TEST_P(HttpTimeoutIntegrationTest, PerTryTimeout) {
  initialize();

  codec_client_ = makeHttpConnection(makeClientConnection(lookupPort("http")));
  auto encoder_decoder = codec_client_->startRequest(
      Http::TestHeaderMapImpl{{":method", "POST"},
                              {":path", "/test/long/url"},
                              {":scheme", "http"},
                              {":authority", "host"},
                              {"x-forwarded-for", "10.0.0.1"},
                              {"x-envoy-retry-on", "5xx"},
                              {"x-envoy-upstream-rq-timeout-ms", "500"},
                              {"x-envoy-upstream-rq-per-try-timeout-ms", "400"}});
  auto response = std::move(encoder_decoder.second);
  request_encoder_ = &encoder_decoder.first;

  ASSERT_TRUE(fake_upstreams_[0]->waitForHttpConnection(*dispatcher_, fake_upstream_connection_));
  ASSERT_TRUE(fake_upstream_connection_->waitForNewStream(*dispatcher_, upstream_request_));
  ASSERT_TRUE(upstream_request_->waitForHeadersComplete());
  codec_client_->sendData(*request_encoder_, 0, true);

  ASSERT_TRUE(upstream_request_->waitForEndStream(*dispatcher_));

  // Trigger per try timeout (but not global timeout).
  timeSystem().sleep(std::chrono::milliseconds(400));

  // Wait for a second request to be sent upstream
  ASSERT_TRUE(fake_upstream_connection_->waitForNewStream(*dispatcher_, upstream_request_));
  ASSERT_TRUE(upstream_request_->waitForHeadersComplete());
  ASSERT_TRUE(upstream_request_->waitForEndStream(*dispatcher_));

  // Trigger global timeout.
  timeSystem().sleep(std::chrono::milliseconds(100));
  response->waitForHeaders();

  codec_client_->close();

  EXPECT_TRUE(upstream_request_->complete());
  EXPECT_EQ(0U, upstream_request_->bodyLength());

  EXPECT_TRUE(response->complete());
  EXPECT_EQ("504", response->headers().Status()->value().getStringView());
}

} // namespace Envoy
<commit_msg>http timeout integration test: wait for 15s for upstream reset (#6646)<commit_after>#include "test/integration/http_timeout_integration_test.h"

#include "gtest/gtest.h"

namespace Envoy {

INSTANTIATE_TEST_SUITE_P(IpVersions, HttpTimeoutIntegrationTest,
                         testing::ValuesIn(TestEnvironment::getIpVersionsForTest()),
                         TestUtility::ipTestParamsToString);

// Sends a request with a global timeout specified, sleeps for longer than the
// timeout, and ensures that a timeout is received.
TEST_P(HttpTimeoutIntegrationTest, GlobalTimeout) {
  initialize();

  codec_client_ = makeHttpConnection(makeClientConnection(lookupPort("http")));
  auto encoder_decoder = codec_client_->startRequest(
      Http::TestHeaderMapImpl{{":method", "POST"},
                              {":path", "/test/long/url"},
                              {":scheme", "http"},
                              {":authority", "host"},
                              {"x-forwarded-for", "10.0.0.1"},
                              {"x-envoy-upstream-rq-timeout-ms", "500"}});
  auto response = std::move(encoder_decoder.second);
  request_encoder_ = &encoder_decoder.first;

  ASSERT_TRUE(fake_upstreams_[0]->waitForHttpConnection(*dispatcher_, fake_upstream_connection_));
  ASSERT_TRUE(fake_upstream_connection_->waitForNewStream(*dispatcher_, upstream_request_));
  ASSERT_TRUE(upstream_request_->waitForHeadersComplete());
  codec_client_->sendData(*request_encoder_, 0, true);

  ASSERT_TRUE(upstream_request_->waitForEndStream(*dispatcher_));

  // Trigger global timeout.
  timeSystem().sleep(std::chrono::milliseconds(501));

  // Ensure we got a timeout downstream and canceled the upstream request.
  response->waitForHeaders();
  ASSERT_TRUE(upstream_request_->waitForReset(std::chrono::seconds(15)));

  codec_client_->close();

  EXPECT_TRUE(upstream_request_->complete());
  EXPECT_EQ(0U, upstream_request_->bodyLength());

  EXPECT_TRUE(response->complete());
  EXPECT_EQ("504", response->headers().Status()->value().getStringView());
}

// Sends a request with a global timeout and per try timeout specified, sleeps
// for longer than the per try but slightly less than the global timeout.
// Ensures that two requests are attempted and a timeout is returned
// downstream.
TEST_P(HttpTimeoutIntegrationTest, PerTryTimeout) {
  initialize();

  codec_client_ = makeHttpConnection(makeClientConnection(lookupPort("http")));
  auto encoder_decoder = codec_client_->startRequest(
      Http::TestHeaderMapImpl{{":method", "POST"},
                              {":path", "/test/long/url"},
                              {":scheme", "http"},
                              {":authority", "host"},
                              {"x-forwarded-for", "10.0.0.1"},
                              {"x-envoy-retry-on", "5xx"},
                              {"x-envoy-upstream-rq-timeout-ms", "500"},
                              {"x-envoy-upstream-rq-per-try-timeout-ms", "400"}});
  auto response = std::move(encoder_decoder.second);
  request_encoder_ = &encoder_decoder.first;

  ASSERT_TRUE(fake_upstreams_[0]->waitForHttpConnection(*dispatcher_, fake_upstream_connection_));
  ASSERT_TRUE(fake_upstream_connection_->waitForNewStream(*dispatcher_, upstream_request_));
  ASSERT_TRUE(upstream_request_->waitForHeadersComplete());
  codec_client_->sendData(*request_encoder_, 0, true);

  ASSERT_TRUE(upstream_request_->waitForEndStream(*dispatcher_));

  // Trigger per try timeout (but not global timeout).
  timeSystem().sleep(std::chrono::milliseconds(400));

  // Wait for a second request to be sent upstream
  ASSERT_TRUE(fake_upstream_connection_->waitForNewStream(*dispatcher_, upstream_request_));
  ASSERT_TRUE(upstream_request_->waitForHeadersComplete());
  ASSERT_TRUE(upstream_request_->waitForEndStream(*dispatcher_));

  // Trigger global timeout.
  timeSystem().sleep(std::chrono::milliseconds(100));
  response->waitForHeaders();

  codec_client_->close();

  EXPECT_TRUE(upstream_request_->complete());
  EXPECT_EQ(0U, upstream_request_->bodyLength());

  EXPECT_TRUE(response->complete());
  EXPECT_EQ("504", response->headers().Status()->value().getStringView());
}

} // namespace Envoy
<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <cstdio>
#include <cassert>
#include <JSON.h>
#include <sstream>

void test_null() {
    /* a null object */

    // construct
    JSON a, b;

    // copy assign
    b = JSON();

    // copy construct
    JSON c(a);

    // copy construct
    JSON d = a;

    // assign operator
    JSON e = JSON();

    // compare
    assert(a == b);

    // type
    assert(a.type() == JSON::null);

    // empty and size
    assert(a.size() == 0);
    assert(a.empty() == true);

    // output
    std::cout << a << '\n';

    // string represetations
    assert(a.toString() == std::string("null"));

    // invalid conversion to int
    try {
        int i = 0;
        i = a;
        assert(false);
    } catch (const std::exception& ex) {
        assert(ex.what() == std::string("cannot cast null to JSON number"));
    }

    // invalid conversion to double
    try {
        double f = 0;
        f = a;
        assert(false);
    } catch (const std::exception& ex) {
        assert(ex.what() == std::string("cannot cast null to JSON number"));
    }

    // invalid conversion to bool
    try {
        bool b = a;
        assert(false);
    } catch (const std::exception& ex) {
        assert(ex.what() == std::string("cannot cast null to JSON Boolean"));
    }

    // invalid conversion to string
    try {
        std::string s = a;
        assert(false);
    } catch (const std::exception& ex) {
        assert(ex.what() == std::string("cannot cast null to JSON string"));
    }
}

void test_bool() {
    JSON True = true;
    JSON False = false;

    bool x = True;
}

void test_string() {
    /* a string object */

    // construct
    JSON a = "object a";
    JSON b;

    // copy assign
    b = JSON("object a");

    // copy construct
    JSON c(a);

    // copy construct
    JSON d = a;

    // assign operator
    JSON e = JSON("");

    // compare
    assert(a == b);

    // type
    assert(a.type() == JSON::string);

    // empty and size
    assert(a.size() == 1);
    assert(a.empty() == false);

    // output
    std::cout << a << '\n';

    // string represetations
    assert(a.toString() == std::string("\"object a\""));

    // invalid conversion to int
    try {
        int i = 0;
        i = a;
        assert(false);
    } catch (const std::exception& ex) {
        assert(ex.what() == std::string("cannot cast string to JSON number"));
    }

    // invalid conversion to double
    try {
        double f = 0;
        f = a;
        assert(false);
    } catch (const std::exception& ex) {
        assert(ex.what() == std::string("cannot cast string to JSON number"));
    }

    // invalid conversion to bool
    try {
        bool b = false;
        b = a;
        assert(false);
    } catch (const std::exception& ex) {
        assert(ex.what() == std::string("cannot cast string to JSON Boolean"));
    }

    {
        // get payload
        std::string* s1 = a.data().string;
        std::string s2 = a;
        assert(*s1 == s2);
    }
}

void test_array() {
    JSON a;
    a += JSON();
    a += 1;
    a += 1.0;
    a += true;
    a += "string";

    // type
    assert(a.type() == JSON::array);

    // empty and size
    assert(a.size() == 5);
    assert(a.empty() == false);

    // output
    std::cout << a << '\n';

    // check for elements
    assert(a[1] == JSON(1));
    assert(a[2] == JSON(1.0));
    assert(a[3] == JSON(true));
    assert(a[4] == JSON("string"));

    // invalid access to element
    try {
        a[5] = 1;
        assert(false);
    } catch (const std::exception& ex) {
        assert(ex.what() == std::string("cannot access element at index 5"));
    }

    // get elements
    {
        int i = a[1];
        double d = a[2];
        bool b = a[3];
        std::string s = a[4];
    }

    // set elements
    a[1] = 2;

#ifdef __cplusplus11
    // construction from initializer list
    JSON b = {JSON(), 2, 1.0, true, "string"};
    assert(a == b);
#endif

    // iterators
    {
        size_t count = 0;
        for (JSON::iterator i = a.begin(); i != a.end(); ++i) {
            std::cerr << *i << '\n';
            count++;
        }
        assert(count == a.size());
    }

    {
        size_t count = 0;
        for (JSON::const_iterator i = a.begin(); i != a.end(); ++i) {
            std::cerr << *i << '\n';
            count++;
        }
        assert(count == a.size());
    }

    {
        size_t count = 0;
        for (JSON::const_iterator i = a.cbegin(); i != a.cend(); ++i) {
            std::cerr << *i << '\n';
            count++;
        }
        assert(count == a.size());
    }

#ifdef __cplusplus11
    {
        size_t count = 0;
        for (auto element : a) {
            std::cerr << element << '\n';
            count++;
        }
        assert(count == a.size());
    }
#endif

    {
        JSON::iterator i;
        size_t count = 0;
        for (i = a.begin(); i != a.end(); ++i) {
            std::cerr << *i << '\n';
            count++;
        }
        assert(count == a.size());
    }

    {
        JSON::const_iterator i;
        size_t count = 0;
        for (i = a.begin(); i != a.end(); ++i) {
            std::cerr << *i << '\n';
            count++;
        }
        assert(count == a.size());
    }

    {
        JSON::const_iterator i;
        size_t count = 0;
        for (i = a.cbegin(); i != a.cend(); ++i) {
            std::cerr << *i << '\n';
            count++;
        }
        assert(count == a.size());
    }

    {
        // get payload
        std::vector<JSON>* array = a.data().array;
        assert(array->size() == a.size());
        assert(array->empty() == a.empty());
    }
}

void test_object() {
    // check find()
    {
        JSON o;
        o["foo"] = "bar";

        JSON::iterator i1 = o.find("foo");
        assert(i1 != o.end());
        assert(i1.value() == "bar");
        assert(i1.key() == "foo");
        assert(*i1 == "bar");

        JSON::iterator i2 = o.find("baz");
        assert(i2 == o.end());

        JSON a;
        a += "foo";
        a += "bar";
        JSON::iterator i;
        i = a.find("foo");
        assert(i == a.end());
    }
}

void test_streaming() {
    // stream text representation into stream
    std::stringstream i;
    i << "{ \"foo\": true, \"baz\": [1,2,3,4] }";

    // create JSON from stream
    {
        JSON j, k;
        i >> j;
        k << i;
        assert(j.toString() == k.toString());
    }

    // roundtrip
    {
        std::stringstream o;
        JSON j, k;
        i >> j;
        j >> o;
        o >> k;
        assert(j.toString() == k.toString());
    }

    // check numbers
    {
        std::stringstream number_stream;
        number_stream << "[0, -1, 1, 1.0, -1.0, 1.0e+1, 1.0e-1, 1.0E+1, 1.0E-1, -1.2345678e-12345678]";
        JSON j;
        j << number_stream;
    }

    // check Unicode
    {
        std::stringstream unicode_stream;
        unicode_stream << "[\"öäüÖÄÜß\", \"ÀÁÂÃĀĂȦ\", \"★☆→➠♥♦☁\"]";
        JSON j;
        j << unicode_stream;
    }

    // check escaped strings
    {
        std::stringstream escaped_stream;
        escaped_stream << "[\"\\\"Hallo\\\"\", \"\u0123\"]";
        JSON j;
        j << escaped_stream;
    }
}

int main() {
    test_null();
    test_bool();
    test_string();
    test_array();
    test_object();
    test_streaming();

    return 0;
}
<commit_msg>added debug output to test cases<commit_after>#include <iostream>
#include <fstream>
#include <cstdio>
#include <cassert>
#include <JSON.h>
#include <sstream>

void test_null() {
    std::cerr << "entering test_null()\n";

    /* a null object */

    // construct
    JSON a, b;

    // copy assign
    b = JSON();

    // copy construct
    JSON c(a);

    // copy construct
    JSON d = a;

    // assign operator
    JSON e = JSON();

    // compare
    assert(a == b);

    // type
    assert(a.type() == JSON::null);

    // empty and size
    assert(a.size() == 0);
    assert(a.empty() == true);

    // output
    std::cout << a << '\n';

    // string represetations
    assert(a.toString() == std::string("null"));

    // invalid conversion to int
    try {
        int i = 0;
        i = a;
        assert(false);
    } catch (const std::exception& ex) {
        assert(ex.what() == std::string("cannot cast null to JSON number"));
    }

    // invalid conversion to double
    try {
        double f = 0;
        f = a;
        assert(false);
    } catch (const std::exception& ex) {
        assert(ex.what() == std::string("cannot cast null to JSON number"));
    }

    // invalid conversion to bool
    try {
        bool b = a;
        assert(false);
    } catch (const std::exception& ex) {
        assert(ex.what() == std::string("cannot cast null to JSON Boolean"));
    }

    // invalid conversion to string
    try {
        std::string s = a;
        assert(false);
    } catch (const std::exception& ex) {
        assert(ex.what() == std::string("cannot cast null to JSON string"));
    }

    std::cerr << "leaving test_null()\n";
}

void test_bool() {
    std::cerr << "entering test_bool()\n";

    JSON True = true;
    JSON False = false;

    bool x = True;

    std::cerr << "leaving test_bool()\n";
}

void test_string() {
    std::cerr << "entering test_string()\n";

    /* a string object */

    // construct
    JSON a = "object a";
    JSON b;

    // copy assign
    b = JSON("object a");

    // copy construct
    JSON c(a);

    // copy construct
    JSON d = a;

    // assign operator
    JSON e = JSON("");

    // compare
    assert(a == b);

    // type
    assert(a.type() == JSON::string);

    // empty and size
    assert(a.size() == 1);
    assert(a.empty() == false);

    // output
    std::cout << a << '\n';

    // string represetations
    assert(a.toString() == std::string("\"object a\""));

    // invalid conversion to int
    try {
        int i = 0;
        i = a;
        assert(false);
    } catch (const std::exception& ex) {
        assert(ex.what() == std::string("cannot cast string to JSON number"));
    }

    // invalid conversion to double
    try {
        double f = 0;
        f = a;
        assert(false);
    } catch (const std::exception& ex) {
        assert(ex.what() == std::string("cannot cast string to JSON number"));
    }

    // invalid conversion to bool
    try {
        bool b = false;
        b = a;
        assert(false);
    } catch (const std::exception& ex) {
        assert(ex.what() == std::string("cannot cast string to JSON Boolean"));
    }

    {
        // get payload
        std::string* s1 = a.data().string;
        std::string s2 = a;
        assert(*s1 == s2);
    }

    std::cerr << "leaving test_string()\n";
}

void test_array() {
    std::cerr << "entering test_array()\n";

    JSON a;
    a += JSON();
    a += 1;
    a += 1.0;
    a += true;
    a += "string";

    // type
    assert(a.type() == JSON::array);

    // empty and size
    assert(a.size() == 5);
    assert(a.empty() == false);

    // output
    std::cout << a << '\n';

    // check for elements
    assert(a[1] == JSON(1));
    assert(a[2] == JSON(1.0));
    assert(a[3] == JSON(true));
    assert(a[4] == JSON("string"));

    // invalid access to element
    try {
        a[5] = 1;
        assert(false);
    } catch (const std::exception& ex) {
        assert(ex.what() == std::string("cannot access element at index 5"));
    }

    // get elements
    {
        int i = a[1];
        double d = a[2];
        bool b = a[3];
        std::string s = a[4];
    }

    // set elements
    a[1] = 2;

#ifdef __cplusplus11
    // construction from initializer list
    JSON b = {JSON(), 2, 1.0, true, "string"};
    assert(a == b);
#endif

    // iterators
    {
        size_t count = 0;
        for (JSON::iterator i = a.begin(); i != a.end(); ++i) {
            std::cerr << *i << '\n';
            count++;
        }
        assert(count == a.size());
    }

    {
        size_t count = 0;
        for (JSON::const_iterator i = a.begin(); i != a.end(); ++i) {
            std::cerr << *i << '\n';
            count++;
        }
        assert(count == a.size());
    }

    {
        size_t count = 0;
        for (JSON::const_iterator i = a.cbegin(); i != a.cend(); ++i) {
            std::cerr << *i << '\n';
            count++;
        }
        assert(count == a.size());
    }

#ifdef __cplusplus11
    {
        size_t count = 0;
        for (auto element : a) {
            std::cerr << element << '\n';
            count++;
        }
        assert(count == a.size());
    }
#endif

    {
        JSON::iterator i;
        size_t count = 0;
        for (i = a.begin(); i != a.end(); ++i) {
            std::cerr << *i << '\n';
            count++;
        }
        assert(count == a.size());
    }

    {
        JSON::const_iterator i;
        size_t count = 0;
        for (i = a.begin(); i != a.end(); ++i) {
            std::cerr << *i << '\n';
            count++;
        }
        assert(count == a.size());
    }

    {
        JSON::const_iterator i;
        size_t count = 0;
        for (i = a.cbegin(); i != a.cend(); ++i) {
            std::cerr << *i << '\n';
            count++;
        }
        assert(count == a.size());
    }

    {
        // get payload
        std::vector<JSON>* array = a.data().array;
        assert(array->size() == a.size());
        assert(array->empty() == a.empty());
    }

    std::cerr << "leaving test_array()\n";
}

void test_object() {
    std::cerr << "entering test_object()\n";

    // check find()
    {
        JSON o;
        o["foo"] = "bar";

        JSON::iterator i1 = o.find("foo");
        assert(i1 != o.end());
        assert(i1.value() == "bar");
        assert(i1.key() == "foo");
        assert(*i1 == "bar");

        JSON::iterator i2 = o.find("baz");
        assert(i2 == o.end());

        JSON a;
        a += "foo";
        a += "bar";
        JSON::iterator i;
        i = a.find("foo");
        assert(i == a.end());
    }

    std::cerr << "leaving test_object()\n";
}

void test_streaming() {
    std::cerr << "entering test_streaming()\n";

    // stream text representation into stream
    std::stringstream i;
    i << "{ \"foo\": true, \"baz\": [1,2,3,4] }";

    // create JSON from stream
    {
        JSON j, k;
        i >> j;
        k << i;
        assert(j.toString() == k.toString());
    }

    // roundtrip
    {
        std::stringstream o;
        JSON j, k;
        i >> j;
        j >> o;
        o >> k;
        assert(j.toString() == k.toString());
    }

    // check numbers
    {
        std::stringstream number_stream;
        number_stream << "[0, -1, 1, 1.0, -1.0, 1.0e+1, 1.0e-1, 1.0E+1, 1.0E-1, -1.2345678e-12345678]";
        JSON j;
        j << number_stream;
    }

    // check Unicode
    {
        std::stringstream unicode_stream;
        unicode_stream << "[\"öäüÖÄÜß\", \"ÀÁÂÃĀĂȦ\", \"★☆→➠♥♦☁\"]";
        JSON j;
        j << unicode_stream;
    }

    // check escaped strings
    {
        std::stringstream escaped_stream;
        escaped_stream << "[\"\\\"Hallo\\\"\", \"\u0123\"]";
        JSON j;
        j << escaped_stream;
    }

    std::cerr << "leaving test_streaming()\n";
}

int main() {
    test_null();
    test_bool();
    test_string();
    test_array();
    test_object();
    test_streaming();

    return 0;
}
<|endoftext|>