<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/p9_mss_scrub.C $    */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2016                        */
/* [+] 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 p9_mss_scrub.C
/// @brief Begin background scrub
///
// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 1
// *HWP Consumed by: FSP:HB

#include <fapi2.H>
#include <p9_mss_scrub.H>

#include <lib/dimm/rank.H>
#include <lib/mcbist/address.H>
#include <lib/mcbist/mcbist.H>
#include <lib/mcbist/patterns.H>
#include <lib/mcbist/memdiags.H>
#include <lib/mcbist/sim.H>
#include <lib/utils/count_dimm.H>

using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_MCA;
using fapi2::TARGET_TYPE_SYSTEM;
using fapi2::FAPI2_RC_SUCCESS;

///
/// @brief Begin background scrub
/// @param[in] i_target MCBIST
/// @return FAPI2_RC_SUCCESS iff ok
///
fapi2::ReturnCode p9_mss_scrub( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target )
{
    FAPI_INF("Start mss scrub");

    // If there are no DIMM we don't need to bother. In fact, we can't as we didn't setup
    // attributes for the PHY, etc.
    if (mss::count_dimm(i_target) == 0)
    {
        FAPI_INF("... skipping scrub for %s - no DIMM ...", mss::c_str(i_target));
        return fapi2::FAPI2_RC_SUCCESS;
    }

    // If we're running in the simulator, we want to only touch the addresses which training touched
    uint8_t is_sim = 0;
    bool l_poll_results = false;
    fapi2::buffer<uint64_t> l_status;

    // A small vector of addresses to poll during the polling loop
    static const std::vector<mss::poll_probe<fapi2::TARGET_TYPE_MCBIST>> l_probes =
    {
        {i_target, "mcbist current address", MCBIST_MCBMCATQ},
    };

    // We'll fill in the initial delay below
    mss::poll_parameters l_poll_parameters(0, 200, 10 * mss::DELAY_1MS, 200, 500);
    uint64_t l_memory_size = 0;

    FAPI_TRY( mss::eff_memory_size(i_target, l_memory_size) );
    l_poll_parameters.iv_initial_delay = mss::calculate_initial_delay(i_target, (l_memory_size * mss::BYTES_PER_GB));

    FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_IS_SIMULATION, fapi2::Target<TARGET_TYPE_SYSTEM>(), is_sim) );

    if (is_sim)
    {
        // Use some sort of pattern in sim in case the verification folks need to look for something
        // TK. Need a verification pattern. This is a not-good pattern for verification ... We don't really
        // have a good pattern for verification defined.
        FAPI_INF("running mss sim init in place of scrub");
        return mss::mcbist::sim::sf_init(i_target, mss::mcbist::PATTERN_0);
    }

    // In Cronus on hardware (which is how we got here - f/w doesn't call this) we want
    // to call sf_init (0's)
    // TK we need to check FIR given the way this is right now, we should adjust with better stop
    // conditions when we learn more about what we want to find in the lab
    FAPI_TRY( memdiags::sf_init(i_target, mss::mcbist::PATTERN_0) );

    // Poll for completion.
    l_poll_results = mss::poll(i_target, MCBIST_MCBISTFIRQ, l_poll_parameters,
                               [&l_status](const size_t poll_remaining,
                                           const fapi2::buffer<uint64_t>& stat_reg) -> bool
    {
        FAPI_DBG("mcbist firq 0x%llx, remaining: %d", stat_reg, poll_remaining);
        l_status = stat_reg;
        return l_status.getBit<MCBIST_MCBISTFIRQ_MCBIST_PROGRAM_COMPLETE>() == true;
    },
    l_probes);

    FAPI_ASSERT( l_poll_results == true,
                 fapi2::MSS_MEMDIAGS_SUPERFAST_INIT_FAILED_TO_INIT().set_TARGET(i_target),
                 "p9_mss_scrub (init) timedout %s", mss::c_str(i_target) );

fapi_try_exit:
    return fapi2::current_err;
}
<commit_msg>Change mss_scrub timeout to account for slow MCBIST<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/p9_mss_scrub.C $    */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2016                        */
/* [+] 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 p9_mss_scrub.C
/// @brief Begin background scrub
///
// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 1
// *HWP Consumed by: FSP:HB

#include <fapi2.H>
#include <p9_mss_scrub.H>

#include <lib/dimm/rank.H>
#include <lib/mcbist/address.H>
#include <lib/mcbist/mcbist.H>
#include <lib/mcbist/patterns.H>
#include <lib/mcbist/memdiags.H>
#include <lib/mcbist/sim.H>
#include <lib/utils/count_dimm.H>

using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_MCA;
using fapi2::TARGET_TYPE_SYSTEM;
using fapi2::FAPI2_RC_SUCCESS;

///
/// @brief Begin background scrub
/// @param[in] i_target MCBIST
/// @return FAPI2_RC_SUCCESS iff ok
///
fapi2::ReturnCode p9_mss_scrub( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target )
{
    FAPI_INF("Start mss scrub");

    // If there are no DIMM we don't need to bother. In fact, we can't as we didn't setup
    // attributes for the PHY, etc.
    if (mss::count_dimm(i_target) == 0)
    {
        FAPI_INF("... skipping scrub for %s - no DIMM ...", mss::c_str(i_target));
        return fapi2::FAPI2_RC_SUCCESS;
    }

    // If we're running in the simulator, we want to only touch the addresses which training touched
    uint8_t is_sim = 0;
    bool l_poll_results = false;
    fapi2::buffer<uint64_t> l_status;

    // A small vector of addresses to poll during the polling loop
    static const std::vector<mss::poll_probe<fapi2::TARGET_TYPE_MCBIST>> l_probes =
    {
        {i_target, "mcbist current address", MCBIST_MCBMCATQ},
    };

    // We'll fill in the initial delay below
    mss::poll_parameters l_poll_parameters(0, 200, 100 * mss::DELAY_1MS, 200, 500);
    uint64_t l_memory_size = 0;

    FAPI_TRY( mss::eff_memory_size(i_target, l_memory_size) );
    l_poll_parameters.iv_initial_delay = mss::calculate_initial_delay(i_target, (l_memory_size * mss::BYTES_PER_GB));

    FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_IS_SIMULATION, fapi2::Target<TARGET_TYPE_SYSTEM>(), is_sim) );

    if (is_sim)
    {
        // Use some sort of pattern in sim in case the verification folks need to look for something
        // TK. Need a verification pattern. This is a not-good pattern for verification ... We don't really
        // have a good pattern for verification defined.
        FAPI_INF("running mss sim init in place of scrub");
        return mss::mcbist::sim::sf_init(i_target, mss::mcbist::PATTERN_0);
    }

    // In Cronus on hardware (which is how we got here - f/w doesn't call this) we want
    // to call sf_init (0's)
    // TK we need to check FIR given the way this is right now, we should adjust with better stop
    // conditions when we learn more about what we want to find in the lab
    FAPI_TRY( memdiags::sf_init(i_target, mss::mcbist::PATTERN_0) );

    // Poll for completion.
    l_poll_results = mss::poll(i_target, MCBIST_MCBISTFIRQ, l_poll_parameters,
                               [&l_status](const size_t poll_remaining,
                                           const fapi2::buffer<uint64_t>& stat_reg) -> bool
    {
        FAPI_DBG("mcbist firq 0x%llx, remaining: %d", stat_reg, poll_remaining);
        l_status = stat_reg;
        return l_status.getBit<MCBIST_MCBISTFIRQ_MCBIST_PROGRAM_COMPLETE>() == true;
    },
    l_probes);

    FAPI_ASSERT( l_poll_results == true,
                 fapi2::MSS_MEMDIAGS_SUPERFAST_INIT_FAILED_TO_INIT().set_TARGET(i_target),
                 "p9_mss_scrub (init) timedout %s", mss::c_str(i_target) );

fapi_try_exit:
    return fapi2::current_err;
}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/p9_mss_scrub.C $    */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,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 p9_mss_scrub.C
/// @brief Begin background scrub
///
// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 1
// *HWP Consumed by: FSP:HB

#include <fapi2.H>
#include <p9_mss_scrub.H>

#include <lib/dimm/rank.H>
#include <lib/mcbist/address.H>
#include <lib/mcbist/mcbist.H>
#include <lib/mcbist/patterns.H>
#include <lib/mcbist/memdiags.H>
#include <lib/mcbist/sim.H>
#include <lib/utils/count_dimm.H>
#include <lib/fir/memdiags_fir.H>

using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_MCA;
using fapi2::TARGET_TYPE_SYSTEM;
using fapi2::FAPI2_RC_SUCCESS;

