<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/generic/memory/lib/utils/mss_field.H $             */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2018,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file mss_field.H
/// @brief API for data fields and operations
///

// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: HB:FSP

#ifndef _MSS_FIELD_H_
#define _MSS_FIELD_H_

#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
#include <generic/memory/lib/utils/mss_generic_check.H>

namespace mss
{

///
/// @class field_t
/// @brief data structure for byte fields
/// @note holds byte index, start bit, and bit length of a decoded field
///
class field_t
{
    private:

        const size_t iv_byte;
        const size_t iv_start;
        const size_t iv_length;

    public:

        // default ctor deleted
        field_t() = delete;

        ///
        /// @brief ctor
        /// @param[in] i_byte_index
        /// @param[in] i_start_bit
        /// @param[in] i_bit_length
        ///
        constexpr field_t(const size_t i_byte_index,
                          const size_t i_start_bit,
                          const size_t i_bit_length)
            : iv_byte(i_byte_index),
              iv_start(i_start_bit),
              iv_length(i_bit_length)
        {}

        ///
        /// @brief default dtor
        ///
        ~field_t() = default;

        ///
        /// @brief Byte index getter
        /// @return the byte index for this field
        ///
        constexpr size_t get_byte() const
        {
            return iv_byte;
        }

        ///
        /// @brief Starting bit getter
        /// @return the starting bit position for this field
        ///
        constexpr size_t get_start() const
        {
            return iv_start;
        }