///
/// @brief Begin background scrub
/// @param[in] i_target MCBIST
/// @return FAPI2_RC_SUCCESS iff ok
///
fapi2::ReturnCode p9_mss_scrub( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target )
{
    FAPI_INF("Start mss scrub");

    // If there are no DIMM we don't need to bother. In fact, we can't as we didn't setup
    // attributes for the PHY, etc.
    if (mss::count_dimm(i_target) == 0)
    {
        FAPI_INF("... skipping scrub for %s - no DIMM ...", mss::c_str(i_target));
        return fapi2::FAPI2_RC_SUCCESS;
    }

    // If we're running in the simulator, we want to only touch the addresses which training touched
    uint8_t l_sim = 0;
    bool l_poll_results = false;
    fapi2::buffer<uint64_t> l_status;

    // A small vector of addresses to poll during the polling loop
    const std::vector<mss::poll_probe<fapi2::TARGET_TYPE_MCBIST>> l_probes =
    {
        {i_target, "mcbist current address", MCBIST_MCBMCATQ},
    };

    // We'll fill in the initial delay below
    mss::poll_parameters l_poll_parameters(0, 200, 100 * mss::DELAY_1MS, 200, 10000);
    uint64_t l_memory_size = 0;

    FAPI_TRY( mss::eff_memory_size(i_target, l_memory_size) );
    l_poll_parameters.iv_initial_delay = mss::calculate_initial_delay(i_target, (l_memory_size * mss::BYTES_PER_GB));

    FAPI_TRY( mss::is_simulation( l_sim) );

    if (l_sim)
    {
        fapi2::ReturnCode l_rc;

        // Use some sort of pattern in sim in case the verification folks need to look for something
        // TK. Need a verification pattern. This is a not-good pattern for verification ... We don't really
        // have a good pattern for verification defined.
        FAPI_INF("running mss sim init in place of scrub");
        l_rc = mss::mcbist::sim::sf_init(i_target, mss::mcbist::PATTERN_0);

        // Unmask firs and turn off FIFO mode before returning
        FAPI_TRY ( mss::unmask::after_memdiags( i_target ) );
        FAPI_TRY ( mss::unmask::after_background_scrub( i_target ) );
        FAPI_TRY ( mss::reset_reorder_queue_settings(i_target) );

        return l_rc;
    }

    // In Cronus on hardware (which is how we got here - f/w doesn't call this) we want
    // to call sf_init (0's)
    // TK we need to check FIR given the way this is right now, we should adjust with better stop
    // conditions when we learn more about what we want to find in the lab
    FAPI_TRY( memdiags::sf_init(i_target, mss::mcbist::PATTERN_0) );

    // Poll for completion.
    l_poll_results = mss::poll(i_target, MCBIST_MCBISTFIRQ, l_poll_parameters,
                               [&l_status](const size_t poll_remaining,
                                           const fapi2::buffer<uint64_t>& stat_reg) -> bool
    {
        FAPI_DBG("mcbist firq 0x%llx, remaining: %d", stat_reg, poll_remaining);
        l_status = stat_reg;
        return l_status.getBit<MCBIST_MCBISTFIRQ_MCBIST_PROGRAM_COMPLETE>() == true;
    },
    l_probes);

    FAPI_ASSERT( l_poll_results == true,
                 fapi2::MSS_MEMDIAGS_SUPERFAST_INIT_FAILED_TO_INIT().set_MCBIST_TARGET(i_target),
                 "p9_mss_scrub (init) timedout %s", mss::c_str(i_target) );

    // Unmask firs after memdiags and turn off FIFO mode
    FAPI_TRY ( mss::unmask::after_memdiags( i_target ) );
    FAPI_TRY ( mss::reset_reorder_queue_settings(i_target) );

    // Start background scrub
    FAPI_TRY ( memdiags::background_scrub( i_target,
                                           mss::mcbist::stop_conditions(),
                                           mss::mcbist::speed::BG_SCRUB,
                                           mss::mcbist::address() ) );

    // Unmask firs after background scrub is started
    FAPI_TRY ( mss::unmask::after_background_scrub( i_target ) );

fapi_try_exit:
    return fapi2::current_err;
}
<commit_msg>Changed API related to mss_memdiags ipl change<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/p9_mss_scrub.C $    */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,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 p9_mss_scrub.C
/// @brief Begin background scrub
///
// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 1
// *HWP Consumed by: FSP:HB

#include <fapi2.H>
#include <p9_mss_scrub.H>

#include <lib/dimm/rank.H>
#include <lib/mcbist/address.H>
#include <lib/mcbist/mcbist.H>
#include <lib/mcbist/patterns.H>
#include <lib/mcbist/memdiags.H>
#include <lib/mcbist/sim.H>
#include <lib/utils/count_dimm.H>
#include <lib/fir/memdiags_fir.H>

using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_MCA;
using fapi2::TARGET_TYPE_SYSTEM;
using fapi2::FAPI2_RC_SUCCESS;

///
/// @brief Begin background scrub
/// @param[in] i_target MCBIST
/// @return FAPI2_RC_SUCCESS iff ok
///
fapi2::ReturnCode p9_mss_scrub( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target )
{
    FAPI_INF("Start mss scrub");

    // If there are no DIMM we don't need to bother. In fact, we can't as we didn't setup
    // attributes for the PHY, etc.
    if (mss::count_dimm(i_target) == 0)
    {
        FAPI_INF("... skipping scrub for %s - no DIMM ...", mss::c_str(i_target));
        return fapi2::FAPI2_RC_SUCCESS;
    }

    // If we're running in the simulator, we want to only touch the addresses which training touched
    uint8_t l_sim = 0;
    bool l_poll_results = false;
    fapi2::buffer<uint64_t> l_status;

    // A small vector of addresses to poll during the polling loop
    const std::vector<mss::poll_probe<fapi2::TARGET_TYPE_MCBIST>> l_probes =
    {
        {i_target, "mcbist current address", MCBIST_MCBMCATQ},
    };

    // We'll fill in the initial delay below
    mss::poll_parameters l_poll_parameters(0, 200, 100 * mss::DELAY_1MS, 200, 10000);
    uint64_t l_memory_size = 0;

    FAPI_TRY( mss::eff_memory_size(i_target, l_memory_size) );
    l_poll_parameters.iv_initial_delay = mss::calculate_initial_delay(i_target, (l_memory_size * mss::BYTES_PER_GB));

    FAPI_TRY( mss::is_simulation( l_sim) );

    if (l_sim)
    {
        fapi2::ReturnCode l_rc;

        // Use some sort of pattern in sim in case the verification folks need to look for something
        // TK. Need a verification pattern. This is a not-good pattern for verification ... We don't really
        // have a good pattern for verification defined.
        FAPI_INF("running mss sim init in place of scrub");
        l_rc = mss::mcbist::sim::sf_init(i_target, mss::mcbist::PATTERN_0);

        // Unmask firs and turn off FIFO mode before returning
        FAPI_TRY ( mss::unmask::after_memdiags( i_target ) );
        FAPI_TRY ( mss::unmask::after_background_scrub( i_target ) );
        FAPI_TRY ( mss::reset_reorder_queue_settings(i_target) );

        return l_rc;
    }

    // In Cronus on hardware (which is how we got here - f/w doesn't call this) we want
    // to call sf_init (0's)
    // TK we need to check FIR given the way this is right now, we should adjust with better stop
    // conditions when we learn more about what we want to find in the lab
    FAPI_TRY( mss::memdiags::sf_init(i_target, mss::mcbist::PATTERN_0) );

    // Poll for completion.
    l_poll_results = mss::poll(i_target, MCBIST_MCBISTFIRQ, l_poll_parameters,
                               [&l_status](const size_t poll_remaining,
                                           const fapi2::buffer<uint64_t>& stat_reg) -> bool
    {
        FAPI_DBG("mcbist firq 0x%llx, remaining: %d", stat_reg, poll_remaining);
        l_status = stat_reg;
        return l_status.getBit<MCBIST_MCBISTFIRQ_MCBIST_PROGRAM_COMPLETE>() == true;
    },
    l_probes);

    FAPI_ASSERT( l_poll_results == true,
                 fapi2::MSS_MEMDIAGS_SUPERFAST_INIT_FAILED_TO_INIT().set_MCBIST_TARGET(i_target),
                 "p9_mss_scrub (init) timedout %s", mss::c_str(i_target) );

    // Unmask firs after memdiags and turn off FIFO mode
    FAPI_TRY ( mss::unmask::after_memdiags( i_target ) );
    FAPI_TRY ( mss::reset_reorder_queue_settings(i_target) );

    // Start background scrub
    FAPI_TRY ( mss::memdiags::background_scrub( i_target,
               mss::mcbist::stop_conditions(),
               mss::mcbist::speed::BG_SCRUB,
               mss::mcbist::address() ) );

    // Unmask firs after background scrub is started
    FAPI_TRY ( mss::unmask::after_background_scrub( i_target ) );

fapi_try_exit:
    return fapi2::current_err;
}
<|endoftext|>


<commit_before>#ifndef STAN_MATH_REV_MAT_FUN_TRACE_GEN_INV_QUAD_FORM_LDLT_HPP
#define STAN_MATH_REV_MAT_FUN_TRACE_GEN_INV_QUAD_FORM_LDLT_HPP

#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <stan/math/rev/core.hpp>
#include <stan/math/prim/scal/meta/is_var.hpp>
#include <stan/math/rev/scal/meta/is_var.hpp>
#include <stan/math/prim/mat/err/check_multiplicable.hpp>
#include <stan/math/prim/mat/err/check_square.hpp>
#include <stan/math/rev/mat/fun/trace_inv_quad_form_ldlt.hpp>
#include <type_traits>

namespace stan {
namespace math {

/**
 * Compute the trace of an inverse quadratic form.  I.E., this computes
 *       trace(D B^T A^-1 B)
 * where D is a square matrix and the LDLT_factor of A is provided.
 **/
template <typename T1, int R1, int C1, typename T2, int R2, int C2, typename T3,
          int R3, int C3>
inline
    typename std::enable_if<stan::is_var<T1>::value || stan::is_var<T2>::value
                                || stan::is_var<T3>::value,
                            var>::type
    trace_gen_inv_quad_form_ldlt(const Eigen::Matrix<T1, R1, C1> &D,
                                 const LDLT_factor<T2, R2, C2> &A,
                                 const Eigen::Matrix<T3, R3, C3> &B) {
  check_square("trace_gen_inv_quad_form_ldlt", "D", D);
  check_multiplicable("trace_gen_inv_quad_form_ldlt", "A", A, "B", B);
  check_multiplicable("trace_gen_inv_quad_form_ldlt", "B", B, "D", D);

  internal::trace_inv_quad_form_ldlt_impl<T2, R2, C2, T3, R3, C3> *_impl
      = new internal::trace_inv_quad_form_ldlt_impl<T2, R2, C2, T3, R3, C3>(D, A, B);

  return var(new trace_inv_quad_form_ldlt_vari<T2, R2, C2, T3, R3, C3>(_impl));
}

}  // namespace math
}  // namespace stan
#endif
<commit_msg>and another<commit_after>#ifndef STAN_MATH_REV_MAT_FUN_TRACE_GEN_INV_QUAD_FORM_LDLT_HPP
#define STAN_MATH_REV_MAT_FUN_TRACE_GEN_INV_QUAD_FORM_LDLT_HPP

#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <stan/math/rev/core.hpp>
#include <stan/math/prim/scal/meta/is_var.hpp>
#include <stan/math/rev/scal/meta/is_var.hpp>
#include <stan/math/prim/mat/err/check_multiplicable.hpp>
#include <stan/math/prim/mat/err/check_square.hpp>
#include <stan/math/rev/mat/fun/trace_inv_quad_form_ldlt.hpp>
#include <type_traits>

namespace stan {
namespace math {

/**
 * Compute the trace of an inverse quadratic form.  I.E., this computes
 *       trace(D B^T A^-1 B)
 * where D is a square matrix and the LDLT_factor of A is provided.
 **/
template <typename T1, int R1, int C1, typename T2, int R2, int C2, typename T3,
          int R3, int C3>
inline
    typename std::enable_if<stan::is_var<T1>::value || stan::is_var<T2>::value
                                || stan::is_var<T3>::value,
                            var>::type
    trace_gen_inv_quad_form_ldlt(const Eigen::Matrix<T1, R1, C1> &D,
                                 const LDLT_factor<T2, R2, C2> &A,
                                 const Eigen::Matrix<T3, R3, C3> &B) {
  check_square("trace_gen_inv_quad_form_ldlt", "D", D);
  check_multiplicable("trace_gen_inv_quad_form_ldlt", "A", A, "B", B);
  check_multiplicable("trace_gen_inv_quad_form_ldlt", "B", B, "D", D);

  internal::trace_inv_quad_form_ldlt_impl<T2, R2, C2, T3, R3, C3> *_impl
      = new internal::trace_inv_quad_form_ldlt_impl<T2, R2, C2, T3, R3, C3>(D, A, B);

  return var(new internal::trace_inv_quad_form_ldlt_vari<T2, R2, C2, T3, R3, C3>(_impl));
}

}  // namespace math
}  // namespace stan
#endif
<|endoftext|>


<commit_before>#include "WinRTMidi.h"
#include "WinRTMidiportWatcher.h"

using namespace WinRT;
using namespace Windows::Devices::Midi;
using namespace Windows::Storage::Streams;
using namespace std::placeholders;

/*****************************************************
    MidiInPortImpl
*****************************************************/

MidiInPortImpl::MidiInPortImpl()
    : mCallback(nullptr)
{
    mPort = ref new WinRTMidiInPort;
    mPort->SetMidiInCallback(std::bind(&MidiInPortImpl::MidiInCallback, this, _1, _2));
}

MidiInPortImpl::~MidiInPortImpl()
{

}

void MidiInPortImpl::OpenPort(unsigned int index)
{
    mPort->OpenPort(index);
}

void MidiInPortImpl::ClosePort()
{
    mPort->ClosePort();
}

void MidiInPortImpl::MidiInCallback(double timestamp, std::vector<unsigned char>* message)
{
    if (mCallback)
    {
        mCallback(this, timestamp, message);
    }
}

void MidiInPortImpl::RemoveCallback()
{
    mCallback = nullptr;
}

void MidiInPortImpl::SetCallback(const IMidiInCallbackType& callback)
{
    mCallback = callback;
}

void MidiInPortImpl::Destroy()
{
    delete this;
}

/*****************************************************
    WinRTMidiInPort
*****************************************************/

WinRTMidiInPort::WinRTMidiInPort()
    : mMessageReceivedCallback(nullptr)
{
}

WinRTMidiInPort::~WinRTMidiInPort()
{

}

//Blocks until port is open
void WinRTMidiInPort::OpenPort(int index)
{
    auto id = WinRTMidiInPortWatcher::getInstance()->GetPortId(index);
    OpenPort(id);
}

//Blocks until port is open
void WinRTMidiInPort::OpenPort(Platform::String^ id)
{
    try
    {
        mLastMessageTime = 0;
        mFirstMessage = true;
        auto task = MidiInPort::FromIdAsync(id);
        mMidiInPort = task->GetResults();
        mMidiInPort->MessageReceived += ref new Windows::Foundation::TypedEventHandler<MidiInPort ^, MidiMessageReceivedEventArgs ^>(this, &WinRTMidiInPort::OnMidiInMessageReceived);
    }
    catch (Platform::Exception^ ex)
    {

    }
}

void WinRTMidiInPort::ClosePort(void)
{
    mMidiInPort = nullptr;
}

void WinRTMidiInPort::OnMidiInMessageReceived(MidiInPort^ sender, MidiMessageReceivedEventArgs^ args)
{
    if (mMessageReceivedCallback)
    {
        if (mFirstMessage)
        {
            mFirstMessage = false;
            mLastMessageTime = args->Message->Timestamp.Duration;
        }

        double timestamp = (args->Message->Timestamp.Duration - mLastMessageTime) * .0001;
        mLastMessageTime = args->Message->Timestamp.Duration;

        auto buffer = args->Message->RawData;
        DataReader^ reader = DataReader::FromBuffer(buffer);
        mMidiMessage.resize(buffer->Length);
        reader->ReadBytes(Platform::ArrayReference<unsigned char>(&mMidiMessage[0], buffer->Length));

        mMessageReceivedCallback((double)timestamp, &mMidiMessage);
        mMidiMessage.clear();
    }
}

/*****************************************************
    WinRTMidiOutPort
*****************************************************/

WinRTMidiOutPort::WinRTMidiOutPort()
{
}

WinRTMidiOutPort::~WinRTMidiOutPort()
{
}

//Blocks until port is open
void WinRTMidiOutPort::OpenPort(Platform::String^ id)
{
    try
    {
        auto task = MidiOutPort::FromIdAsync(id);
        mMidiOutPort = task->GetResults();
    }
    catch (Platform::Exception^ ex)
    {

    }
}

void WinRTMidiOutPort::ClosePort(void)
{
    mMidiOutPort = nullptr;
}

<commit_msg>use async task to create midi in port<commit_after>#include "WinRTMidi.h"
#include "WinRTMidiportWatcher.h"
#include <ppltasks.h>

using namespace WinRT;
using namespace Windows::Devices::Midi;
using namespace Windows::Storage::Streams;
using namespace std::placeholders;
using namespace concurrency;

/*****************************************************
    MidiInPortImpl
*****************************************************/

MidiInPortImpl::MidiInPortImpl()
    : mCallback(nullptr)
{
    mPort = ref new WinRTMidiInPort;
    mPort->SetMidiInCallback(std::bind(&MidiInPortImpl::MidiInCallback, this, _1, _2));
}

MidiInPortImpl::~MidiInPortImpl()
{

}

void MidiInPortImpl::OpenPort(unsigned int index)
{
    mPort->OpenPort(index);
}

void MidiInPortImpl::ClosePort()
{
    mPort->ClosePort();
}

void MidiInPortImpl::MidiInCallback(double timestamp, std::vector<unsigned char>* message)
{
    if (mCallback)
    {
        mCallback(this, timestamp, message);
    }
}

void MidiInPortImpl::RemoveCallback()
{
    mCallback = nullptr;
}

void MidiInPortImpl::SetCallback(const IMidiInCallbackType& callback)
{
    mCallback = callback;
}

void MidiInPortImpl::Destroy()
{
    delete this;
}

/*****************************************************
    WinRTMidiInPort
*****************************************************/

WinRTMidiInPort::WinRTMidiInPort()
    : mMessageReceivedCallback(nullptr)
{
}

WinRTMidiInPort::~WinRTMidiInPort()
{

}

//Blocks until port is open
void WinRTMidiInPort::OpenPort(int index)
{
    auto id = WinRTMidiInPortWatcher::getInstance()->GetPortId(index);
    OpenPort(id);
}

//Blocks until port is open
void WinRTMidiInPort::OpenPort(Platform::String^ id)
{
    mLastMessageTime = 0;
    mFirstMessage = true;
    auto task = create_task(MidiInPort::FromIdAsync(id));

    // wait for port to be created
    task.wait();

    // get results
    try
    {
        mMidiInPort = task.get();
        mMidiInPort->MessageReceived += ref new Windows::Foundation::TypedEventHandler<MidiInPort ^, MidiMessageReceivedEventArgs ^>(this, &WinRTMidiInPort::OnMidiInMessageReceived);
    }
    catch (Platform::Exception^ ex)
    {

    }
}

void WinRTMidiInPort::ClosePort(void)
{
    mMidiInPort = nullptr;
}

void WinRTMidiInPort::OnMidiInMessageReceived(MidiInPort^ sender, MidiMessageReceivedEventArgs^ args)
{
    if (mMessageReceivedCallback)
    {
        if (mFirstMessage)
        {
            mFirstMessage = false;
            mLastMessageTime = args->Message->Timestamp.Duration;
        }

        double timestamp = (args->Message->Timestamp.Duration - mLastMessageTime) * .0001;
        mLastMessageTime = args->Message->Timestamp.Duration;

        auto buffer = args->Message->RawData;
        DataReader^ reader = DataReader::FromBuffer(buffer);
        mMidiMessage.resize(buffer->Length);
        reader->ReadBytes(Platform::ArrayReference<unsigned char>(&mMidiMessage[0], buffer->Length));

        mMessageReceivedCallback((double)timestamp, &mMidiMessage);
        mMidiMessage.clear();
    }
}

/*****************************************************
    WinRTMidiOutPort
*****************************************************/

WinRTMidiOutPort::WinRTMidiOutPort()
{
}

WinRTMidiOutPort::~WinRTMidiOutPort()
{
}

//Blocks until port is open
void WinRTMidiOutPort::OpenPort(Platform::String^ id)
{
    try
    {
        auto task = MidiOutPort::FromIdAsync(id);
        mMidiOutPort = task->GetResults();
    }
    catch (Platform::Exception^ ex)
    {

    }
}

void WinRTMidiOutPort::ClosePort(void)
{
    mMidiOutPort = nullptr;
}

<|endoftext|>


<commit_before>//
// Aspia Project
// Copyright (C) 2016-2022 Dmitry Chapyshev <dmitry@aspia.ru>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//

#include "client/ui/client_window.h"

#include "base/logging.h"
#include "base/net/address.h"
#include "build/build_config.h"
#include "client/config_factory.h"
#include "client/router_config_storage.h"
#include "client/ui/application.h"
#include "client/ui/client_settings.h"
#include "client/ui/client_settings_dialog.h"
#include "client/ui/desktop_config_dialog.h"
#include "client/ui/qt_desktop_window.h"
#include "client/ui/qt_file_manager_window.h"
#include "client/ui/qt_system_info_window.h"
#include "client/ui/update_settings_dialog.h"
#include "common/desktop_session_constants.h"
#include "common/ui/about_dialog.h"
#include "common/ui/language_action.h"
#include "common/ui/session_type.h"
#include "common/ui/update_dialog.h"
#include "common/ui/update_checker.h"

#include <QActionGroup>
#include <QDesktopServices>
#include <QMessageBox>
#include <QUrl>