        ///
        /// @brief bit length getter
        /// @return the bit length of this field
        ///
        constexpr size_t get_length() const
        {
            return iv_length;
        }

};// field_t

///
/// @brief Checks input field against a custom conditional
/// @tparam T field input type
/// @tparam F Callable object type
/// @param[in] i_field Extracted field
/// @param[in] i_comparison_val value we are comparing against
/// @param[in] i_op comparison operator function object
/// @return boolean true or false
///
template < typename T, typename F >
bool conditional(const T i_field,
                 const size_t i_comparison_val,
                 const F i_op)
{
    return i_op(i_field, i_comparison_val);
}

///
/// @brief Helper function to extract byte information
/// @tparam F the field to extract
/// @tparam T the fapi2 target type
/// @param[in] i_target the fapi2 target
/// @param[in] i_data the data
/// @param[in] i_ffdc_codes FFDC code
/// @param[out] o_value raw value for this field
/// @return FAPI2_RC_SUCCESS iff okay
///
template< const field_t& F, fapi2::TargetType T >
fapi2::ReturnCode get_field(const fapi2::Target<T>& i_target,
                            const std::vector<uint8_t>& i_data,
                            const generic_ffdc_codes i_ffdc_codes,
                            uint8_t& o_value)
{
    constexpr size_t BYTE = F.get_byte();

    FAPI_ASSERT( BYTE < i_data.size(),
                 fapi2::MSS_OUT_OF_BOUNDS_INDEXING()
                 .set_INDEX(BYTE)
                 .set_LIST_SIZE(i_data.size())
                 .set_FUNCTION(i_ffdc_codes)
                 .set_TARGET(i_target),
                 "Out of bounds indexing (with %d) on a list of size %d for %s",
                 BYTE,
                 i_data.size(),
                 spd::c_str(i_target));

    {
        // Extracting desired bits
        const fapi2::buffer<uint8_t> l_buffer(i_data[BYTE]);
        l_buffer.extractToRight<F.get_start(), F.get_length()>(o_value);

        FAPI_DBG("%s data[%d] = 0x%02x. Field with start bit %d, bit len %d, has data 0x%02x.",
                 spd::c_str(i_target),
                 BYTE,
                 i_data[BYTE],
                 F.get_start(),
                 F.get_length(),
                 o_value);
    }

    return fapi2::FAPI2_RC_SUCCESS;

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief Helper function to set byte field information
/// @tparam F the field to extract
/// @tparam T the fapi2 target type
/// @param[in] i_target the fapi2 target
/// @param[in] i_setting the setting to set
/// @param[in] i_ffdc_codes FFDC code
/// @param[in,out] io_data the data to modify
/// @return FAPI2_RC_SUCCESS iff okay
///
template< const field_t& F, fapi2::TargetType T >
fapi2::ReturnCode set_field(const fapi2::Target<T>& i_target,
                            const size_t i_setting,
                            const generic_ffdc_codes i_ffdc_codes,
                            std::vector<uint8_t>& io_data)
{
    constexpr size_t BYTE = F.get_byte();

    FAPI_ASSERT( BYTE < io_data.size(),
                 fapi2::MSS_OUT_OF_BOUNDS_INDEXING()
                 .set_INDEX(BYTE)
                 .set_LIST_SIZE(io_data.size())
                 .set_FUNCTION(i_ffdc_codes)
                 .set_TARGET(i_target),
                 "Out of bounds indexing (with %d) on a list of size %d for %s",
                 BYTE,
                 io_data.size(),
                 spd::c_str(i_target));

    {
        // Insert desired setting
        fapi2::buffer<uint8_t> l_buffer(io_data[BYTE]);
        l_buffer.insertFromRight<F.get_start(), F.get_length()>(i_setting);

        io_data[BYTE] = static_cast<uint8_t>(l_buffer);

        FAPI_DBG("%s data[%d] = 0x%02x. Field with start bit %d, bit len %d, has data 0x%02x.",
                 spd::c_str(i_target),
                 BYTE,
                 io_data[BYTE],
                 F.get_start(),
                 F.get_length(),
                 i_setting);
    }

    return fapi2::FAPI2_RC_SUCCESS;

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief byte field reader
/// @tparam F the byte field to read
/// @tparam TT traits associated with F - required
/// @tparam T the fapi2 target type
/// @tparam IT data input type
/// @tparam OT data output type
/// @param[in] i_target the dimm target
/// @param[in] i_data the data
/// @param[in] i_ffdc_codes FFDC code
/// @param[out] o_value raw value for this field
/// @return FAPI2_RC_SUCCESS iff okay
///
template< const field_t& F,
          typename TT,
          fapi2::TargetType T,
          typename IT,
          typename OT >
inline fapi2::ReturnCode get_field( const fapi2::Target<T>& i_target,
                                    const std::vector<IT>& i_data,
                                    const generic_ffdc_codes i_ffdc_codes,
                                    OT& o_value )
{
    IT l_temp = 0;
    FAPI_TRY( get_field<F>(i_target, i_data, i_ffdc_codes, l_temp),
              "Failed get_field() for %s", spd::c_str(i_target) );

    // Test if retrieved data seems valid
    FAPI_TRY( check::invalid_value(i_target,
                                   conditional( l_temp,
                                           TT::COMPARISON_VAL,
                                           typename TT::template COMPARISON_OP<IT>() ),
                                   F.get_byte(),
                                   l_temp,
                                   i_ffdc_codes),
              "Failed fail_for_invalid_value() for %s", spd::c_str(i_target) );

    // Output should only change if data check passes
    o_value = static_cast<OT>(l_temp);

    FAPI_ASSERT( o_value == l_temp,
                 fapi2::MSS_CONVERSION_ERROR()
                 .set_ORIGINAL_VAL(l_temp)
                 .set_CONVERTED_VAL(o_value)
                 .set_TARGET(i_target)
                 .set_FUNCTION(i_ffdc_codes),
                 "Conversion error between original %d to converted %d value for %s",
                 l_temp, o_value, spd::c_str(i_target) );

    FAPI_INF("%s: 0x%02x for %s",
             TT::FIELD_STR,
             o_value,
             spd::c_str(i_target));

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief byte field writer
/// @tparam F the byte field to read
/// @tparam TT traits associated with writer
/// @tparam T the fapi2 target type
/// @tparam IT data input type
/// @tparam OT data output type
/// @param[in] i_target the dimm target
/// @param[in] i_setting value to set for field
/// @param[in] i_ffdc_codes FFDC code
/// @param[in,out] io_data the data to modify
/// @return FAPI2_RC_SUCCESS iff okay
///
template< const field_t& F,
          typename TT,
          fapi2::TargetType T,
          typename IT,
          typename OT >
fapi2::ReturnCode set_field( const fapi2::Target<T>& i_target,
                             const size_t i_setting,
                             const generic_ffdc_codes i_ffdc_codes,
                             std::vector<OT>& io_data )
{
    constexpr size_t BYTE = F.get_byte();

    // Test if the data we want to set is valid for this field
    FAPI_TRY( check::invalid_value(i_target,
                                   conditional( i_setting,
                                           TT::COMPARISON_VAL,
                                           typename TT::template COMPARISON_OP<IT>() ),
                                   BYTE,
                                   i_setting,
                                   i_ffdc_codes),
              "Failed fail_for_invalid_value() for %s", spd::c_str(i_target) );

    FAPI_TRY( set_field<F>(i_target, i_setting, i_ffdc_codes, io_data),
              "Failed set_field() for %s", spd::c_str(i_target) );

    FAPI_INF("%s: Set value of 0x%02x. Data for buffer at byte %d, is now 0x%02x for %s",
             TT::FIELD_STR,
             i_setting,
             BYTE,
             io_data[BYTE],
             spd::c_str(i_target));

fapi_try_exit:
    return fapi2::current_err;
}

}// mss

#endif
<commit_msg>Added I2C fields, EXP_FW_STATUS API<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/generic/memory/lib/utils/mss_field.H $             */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2018,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file mss_field.H
/// @brief API for data fields and operations
///

// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: HB:FSP

#ifndef _MSS_FIELD_H_
#define _MSS_FIELD_H_

#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
#include <generic/memory/lib/utils/mss_generic_check.H>

namespace mss
{

///
/// @class field_t
/// @brief data structure for byte fields
/// @note holds byte index, start bit, and bit length of a decoded field
///
class field_t
{
    private:

        const size_t iv_byte;
        const size_t iv_start;
        const size_t iv_length;

    public:

        // default ctor deleted
        field_t() = delete;

        ///
        /// @brief ctor
        /// @param[in] i_byte_index
        /// @param[in] i_start_bit
        /// @param[in] i_bit_length
        ///
        constexpr field_t(const size_t i_byte_index,
                          const size_t i_start_bit,
                          const size_t i_bit_length)
            : iv_byte(i_byte_index),
              iv_start(i_start_bit),
              iv_length(i_bit_length)
        {}

        ///
        /// @brief default dtor
        ///
        ~field_t() = default;

        ///
        /// @brief Byte index getter
        /// @return the byte index for this field
        ///
        constexpr size_t get_byte() const
        {
            return iv_byte;
        }

        ///
        /// @brief Starting bit getter
        /// @return the starting bit position for this field
        ///
        constexpr size_t get_start() const
        {
            return iv_start;
        }

        ///
        /// @brief bit length getter
        /// @return the bit length of this field
        ///
        constexpr size_t get_length() const
        {
            return iv_length;
        }

};// field_t

///
/// @brief Checks input field against a custom conditional
/// @tparam T field input type
/// @tparam F Callable object type
/// @param[in] i_field Extracted field
/// @param[in] i_comparison_val value we are comparing against
/// @param[in] i_op comparison operator function object
/// @return boolean true or false
///
template < typename T, typename F >
bool conditional(const T i_field,
                 const size_t i_comparison_val,
                 const F i_op)
{
    return i_op(i_field, i_comparison_val);
}

///
/// @brief Helper function to extract byte information
/// @tparam F the field to extract
/// @tparam T the fapi2 target type
/// @tparam IT data input type
/// @tparam OT data output type
/// @tparam FFDC ffdc code type
/// @param[in] i_target the fapi2 target
/// @param[in] i_data the data
/// @param[in] i_ffdc_codes FFDC code
/// @param[out] o_value raw value for this field
/// @return FAPI2_RC_SUCCESS iff okay
///
template< const field_t& F,
          fapi2::TargetType T,
          typename IT,
          typename OT,
          typename FFDC >
fapi2::ReturnCode get_field(const fapi2::Target<T>& i_target,
                            const std::vector<IT>& i_data,
                            const FFDC i_ffdc_codes,
                            OT& o_value)
{
    constexpr size_t BYTE = F.get_byte();

    FAPI_ASSERT( BYTE < i_data.size(),
                 fapi2::MSS_OUT_OF_BOUNDS_INDEXING()
                 .set_INDEX(BYTE)
                 .set_LIST_SIZE(i_data.size())
                 .set_FUNCTION(i_ffdc_codes)
                 .set_TARGET(i_target),
                 "Out of bounds indexing (with %d) on a list of size %d for %s",
                 BYTE,
                 i_data.size(),
                 spd::c_str(i_target));

    {
        // Extracting desired bits
        const fapi2::buffer<OT> l_buffer(i_data[BYTE]);
        l_buffer.template extractToRight<F.get_start(), F.get_length()>(o_value);

        FAPI_DBG("%s data[%d] = 0x%02x. Field with start bit %d, bit len %d, has data 0x%02x.",
                 spd::c_str(i_target),
                 BYTE,
                 i_data[BYTE],
                 F.get_start(),
                 F.get_length(),
                 o_value);
    }

    return fapi2::FAPI2_RC_SUCCESS;

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief Helper function to set byte field information
/// @tparam F the field to extract
/// @tparam T the fapi2 target type
/// @tparam IT data input type
/// @tparam OT data output type
/// @tparam FFDC ffdc code type
/// @param[in] i_target the fapi2 target
/// @param[in] i_setting the setting to set
/// @param[in] i_ffdc_codes FFDC code
/// @param[in,out] io_data the data to modify
/// @return FAPI2_RC_SUCCESS iff okay
///
template< const field_t& F,
          fapi2::TargetType T,
          typename IT,
          typename OT,
          typename FFDC >
fapi2::ReturnCode set_field(const fapi2::Target<T>& i_target,
                            const IT i_setting,
                            const FFDC i_ffdc_codes,
                            std::vector<OT>& io_data)
{
    constexpr size_t BYTE = F.get_byte();

    FAPI_ASSERT( BYTE < io_data.size(),
                 fapi2::MSS_OUT_OF_BOUNDS_INDEXING()
                 .set_INDEX(BYTE)
                 .set_LIST_SIZE(io_data.size())
                 .set_FUNCTION(i_ffdc_codes)
                 .set_TARGET(i_target),
                 "Out of bounds indexing (with %d) on a list of size %d for %s",
                 BYTE,
                 io_data.size(),
                 spd::c_str(i_target));

    {
        // Insert desired setting
        fapi2::buffer<OT> l_buffer(io_data[BYTE]);
        l_buffer.template insertFromRight<F.get_start(), F.get_length()>(i_setting);

        io_data[BYTE] = static_cast<OT>(l_buffer);

        FAPI_DBG("%s data[%d] = 0x%02x. Field with start bit %d, bit len %d, has data 0x%02x.",
                 spd::c_str(i_target),
                 BYTE,
                 io_data[BYTE],
                 F.get_start(),
                 F.get_length(),
                 i_setting);
    }

    return fapi2::FAPI2_RC_SUCCESS;

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief byte field reader
/// @tparam F the byte field to read
/// @tparam TT traits associated with F - required
/// @tparam T the fapi2 target type
/// @tparam IT data input type
/// @tparam OT data output type
/// @param[in] i_target the dimm target
/// @param[in] i_data the data
/// @param[in] i_ffdc_codes FFDC code
/// @param[out] o_value raw value for this field
/// @return FAPI2_RC_SUCCESS iff okay
///
template< const field_t& F,
          typename TT,
          fapi2::TargetType T,
          typename IT,
          typename OT,
          typename FFDC >
inline fapi2::ReturnCode get_field( const fapi2::Target<T>& i_target,
                                    const std::vector<IT>& i_data,
                                    const FFDC i_ffdc_codes,
                                    OT& o_value )
{
    IT l_temp = 0;
    FAPI_TRY( get_field<F>(i_target, i_data, i_ffdc_codes, l_temp),
              "Failed get_field() for %s", spd::c_str(i_target) );

    // Test if retrieved data seems valid
    FAPI_TRY( check::invalid_value(i_target,
                                   conditional( l_temp,
                                           TT::COMPARISON_VAL,
                                           typename TT::template COMPARISON_OP<IT>() ),
                                   F.get_byte(),
                                   l_temp,
                                   i_ffdc_codes),
              "Failed fail_for_invalid_value() for %s", spd::c_str(i_target) );

    // Output should only change if data check passes
    o_value = static_cast<OT>(l_temp);

    FAPI_ASSERT( o_value == l_temp,
                 fapi2::MSS_CONVERSION_ERROR()
                 .set_ORIGINAL_VAL(l_temp)
                 .set_CONVERTED_VAL(o_value)
                 .set_TARGET(i_target)
                 .set_FUNCTION(i_ffdc_codes),
                 "Conversion error between original %d to converted %d value for %s",
                 l_temp, o_value, spd::c_str(i_target) );

    FAPI_INF("%s: 0x%02x for %s",
             TT::FIELD_STR,
             o_value,
             spd::c_str(i_target));

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief byte field writer
/// @tparam F the byte field to read
/// @tparam TT traits associated with writer
/// @tparam T the fapi2 target type
/// @tparam IT data input type
/// @tparam OT data output type
/// @tparam FFDC ffdc code type
/// @param[in] i_target the dimm target
/// @param[in] i_setting value to set for field
/// @param[in] i_ffdc_codes FFDC code
/// @param[in,out] io_data the data to modify
/// @return FAPI2_RC_SUCCESS iff okay
///
template< const field_t& F,
          typename TT,
          fapi2::TargetType T,
          typename IT,
          typename OT,
          typename FFDC >
fapi2::ReturnCode set_field( const fapi2::Target<T>& i_target,
                             const IT i_setting,
                             const FFDC i_ffdc_codes,
                             std::vector<OT>& io_data )
{
    constexpr size_t BYTE = F.get_byte();

    // Test if the data we want to set is valid for this field
    FAPI_TRY( check::invalid_value(i_target,
                                   conditional( i_setting,
                                           TT::COMPARISON_VAL,
                                           typename TT::template COMPARISON_OP<IT>() ),
                                   BYTE,
                                   i_setting,
                                   i_ffdc_codes),
              "Failed fail_for_invalid_value() for %s", spd::c_str(i_target) );

    FAPI_TRY( set_field<F>(i_target, i_setting, i_ffdc_codes, io_data),
              "Failed set_field() for %s", spd::c_str(i_target) );

    FAPI_INF("%s: Set value of 0x%02x. Data for buffer at byte %d, is now 0x%02x for %s",
             TT::FIELD_STR,
             i_setting,
             BYTE,
             io_data[BYTE],
             spd::c_str(i_target));

fapi_try_exit:
    return fapi2::current_err;
}

}// mss

#endif
<|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
//
//                         Peloton
//
// tpch.cpp
//
// Identification: src/main/tpch/tpch.cpp
//
// Copyright (c) 2015-17, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include <cstdio>
#include <getopt.h>
#include <string>

#include "benchmark/tpch/tpch_configuration.h"
#include "benchmark/tpch/tpch_database.h"
#include "benchmark/tpch/tpch_workload.h"
#include "common/logger.h"

namespace peloton {
namespace benchmark {
namespace tpch {

void Usage(FILE *out) {
  fprintf(out,
          "Command line options : tpch <options> \n"
          "   -h --help              :  print help message \n"
          "   -i --input-dir         :  location of data \n"
          "   -n --num-runs          :  the number of runs to execute for each query \n"
          "   -s --suffix            :  input file suffix \n"
          "   -d --dict-encode       :  dictionary encode \n"
          "   -q --queries           :  comma-separated list of queries to run (i.g., 1,14 for Q1 and Q14) \n");
}

static struct option opts[] = {
    {"input-dir", required_argument, NULL, 'i'},
    {"dict-encode", optional_argument, NULL, 'd'},
    {"queries", optional_argument, NULL, 'q'},
    {NULL, 0, NULL, 0}};

void ParseArguments(int argc, char **argv, Configuration &config) {
  config.suffix = "tbl";

  // Parse args
  while (1) {
    int idx = 0;
    int c = getopt_long(argc, argv, "hi:nsdq:", opts, &idx);

    if (c == -1) break;

    switch (c) {
      case 'i': {
        char *input = optarg;
        config.data_dir = input;
        break;
      }
      case 'n': {
        char *input = optarg;
        config.num_runs = static_cast<uint32_t>(std::atoi(input));
      }
      case 'd': {
        config.dictionary_encode = true;
        break;
      }
      case 'q': {
        char *csv_queries = optarg;
        config.SetRunnableQueries(csv_queries);
        break;
      }
      case 'h': {
        Usage(stderr);
        exit(EXIT_FAILURE);
      }
      default: {
        LOG_ERROR("Unknown option: -%c-", c);
        Usage(stderr);
        exit(EXIT_FAILURE);
      }
    }
  }

  // Validate everything
  if (!config.IsValid()) {
    exit(EXIT_FAILURE);
  }

  LOG_INFO("Input directory   : '%s'", config.data_dir.c_str());
  LOG_INFO("Dictionary encode : %s",
           config.dictionary_encode ? "true" : "false");
  for (uint32_t i = 0; i < 22; i++) {
    LOG_INFO("Run query %u : %s", i + 1,
             config.queries_to_run[i] ? "true" : "false");
  }
}

void RunBenchmark(const Configuration &config) {
  // Create the DB instance
  TPCHDatabase tpch_db{config};

  // Create the benchmark
  TPCHBenchmark tpch_benchmark{config, tpch_db};

  // Run the benchmark
  tpch_benchmark.RunBenchmark();
}

}  // namespace tpch
}  // namespace benchmark
}  // namespace peloton

// Entry point
int main(int argc, char **argv) {
  // The configuration
  peloton::benchmark::tpch::Configuration config;

  // Parse arguments
  peloton::benchmark::tpch::ParseArguments(argc, argv, config);

  // Run workload
  peloton::benchmark::tpch::RunBenchmark(config);

  return 0;
}<commit_msg>Small fix to correctly handle command line arguments for TPCH benchmark<commit_after>//===----------------------------------------------------------------------===//
//
//                         Peloton
//
// tpch.cpp
//
// Identification: src/main/tpch/tpch.cpp
//
// Copyright (c) 2015-17, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include <cstdio>
#include <getopt.h>
#include <string>

#include "benchmark/tpch/tpch_configuration.h"
#include "benchmark/tpch/tpch_database.h"
#include "benchmark/tpch/tpch_workload.h"
#include "common/logger.h"

namespace peloton {
namespace benchmark {
namespace tpch {

void Usage(FILE *out) {
  fprintf(out,
          "Command line options : tpch <options> \n"
          "   -h --help              :  print help message \n"
          "   -i --input-dir         :  location of data \n"
          "   -n --num-runs          :  the number of runs to execute for each query \n"
          "   -s --suffix            :  input file suffix \n"
          "   -d --dict-encode       :  dictionary encode \n"
          "   -q --queries           :  comma-separated list of queries to run (i.g., 1,14 for Q1 and Q14) \n");
}

static struct option opts[] = {
    {"input-dir", required_argument, NULL, 'i'},
    {"dict-encode", optional_argument, NULL, 'd'},
    {"queries", optional_argument, NULL, 'q'},
    {NULL, 0, NULL, 0}};

void ParseArguments(int argc, char **argv, Configuration &config) {
  config.suffix = "tbl";

  // Parse args
  while (1) {
    int idx = 0;
    int c = getopt_long(argc, argv, "hi:n:s:dq:", opts, &idx);

    if (c == -1) break;

    switch (c) {
      case 'i': {
        char *input = optarg;
        config.data_dir = input;
        break;
      }
      case 'n': {
        char *input = optarg;
        config.num_runs = static_cast<uint32_t>(std::atoi(input));
      }
      case 'd': {
        config.dictionary_encode = true;
        break;
      }
      case 'q': {
        char *csv_queries = optarg;
        config.SetRunnableQueries(csv_queries);
        break;
      }
      case 'h': {
        Usage(stderr);
        exit(EXIT_FAILURE);
      }
      default: {
        LOG_ERROR("Unknown option: -%c-", c);
        Usage(stderr);
        exit(EXIT_FAILURE);
      }
    }
  }

  // Validate everything
  if (!config.IsValid()) {
    exit(EXIT_FAILURE);
  }

  LOG_INFO("Input directory   : '%s'", config.data_dir.c_str());
  LOG_INFO("Dictionary encode : %s",
           config.dictionary_encode ? "true" : "false");
  for (uint32_t i = 0; i < 22; i++) {
    LOG_INFO("Run query %u : %s", i + 1,
             config.queries_to_run[i] ? "true" : "false");
  }
}

void RunBenchmark(const Configuration &config) {
  // Create the DB instance
  TPCHDatabase tpch_db{config};

  // Create the benchmark
  TPCHBenchmark tpch_benchmark{config, tpch_db};

  // Run the benchmark
  tpch_benchmark.RunBenchmark();
}

}  // namespace tpch
}  // namespace benchmark
}  // namespace peloton

// Entry point
int main(int argc, char **argv) {
  // The configuration
  peloton::benchmark::tpch::Configuration config;

  // Parse arguments
  peloton::benchmark::tpch::ParseArguments(argc, argv, config);

  // Run workload
  peloton::benchmark::tpch::RunBenchmark(config);

  return 0;
}<|endoftext|>


<commit_before>
//
// This source file is part of appleseed.
// Visit http://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2010 Francois Beaune
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

// Interface header.
#include "masterrenderer.h"

// appleseed.renderer headers.
#include "renderer/kernel/intersection/intersector.h"
#include "renderer/kernel/lighting/drt/drt.h"
#include "renderer/kernel/lighting/ilightingengine.h"
#include "renderer/kernel/lighting/lightsampler.h"
#include "renderer/kernel/lighting/pathtracing/pathtracing.h"
#include "renderer/kernel/rendering/debug/blanktilerenderer.h"
#include "renderer/kernel/rendering/debug/debugtilerenderer.h"
#include "renderer/kernel/rendering/generic/genericframerenderer.h"
#include "renderer/kernel/rendering/generic/genericsamplerenderer.h"
#include "renderer/kernel/rendering/generic/generictilerenderer.h"
#include "renderer/kernel/rendering/progressive/progressiveframerenderer.h"
#include "renderer/kernel/rendering/iframerenderer.h"
#include "renderer/kernel/rendering/isamplerenderer.h"
#include "renderer/kernel/rendering/itilecallback.h"
#include "renderer/kernel/rendering/itilerenderer.h"
#include "renderer/kernel/shading/shadingcontext.h"
#include "renderer/kernel/shading/shadingengine.h"
#include "renderer/kernel/texturing/texturecache.h"
#include "renderer/modeling/bsdf/bsdf.h"
#include "renderer/modeling/camera/camera.h"
#include "renderer/modeling/edf/edf.h"
#include "renderer/modeling/environmentedf/environmentedf.h"
#include "renderer/modeling/environmentshader/environmentshader.h"
#include "renderer/modeling/input/inputparams.h"
#include "renderer/modeling/input/uniforminputevaluator.h"
#include "renderer/modeling/project/project.h"
#include "renderer/modeling/scene/assembly.h"
#include "renderer/modeling/scene/containers.h"
#include "renderer/modeling/scene/scene.h"
#include "renderer/modeling/surfaceshader/surfaceshader.h"

// appleseed.foundation headers.
#include "foundation/core/exception.h"
#include "foundation/utility/foreach.h"

// Standard headers.
#include <exception>

using namespace foundation;
using namespace std;

namespace renderer
{

//
// MasterRenderer class implementation.
//

// Constructor.
MasterRenderer::MasterRenderer(
    Project&                project,
    const ParamArray&       params,
    const Mode              mode,
    IRendererController*    renderer_controller,
    ITileCallbackFactory*   tile_callback_factory)
  : m_project(project)
  , m_params(params)
  , m_mode(mode)
  , m_renderer_controller(renderer_controller)
  , m_tile_callback_factory(tile_callback_factory)
{
}

// Return the parameters of the master renderer.
ParamArray& MasterRenderer::get_parameters()
{
    return m_params;
}
const ParamArray& MasterRenderer::get_parameters() const
{
    return m_params;
}

// Render the project.
void MasterRenderer::render()
{
    try
    {
        do_render();
    }
    catch (const Exception& e)
    {
        m_renderer_controller->on_rendering_abort();
        RENDERER_LOG_ERROR("master renderer failed: %s", e.what());
    }
    catch (const bad_alloc&)
    {
        m_renderer_controller->on_rendering_abort();
        RENDERER_LOG_ERROR("master renderer failed: memory allocation failure");
    }
    catch (...)
    {
        m_renderer_controller->on_rendering_abort();
        RENDERER_LOG_ERROR("master renderer failed: unknown exception");
    }
}

// Continuously render from scratch.
void MasterRenderer::do_render()
{
    while (true)
    {
        // Notify the rendering controller that rendering is beginning.
        m_renderer_controller->on_rendering_begin();

        // Initialize the rendering components and render until completed or aborted.
        const IRendererController::Status status = render_from_scratch();

        // In non-continuous rendering mode, stop after one frame.
        if (m_mode == RenderOnce)
        {
            m_renderer_controller->on_rendering_success();
            break;
        }

        // If rendering was aborted, stop.
        if (status == IRendererController::AbortRendering)
        {
            m_renderer_controller->on_rendering_abort();
            break;
        }
    }
}

// Initialize the rendering components and render until completed or aborted.
IRendererController::Status MasterRenderer::render_from_scratch()
{
    assert(m_project.get_scene());
    assert(m_project.get_frame());

    // Create a light sampler.
    LightSampler light_sampler(*m_project.get_scene());

    // Create a lighting engine factory.
    auto_ptr<ILightingEngineFactory> lighting_engine_factory;
    const string lighting_engine_param =
        m_params.get_required<string>("lighting_engine", "pt");
    if (lighting_engine_param == "drt")
    {
        // Distribution ray tracing.
        lighting_engine_factory.reset(
            new DRTLightingEngineFactory(light_sampler, m_params.child("drt")));
    }
    else
    {
        // Path tracing.
        lighting_engine_factory.reset(
            new PTLightingEngineFactory(light_sampler, m_params.child("pt")));
    }

    // Create a shading engine.
    ShadingEngine shading_engine(m_params.child("shading_engine"));

    // Create a sample renderer factory.
    auto_ptr<ISampleRendererFactory> sample_renderer_factory;
    const string sample_renderer_param =
        m_params.get_required<string>("sample_renderer", "generic");
    {
        // Generic sample renderer.
        sample_renderer_factory.reset(
            new GenericSampleRendererFactory(
                *m_project.get_scene(),
                m_project.get_trace_context(),
                lighting_engine_factory.get(),
                shading_engine,
                m_params.child("generic_sample_renderer")));
    }

    // Create a tile renderer factory.
    auto_ptr<ITileRendererFactory> tile_renderer_factory;
    const string tile_renderer_param =
        m_params.get_required<string>("tile_renderer", "generic");
    if (tile_renderer_param == "blank")
    {
        // Blank tile renderer factory.
        tile_renderer_factory.reset(new BlankTileRendererFactory());
    }
    else if (tile_renderer_param == "debug")
    {
        // Debug tile renderer factory.
        tile_renderer_factory.reset(new DebugTileRendererFactory());
    }
    else
    {
        // Generic tile renderer factory.
        tile_renderer_factory.reset(
            new GenericTileRendererFactory(
                *m_project.get_frame(),
                sample_renderer_factory.get(),
                m_params.child("generic_tile_renderer")));
    }

    // Create a frame renderer.
    auto_release_ptr<IFrameRenderer> frame_renderer;
    const string frame_renderer_param =
        m_params.get_required<string>("frame_renderer", "generic");
    if (frame_renderer_param == "progressive")
    {
        // Progressive frame renderer.
        frame_renderer.reset(
            ProgressiveFrameRendererFactory::create(
                *m_project.get_frame(),
                sample_renderer_factory.get(),
                m_tile_callback_factory,
                m_params.child("progressive_frame_renderer")));
    }
    else
    {
        // Generic frame renderer.
        frame_renderer.reset(
            GenericFrameRendererFactory::create(
                *m_project.get_frame(),
                tile_renderer_factory.get(),
                m_tile_callback_factory,
                m_params.child("generic_frame_renderer")));
    }

    // Execute the main rendering loop.
    return render_until_completed_or_aborted(frame_renderer.get());
}

// Render (one or many frames) until rendering is completed or aborted.
IRendererController::Status MasterRenderer::render_until_completed_or_aborted(
    IFrameRenderer* frame_renderer)
{
    while (true)
    {
        assert(!frame_renderer->is_rendering());

        // Notify the rendering controller that a frame is about to be rendered.
        m_renderer_controller->on_frame_begin();

        // Perform pre-frame rendering actions.
        on_frame_begin();

        // Start rendering the frame.
        frame_renderer->start_rendering();

        // Wait until rendering of the frame is complete.
        const IRendererController::Status status = wait_until_frame_complete(frame_renderer);
        assert(!frame_renderer->is_rendering());

        // Perform post-frame rendering actions.
        on_frame_end();

        // Notify the rendering controller that a frame is finished rendering.
        m_renderer_controller->on_frame_end();

        // In non-continuous rendering mode, return after one frame.
        if (m_mode == RenderOnce)
            return IRendererController::ContinueRendering;

        // If rendering was aborted or reinitialized, return.
        if (status == IRendererController::AbortRendering ||
            status == IRendererController::ReinitializeRendering)
            return status;
    }
}

// Wait until the frame being rendered is complete, or rendering was aborted.
IRendererController::Status MasterRenderer::wait_until_frame_complete(
    IFrameRenderer* frame_renderer)
{
    while (frame_renderer->is_rendering())
    {
        // Report progress and retrieve status.
        const IRendererController::Status status = m_renderer_controller->on_progress();

        // Return if rendering was aborted or restarted.
        if (status != IRendererController::ContinueRendering)
        {
            frame_renderer->stop_rendering();
            return status;
        }
    }

    return IRendererController::ContinueRendering;
}

namespace
{
    //
    // Invoke on_frame_begin() / on_frame_end() on all entities of a collection.
    //

    template <typename EntityCollection>
    void invoke_on_frame_begin_collection(
        EntityCollection&       entities,
        const Scene&            scene)
    {
        for (each<EntityCollection> i = entities; i; ++i)
            invoke_on_frame_begin(*i, scene);
    }

    template <typename EntityCollection>
    void invoke_on_frame_begin_collection(
        EntityCollection&       entities,
        const Scene&            scene,
        UniformInputEvaluator&  input_evaluator)
    {
        for (each<EntityCollection> i = entities; i; ++i)
            invoke_on_frame_begin(*i, scene, input_evaluator);
    }

    template <typename EntityCollection>
    void invoke_on_frame_end_collection(
        EntityCollection&       entities,
        const Scene&            scene)
    {
        for (each<EntityCollection> i = entities; i; ++i)
            invoke_on_frame_end(*i, scene);
    }

    //
    // Invoke on_frame_begin() / on_frame_end() on a single entity.
    //

    template <typename Entity>
    void invoke_on_frame_begin(
        Entity&                 entity,
        const Scene&            scene)
    {
        entity.on_frame_begin(scene);
    }

    template <typename Entity>
    void invoke_on_frame_begin(
        Entity&                 entity,
        const Scene&            scene,
        UniformInputEvaluator&  input_evaluator)
    {
        const void* data =
            input_evaluator.evaluate(entity.get_inputs());

        entity.on_frame_begin(scene, data);
    }

    template <typename Entity>
    void invoke_on_frame_end(
        Entity&                 entity,
        const Scene&            scene)
    {
        entity.on_frame_end(scene);
    }

    //
    // Invoke on_frame_begin() / on_frame_end() on all entities of an assembly.
    //

    template <>
    void invoke_on_frame_begin(
        Assembly&               assembly,
        const Scene&            scene,
        UniformInputEvaluator&  input_evaluator)
    {
        invoke_on_frame_begin_collection(assembly.surface_shaders(), scene);
        invoke_on_frame_begin_collection(assembly.bsdfs(), scene, input_evaluator);
        invoke_on_frame_begin_collection(assembly.edfs(), scene, input_evaluator);
    }

    template <>
    void invoke_on_frame_end(
        Assembly&               assembly,
        const Scene&            scene)
    {
        invoke_on_frame_end_collection(assembly.edfs(), scene);
        invoke_on_frame_end_collection(assembly.bsdfs(), scene);
        invoke_on_frame_end_collection(assembly.surface_shaders(), scene);
    }
}

// Perform pre-frame rendering actions.
void MasterRenderer::on_frame_begin() const
{
    const Scene& scene = *m_project.get_scene();

    assert(scene.get_camera());
    Intersector intersector(m_project.get_trace_context(), false);
    scene.get_camera()->on_frame_begin(scene, intersector);

    UniformInputEvaluator input_evaluator;

    invoke_on_frame_begin_collection(scene.environment_edfs(), scene);
    invoke_on_frame_begin_collection(scene.environment_shaders(), scene);
    invoke_on_frame_begin_collection(scene.assemblies(), scene, input_evaluator);
}

// Perform post-frame rendering actions.
void MasterRenderer::on_frame_end() const
{
    const Scene& scene = *m_project.get_scene();

    invoke_on_frame_end_collection(scene.assemblies(), scene);
    invoke_on_frame_end_collection(scene.environment_shaders(), scene);
    invoke_on_frame_end_collection(scene.environment_edfs(), scene);

    assert(scene.get_camera());
    scene.get_camera()->on_frame_end(scene);
}

}   // namespace renderer
<commit_msg>made error messages more user-friendly.<commit_after>
//
// This source file is part of appleseed.
// Visit http://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2010 Francois Beaune
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

// Interface header.
#include "masterrenderer.h"

// appleseed.renderer headers.
#include "renderer/kernel/intersection/intersector.h"
#include "renderer/kernel/lighting/drt/drt.h"
#include "renderer/kernel/lighting/ilightingengine.h"
#include "renderer/kernel/lighting/lightsampler.h"
#include "renderer/kernel/lighting/pathtracing/pathtracing.h"
#include "renderer/kernel/rendering/debug/blanktilerenderer.h"
#include "renderer/kernel/rendering/debug/debugtilerenderer.h"
#include "renderer/kernel/rendering/generic/genericframerenderer.h"
#include "renderer/kernel/rendering/generic/genericsamplerenderer.h"
#include "renderer/kernel/rendering/generic/generictilerenderer.h"
#include "renderer/kernel/rendering/progressive/progressiveframerenderer.h"
#include "renderer/kernel/rendering/iframerenderer.h"
#include "renderer/kernel/rendering/isamplerenderer.h"
#include "renderer/kernel/rendering/itilecallback.h"
#include "renderer/kernel/rendering/itilerenderer.h"
#include "renderer/kernel/shading/shadingcontext.h"
#include "renderer/kernel/shading/shadingengine.h"
#include "renderer/kernel/texturing/texturecache.h"
#include "renderer/modeling/bsdf/bsdf.h"
#include "renderer/modeling/camera/camera.h"
#include "renderer/modeling/edf/edf.h"
#include "renderer/modeling/environmentedf/environmentedf.h"
#include "renderer/modeling/environmentshader/environmentshader.h"
#include "renderer/modeling/input/inputparams.h"
#include "renderer/modeling/input/uniforminputevaluator.h"
#include "renderer/modeling/project/project.h"
#include "renderer/modeling/scene/assembly.h"
#include "renderer/modeling/scene/containers.h"
#include "renderer/modeling/scene/scene.h"
#include "renderer/modeling/surfaceshader/surfaceshader.h"

// appleseed.foundation headers.
#include "foundation/core/exception.h"
#include "foundation/utility/foreach.h"

// Standard headers.
#include <exception>

using namespace foundation;
using namespace std;

namespace renderer
{

//
// MasterRenderer class implementation.
//

// Constructor.
MasterRenderer::MasterRenderer(
    Project&                project,
    const ParamArray&       params,
    const Mode              mode,
    IRendererController*    renderer_controller,
    ITileCallbackFactory*   tile_callback_factory)
  : m_project(project)
  , m_params(params)
  , m_mode(mode)
  , m_renderer_controller(renderer_controller)
  , m_tile_callback_factory(tile_callback_factory)
{
}

// Return the parameters of the master renderer.
ParamArray& MasterRenderer::get_parameters()
{
    return m_params;
}
const ParamArray& MasterRenderer::get_parameters() const
{
    return m_params;
}

// Render the project.
void MasterRenderer::render()
{
    try
    {
        do_render();
    }
    catch (const Exception& e)
    {
        m_renderer_controller->on_rendering_abort();
        RENDERER_LOG_ERROR("rendering failed: %s", e.what());
    }
    catch (const bad_alloc&)
    {
        m_renderer_controller->on_rendering_abort();
        RENDERER_LOG_ERROR("rendering failed: ran out of memory");
    }
    catch (...)
    {
        m_renderer_controller->on_rendering_abort();
        RENDERER_LOG_ERROR("rendering failed: unknown exception");
    }
}

// Continuously render from scratch.
void MasterRenderer::do_render()
{
    while (true)
    {
        // Notify the rendering controller that rendering is beginning.
        m_renderer_controller->on_rendering_begin();

        // Initialize the rendering components and render until completed or aborted.
        const IRendererController::Status status = render_from_scratch();

        // In non-continuous rendering mode, stop after one frame.
        if (m_mode == RenderOnce)
        {
            m_renderer_controller->on_rendering_success();
            break;
        }

        // If rendering was aborted, stop.
        if (status == IRendererController::AbortRendering)
        {
            m_renderer_controller->on_rendering_abort();
            break;
        }
    }
}

// Initialize the rendering components and render until completed or aborted.
IRendererController::Status MasterRenderer::render_from_scratch()
{
    assert(m_project.get_scene());
    assert(m_project.get_frame());

    // Create a light sampler.
    LightSampler light_sampler(*m_project.get_scene());

    // Create a lighting engine factory.
    auto_ptr<ILightingEngineFactory> lighting_engine_factory;
    const string lighting_engine_param =
        m_params.get_required<string>("lighting_engine", "pt");
    if (lighting_engine_param == "drt")
    {
        // Distribution ray tracing.
        lighting_engine_factory.reset(
            new DRTLightingEngineFactory(light_sampler, m_params.child("drt")));
    }
    else
    {
        // Path tracing.
        lighting_engine_factory.reset(
            new PTLightingEngineFactory(light_sampler, m_params.child("pt")));
    }

    // Create a shading engine.
    ShadingEngine shading_engine(m_params.child("shading_engine"));

    // Create a sample renderer factory.
    auto_ptr<ISampleRendererFactory> sample_renderer_factory;
    const string sample_renderer_param =
        m_params.get_required<string>("sample_renderer", "generic");
    {
        // Generic sample renderer.
        sample_renderer_factory.reset(
            new GenericSampleRendererFactory(
                *m_project.get_scene(),
                m_project.get_trace_context(),
                lighting_engine_factory.get(),
                shading_engine,
                m_params.child("generic_sample_renderer")));
    }

    // Create a tile renderer factory.
    auto_ptr<ITileRendererFactory> tile_renderer_factory;
    const string tile_renderer_param =
        m_params.get_required<string>("tile_renderer", "generic");
    if (tile_renderer_param == "blank")
    {
        // Blank tile renderer factory.
        tile_renderer_factory.reset(new BlankTileRendererFactory());
    }
    else if (tile_renderer_param == "debug")
    {
        // Debug tile renderer factory.
        tile_renderer_factory.reset(new DebugTileRendererFactory());
    }
    else
    {
        // Generic tile renderer factory.
        tile_renderer_factory.reset(
            new GenericTileRendererFactory(
                *m_project.get_frame(),
                sample_renderer_factory.get(),
                m_params.child("generic_tile_renderer")));
    }

    // Create a frame renderer.
    auto_release_ptr<IFrameRenderer> frame_renderer;
    const string frame_renderer_param =
        m_params.get_required<string>("frame_renderer", "generic");
    if (frame_renderer_param == "progressive")
    {
        // Progressive frame renderer.
        frame_renderer.reset(
            ProgressiveFrameRendererFactory::create(
                *m_project.get_frame(),
                sample_renderer_factory.get(),
                m_tile_callback_factory,
                m_params.child("progressive_frame_renderer")));
    }
    else
    {
        // Generic frame renderer.
        frame_renderer.reset(
            GenericFrameRendererFactory::create(
                *m_project.get_frame(),
                tile_renderer_factory.get(),
                m_tile_callback_factory,
                m_params.child("generic_frame_renderer")));
    }

    // Execute the main rendering loop.
    return render_until_completed_or_aborted(frame_renderer.get());
}

// Render (one or many frames) until rendering is completed or aborted.
IRendererController::Status MasterRenderer::render_until_completed_or_aborted(
    IFrameRenderer* frame_renderer)
{
    while (true)
    {
        assert(!frame_renderer->is_rendering());

        // Notify the rendering controller that a frame is about to be rendered.
        m_renderer_controller->on_frame_begin();

        // Perform pre-frame rendering actions.
        on_frame_begin();

        // Start rendering the frame.
        frame_renderer->start_rendering();

        // Wait until rendering of the frame is complete.
        const IRendererController::Status status = wait_until_frame_complete(frame_renderer);
        assert(!frame_renderer->is_rendering());

        // Perform post-frame rendering actions.
        on_frame_end();

        // Notify the rendering controller that a frame is finished rendering.
        m_renderer_controller->on_frame_end();

        // In non-continuous rendering mode, return after one frame.
        if (m_mode == RenderOnce)
            return IRendererController::ContinueRendering;

        // If rendering was aborted or reinitialized, return.
        if (status == IRendererController::AbortRendering ||
            status == IRendererController::ReinitializeRendering)
            return status;
    }
}

// Wait until the frame being rendered is complete, or rendering was aborted.
IRendererController::Status MasterRenderer::wait_until_frame_complete(
    IFrameRenderer* frame_renderer)
{
    while (frame_renderer->is_rendering())
    {
        // Report progress and retrieve status.
        const IRendererController::Status status = m_renderer_controller->on_progress();

        // Return if rendering was aborted or restarted.
        if (status != IRendererController::ContinueRendering)
        {
            frame_renderer->stop_rendering();
            return status;
        }
    }

    return IRendererController::ContinueRendering;
}

namespace
{
    //
    // Invoke on_frame_begin() / on_frame_end() on all entities of a collection.
    //

    template <typename EntityCollection>
    void invoke_on_frame_begin_collection(
        EntityCollection&       entities,
        const Scene&            scene)
    {
        for (each<EntityCollection> i = entities; i; ++i)
            invoke_on_frame_begin(*i, scene);
    }

    template <typename EntityCollection>
    void invoke_on_frame_begin_collection(
        EntityCollection&       entities,
        const Scene&            scene,
        UniformInputEvaluator&  input_evaluator)
    {
        for (each<EntityCollection> i = entities; i; ++i)
            invoke_on_frame_begin(*i, scene, input_evaluator);
    }

    template <typename EntityCollection>
    void invoke_on_frame_end_collection(
        EntityCollection&       entities,
        const Scene&            scene)
    {
        for (each<EntityCollection> i = entities; i; ++i)
            invoke_on_frame_end(*i, scene);
    }

    //
    // Invoke on_frame_begin() / on_frame_end() on a single entity.
    //

    template <typename Entity>
    void invoke_on_frame_begin(
        Entity&                 entity,
        const Scene&            scene)
    {
        entity.on_frame_begin(scene);
    }

    template <typename Entity>
    void invoke_on_frame_begin(
        Entity&                 entity,
        const Scene&            scene,
        UniformInputEvaluator&  input_evaluator)
    {
        const void* data =
            input_evaluator.evaluate(entity.get_inputs());

        entity.on_frame_begin(scene, data);
    }

    template <typename Entity>
    void invoke_on_frame_end(
        Entity&                 entity,
        const Scene&            scene)
    {
        entity.on_frame_end(scene);
    }

    //
    // Invoke on_frame_begin() / on_frame_end() on all entities of an assembly.
    //

    template <>
    void invoke_on_frame_begin(
        Assembly&               assembly,
        const Scene&            scene,
        UniformInputEvaluator&  input_evaluator)
    {
        invoke_on_frame_begin_collection(assembly.surface_shaders(), scene);
        invoke_on_frame_begin_collection(assembly.bsdfs(), scene, input_evaluator);
        invoke_on_frame_begin_collection(assembly.edfs(), scene, input_evaluator);
    }

    template <>
    void invoke_on_frame_end(
        Assembly&               assembly,
        const Scene&            scene)
    {
        invoke_on_frame_end_collection(assembly.edfs(), scene);
        invoke_on_frame_end_collection(assembly.bsdfs(), scene);
        invoke_on_frame_end_collection(assembly.surface_shaders(), scene);
    }
}

// Perform pre-frame rendering actions.
void MasterRenderer::on_frame_begin() const
{
    const Scene& scene = *m_project.get_scene();

    assert(scene.get_camera());
    Intersector intersector(m_project.get_trace_context(), false);
    scene.get_camera()->on_frame_begin(scene, intersector);

    UniformInputEvaluator input_evaluator;

    invoke_on_frame_begin_collection(scene.environment_edfs(), scene);
    invoke_on_frame_begin_collection(scene.environment_shaders(), scene);
    invoke_on_frame_begin_collection(scene.assemblies(), scene, input_evaluator);
}

// Perform post-frame rendering actions.
void MasterRenderer::on_frame_end() const
{
    const Scene& scene = *m_project.get_scene();

    invoke_on_frame_end_collection(scene.assemblies(), scene);
    invoke_on_frame_end_collection(scene.environment_shaders(), scene);
    invoke_on_frame_end_collection(scene.environment_edfs(), scene);

    assert(scene.get_camera());
    scene.get_camera()->on_frame_end(scene);
}

}   // namespace renderer
<|endoftext|>


<commit_before>// Copyright (C) 2015 The Regents of the University of California (Regents).
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//
//     * Neither the name of The Regents or University of California nor the
//       names of its contributors may be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// Please contact the author of this library if you have any questions.
// Author: Chris Sweeney (cmsweeney@cs.ucsb.edu)

#include "theia/sfm/bundle_adjustment/bundle_adjust_two_views.h"

#include <ceres/ceres.h>
#include <Eigen/Core>
#include <vector>

#include "theia/matching/feature_correspondence.h"
#include "theia/sfm/bundle_adjustment/angular_epipolar_error.h"
#include "theia/sfm/bundle_adjustment/bundle_adjustment.h"
#include "theia/sfm/bundle_adjustment/unit_norm_three_vector_parameterization.h"
#include "theia/sfm/camera/camera.h"
#include "theia/sfm/camera/reprojection_error.h"
#include "theia/sfm/camera_intrinsics_prior.h"
#include "theia/sfm/triangulation/triangulation.h"
#include "theia/sfm/twoview_info.h"
#include "theia/sfm/types.h"
#include "theia/util/timer.h"

namespace theia {

namespace {

void SetSolverOptions(const BundleAdjustmentOptions& options,
                      ceres::Solver::Options* solver_options) {
  CHECK_NOTNULL(solver_options);
  solver_options->linear_solver_type = ceres::DENSE_SCHUR;
  solver_options->visibility_clustering_type = ceres::CANONICAL_VIEWS;
  solver_options->logging_type = ceres::SILENT;
  solver_options->num_threads = options.num_threads;
  solver_options->num_linear_solver_threads = options.num_threads;
  solver_options->max_num_iterations = 200;
  // Solver options takes ownership of the ordering so that we can order the BA
  // problem by points and cameras.
  solver_options->linear_solver_ordering.reset(
      new ceres::ParameterBlockOrdering);
}

// The only intrinsic parameter we want to optimize is the focal length, so we
// keep all intrinsics constant except for focal length by default.
void AddCameraParametersToProblem(const bool constant_extrinsic_parameters,
                                  const bool constant_intrinsic_parameters,
                                  double* camera_parameters,
                                  ceres::Problem* problem) {
  std::vector<int> constant_intrinsics;

  // Set the extrinsics parameters to constant if desired.
  if (constant_extrinsic_parameters) {
    for (int i = 0; i < Camera::kExtrinsicsSize; i++) {
      constant_intrinsics.push_back(i);
    }
  }

  // Keep focal length constant if desired.
  if (constant_intrinsic_parameters) {
    constant_intrinsics.push_back(Camera::kExtrinsicsSize +
                                  Camera::FOCAL_LENGTH);
  }

  // NOTE: We start at index 1 because the focal length was handled previously.
  for (int i = 1; i < Camera::kIntrinsicsSize; i++) {
    constant_intrinsics.push_back(Camera::kExtrinsicsSize + i);
  }

  if (constant_intrinsics.size() != Camera::kParameterSize) {
    ceres::SubsetParameterization* subset_parameterization =
      new ceres::SubsetParameterization(Camera::kParameterSize,
                                        constant_intrinsics);
    problem->AddParameterBlock(camera_parameters,
                               Camera::kParameterSize,
                               subset_parameterization);
  } else {
    problem->AddParameterBlock(camera_parameters, Camera::kParameterSize);
    problem->SetParameterBlockConstant(camera_parameters);
  }
}

}  // namespace

// Triangulates all 3d points and performs standard bundle adjustment on the
// points and cameras.
BundleAdjustmentSummary BundleAdjustTwoViews(
    const TwoViewBundleAdjustmentOptions& options,
    const std::vector<FeatureCorrespondence>& correspondences,
    Camera* camera1,
    Camera* camera2,
    std::vector<Eigen::Vector4d>* points3d) {
  CHECK_NOTNULL(camera1);
  CHECK_NOTNULL(camera2);
  CHECK_NOTNULL(points3d);
  CHECK_EQ(points3d->size(), correspondences.size());

  BundleAdjustmentSummary summary;

  // Start setup timer.
  Timer timer;

  // Set problem options.
  ceres::Problem::Options problem_options;
  ceres::Problem problem(problem_options);

  // Set solver options.
  ceres::Solver::Options solver_options;
  SetSolverOptions(options.ba_options, &solver_options);
  ceres::ParameterBlockOrdering* parameter_ordering =
      solver_options.linear_solver_ordering.get();

  // Add the two cameras as parameter blocks.
  AddCameraParametersToProblem(true,
                               options.constant_camera1_intrinsics,
                               camera1->mutable_parameters(),
                               &problem);
  AddCameraParametersToProblem(false,
                               options.constant_camera2_intrinsics,
                               camera2->mutable_parameters(),
                               &problem);
  parameter_ordering->AddElementToGroup(camera1->mutable_parameters(), 1);
  parameter_ordering->AddElementToGroup(camera2->mutable_parameters(), 1);

  // Add triangulated points to the problem.
  for (int i = 0; i < points3d->size(); i++) {
    problem.AddResidualBlock(
        ReprojectionError::Create(correspondences[i].feature1),
        NULL,
        camera1->mutable_extrinsics(),
        camera1->mutable_intrinsics(),
        points3d->at(i).data());
    problem.AddResidualBlock(
        ReprojectionError::Create(correspondences[i].feature2),
        NULL,
        camera2->mutable_extrinsics(),
        camera2->mutable_intrinsics(),
        points3d->at(i).data());

    parameter_ordering->AddElementToGroup(points3d->at(i).data(), 0);
  }

  // End setup time.
  summary.setup_time_in_seconds = timer.ElapsedTimeInSeconds();

  // Solve the problem.
  ceres::Solver::Summary solver_summary;
  ceres::Solve(solver_options, &problem, &solver_summary);
  LOG_IF(INFO, options.ba_options.verbose) << solver_summary.FullReport();

  // Set the BundleAdjustmentSummary.
  summary.solve_time_in_seconds = solver_summary.total_time_in_seconds;
  summary.initial_cost = solver_summary.initial_cost;
  summary.final_cost = solver_summary.final_cost;

  // This only indicates whether the optimization was successfully run and makes
  // no guarantees on the quality or convergence.
  summary.success = solver_summary.termination_type != ceres::FAILURE;

  return summary;
}

BundleAdjustmentSummary BundleAdjustTwoViewsAngular(
    const BundleAdjustmentOptions& options,
    const std::vector<FeatureCorrespondence>& correspondences,
    TwoViewInfo* info) {
  CHECK_NOTNULL(info);

  BundleAdjustmentSummary summary;

  // Start setup timer.
  Timer timer;

  // Set problem options.
  ceres::Problem::Options problem_options;

  ceres::Problem problem(problem_options);

  // Set solver options.
  ceres::Solver::Options solver_options;
  SetSolverOptions(options, &solver_options);
  // Allow Ceres to determine the ordering.
  solver_options.linear_solver_ordering.reset();

  // Add the relative rotation as a parameter block.
  const int kParameterBlockSize = 3;
  problem.AddParameterBlock(info->rotation_2.data(), kParameterBlockSize);
  // Add the position as a parameter block, ensuring that the norm is 1.
  ceres::LocalParameterization* position_parameterization =
      new ceres::AutoDiffLocalParameterization<
          UnitNormThreeVectorParameterization, 3, 3>;
  problem.AddParameterBlock(info->position_2.data(),
                            kParameterBlockSize,
                            position_parameterization);

  // Add all the epipolar constraints from feature matches.
  for (const FeatureCorrespondence& match : correspondences) {
    problem.AddResidualBlock(
        AngularEpipolarError::Create(match.feature1, match.feature2),
        NULL,
        info->rotation_2.data(),
        info->position_2.data());
  }

  // End setup time.
  summary.setup_time_in_seconds = timer.ElapsedTimeInSeconds();

  // Solve the problem.
  ceres::Solver::Summary solver_summary;
  ceres::Solve(solver_options, &problem, &solver_summary);
  LOG_IF(INFO, options.verbose) << solver_summary.FullReport();

  // Set the BundleAdjustmentSummary.
  summary.solve_time_in_seconds = solver_summary.total_time_in_seconds;
  summary.initial_cost = solver_summary.initial_cost;
  summary.final_cost = solver_summary.final_cost;

  // This only indicates whether the optimization was successfully run and makes
  // no guarantees on the quality or convergence.
  summary.success = solver_summary.termination_type != ceres::FAILURE;
  return summary;
}

}  // namespace theia
<commit_msg>Adjust two-view BA to work properly thanks to @stoyanovd<commit_after>// Copyright (C) 2015 The Regents of the University of California (Regents).
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//
//     * Neither the name of The Regents or University of California nor the
//       names of its contributors may be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// Please contact the author of this library if you have any questions.
// Author: Chris Sweeney (cmsweeney@cs.ucsb.edu)

#include "theia/sfm/bundle_adjustment/bundle_adjust_two_views.h"

#include <ceres/ceres.h>
#include <Eigen/Core>
#include <vector>

#include "theia/matching/feature_correspondence.h"
#include "theia/sfm/bundle_adjustment/angular_epipolar_error.h"
#include "theia/sfm/bundle_adjustment/bundle_adjustment.h"
#include "theia/sfm/bundle_adjustment/unit_norm_three_vector_parameterization.h"
#include "theia/sfm/camera/camera.h"
#include "theia/sfm/camera/reprojection_error.h"
#include "theia/sfm/camera_intrinsics_prior.h"
#include "theia/sfm/triangulation/triangulation.h"
#include "theia/sfm/twoview_info.h"
#include "theia/sfm/types.h"
#include "theia/util/timer.h"

namespace theia {

namespace {

void SetSolverOptions(const BundleAdjustmentOptions& options,
                      ceres::Solver::Options* solver_options) {
  CHECK_NOTNULL(solver_options);
  solver_options->linear_solver_type = ceres::DENSE_SCHUR;
  solver_options->visibility_clustering_type = ceres::CANONICAL_VIEWS;
  solver_options->logging_type = ceres::SILENT;
  solver_options->num_threads = options.num_threads;
  solver_options->num_linear_solver_threads = options.num_threads;
  solver_options->max_num_iterations = 200;
  // Solver options takes ownership of the ordering so that we can order the BA
  // problem by points and cameras.
  solver_options->linear_solver_ordering.reset(
      new ceres::ParameterBlockOrdering);
}

// The only intrinsic parameter we want to optimize is the focal length, so we
// keep all intrinsics constant except for focal length by default.
void AddCameraParametersToProblem(const bool constant_extrinsic_parameters,
                                  const bool constant_intrinsic_parameters,
                                  double* camera_extrinsics,
                                  double* camera_intrinsics,
                                  ceres::Problem* problem) {
  // Add extrinsics to problem
  problem->AddParameterBlock(camera_extrinsics, Camera::kExtrinsicsSize);
  if (constant_extrinsic_parameters) {
    problem->SetParameterBlockConstant(camera_extrinsics);
  }

  std::vector<int> constant_intrinsics;
  // Keep focal length constant if desired.
  if (constant_intrinsic_parameters) {
    constant_intrinsics.push_back(Camera::FOCAL_LENGTH);
  }

  // NOTE: We start at index 1 because the focal length was handled previously.
  for (int i = 1; i < Camera::kIntrinsicsSize; i++) {
    constant_intrinsics.push_back(i);
  }

  // Add intrinsics to problem
  if (constant_intrinsics.size() != Camera::kIntrinsicsSize) {
    ceres::SubsetParameterization* subset_parameterization =
      new ceres::SubsetParameterization(Camera::kIntrinsicsSize,
                                        constant_intrinsics);
    problem->AddParameterBlock(camera_intrinsics,
                               Camera::kIntrinsicsSize,
                               subset_parameterization);
  } else {
    problem->AddParameterBlock(camera_intrinsics, Camera::kIntrinsicsSize);
    problem->SetParameterBlockConstant(camera_intrinsics);
  }
}

}  // namespace

// Triangulates all 3d points and performs standard bundle adjustment on the
// points and cameras.
BundleAdjustmentSummary BundleAdjustTwoViews(
    const TwoViewBundleAdjustmentOptions& options,
    const std::vector<FeatureCorrespondence>& correspondences,
    Camera* camera1,
    Camera* camera2,
    std::vector<Eigen::Vector4d>* points3d) {
  CHECK_NOTNULL(camera1);
  CHECK_NOTNULL(camera2);
  CHECK_NOTNULL(points3d);
  CHECK_EQ(points3d->size(), correspondences.size());

  BundleAdjustmentSummary summary;

  // Start setup timer.
  Timer timer;

  // Set problem options.
  ceres::Problem::Options problem_options;
  ceres::Problem problem(problem_options);

  // Set solver options.
  ceres::Solver::Options solver_options;
  SetSolverOptions(options.ba_options, &solver_options);
  ceres::ParameterBlockOrdering* parameter_ordering =
      solver_options.linear_solver_ordering.get();

  // Add the two cameras as parameter blocks.
  AddCameraParametersToProblem(true,
                               options.constant_camera1_intrinsics,
                               camera1->mutable_extrinsics(),
                               camera1->mutable_intrinsics(),
                               &problem);
  AddCameraParametersToProblem(false,
                               options.constant_camera2_intrinsics,
                               camera2->mutable_extrinsics(),
                               camera2->mutable_intrinsics(),
                               &problem);
  parameter_ordering->AddElementToGroup(camera1->mutable_extrinsics(), 2);
  parameter_ordering->AddElementToGroup(camera1->mutable_intrinsics(), 1);

  parameter_ordering->AddElementToGroup(camera2->mutable_extrinsics(), 2);
  parameter_ordering->AddElementToGroup(camera2->mutable_intrinsics(), 1);

  // Add triangulated points to the problem.
  for (int i = 0; i < points3d->size(); i++) {
    problem.AddResidualBlock(
        ReprojectionError::Create(correspondences[i].feature1),
        NULL,
        camera1->mutable_extrinsics(),
        camera1->mutable_intrinsics(),
        points3d->at(i).data());
    problem.AddResidualBlock(
        ReprojectionError::Create(correspondences[i].feature2),
        NULL,
        camera2->mutable_extrinsics(),
        camera2->mutable_intrinsics(),
        points3d->at(i).data());

    parameter_ordering->AddElementToGroup(points3d->at(i).data(), 0);
  }

  // End setup time.
  summary.setup_time_in_seconds = timer.ElapsedTimeInSeconds();

  // Solve the problem.
  ceres::Solver::Summary solver_summary;
  ceres::Solve(solver_options, &problem, &solver_summary);
  LOG_IF(INFO, options.ba_options.verbose) << solver_summary.FullReport();

  // Set the BundleAdjustmentSummary.
  summary.solve_time_in_seconds = solver_summary.total_time_in_seconds;
  summary.initial_cost = solver_summary.initial_cost;
  summary.final_cost = solver_summary.final_cost;

  // This only indicates whether the optimization was successfully run and makes
  // no guarantees on the quality or convergence.
  summary.success = solver_summary.termination_type != ceres::FAILURE;

  return summary;
}

BundleAdjustmentSummary BundleAdjustTwoViewsAngular(
    const BundleAdjustmentOptions& options,
    const std::vector<FeatureCorrespondence>& correspondences,
    TwoViewInfo* info) {
  CHECK_NOTNULL(info);

  BundleAdjustmentSummary summary;

  // Start setup timer.
  Timer timer;

  // Set problem options.
  ceres::Problem::Options problem_options;

  ceres::Problem problem(problem_options);

  // Set solver options.
  ceres::Solver::Options solver_options;
  SetSolverOptions(options, &solver_options);
  // Allow Ceres to determine the ordering.
  solver_options.linear_solver_ordering.reset();

  // Add the relative rotation as a parameter block.
  const int kParameterBlockSize = 3;
  problem.AddParameterBlock(info->rotation_2.data(), kParameterBlockSize);
  // Add the position as a parameter block, ensuring that the norm is 1.
  ceres::LocalParameterization* position_parameterization =
      new ceres::AutoDiffLocalParameterization<
          UnitNormThreeVectorParameterization, 3, 3>;
  problem.AddParameterBlock(info->position_2.data(),
                            kParameterBlockSize,
                            position_parameterization);

  // Add all the epipolar constraints from feature matches.
  for (const FeatureCorrespondence& match : correspondences) {
    problem.AddResidualBlock(
        AngularEpipolarError::Create(match.feature1, match.feature2),
        NULL,
        info->rotation_2.data(),
        info->position_2.data());
  }

  // End setup time.
  summary.setup_time_in_seconds = timer.ElapsedTimeInSeconds();

  // Solve the problem.
  ceres::Solver::Summary solver_summary;
  ceres::Solve(solver_options, &problem, &solver_summary);
  LOG_IF(INFO, options.verbose) << solver_summary.FullReport();

  // Set the BundleAdjustmentSummary.
  summary.solve_time_in_seconds = solver_summary.total_time_in_seconds;
  summary.initial_cost = solver_summary.initial_cost;
  summary.final_cost = solver_summary.final_cost;

  // This only indicates whether the optimization was successfully run and makes
  // no guarantees on the quality or convergence.
  summary.success = solver_summary.termination_type != ceres::FAILURE;
  return summary;
}

}  // namespace theia
<|endoftext|>


<commit_before>#include "mode_calc_rmsd.hpp"

#include <mill/util/scalar_type_of.hpp>
#include <mill/util/file_extension.hpp>
#include <mill/math/RMSDCalculator.hpp>
#include <mill/math/BestFitStructure.hpp>
#include <mill/pdb/PDBReader.hpp>
#include <mill/traj.hpp>
#include <fstream>

namespace mill
{

const char* mode_calc_rmsd_usage() noexcept
{
    return "usage: mill calc rmsd [traj file] [ref file] [align(opt): \"true\"|\"false\"]\n"
           "    files can be a pdb|xyz|dcd file.\n"
           "    The last argument is optianl.\n"
           "    If true (default), perform alignment by minimizing RMSD.\n"
           "    otherwise, it calculates RMSD without minimization.\n";
}

int mode_calc_rmsd(std::deque<std::string_view> args)
{
    using vector_type = Vector<double, 3>;
    if(args.empty())
    {
        log::error("mill calc rmsd: too few arguments.");
        log::error(mode_calc_rmsd_usage());
        return 1;
    }

    const auto fname = args.front();
    if(fname == "help")
    {
        log::info(mode_calc_rmsd_usage());
        return 0;
    }

    if(fname.size() < 5)
    {
        log::error("mill calc rmsd: unknown file format: ", fname);
        log::error(mode_calc_rmsd_usage());
        return 1;
    }

    std::vector<std::vector<vector_type>> traj;

    if(extension_of(fname) == ".dcd" || extension_of(fname) == ".xyz")
    {
        log::info("mill calc rmsd: reading ", fname);
        for(const auto& snapshot : reader(fname))
        {
            std::vector<vector_type> ss; ss.reserve(snapshot.size());
            for(const auto& particle : snapshot)
            {
                ss.push_back(particle.position());
            }
            traj.push_back(std::move(ss));
        }
        log::info("mill calc rmsd: done. ", fname, " has ", traj.size(),
                        " snapshots.");
    }
    else
    {
        log::error("mill calc rmsd: unknown file format: ", fname);
        log::error(mode_calc_rmsd_usage());
        return 1;
    }

    const auto refname = args.at(1);
    std::vector<vector_type> ref;

    if(extension_of(refname) == ".pdb")
    {
        log::error("mill calc rmsd: unknown file format: ", refname);
        return 1;
    }
    else if(extension_of(refname) == ".xyz")
    {
        log::info("mill calc rmsd: reading ", refname, " as a XYZ file...");
        XYZReader reader(refname);
        if(const auto first_frame = reader.read_frame())
        {
            for(const auto& particle : *first_frame)
            {
                ref.push_back(particle.position());
            }
        }
        log::info("mill calc rmsd: done. reference structure has ",
                        ref.size(), " particles.");
    }
    else
    {
        log::error("mill calc rmsd: invalid argument: ", refname);
        log::error(mode_calc_rmsd_usage());
        return 1;
    }

    const bool do_align = [&]{
        if(args.size() == 2) {return true;}
        return args.at(2) == "true";
    }();

    std::ofstream ofs("mill_rmsd.dat");
    ofs << "#t rmsd\n";

    if(do_align)
    {
        BestFit<typename scalar_type_of<vector_type>::type> bestfit;
        bestfit.set_reference(ref);
        for(std::size_t i=0; i<traj.size(); ++i)
        {
            ofs << i << ' ' << rmsd(ref, bestfit.fit(traj[i])) << '\n';
        }
    }
    else
    {
        for(std::size_t i=0; i<traj.size(); ++i)
        {
            ofs << i << ' ' << rmsd(ref, traj[i]) << '\n';
        }
    }
    return 0;
}

}//mill
<commit_msg>:children_crossing: enable to pass an argument<commit_after>#include "mode_calc_rmsd.hpp"

#include <mill/util/scalar_type_of.hpp>
#include <mill/util/file_extension.hpp>
#include <mill/util/cmdarg.hpp>
#include <mill/math/RMSDCalculator.hpp>
#include <mill/math/BestFitStructure.hpp>
#include <mill/pdb/PDBReader.hpp>
#include <mill/traj.hpp>
#include <fstream>

namespace mill
{

const char* mode_calc_rmsd_usage() noexcept
{
    return "usage: mill calc rmsd [traj file] [ref file]\n"
           "optinal args:\n"
           "    --align=(true|false) [by default, true]\n"
           "        If true (default), perform alignment by minimizing RMSD.\n"
           "        otherwise, it calculates RMSD without minimization.\n"
           "    --output=<filename>  [by default, \"mill_rmsd.dat\"]\n"
           "        output data file.\n";
}

int mode_calc_rmsd(std::deque<std::string_view> args)
{
    using vector_type = Vector<double, 3>;
    if(args.empty())
    {
        log::error("mill calc rmsd: too few arguments.");
        log::error(mode_calc_rmsd_usage());
        return 1;
    }

    // remove unordered argumnets
    const auto do_align = pop_argument<bool       >(args, "align" ).value_or(true);
    const auto output   = pop_argument<std::string>(args, "output").value_or("mill_rmsd.dat");

    const auto fname = args.front();
    if(fname == "help")
    {
        log::info(mode_calc_rmsd_usage());
        return 0;
    }

    if(fname.size() < 5)
    {
        log::error("mill calc rmsd: unknown file format: ", fname);
        log::error(mode_calc_rmsd_usage());
        return 1;
    }

    std::vector<std::vector<vector_type>> traj;

    if(extension_of(fname) == ".dcd" || extension_of(fname) == ".xyz")
    {
        log::info("mill calc rmsd: reading ", fname);
        for(const auto& snapshot : reader(fname))
        {
            std::vector<vector_type> ss; ss.reserve(snapshot.size());
            for(const auto& particle : snapshot)
            {
                ss.push_back(particle.position());
            }
            traj.push_back(std::move(ss));
        }
        log::info("mill calc rmsd: done. ", fname, " has ", traj.size(),
                        " snapshots.");
    }
    else
    {
        log::error("mill calc rmsd: unknown file format: ", fname);
        log::error(mode_calc_rmsd_usage());
        return 1;
    }

    const auto refname = args.at(1);
    std::vector<vector_type> ref;

    if(extension_of(refname) == ".pdb")
    {
        log::error("mill calc rmsd: unknown file format: ", refname);
        return 1;
    }
    else if(extension_of(refname) == ".xyz")
    {
        log::info("mill calc rmsd: reading ", refname, " as a XYZ file...");
        XYZReader reader(refname);
        if(const auto first_frame = reader.read_frame())
        {
            for(const auto& particle : *first_frame)
            {
                ref.push_back(particle.position());
            }
        }
        log::info("mill calc rmsd: done. reference structure has ",
                        ref.size(), " particles.");
    }
    else
    {
        log::error("mill calc rmsd: invalid argument: ", refname);
        log::error(mode_calc_rmsd_usage());
        return 1;
    }

    std::ofstream ofs(output);
    ofs << "#t rmsd\n";
    if(do_align)
    {
        BestFit<typename scalar_type_of<vector_type>::type> bestfit;
        bestfit.set_reference(ref);
        for(std::size_t i=0; i<traj.size(); ++i)
        {
            ofs << i << ' ' << rmsd(ref, bestfit.fit(traj[i])) << '\n';
        }
    }
    else
    {
        for(std::size_t i=0; i<traj.size(); ++i)
        {
            ofs << i << ' ' << rmsd(ref, traj[i]) << '\n';
        }
    }
    return 0;
}

}//mill
<|endoftext|>


<commit_before>#include <iostream>
#include <vector>

using namespace std;

long minimum(long left, long right){
    if (left<right) return left;
    else return right;

}

int minimum(vector<long>* nmbrs){
    long  min;
    for ( auto &i : *nmbrs ){
        if(min == NULL or i < min){
            min = i;
        }
        if (min == 0) {
            return min;
        }
    }
    return min;
}

int maximum(long left, long right){
    if (left>right) return left;
    else return right;
}

long damerau_levenshtein(string* left, string* right, long l_len, long r_len){

    if (minimum(r_len, l_len) == 0){
        return maximum(l_len, r_len);
    }

    vector<long> vals;

    if ((l_len > 1 and r_len > 1) and
            (left->at(l_len-1) == right->at(r_len-2)) and
            (left->at(l_len-2) == right->at(r_len-1))) {

        vals.push_back(damerau_levenshtein(left, right, l_len - 1, r_len) + 1);
        vals.push_back(damerau_levenshtein(left, right, l_len, r_len - 1) + 1);
        if (left->at(l_len-1) == right->at(r_len-1)) {
            vals.push_back(damerau_levenshtein(left, right , l_len - 1, r_len - 1));
        }
        else{
                vals.push_back(damerau_levenshtein(left, right , l_len - 1, r_len - 1) + 1);

            }
        vals.push_back(damerau_levenshtein(left, right , l_len - 2, r_len - 2) + 1);
        return minimum(&vals);
    }

    else{
        vals.push_back(damerau_levenshtein(left, right, l_len - 1, r_len) + 1);
        vals.push_back(damerau_levenshtein(left, right, l_len, r_len - 1) + 1);
        if (left->at(l_len-1) == right->at(r_len-1)) {
            vals.push_back(damerau_levenshtein(left, right, l_len, r_len - 1));
        }
        else {
            vals.push_back(damerau_levenshtein(left, right, l_len - 1, r_len - 1) + 1);

        }
        return minimum(&vals);
    }
}

int main(int argc, char* argv[]) {

    if (argc == 3) {
        string left, right;
        left = string(argv[1]);
        right = string(argv[2]);

        int dist = damerau_levenshtein(&left, &right, left.length(), right.length());
        cout << "The damerau levenshtein distance between " + left + " and " + right + " is " + to_string(dist) <<endl;
        return 0;
    } else {
        cout << "Only accepting two arguments" << endl;
        return -1;
    }
}<commit_msg>fixed and finished switch to length based<commit_after>#include <iostream>
#include <vector>

using namespace std;

long minimum(long left, long right){
    if (left<right) return left;
    else return right;

}

int minimum(vector<long>* nmbrs){
    long  min;
    for ( auto &i : *nmbrs ){
        if(min == NULL or i < min){
            min = i;
        }
        if (min == 0) {
            return min;
        }
    }
    return min;
}

int maximum(long left, long right){
    if (left>right) return left;
    else return right;
}

long damerau_levenshtein(string* left, string* right, long l_final_char_idx, long r_final_char_idx){

    if (minimum(l_final_char_idx, r_final_char_idx) == 0){
        return maximum(l_final_char_idx, r_final_char_idx);
    }

    vector<long> vals;

    if (( l_final_char_idx > 1 and  r_final_char_idx > 1) and
            (left->at(l_final_char_idx) == right->at(r_final_char_idx - 1)) and
            (left->at(l_final_char_idx -1 ) == right->at(r_final_char_idx))) {

        vals.push_back(damerau_levenshtein(left, right, l_final_char_idx -1 , r_final_char_idx) + 1);
        vals.push_back(damerau_levenshtein(left, right, l_final_char_idx, r_final_char_idx - 1) + 1);
        if (left->at(l_final_char_idx) == right->at(r_final_char_idx)) {
            vals.push_back(damerau_levenshtein(left, right , l_final_char_idx - 1, r_final_char_idx - 1));
        }
        else{
            vals.push_back(damerau_levenshtein(left, right , l_final_char_idx - 1, r_final_char_idx - 1) + 1);
        }
        vals.push_back(damerau_levenshtein(left, right , l_final_char_idx - 2, r_final_char_idx - 2) + 1);
        return minimum(&vals);
    }
    else{
        vals.push_back(damerau_levenshtein(left, right, l_final_char_idx - 1, r_final_char_idx) + 1);
        vals.push_back(damerau_levenshtein(left, right, l_final_char_idx, r_final_char_idx - 1) + 1);
        if (left->at(l_final_char_idx) == right->at(r_final_char_idx)) {
            vals.push_back(damerau_levenshtein(left, right, l_final_char_idx - 1, r_final_char_idx - 1));
        }
        else {
            vals.push_back(damerau_levenshtein(left, right, l_final_char_idx - 1, r_final_char_idx - 1) + 1);

        }
        return minimum(&vals);
    }
}

int main(int argc, char* argv[]) {

    if (argc == 3) {
        string left, right;
        left = string(argv[1]);
        right = string(argv[2]);

        int dist = damerau_levenshtein(&left, &right, left.length() - 1, right.length() - 1);
        cout << "The damerau levenshtein distance between " + left + " and " + right + " is " + to_string(dist) <<endl;
        return 0;
    } else {
        cout << "Only accepting two arguments" << endl;
        return -1;
    }
}<|endoftext|>