namespace client {

ClientWindow::ClientWindow(QWidget* parent)
    : QMainWindow(parent)
{
    ClientSettings& settings = Application::instance()->settings();
    Application::instance()->setAttribute(
        Qt::AA_DontShowIconsInMenus, !settings.showIconsInMenus());

    ui.setupUi(this);
    setFixedHeight(sizeHint().height());

    createLanguageMenu(settings.locale());
    reloadSessionTypes();

    QComboBox* combo_address = ui.combo_address;

    combo_address->addItems(settings.addressList());
    combo_address->setCurrentIndex(0);

    ui.action_show_icons_in_menus->setChecked(settings.showIconsInMenus());
    connect(ui.action_show_icons_in_menus, &QAction::triggered, this, [=](bool enable)
    {
        Application* instance = Application::instance();
        instance->setAttribute(Qt::AA_DontShowIconsInMenus, !enable);
        instance->settings().setShowIconsInMenus(enable);
    });

    connect(combo_address->lineEdit(), &QLineEdit::returnPressed, this, &ClientWindow::connectToHost);

    connect(ui.menu_language, &QMenu::triggered, this, &ClientWindow::onLanguageChanged);
    connect(ui.action_settings, &QAction::triggered, this, &ClientWindow::onSettings);
    connect(ui.action_help, &QAction::triggered, this, &ClientWindow::onHelp);
    connect(ui.action_about, &QAction::triggered, this, &ClientWindow::onAbout);
    connect(ui.action_exit, &QAction::triggered, this, &ClientWindow::close);

    connect(ui.combo_session_type, QOverload<int>::of(&QComboBox::currentIndexChanged),
            this, &ClientWindow::sessionTypeChanged);

    connect(ui.button_session_config, &QPushButton::clicked,
            this, &ClientWindow::sessionConfigButtonPressed);

    connect(ui.button_connect, &QPushButton::clicked, this, &ClientWindow::connectToHost);

#if defined(OS_WIN)
    connect(ui.action_check_for_updates, &QAction::triggered, this, &ClientWindow::onCheckUpdates);
    connect(ui.action_update_settings, &QAction::triggered, this, [this]()
    {
        UpdateSettingsDialog(this).exec();
    });

    if (settings.checkUpdates())
    {
        common::UpdateChecker* checker = new common::UpdateChecker(this);

        checker->setUpdateServer(settings.updateServer());
        checker->setPackageName(QStringLiteral("client"));

        connect(checker, &common::UpdateChecker::finished, this, &ClientWindow::onUpdateChecked);
        connect(checker, &common::UpdateChecker::finished, checker, &common::UpdateChecker::deleteLater);

        checker->start();
    }
#else
    ui.action_check_for_updates->setVisible(false);
    ui.action_update_settings->setVisible(false);
#endif

    combo_address->setFocus();
}

ClientWindow::~ClientWindow() = default;

void ClientWindow::closeEvent(QCloseEvent* /* event */)
{
    QApplication::quit();
}

void ClientWindow::onLanguageChanged(QAction* action)
{
    QString new_locale = static_cast<common::LanguageAction*>(action)->locale();
    client::Application* application = client::Application::instance();

    application->settings().setLocale(new_locale);
    application->setLocale(new_locale);

    ui.retranslateUi(this);
    reloadSessionTypes();
}

void ClientWindow::onSettings()
{
    ClientSettingsDialog(this).exec();
}

void ClientWindow::onHelp()
{
    QDesktopServices::openUrl(QUrl(QStringLiteral("https://aspia.org/help")));
}

void ClientWindow::onAbout()
{
    common::AboutDialog(tr("Aspia Client"), this).exec();
}

void ClientWindow::sessionTypeChanged(int item_index)
{
    proto::SessionType session_type = static_cast<proto::SessionType>(
        ui.combo_session_type->itemData(item_index).toInt());

    switch (session_type)
    {
        case proto::SESSION_TYPE_DESKTOP_MANAGE:
        case proto::SESSION_TYPE_DESKTOP_VIEW:
            ui.button_session_config->setEnabled(true);
            break;

        default:
            ui.button_session_config->setEnabled(false);
            break;
    }

    Application::instance()->settings().setSessionType(session_type);
}

void ClientWindow::sessionConfigButtonPressed()
{
    proto::SessionType session_type = static_cast<proto::SessionType>(
        ui.combo_session_type->currentData().toInt());
    ClientSettings& settings = Application::instance()->settings();

    switch (session_type)
    {
        case proto::SESSION_TYPE_DESKTOP_MANAGE:
        {
            DesktopConfigDialog dialog(session_type,
                                       settings.desktopManageConfig(),
                                       common::kSupportedVideoEncodings,
                                       this);

            if (dialog.exec() == DesktopConfigDialog::Accepted)
                settings.setDesktopManageConfig(dialog.config());
        }
        break;

        case proto::SESSION_TYPE_DESKTOP_VIEW:
        {
            DesktopConfigDialog dialog(session_type,
                                       settings.desktopViewConfig(),
                                       common::kSupportedVideoEncodings,
                                       this);

            if (dialog.exec() == DesktopConfigDialog::Accepted)
                settings.setDesktopViewConfig(dialog.config());
        }
        break;

        default:
            break;
    }
}

void ClientWindow::connectToHost()
{
    RouterConfig router_config = RouterConfigStorage().routerConfig();
    Config config;

    QComboBox* combo_address = ui.combo_address;
    QString current_address = combo_address->currentText();

    bool host_id_entered = true;

    for (int i = 0; i < current_address.length(); ++i)
    {
        if (!current_address[i].isDigit())
        {
            host_id_entered = false;
            break;
        }
    }

    if (!host_id_entered)
    {
        LOG(LS_INFO) << "Direct connection selected";

        base::Address address = base::Address::fromString(
            current_address.toStdU16String(), DEFAULT_HOST_TCP_PORT);

        if (!address.isValid())
        {
            QMessageBox::warning(this,
                                 tr("Warning"),
                                 tr("An invalid computer address was entered."),
                                 QMessageBox::Ok);
            combo_address->setFocus();
            return;
        }

        config.address_or_id = address.host();
        config.port = address.port();
    }
    else
    {
        LOG(LS_INFO) << "Relay connection selected";

        if (!router_config.isValid())
        {
            QMessageBox::warning(this,
                                 tr("Warning"),
                                 tr("A host ID was entered, but the router was not configured. "
                                    "You need to configure your router before connecting."),
                                 QMessageBox::Ok);
            return;
        }

        config.address_or_id = current_address.toStdU16String();
    }

    int current_index = combo_address->findText(current_address);
    if (current_index != -1)
        combo_address->removeItem(current_index);

    combo_address->insertItem(0, current_address);
    combo_address->setCurrentIndex(0);

    QStringList address_list;
    for (int i = 0; i < std::min(combo_address->count(), 15); ++i)
        address_list.append(combo_address->itemText(i));

    ClientSettings& settings = Application::instance()->settings();
    settings.setAddressList(address_list);

    if (host_id_entered)
        config.router_config = std::move(router_config);

    config.session_type = static_cast<proto::SessionType>(
        ui.combo_session_type->currentData().toInt());

    SessionWindow* session_window = nullptr;

    switch (config.session_type)
    {
        case proto::SESSION_TYPE_DESKTOP_MANAGE:
            session_window = new QtDesktopWindow(config.session_type, settings.desktopManageConfig());
            break;

        case proto::SESSION_TYPE_DESKTOP_VIEW:
            session_window = new QtDesktopWindow(config.session_type, settings.desktopViewConfig());
            break;

        case proto::SESSION_TYPE_FILE_TRANSFER:
            session_window = new client::QtFileManagerWindow();
            break;

        case proto::SESSION_TYPE_SYSTEM_INFO:
            session_window = new client::QtSystemInfoWindow();
            break;

        case proto::SESSION_TYPE_TEXT_CHAT:
            // TODO: Implement me!
            break;

        default:
            NOTREACHED();
            break;
    }

    if (!session_window)
        return;

    session_window->setAttribute(Qt::WA_DeleteOnClose);
    if (!session_window->connectToHost(config))
        session_window->close();
}

void ClientWindow::onCheckUpdates()
{
#if defined(OS_WIN)
    common::UpdateDialog(Application::instance()->settings().updateServer(),
                         QStringLiteral("client"),
                         this).exec();
#endif
}

void ClientWindow::onUpdateChecked(const QByteArray& result)
{
    common::UpdateInfo update_info = common::UpdateInfo::fromXml(result);
    if (!update_info.isValid() || !update_info.hasUpdate())
        return;

    base::Version current_version(ASPIA_VERSION_MAJOR, ASPIA_VERSION_MINOR, ASPIA_VERSION_PATCH);

    if (update_info.version() > current_version)
        common::UpdateDialog(update_info, this).exec();
}

void ClientWindow::createLanguageMenu(const QString& current_locale)
{
    QActionGroup* language_group = new QActionGroup(this);

    for (const auto& locale : qt_base::Application::instance()->localeList())
    {
        common::LanguageAction* action_language =
            new common::LanguageAction(locale.first, locale.second, this);

        action_language->setActionGroup(language_group);
        action_language->setCheckable(true);

        if (current_locale == locale.first)
            action_language->setChecked(true);

        ui.menu_language->addAction(action_language);
    }
}

void ClientWindow::reloadSessionTypes()
{
    proto::SessionType current_session_type = Application::instance()->settings().sessionType();
    QComboBox* combobox = ui.combo_session_type;

    auto add_session = [=](const QString& icon, proto::SessionType session_type)
    {
        combobox->addItem(QIcon(icon),
                          common::sessionTypeToLocalizedString(session_type),
                          QVariant(session_type));
    };

    combobox->clear();

    add_session(QStringLiteral(":/img/monitor-keyboard.png"), proto::SESSION_TYPE_DESKTOP_MANAGE);
    add_session(QStringLiteral(":/img/monitor.png"), proto::SESSION_TYPE_DESKTOP_VIEW);
    add_session(QStringLiteral(":/img/folder-stand.png"), proto::SESSION_TYPE_FILE_TRANSFER);
    add_session(QStringLiteral(":/img/computer_info.png"), proto::SESSION_TYPE_SYSTEM_INFO);
    add_session(QStringLiteral(":/img/text_chat.png"), proto::SESSION_TYPE_TEXT_CHAT);

    int item_index = combobox->findData(QVariant(current_session_type));
    if (item_index != -1)
    {
        combobox->setCurrentIndex(item_index);
        sessionTypeChanged(item_index);
    }
}

} // namespace client
<commit_msg>Disable unimplemented feature.<commit_after>//
// Aspia Project
// Copyright (C) 2016-2022 Dmitry Chapyshev <dmitry@aspia.ru>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//

#include "client/ui/client_window.h"

#include "base/logging.h"
#include "base/net/address.h"
#include "build/build_config.h"
#include "client/config_factory.h"
#include "client/router_config_storage.h"
#include "client/ui/application.h"
#include "client/ui/client_settings.h"
#include "client/ui/client_settings_dialog.h"
#include "client/ui/desktop_config_dialog.h"
#include "client/ui/qt_desktop_window.h"
#include "client/ui/qt_file_manager_window.h"
#include "client/ui/qt_system_info_window.h"
#include "client/ui/update_settings_dialog.h"
#include "common/desktop_session_constants.h"
#include "common/ui/about_dialog.h"
#include "common/ui/language_action.h"
#include "common/ui/session_type.h"
#include "common/ui/update_dialog.h"
#include "common/ui/update_checker.h"

#include <QActionGroup>
#include <QDesktopServices>
#include <QMessageBox>
#include <QUrl>

namespace client {

ClientWindow::ClientWindow(QWidget* parent)
    : QMainWindow(parent)
{
    ClientSettings& settings = Application::instance()->settings();
    Application::instance()->setAttribute(
        Qt::AA_DontShowIconsInMenus, !settings.showIconsInMenus());

    ui.setupUi(this);
    setFixedHeight(sizeHint().height());

    createLanguageMenu(settings.locale());
    reloadSessionTypes();

    QComboBox* combo_address = ui.combo_address;

    combo_address->addItems(settings.addressList());
    combo_address->setCurrentIndex(0);

    ui.action_show_icons_in_menus->setChecked(settings.showIconsInMenus());
    connect(ui.action_show_icons_in_menus, &QAction::triggered, this, [=](bool enable)
    {
        Application* instance = Application::instance();
        instance->setAttribute(Qt::AA_DontShowIconsInMenus, !enable);
        instance->settings().setShowIconsInMenus(enable);
    });

    connect(combo_address->lineEdit(), &QLineEdit::returnPressed, this, &ClientWindow::connectToHost);

    connect(ui.menu_language, &QMenu::triggered, this, &ClientWindow::onLanguageChanged);
    connect(ui.action_settings, &QAction::triggered, this, &ClientWindow::onSettings);
    connect(ui.action_help, &QAction::triggered, this, &ClientWindow::onHelp);
    connect(ui.action_about, &QAction::triggered, this, &ClientWindow::onAbout);
    connect(ui.action_exit, &QAction::triggered, this, &ClientWindow::close);

    connect(ui.combo_session_type, QOverload<int>::of(&QComboBox::currentIndexChanged),
            this, &ClientWindow::sessionTypeChanged);

    connect(ui.button_session_config, &QPushButton::clicked,
            this, &ClientWindow::sessionConfigButtonPressed);

    connect(ui.button_connect, &QPushButton::clicked, this, &ClientWindow::connectToHost);

#if defined(OS_WIN)
    connect(ui.action_check_for_updates, &QAction::triggered, this, &ClientWindow::onCheckUpdates);
    connect(ui.action_update_settings, &QAction::triggered, this, [this]()
    {
        UpdateSettingsDialog(this).exec();
    });

    if (settings.checkUpdates())
    {
        common::UpdateChecker* checker = new common::UpdateChecker(this);

        checker->setUpdateServer(settings.updateServer());
        checker->setPackageName(QStringLiteral("client"));

        connect(checker, &common::UpdateChecker::finished, this, &ClientWindow::onUpdateChecked);
        connect(checker, &common::UpdateChecker::finished, checker, &common::UpdateChecker::deleteLater);

        checker->start();
    }
#else
    ui.action_check_for_updates->setVisible(false);
    ui.action_update_settings->setVisible(false);
#endif

    combo_address->setFocus();
}

ClientWindow::~ClientWindow() = default;

void ClientWindow::closeEvent(QCloseEvent* /* event */)
{
    QApplication::quit();
}

void ClientWindow::onLanguageChanged(QAction* action)
{
    QString new_locale = static_cast<common::LanguageAction*>(action)->locale();
    client::Application* application = client::Application::instance();

    application->settings().setLocale(new_locale);
    application->setLocale(new_locale);

    ui.retranslateUi(this);
    reloadSessionTypes();
}

void ClientWindow::onSettings()
{
    ClientSettingsDialog(this).exec();
}

void ClientWindow::onHelp()
{
    QDesktopServices::openUrl(QUrl(QStringLiteral("https://aspia.org/help")));
}

void ClientWindow::onAbout()
{
    common::AboutDialog(tr("Aspia Client"), this).exec();
}

void ClientWindow::sessionTypeChanged(int item_index)
{
    proto::SessionType session_type = static_cast<proto::SessionType>(
        ui.combo_session_type->itemData(item_index).toInt());

    switch (session_type)
    {
        case proto::SESSION_TYPE_DESKTOP_MANAGE:
        case proto::SESSION_TYPE_DESKTOP_VIEW:
            ui.button_session_config->setEnabled(true);
            break;

        default:
            ui.button_session_config->setEnabled(false);
            break;
    }

    Application::instance()->settings().setSessionType(session_type);
}

void ClientWindow::sessionConfigButtonPressed()
{
    proto::SessionType session_type = static_cast<proto::SessionType>(
        ui.combo_session_type->currentData().toInt());
    ClientSettings& settings = Application::instance()->settings();

    switch (session_type)
    {
        case proto::SESSION_TYPE_DESKTOP_MANAGE:
        {
            DesktopConfigDialog dialog(session_type,
                                       settings.desktopManageConfig(),
                                       common::kSupportedVideoEncodings,
                                       this);

            if (dialog.exec() == DesktopConfigDialog::Accepted)
                settings.setDesktopManageConfig(dialog.config());
        }
        break;

        case proto::SESSION_TYPE_DESKTOP_VIEW:
        {
            DesktopConfigDialog dialog(session_type,
                                       settings.desktopViewConfig(),
                                       common::kSupportedVideoEncodings,
                                       this);

            if (dialog.exec() == DesktopConfigDialog::Accepted)
                settings.setDesktopViewConfig(dialog.config());
        }
        break;

        default:
            break;
    }
}

void ClientWindow::connectToHost()
{
    RouterConfig router_config = RouterConfigStorage().routerConfig();
    Config config;

    QComboBox* combo_address = ui.combo_address;
    QString current_address = combo_address->currentText();

    bool host_id_entered = true;

    for (int i = 0; i < current_address.length(); ++i)
    {
        if (!current_address[i].isDigit())
        {
            host_id_entered = false;
            break;
        }
    }

    if (!host_id_entered)
    {
        LOG(LS_INFO) << "Direct connection selected";

        base::Address address = base::Address::fromString(
            current_address.toStdU16String(), DEFAULT_HOST_TCP_PORT);

        if (!address.isValid())
        {
            QMessageBox::warning(this,
                                 tr("Warning"),
                                 tr("An invalid computer address was entered."),
                                 QMessageBox::Ok);
            combo_address->setFocus();
            return;
        }

        config.address_or_id = address.host();
        config.port = address.port();
    }
    else
    {
        LOG(LS_INFO) << "Relay connection selected";

        if (!router_config.isValid())
        {
            QMessageBox::warning(this,
                                 tr("Warning"),
                                 tr("A host ID was entered, but the router was not configured. "
                                    "You need to configure your router before connecting."),
                                 QMessageBox::Ok);
            return;
        }

        config.address_or_id = current_address.toStdU16String();
    }

    int current_index = combo_address->findText(current_address);
    if (current_index != -1)
        combo_address->removeItem(current_index);

    combo_address->insertItem(0, current_address);
    combo_address->setCurrentIndex(0);

    QStringList address_list;
    for (int i = 0; i < std::min(combo_address->count(), 15); ++i)
        address_list.append(combo_address->itemText(i));

    ClientSettings& settings = Application::instance()->settings();
    settings.setAddressList(address_list);

    if (host_id_entered)
        config.router_config = std::move(router_config);

    config.session_type = static_cast<proto::SessionType>(
        ui.combo_session_type->currentData().toInt());

    SessionWindow* session_window = nullptr;

    switch (config.session_type)
    {
        case proto::SESSION_TYPE_DESKTOP_MANAGE:
            session_window = new QtDesktopWindow(config.session_type, settings.desktopManageConfig());
            break;

        case proto::SESSION_TYPE_DESKTOP_VIEW:
            session_window = new QtDesktopWindow(config.session_type, settings.desktopViewConfig());
            break;

        case proto::SESSION_TYPE_FILE_TRANSFER:
            session_window = new client::QtFileManagerWindow();
            break;

        case proto::SESSION_TYPE_SYSTEM_INFO:
            session_window = new client::QtSystemInfoWindow();
            break;

        case proto::SESSION_TYPE_TEXT_CHAT:
            // TODO: Implement me!
            break;

        default:
            NOTREACHED();
            break;
    }

    if (!session_window)
        return;

    session_window->setAttribute(Qt::WA_DeleteOnClose);
    if (!session_window->connectToHost(config))
        session_window->close();
}

void ClientWindow::onCheckUpdates()
{
#if defined(OS_WIN)
    common::UpdateDialog(Application::instance()->settings().updateServer(),
                         QStringLiteral("client"),
                         this).exec();
#endif
}

void ClientWindow::onUpdateChecked(const QByteArray& result)
{
    common::UpdateInfo update_info = common::UpdateInfo::fromXml(result);
    if (!update_info.isValid() || !update_info.hasUpdate())
        return;

    base::Version current_version(ASPIA_VERSION_MAJOR, ASPIA_VERSION_MINOR, ASPIA_VERSION_PATCH);

    if (update_info.version() > current_version)
        common::UpdateDialog(update_info, this).exec();
}

void ClientWindow::createLanguageMenu(const QString& current_locale)
{
    QActionGroup* language_group = new QActionGroup(this);

    for (const auto& locale : qt_base::Application::instance()->localeList())
    {
        common::LanguageAction* action_language =
            new common::LanguageAction(locale.first, locale.second, this);

        action_language->setActionGroup(language_group);
        action_language->setCheckable(true);

        if (current_locale == locale.first)
            action_language->setChecked(true);

        ui.menu_language->addAction(action_language);
    }
}

void ClientWindow::reloadSessionTypes()
{
    proto::SessionType current_session_type = Application::instance()->settings().sessionType();
    QComboBox* combobox = ui.combo_session_type;

    auto add_session = [=](const QString& icon, proto::SessionType session_type)
    {
        combobox->addItem(QIcon(icon),
                          common::sessionTypeToLocalizedString(session_type),
                          QVariant(session_type));
    };

    combobox->clear();

    add_session(QStringLiteral(":/img/monitor-keyboard.png"), proto::SESSION_TYPE_DESKTOP_MANAGE);
    add_session(QStringLiteral(":/img/monitor.png"), proto::SESSION_TYPE_DESKTOP_VIEW);
    add_session(QStringLiteral(":/img/folder-stand.png"), proto::SESSION_TYPE_FILE_TRANSFER);
    add_session(QStringLiteral(":/img/computer_info.png"), proto::SESSION_TYPE_SYSTEM_INFO);
    //add_session(QStringLiteral(":/img/text_chat.png"), proto::SESSION_TYPE_TEXT_CHAT);

    int item_index = combobox->findData(QVariant(current_session_type));
    if (item_index != -1)
    {
        combobox->setCurrentIndex(item_index);
        sessionTypeChanged(item_index);
    }
}

} // namespace client
<|endoftext|>


<commit_before>#include "scene/image_cache.h"

#include "stb/stb_image.h"

#include <algorithm>

namespace Lantern {

ImageCache::~ImageCache() {
	Clear();
}

uint ImageCache::AddImage(const char *filepath) {
	Image image;
	image.Data = stbi_load(filepath, &image.XSize, &image.YSize, &image.NumChannels, 0);

	m_images.push_back(std::move(image));

	return (uint)m_images.size() - 1;
}

float3 ImageCache::SampleImage(uint imageId, float2 texCoord) {
	Image *image = &m_images[imageId];

	// Closest sampling for now because it's simple
	std::size_t row = (uint)std::round(texCoord.x * (float)image->XSize);
	std::size_t column = (uint)std::round(texCoord.y * (float)image->YSize);

	std::size_t index = (row * image->XSize + column) * image->NumChannels;
	switch (image->NumChannels) {
	case 1:
	{
		float value = (float)image->Data[index] / 256.0f;
		return float3(value, value, value);
	}
	case 2:
		return float3((float)image->Data[index] / 256.0f, (float)image->Data[index + 1] / 256.0f, 0.0f);
	case 3:
	case 4:
		return float3((float)image->Data[index] / 256.0f, (float)image->Data[index + 1] / 256.0f, (float)image->Data[index + 2] / 256.0f);
	default:
		// Error. Return NaN
		return float3((float)std::nan(nullptr), (float)std::nan(nullptr), (float)std::nan(nullptr));
		break;
	}
}

void ImageCache::Clear() {
	for (Image &image : m_images) {
		stbi_image_free(image.Data);
	}

	m_images.clear();
}

}
<commit_msg>Swap row and column<commit_after>#include "scene/image_cache.h"

#include "stb/stb_image.h"

#include <algorithm>

namespace Lantern {

ImageCache::~ImageCache() {
	Clear();
}

uint ImageCache::AddImage(const char *filepath) {
	Image image;
	image.Data = stbi_load(filepath, &image.XSize, &image.YSize, &image.NumChannels, 0);

	m_images.push_back(std::move(image));

	return (uint)m_images.size() - 1;
}

float3 ImageCache::SampleImage(uint imageId, float2 texCoord) {
	Image *image = &m_images[imageId];

	// Closest sampling for now because it's simple
	std::size_t x = (uint)std::round(texCoord.x * (float)image->XSize);
	std::size_t y = (uint)std::round(texCoord.y * (float)image->YSize);

	std::size_t index = (y * image->XSize + x) * image->NumChannels;
	switch (image->NumChannels) {
	case 1:
	{
		float value = (float)image->Data[index] / 256.0f;
		return float3(value);
	}
	case 2:
		return float3((float)image->Data[index] / 256.0f, (float)image->Data[index + 1] / 256.0f, 0.0f);
	case 3:
	case 4:
		return float3((float)image->Data[index] / 256.0f, (float)image->Data[index + 1] / 256.0f, (float)image->Data[index + 2] / 256.0f);
	default:
		// Error. Return NaN
		return float3((float)std::nan(nullptr), (float)std::nan(nullptr), (float)std::nan(nullptr));
		break;
	}
}

void ImageCache::Clear() {
	for (Image &image : m_images) {
		stbi_image_free(image.Data);
	}

	m_images.clear();
}

}
<|endoftext|>


<commit_before>#include <iostream>

#include <boost/log/core.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/utility/setup/console.hpp>

#include "../src/routing/routed_wrapper.h"
#include "../src/structures/vroom/input/input.h"
#include "../src/structures/vroom/job.h"
#include "../src/structures/vroom/vehicle.h"
#include "../src/utils/exceptions.h"

void log_solution(const solution& sol) {
  std::cout << "Total cost: " << sol.summary.cost << std::endl;
  std::cout << "Unassigned: " << sol.summary.unassigned << std::endl;

  // Log unassigned jobs if any.
  std::cout << "Unassigned job ids: [";
  for (const auto& j : sol.unassigned) {
    std::cout << j.id << ", ";
  }
  std::cout << "]" << std::endl;

  // Describe routes in solution.
  for (const auto& route : sol.routes) {
    std::cout << "Steps for vehicle " << route.vehicle
              << " (cost: " << route.cost << ")" << std::endl;

    // Describe all route steps.
    for (const auto& step : route.steps) {
      std::string step_type;
      switch (step.type) {
      case TYPE::START:
        step_type = "Start";
        break;
      case TYPE::END:
        step_type = "End";
        break;
      case TYPE::JOB:
        step_type = "Job";
        break;
      }
      std::cout << step_type;

      // Add job ids.
      if (step.type == TYPE::JOB) {
        std::cout << " " << step.job;
      }

      // Add location if known.
      if (step.location.has_coordinates()) {
        std::cout << " - " << step.location.lon() << ";" << step.location.lat();
      }
      std::cout << std::endl;
    }
  }
}

std::unique_ptr<routed_wrapper> routing_wrapper() {
  // Create a wrapper for OSRM queries.
  return std::make_unique<routed_wrapper>("localhost", // OSRM server
                                          "5000",      // OSRM port
                                          "car"        // Profile
                                          );
}

void run_example_with_osrm() {
  input problem_instance(std::move(routing_wrapper()),
                         false); // Query for route geometry after solving.

  // Create one-dimension capacity restrictions to model the situation
  // where one vehicle can handle 4 jobs.
  amount_t vehicle_capacity(1);
  amount_t job_amount(1);
  vehicle_capacity[0] = 4;
  job_amount[0] = 1;

  // Define vehicles (use boost::none for no start or no end).
  location_t depot({2.35044, 48.71764});
  vehicle_t v1(1,                // id
               depot,            // start
               depot,            // end
               vehicle_capacity, // capacity
               {1, 14});         // skills
  problem_instance.add_vehicle(v1);

  vehicle_t v2(2,                // id
               depot,            // start
               depot,            // end
               vehicle_capacity, // capacity
               {2, 14});         // skills
  problem_instance.add_vehicle(v2);

  // Set jobs id, location, amount and required skills. Last two can
  // be omitted if no constraints are required.
  std::vector<job_t> jobs;
  jobs.push_back(job_t(1, coords_t({1.98935, 48.701}), job_amount, {1}));
  jobs.push_back(job_t(2, coords_t({2.03655, 48.61128}), job_amount, {1}));
  jobs.push_back(job_t(3, coords_t({2.39719, 49.07611}), job_amount, {2}));
  jobs.push_back(job_t(4, coords_t({2.41808, 49.22619}), job_amount, {2}));
  jobs.push_back(job_t(5, coords_t({2.28325, 48.5958}), job_amount, {14}));
  jobs.push_back(job_t(6, coords_t({2.89357, 48.90736}), job_amount, {14}));

  for (const auto& j : jobs) {
    problem_instance.add_job(j);
  }

  // Skills definitions set the following constraints:
  // - jobs 1 and 2 can only be served by vehicle 1
  // - jobs 3 and 4 can only be served by vehicle 2
  // - jobs 5 and 6 can be served by either one of the vehicles

  // Solve!
  try {
    auto sol = problem_instance.solve(2); // Use 2 threads.

    log_solution(sol);
  } catch (const custom_exception& e) {
    std::cerr << "[Error] " << e.get_message() << std::endl;
  }
}

void run_example_with_custom_matrix() {
  input problem_instance(std::move(routing_wrapper()),
                         false); // Query for route geometry after solving.

  // Define custom matrix and bypass OSRM call.
  matrix<cost_t> matrix_input({{0, 2713, 2218, 4317, 5698, 2191, 3528},
                               {2876, 0, 1109, 5198, 6361, 2963, 5385},
                               {2359, 1082, 0, 5797, 7178, 1883, 5008},
                               {4097, 5228, 5584, 0, 2236, 5511, 3669},
                               {5472, 6432, 6959, 2232, 0, 6886, 4581},
                               {2083, 2954, 1887, 5736, 7117, 0, 4593},
                               {3679, 5526, 5166, 3506, 4471, 4631, 0}});
  problem_instance.set_matrix(std::move(matrix_input));

  // Create one-dimension capacity restrictions to model the situation
  // where one vehicle can handle 4 jobs.
  amount_t vehicle_capacity(1);
  amount_t job_amount(1);
  vehicle_capacity[0] = 4;
  job_amount[0] = 1;

  // Define vehicles (use boost::none for no start or no end).
  location_t depot(0); // index in the provided matrix.

  vehicle_t v1(1,                // id
               depot,            // start
               depot,            // end
               vehicle_capacity, // capacity
               {1, 14});         // skills
  problem_instance.add_vehicle(v1);

  vehicle_t v2(2,                // id
               depot,            // start
               depot,            // end
               vehicle_capacity, // capacity
               {2, 14});         // skills
  problem_instance.add_vehicle(v2);

  // Set jobs id, index of location in the matrix (coordinates are
  // optional), amount and required skills. Last two can be omitted if
  // no constraints are required.
  std::vector<job_t> jobs;
  jobs.push_back(job_t(1, 1, job_amount, {1}));
  jobs.push_back(job_t(2, 2, job_amount, {1}));
  jobs.push_back(job_t(3, 3, job_amount, {2}));
  jobs.push_back(job_t(4, 4, job_amount, {2}));
  jobs.push_back(job_t(5, 5, job_amount, {14}));
  jobs.push_back(job_t(6, 6, job_amount, {14}));

  for (const auto& j : jobs) {
    problem_instance.add_job(j);
  }

  // Skills definitions set the following constraints:
  // - jobs 1 and 2 can only be served by vehicle 1
  // - jobs 3 and 4 can only be served by vehicle 2
  // - jobs 5 and 6 can be served by either one of the vehicles

  // Solve!
  try {
    auto sol = problem_instance.solve(2); // Use 2 threads.

    log_solution(sol);
  } catch (const custom_exception& e) {
    std::cerr << "[Error] " << e.get_message() << std::endl;
  }
}

int main() {
  // Log level.
  boost::log::core::get()->set_filter(boost::log::trivial::severity >=
                                      boost::log::trivial::error);

  run_example_with_osrm();
  // run_example_with_custom_matrix();

  return 0;
}
<commit_msg>Update libvroom.cpp example to display additional step info.<commit_after>#include <iostream>

#include <boost/log/core.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/utility/setup/console.hpp>

#include "../src/routing/routed_wrapper.h"
#include "../src/structures/vroom/input/input.h"
#include "../src/structures/vroom/job.h"
#include "../src/structures/vroom/vehicle.h"
#include "../src/utils/exceptions.h"

void log_solution(const solution& sol, bool geometry) {
  std::cout << "Total cost: " << sol.summary.cost << std::endl;
  std::cout << "Unassigned: " << sol.summary.unassigned << std::endl;

  // Log unassigned jobs if any.
  std::cout << "Unassigned job ids: [";
  for (const auto& j : sol.unassigned) {
    std::cout << j.id << ", ";
  }
  std::cout << "]" << std::endl;

  // Describe routes in solution.
  for (const auto& route : sol.routes) {
    std::cout << "Steps for vehicle " << route.vehicle
              << " (cost: " << route.cost;
    if (geometry) {
      std::cout << " - duration: " << route.duration;
      std::cout << " - distance: " << route.distance;
    }

    std::cout << ")" << std::endl;

    // Describe all route steps.
    for (const auto& step : route.steps) {
      std::string step_type;
      switch (step.type) {
      case TYPE::START:
        step_type = "Start";
        break;
      case TYPE::END:
        step_type = "End";
        break;
      case TYPE::JOB:
        step_type = "Job";
        break;
      }
      std::cout << step_type;

      // Add job ids.
      if (step.type == TYPE::JOB) {
        std::cout << " " << step.job;
      }

      // Add location if known.
      if (step.location.has_coordinates()) {
        std::cout << " - " << step.location.lon() << ";" << step.location.lat();
      }

      // Add extra step info if geometry is required.
      if (geometry) {
        std::cout << " - arrival: " << step.arrival;
        std::cout << " - distance: " << step.distance;
      }
      std::cout << std::endl;
    }
  }
}

std::unique_ptr<routed_wrapper> routing_wrapper() {
  // Create a wrapper for OSRM queries.
  return std::make_unique<routed_wrapper>("localhost", // OSRM server
                                          "5000",      // OSRM port
                                          "car"        // Profile
                                          );
}

void run_example_with_osrm() {
  bool GEOMETRY = true;

  input problem_instance(std::move(routing_wrapper()),
                         GEOMETRY); // Query for route geometry after solving.

  // Create one-dimension capacity restrictions to model the situation
  // where one vehicle can handle 4 jobs.
  amount_t vehicle_capacity(1);
  amount_t job_amount(1);
  vehicle_capacity[0] = 4;
  job_amount[0] = 1;

  // Define vehicles (use boost::none for no start or no end).
  location_t depot({2.35044, 48.71764});
  vehicle_t v1(1,                // id
               depot,            // start
               depot,            // end
               vehicle_capacity, // capacity
               {1, 14});         // skills
  problem_instance.add_vehicle(v1);

  vehicle_t v2(2,                // id
               depot,            // start
               depot,            // end
               vehicle_capacity, // capacity
               {2, 14});         // skills
  problem_instance.add_vehicle(v2);

  // Set jobs id, location, amount and required skills. Last two can
  // be omitted if no constraints are required.
  std::vector<job_t> jobs;
  jobs.push_back(job_t(1, coords_t({1.98935, 48.701}), job_amount, {1}));
  jobs.push_back(job_t(2, coords_t({2.03655, 48.61128}), job_amount, {1}));
  jobs.push_back(job_t(3, coords_t({2.39719, 49.07611}), job_amount, {2}));
  jobs.push_back(job_t(4, coords_t({2.41808, 49.22619}), job_amount, {2}));
  jobs.push_back(job_t(5, coords_t({2.28325, 48.5958}), job_amount, {14}));
  jobs.push_back(job_t(6, coords_t({2.89357, 48.90736}), job_amount, {14}));

  for (const auto& j : jobs) {
    problem_instance.add_job(j);
  }

  // Skills definitions set the following constraints:
  // - jobs 1 and 2 can only be served by vehicle 1
  // - jobs 3 and 4 can only be served by vehicle 2
  // - jobs 5 and 6 can be served by either one of the vehicles

  // Solve!
  try {
    auto sol = problem_instance.solve(2); // Use 2 threads.

    log_solution(sol, GEOMETRY);
  } catch (const custom_exception& e) {
    std::cerr << "[Error] " << e.get_message() << std::endl;
  }
}

void run_example_with_custom_matrix() {
  bool GEOMETRY = false;

  input problem_instance(std::move(routing_wrapper()),
                         GEOMETRY); // Query for route geometry after solving.

  // Define custom matrix and bypass OSRM call.
  matrix<cost_t> matrix_input({{0, 2713, 2218, 4317, 5698, 2191, 3528},
                               {2876, 0, 1109, 5198, 6361, 2963, 5385},
                               {2359, 1082, 0, 5797, 7178, 1883, 5008},
                               {4097, 5228, 5584, 0, 2236, 5511, 3669},
                               {5472, 6432, 6959, 2232, 0, 6886, 4581},
                               {2083, 2954, 1887, 5736, 7117, 0, 4593},
                               {3679, 5526, 5166, 3506, 4471, 4631, 0}});
  problem_instance.set_matrix(std::move(matrix_input));

  // Create one-dimension capacity restrictions to model the situation
  // where one vehicle can handle 4 jobs.
  amount_t vehicle_capacity(1);
  amount_t job_amount(1);
  vehicle_capacity[0] = 4;
  job_amount[0] = 1;

  // Define vehicles (use boost::none for no start or no end).
  location_t depot(0); // index in the provided matrix.

  vehicle_t v1(1,                // id
               depot,            // start
               depot,            // end
               vehicle_capacity, // capacity
               {1, 14});         // skills
  problem_instance.add_vehicle(v1);

  vehicle_t v2(2,                // id
               depot,            // start
               depot,            // end
               vehicle_capacity, // capacity
               {2, 14});         // skills
  problem_instance.add_vehicle(v2);

  // Set jobs id, index of location in the matrix (coordinates are
  // optional), amount and required skills. Last two can be omitted if
  // no constraints are required.
  std::vector<job_t> jobs;
  jobs.push_back(job_t(1, 1, job_amount, {1}));
  jobs.push_back(job_t(2, 2, job_amount, {1}));
  jobs.push_back(job_t(3, 3, job_amount, {2}));
  jobs.push_back(job_t(4, 4, job_amount, {2}));
  jobs.push_back(job_t(5, 5, job_amount, {14}));
  jobs.push_back(job_t(6, 6, job_amount, {14}));

  for (const auto& j : jobs) {
    problem_instance.add_job(j);
  }

  // Skills definitions set the following constraints:
  // - jobs 1 and 2 can only be served by vehicle 1
  // - jobs 3 and 4 can only be served by vehicle 2
  // - jobs 5 and 6 can be served by either one of the vehicles

  // Solve!
  try {
    auto sol = problem_instance.solve(2); // Use 2 threads.

    log_solution(sol, GEOMETRY);
  } catch (const custom_exception& e) {
    std::cerr << "[Error] " << e.get_message() << std::endl;
  }
}

int main() {
  // Log level.
  boost::log::core::get()->set_filter(boost::log::trivial::severity >=
                                      boost::log::trivial::error);

  run_example_with_osrm();
  // run_example_with_custom_matrix();

  return 0;
}
<|endoftext|>


<commit_before>#pragma once

#include <tudocomp/Algorithm.hpp>
#include <tudocomp/ds/TextDS.hpp>
#include <tudocomp/ds/ArrayMaxHeap.hpp>

#include <tudocomp/compressors/lzss/LZSSFactors.hpp>
#include <boost/heap/pairing_heap.hpp>

namespace tdc {
namespace lcpcomp {

/// Implements the original "Max LCP" selection strategy for LCPComp.
///
/// This strategy constructs a deque containing suffix array entries sorted
/// by their LCP length. The entry with the maximum LCP is selected and
/// overlapping suffices are removed from the deque.
///
/// This was the original naive approach in "Textkompression mithilfe von
/// Enhanced Suffix Arrays" (BA thesis, Patrick Dinklage, 2015).
class BoostHeap : public Algorithm {
private:
    typedef TextDS<> text_t;

public:
    inline static Meta meta() {
        Meta m("lcpcomp_comp", "heap");
        return m;
    }

    using Algorithm::Algorithm; //import constructor

    inline void factorize(text_t& text, const size_t threshold, lzss::FactorBuffer& factors) {

		// Construct SA, ISA and LCP
		env().begin_stat_phase("Construct text ds");
		text.require(text_t::SA | text_t::ISA | text_t::LCP);
		env().end_stat_phase();

        auto& sa = text.require_sa();
        auto& isa = text.require_isa();

        text.require_lcp();
        auto lcpp = text.release_lcp();
        auto lcp_datap = lcpp->relinquish();
        auto& lcp = *lcp_datap;

		struct LCPCompare {
			using lcp_t = decltype(lcp);
			lcp_t& m_lcp;
			LCPCompare(lcp_t& lcp) : m_lcp(lcp) {}

			bool operator()(const len_t i, const len_t j) const {
				return m_lcp[i] < m_lcp[j];
			}

		};

		LCPCompare comp(lcp);

        env().begin_stat_phase("Construct MaxLCPHeap");
		boost::heap::pairing_heap<len_t,boost::heap::compare<LCPCompare>> heap(comp);
		std::vector<decltype(heap)::handle_type> handles(lcp.size());

		handles[0].node_ = nullptr;
        for(size_t i = 1; i < lcp.size(); ++i) {
            if(lcp[i] >= threshold) handles[i] = heap.emplace(i);
			else handles[i].node_ = nullptr;
        }

        env().log_stat("entries", heap.size());
        env().end_stat_phase();

        //Factorize
        env().begin_stat_phase("Process MaxLCPHeap");

        while(heap.size() > 0) {
            //get suffix with longest LCP
            const len_t& m = heap.top();

            //generate factor
            const len_t fpos = sa[m];
            const len_t fsrc = sa[m-1];
            const len_t flen = lcp[m];

            factors.emplace_back(fpos, fsrc, flen);

            //remove overlapped entries
            for(size_t k = 0; k < flen; k++) {
                const len_t pos = isa[fpos + k];
				if(handles[pos].node_ == nullptr) continue;
                heap.erase(handles[pos]);
				handles[pos].node_ = nullptr;
            }

            //correct intersecting entries
            for(size_t k = 0; k < flen && fpos > k; k++) {
                size_t s = fpos - k - 1;
                size_t i = isa[s];
				if(handles[i].node_ != nullptr) {
                    if(s + lcp[i] > fpos) {
                        size_t l = fpos - s;
                        if(l >= threshold) {
							lcp[i] = l;
							heap.decrease(handles[i]);
                        } else {
							heap.erase(handles[i]);
							handles[i].node_ = nullptr;
                        }
                    }
                }
            }
        }

        env().end_stat_phase();

    }
};

}}

<commit_msg>let boostheap behave like plcp<commit_after>#pragma once

#include <tudocomp/Algorithm.hpp>
#include <tudocomp/ds/TextDS.hpp>
#include <tudocomp/ds/ArrayMaxHeap.hpp>

#include <tudocomp/compressors/lzss/LZSSFactors.hpp>
#include <boost/heap/pairing_heap.hpp>

namespace tdc {
namespace lcpcomp {

/// Implements the original "Max LCP" selection strategy for LCPComp.
///
/// This strategy constructs a deque containing suffix array entries sorted
/// by their LCP length. The entry with the maximum LCP is selected and
/// overlapping suffices are removed from the deque.
///
/// This was the original naive approach in "Textkompression mithilfe von
/// Enhanced Suffix Arrays" (BA thesis, Patrick Dinklage, 2015).
class BoostHeap : public Algorithm {
private:
    typedef TextDS<> text_t;

public:
    inline static Meta meta() {
        Meta m("lcpcomp_comp", "heap");
        return m;
    }

    using Algorithm::Algorithm; //import constructor

    inline void factorize(text_t& text, const size_t threshold, lzss::FactorBuffer& factors) {

		// Construct SA, ISA and LCP
		env().begin_stat_phase("Construct text ds");
		text.require(text_t::SA | text_t::ISA | text_t::LCP);
		env().end_stat_phase();

        auto& sa = text.require_sa();
        auto& isa = text.require_isa();

        text.require_lcp();
        auto lcpp = text.release_lcp();
        auto lcp_datap = lcpp->relinquish();
        auto& lcp = *lcp_datap;

		struct LCPCompare {
			using lcp_t = decltype(lcp);
			using sa_t = decltype(sa); //`text_t::isa_type;
			lcp_t& m_lcp;
			sa_t& m_sa;
			LCPCompare(lcp_t& lcp_, sa_t& sa_) : m_lcp(lcp_), m_sa(sa_) {}

			bool operator()(const len_t i, const len_t j) const {
				if(m_lcp[i] == m_lcp[j]) return m_sa[i] > m_sa[j];
				return m_lcp[i] < m_lcp[j];
			}

		};

		LCPCompare comp(lcp,sa);

        env().begin_stat_phase("Construct MaxLCPHeap");
		boost::heap::pairing_heap<len_t,boost::heap::compare<LCPCompare>> heap(comp);
		std::vector<decltype(heap)::handle_type> handles(lcp.size());

		handles[0].node_ = nullptr;
        for(size_t i = 1; i < lcp.size(); ++i) {
            if(lcp[i] >= threshold) handles[i] = heap.emplace(i);
			else handles[i].node_ = nullptr;
        }

        env().log_stat("entries", heap.size());
        env().end_stat_phase();

        //Factorize
        env().begin_stat_phase("Process MaxLCPHeap");

        while(heap.size() > 0) {
            //get suffix with longest LCP
            const len_t& m = heap.top();

            //generate factor
            const len_t fpos = sa[m];
            const len_t fsrc = sa[m-1];
            const len_t flen = lcp[m];

            factors.emplace_back(fpos, fsrc, flen);

            //remove overlapped entries
            for(size_t k = 0; k < flen; k++) {
                const len_t pos = isa[fpos + k];
				if(handles[pos].node_ == nullptr) continue;
                heap.erase(handles[pos]);
				handles[pos].node_ = nullptr;
            }

            //correct intersecting entries
            for(size_t k = 0; k < flen && fpos > k; k++) {
                size_t s = fpos - k - 1;
                size_t i = isa[s];
				if(handles[i].node_ != nullptr) {
                    if(s + lcp[i] > fpos) {
                        size_t l = fpos - s;
                        if(l >= threshold) {
							lcp[i] = l;
							heap.decrease(handles[i]);
                        } else {
							heap.erase(handles[i]);
							handles[i].node_ = nullptr;
                        }
                    }
                }
            }
        }

        env().end_stat_phase();

    }
};

}}

<|endoftext|>


<commit_before>/* Siconos is a program dedicated to modeling, simulation and control
 * of non smooth dynamical systems.
 *
 * Copyright 2018 INRIA.
 *
 * 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.
*/
/*! \file NewtonImpactRollingFrictionNSL.hpp
  Newton-Impact Non-Smooth Law
*/

#ifndef NEWTONIMPACTROLLINGFRICTIONNSLAW_H
#define NEWTONIMPACTROLLINGFRICTIONNSLAW_H

#include "NonSmoothLaw.hpp"

/** Newton Impact-Friction Non Smooth Law
 *
 */
class NewtonImpactRollingFrictionNSL : public NonSmoothLaw
{

private:
  /** serialization hooks
  */
  ACCEPT_SERIALIZATION(NewtonImpactRollingFrictionNSL);

  /** The Newton coefficient of restitution
   */
  double _en;
  double _et;
  /** friction coefficient */
  double _mu;

  /** friction coefficient */
  double _muR;

  /** default constructor
   */
  NewtonImpactRollingFrictionNSL();

public:

  /** basic constructor
   *  \param size size of the ns law
   */
  NewtonImpactRollingFrictionNSL(unsigned int size);

  /** constructor with the value of the NewtonImpactRollingFrictionNSL attributes
   *  \param en double : normal e coefficient
   *  \param et double : tangent e coefficient
   *  \param mu double : friction coefficient
   *  \param muR double : rolling friction coefficient
   *  \param size unsigned int: size of the ns law
   */
  NewtonImpactRollingFrictionNSL(double en, double et, double mu, double muR, unsigned int size);

  /** Destructor */
  ~NewtonImpactRollingFrictionNSL();

  /** check the ns law to see if it is verified
   *  \return a boolean value whioch determines if the NS Law is verified
   */
  bool isVerified(void) const;

  // GETTERS/SETTERS

  /** getter of en
   *  \return the value of en
   */
  inline double en() const
  {
    return _en;
  };

  /** setter of en
   *  \param newVal a double to set en
   */
  inline void setEn(double newVal)
  {
    _en = newVal;
  };

  /** getter of et
   *  \return the value of et
   */
  inline double et() const
  {
    return _et;
  };

  /** setter of et
   * \param newVal a double to set et
   */
  inline void setEt(double newVal)
  {
    _et = newVal;
  };

  /** getter of mu
   * \return the value of mu
   */
  inline double mu() const
  {
    return _mu;
  };

  /** getter of mu
   * \return the value of mu
   */
  inline double muR() const
  {
    return _muR;
  };

  /** setter of mu
   * \param newVal a double to set mu
   */
  inline void setMu(double newVal)
  {
    _mu = newVal;
  };

  /** setter of muR
   * \param newVal a double to set muR
   */
  inline void setMuR(double newVal)
  {
    _muR = newVal;
  };

  // OTHER FUNCTIONS

  /** print the data to the screen
   */
  void display() const;

  /** Visitors hook
   */
  ACCEPT_STD_VISITORS();

};
DEFINE_SPTR(NewtonImpactRollingFrictionNSL)
#endif // NewtonImpactRollingFrictionNSL_H
<commit_msg>[kernel] improve code quality following recommendation of Codacy<commit_after>/* Siconos is a program dedicated to modeling, simulation and control
 * of non smooth dynamical systems.
 *
 * Copyright 2018 INRIA.
 *
 * 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.
*/
/*! \file NewtonImpactRollingFrictionNSL.hpp
  Newton-Impact Non-Smooth Law
*/

#ifndef NEWTONIMPACTROLLINGFRICTIONNSLAW_H
#define NEWTONIMPACTROLLINGFRICTIONNSLAW_H

#include "NonSmoothLaw.hpp"

/** Newton Impact-Friction Non Smooth Law
 *
 */
class NewtonImpactRollingFrictionNSL : public NonSmoothLaw
{

private:
  /** serialization hooks
  */
  ACCEPT_SERIALIZATION(NewtonImpactRollingFrictionNSL);

  /** The Newton coefficient of restitution
   */
  double _en;
  double _et;
  /** friction coefficient */
  double _mu;

  /** friction coefficient */
  double _muR;

  /** default constructor
   */
  NewtonImpactRollingFrictionNSL();

public:

  /** basic constructor
   *  \param size size of the ns law
   */
  explicit NewtonImpactRollingFrictionNSL(unsigned int size);

  /** constructor with the value of the NewtonImpactRollingFrictionNSL attributes
   *  \param en double : normal e coefficient
   *  \param et double : tangent e coefficient
   *  \param mu double : friction coefficient
   *  \param muR double : rolling friction coefficient
   *  \param size unsigned int: size of the ns law
   */
  NewtonImpactRollingFrictionNSL(double en, double et, double mu, double muR, unsigned int size);

  /** Destructor */
  ~NewtonImpactRollingFrictionNSL();

  /** check the ns law to see if it is verified
   *  \return a boolean value whioch determines if the NS Law is verified
   */
  bool isVerified(void) const;

  // GETTERS/SETTERS

  /** getter of en
   *  \return the value of en
   */
  inline double en() const
  {
    return _en;
  };

  /** setter of en
   *  \param newVal a double to set en
   */
  inline void setEn(double newVal)
  {
    _en = newVal;
  };

  /** getter of et
   *  \return the value of et
   */
  inline double et() const
  {
    return _et;
  };

  /** setter of et
   * \param newVal a double to set et
   */
  inline void setEt(double newVal)
  {
    _et = newVal;
  };

  /** getter of mu
   * \return the value of mu
   */
  inline double mu() const
  {
    return _mu;
  };

  /** getter of mu
   * \return the value of mu
   */
  inline double muR() const
  {
    return _muR;
  };

  /** setter of mu
   * \param newVal a double to set mu
   */
  inline void setMu(double newVal)
  {
    _mu = newVal;
  };

  /** setter of muR
   * \param newVal a double to set muR
   */
  inline void setMuR(double newVal)
  {
    _muR = newVal;
  };

  // OTHER FUNCTIONS

  /** print the data to the screen
   */
  void display() const;

  /** Visitors hook
   */
  ACCEPT_STD_VISITORS();

};
DEFINE_SPTR(NewtonImpactRollingFrictionNSL)
#endif // NewtonImpactRollingFrictionNSL_H
<|endoftext|>